mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-29 08:26:37 +01:00
MaterialManager and MaterialGroup refactor
- Material manager builder - No more overload render method/IProgramCallback - MaterialRenderers accept a Program consumer instead
This commit is contained in:
parent
e4a72544ea
commit
52e6d64bd9
7 changed files with 62 additions and 69 deletions
|
@ -30,7 +30,7 @@ import net.minecraftforge.fml.common.Mod;
|
||||||
@Mod.EventBusSubscriber(Dist.CLIENT)
|
@Mod.EventBusSubscriber(Dist.CLIENT)
|
||||||
public class InstancedRenderDispatcher {
|
public class InstancedRenderDispatcher {
|
||||||
|
|
||||||
private static final WorldAttached<MaterialManager<WorldProgram>> materialManagers = new WorldAttached<>($ -> new MaterialManager<>(Contexts.WORLD));
|
private static final WorldAttached<MaterialManager<WorldProgram>> materialManagers = new WorldAttached<>($ -> MaterialManager.builder(Contexts.WORLD).build());
|
||||||
|
|
||||||
private static final WorldAttached<InstanceManager<Entity>> entityInstanceManager = new WorldAttached<>(world -> new EntityInstanceManager(materialManagers.get(world)));
|
private static final WorldAttached<InstanceManager<Entity>> entityInstanceManager = new WorldAttached<>(world -> new EntityInstanceManager(materialManagers.get(world)));
|
||||||
private static final WorldAttached<InstanceManager<TileEntity>> tileInstanceManager = new WorldAttached<>(world -> new TileInstanceManager(materialManagers.get(world)));
|
private static final WorldAttached<InstanceManager<TileEntity>> tileInstanceManager = new WorldAttached<>(world -> new TileInstanceManager(materialManagers.get(world)));
|
||||||
|
|
|
@ -6,10 +6,8 @@ import java.util.Map;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||||
import com.jozufozu.flywheel.backend.state.IRenderState;
|
import com.jozufozu.flywheel.backend.state.IRenderState;
|
||||||
import com.jozufozu.flywheel.core.shader.IProgramCallback;
|
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
|
|
||||||
public class MaterialGroup<P extends WorldProgram> {
|
public class MaterialGroup<P extends WorldProgram> {
|
||||||
|
@ -26,12 +24,16 @@ public class MaterialGroup<P extends WorldProgram> {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(Matrix4f viewProjection, double camX, double camY, double camZ, IProgramCallback<P> callback) {
|
public void render(Matrix4f viewProjection, double camX, double camY, double camZ) {
|
||||||
for (MaterialRenderer<P> renderer : renderers) {
|
for (MaterialRenderer<P> renderer : renderers) {
|
||||||
renderer.render(viewProjection, camX, camY, camZ, callback);
|
renderer.render(viewProjection, camX, camY, camZ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setup(P program) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <D extends InstanceData> InstanceMaterial<D> material(MaterialSpec<D> spec) {
|
public <D extends InstanceData> InstanceMaterial<D> material(MaterialSpec<D> spec) {
|
||||||
return (InstanceMaterial<D>) materials.computeIfAbsent(spec, this::createInstanceMaterial);
|
return (InstanceMaterial<D>) materials.computeIfAbsent(spec, this::createInstanceMaterial);
|
||||||
|
@ -40,7 +42,7 @@ public class MaterialGroup<P extends WorldProgram> {
|
||||||
private InstanceMaterial<?> createInstanceMaterial(MaterialSpec<?> type) {
|
private InstanceMaterial<?> createInstanceMaterial(MaterialSpec<?> type) {
|
||||||
InstanceMaterial<?> material = new InstanceMaterial<>(owner::getOriginCoordinate, type);
|
InstanceMaterial<?> material = new InstanceMaterial<>(owner::getOriginCoordinate, type);
|
||||||
|
|
||||||
this.renderers.add(new MaterialRenderer<>(owner.getProgram(type.getProgramName()), material));
|
this.renderers.add(new MaterialRenderer<>(owner.getProgram(type.getProgramName()), material, this::setup));
|
||||||
|
|
||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.jozufozu.flywheel.backend.material;
|
package com.jozufozu.flywheel.backend.material;
|
||||||
|
|
||||||
|
import java.util.EnumMap;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
@ -12,7 +13,6 @@ import com.jozufozu.flywheel.core.Materials;
|
||||||
import com.jozufozu.flywheel.core.WorldContext;
|
import com.jozufozu.flywheel.core.WorldContext;
|
||||||
import com.jozufozu.flywheel.core.materials.ModelData;
|
import com.jozufozu.flywheel.core.materials.ModelData;
|
||||||
import com.jozufozu.flywheel.core.materials.OrientedData;
|
import com.jozufozu.flywheel.core.materials.OrientedData;
|
||||||
import com.jozufozu.flywheel.core.shader.IProgramCallback;
|
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
import com.jozufozu.flywheel.util.WeakHashSet;
|
import com.jozufozu.flywheel.util.WeakHashSet;
|
||||||
|
|
||||||
|
@ -29,23 +29,32 @@ public class MaterialManager<P extends WorldProgram> {
|
||||||
|
|
||||||
public static int MAX_ORIGIN_DISTANCE = 100;
|
public static int MAX_ORIGIN_DISTANCE = 100;
|
||||||
|
|
||||||
|
protected BlockPos originCoordinate = BlockPos.ZERO;
|
||||||
|
|
||||||
protected final WorldContext<P> context;
|
protected final WorldContext<P> context;
|
||||||
protected GroupFactory<P> groupFactory;
|
protected final GroupFactory<P> groupFactory;
|
||||||
protected boolean ignoreOriginCoordinate;
|
protected final boolean ignoreOriginCoordinate;
|
||||||
|
|
||||||
protected final Map<RenderLayer, Map<IRenderState, MaterialGroup<P>>> layers;
|
protected final Map<RenderLayer, Map<IRenderState, MaterialGroup<P>>> layers;
|
||||||
|
|
||||||
protected BlockPos originCoordinate = BlockPos.ZERO;
|
|
||||||
|
|
||||||
private final WeakHashSet<OriginShiftListener> listeners;
|
private final WeakHashSet<OriginShiftListener> listeners;
|
||||||
|
|
||||||
public MaterialManager(WorldContext<P> context) {
|
public MaterialManager(WorldContext<P> context) {
|
||||||
|
this(context, MaterialGroup::new, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <P extends WorldProgram> Builder<P> builder(WorldContext<P> context) {
|
||||||
|
return new Builder<>(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaterialManager(WorldContext<P> context, GroupFactory<P> groupFactory, boolean ignoreOriginCoordinate) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
this.ignoreOriginCoordinate = ignoreOriginCoordinate;
|
||||||
|
|
||||||
this.layers = new HashMap<>();
|
|
||||||
this.listeners = new WeakHashSet<>();
|
this.listeners = new WeakHashSet<>();
|
||||||
this.groupFactory = MaterialGroup::new;
|
this.groupFactory = groupFactory;
|
||||||
|
|
||||||
|
this.layers = new EnumMap<>(RenderLayer.class);
|
||||||
for (RenderLayer value : RenderLayer.values()) {
|
for (RenderLayer value : RenderLayer.values()) {
|
||||||
layers.put(value, new HashMap<>());
|
layers.put(value, new HashMap<>());
|
||||||
}
|
}
|
||||||
|
@ -53,20 +62,10 @@ public class MaterialManager<P extends WorldProgram> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render every model for every material.
|
* Render every model for every material.
|
||||||
* @param layer Which vanilla {@link RenderType} is being drawn?
|
* @param layer Which vanilla {@link RenderType} is being drawn?
|
||||||
* @param viewProjection How do we get from camera space to clip space?
|
* @param viewProjection How do we get from camera space to clip space?
|
||||||
*/
|
*/
|
||||||
public void render(RenderLayer layer, Matrix4f viewProjection, double camX, double camY, double camZ) {
|
public void render(RenderLayer layer, Matrix4f viewProjection, double camX, double camY, double camZ) {
|
||||||
render(layer, viewProjection, camX, camY, camZ, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render every model for every material.
|
|
||||||
* @param layer Which vanilla {@link RenderType} is being drawn?
|
|
||||||
* @param viewProjection How do we get from camera space to clip space?
|
|
||||||
* @param callback Provide additional uniforms or state here.
|
|
||||||
*/
|
|
||||||
public void render(RenderLayer layer, Matrix4f viewProjection, double camX, double camY, double camZ, IProgramCallback<P> callback) {
|
|
||||||
if (!ignoreOriginCoordinate) {
|
if (!ignoreOriginCoordinate) {
|
||||||
camX -= originCoordinate.getX();
|
camX -= originCoordinate.getX();
|
||||||
camY -= originCoordinate.getY();
|
camY -= originCoordinate.getY();
|
||||||
|
@ -84,7 +83,7 @@ public class MaterialManager<P extends WorldProgram> {
|
||||||
MaterialGroup<P> group = entry.getValue();
|
MaterialGroup<P> group = entry.getValue();
|
||||||
|
|
||||||
state.bind();
|
state.bind();
|
||||||
group.render(viewProjection, camX, camY, camZ, callback);
|
group.render(viewProjection, camX, camY, camZ);
|
||||||
state.unbind();
|
state.unbind();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,16 +147,6 @@ public class MaterialManager<P extends WorldProgram> {
|
||||||
return context.getProgramSupplier(name);
|
return context.getProgramSupplier(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MaterialManager<P> setIgnoreOriginCoordinate(boolean ignoreOriginCoordinate) {
|
|
||||||
this.ignoreOriginCoordinate = ignoreOriginCoordinate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MaterialManager<P> setGroupFactory(GroupFactory<P> factory) {
|
|
||||||
this.groupFactory = factory;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector3i getOriginCoordinate() {
|
public Vector3i getOriginCoordinate() {
|
||||||
return originCoordinate;
|
return originCoordinate;
|
||||||
}
|
}
|
||||||
|
@ -200,4 +189,28 @@ public class MaterialManager<P extends WorldProgram> {
|
||||||
public interface GroupFactory<P extends WorldProgram> {
|
public interface GroupFactory<P extends WorldProgram> {
|
||||||
MaterialGroup<P> create(MaterialManager<P> materialManager, IRenderState state);
|
MaterialGroup<P> create(MaterialManager<P> materialManager, IRenderState state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class Builder<P extends WorldProgram> {
|
||||||
|
protected final WorldContext<P> context;
|
||||||
|
protected GroupFactory<P> groupFactory = MaterialGroup::new;
|
||||||
|
protected boolean ignoreOriginCoordinate;
|
||||||
|
|
||||||
|
public Builder(WorldContext<P> context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<P> setGroupFactory(GroupFactory<P> groupFactory) {
|
||||||
|
this.groupFactory = groupFactory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<P> setIgnoreOriginCoordinate(boolean ignoreOriginCoordinate) {
|
||||||
|
this.ignoreOriginCoordinate = ignoreOriginCoordinate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaterialManager<P> build() {
|
||||||
|
return new MaterialManager<>(context, groupFactory, ignoreOriginCoordinate);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package com.jozufozu.flywheel.backend.material;
|
package com.jozufozu.flywheel.backend.material;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.Instancer;
|
import com.jozufozu.flywheel.backend.instancing.Instancer;
|
||||||
import com.jozufozu.flywheel.core.shader.IProgramCallback;
|
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
|
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
|
@ -13,12 +13,15 @@ public class MaterialRenderer<P extends WorldProgram> {
|
||||||
protected final Supplier<P> program;
|
protected final Supplier<P> program;
|
||||||
protected final InstanceMaterial<?> material;
|
protected final InstanceMaterial<?> material;
|
||||||
|
|
||||||
public MaterialRenderer(Supplier<P> programSupplier, InstanceMaterial<?> material) {
|
protected final Consumer<P> setupFunc;
|
||||||
|
|
||||||
|
public MaterialRenderer(Supplier<P> programSupplier, InstanceMaterial<?> material, Consumer<P> setupFunc) {
|
||||||
this.program = programSupplier;
|
this.program = programSupplier;
|
||||||
this.material = material;
|
this.material = material;
|
||||||
|
this.setupFunc = setupFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(Matrix4f viewProjection, double camX, double camY, double camZ, IProgramCallback<P> setup) {
|
public void render(Matrix4f viewProjection, double camX, double camY, double camZ) {
|
||||||
if (material.nothingToRender()) return;
|
if (material.nothingToRender()) return;
|
||||||
|
|
||||||
P program = this.program.get();
|
P program = this.program.get();
|
||||||
|
@ -27,7 +30,7 @@ public class MaterialRenderer<P extends WorldProgram> {
|
||||||
program.uploadViewProjection(viewProjection);
|
program.uploadViewProjection(viewProjection);
|
||||||
program.uploadCameraPos(camX, camY, camZ);
|
program.uploadCameraPos(camX, camY, camZ);
|
||||||
|
|
||||||
if (setup != null) setup.call(program);
|
setupFunc.accept(program);
|
||||||
|
|
||||||
material.forEachInstancer(Instancer::render);
|
material.forEachInstancer(Instancer::render);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
package com.jozufozu.flywheel.core.crumbling;
|
package com.jozufozu.flywheel.core.crumbling;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
||||||
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
|
||||||
import com.jozufozu.flywheel.backend.material.MaterialGroup;
|
import com.jozufozu.flywheel.backend.material.MaterialGroup;
|
||||||
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
import com.jozufozu.flywheel.backend.state.IRenderState;
|
import com.jozufozu.flywheel.backend.state.IRenderState;
|
||||||
import com.jozufozu.flywheel.core.atlas.AtlasInfo;
|
import com.jozufozu.flywheel.core.atlas.AtlasInfo;
|
||||||
import com.jozufozu.flywheel.core.atlas.SheetData;
|
import com.jozufozu.flywheel.core.atlas.SheetData;
|
||||||
import com.jozufozu.flywheel.core.shader.IProgramCallback;
|
|
||||||
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
|
||||||
|
|
||||||
public class CrumblingGroup<P extends CrumblingProgram> extends MaterialGroup<P> {
|
public class CrumblingGroup<P extends CrumblingProgram> extends MaterialGroup<P> {
|
||||||
|
|
||||||
|
@ -32,11 +30,7 @@ public class CrumblingGroup<P extends CrumblingProgram> extends MaterialGroup<P>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(Matrix4f viewProjection, double camX, double camY, double camZ, IProgramCallback<P> callback) {
|
public void setup(P p) {
|
||||||
super.render(viewProjection, camX, camY, camZ, ((IProgramCallback<P>) this::setup).andThen(callback));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setup(P p) {
|
|
||||||
p.setAtlasSize(width, height);
|
p.setAtlasSize(width, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,7 +148,9 @@ public class CrumblingRenderer {
|
||||||
private final InstanceManager<TileEntity> instanceManager;
|
private final InstanceManager<TileEntity> instanceManager;
|
||||||
|
|
||||||
private State() {
|
private State() {
|
||||||
materialManager = new MaterialManager<>(Contexts.CRUMBLING).setGroupFactory(CrumblingGroup::new);
|
materialManager = MaterialManager.builder(Contexts.CRUMBLING)
|
||||||
|
.setGroupFactory(CrumblingGroup::new)
|
||||||
|
.build();
|
||||||
instanceManager = new CrumblingInstanceManager(materialManager);
|
instanceManager = new CrumblingInstanceManager(materialManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
package com.jozufozu.flywheel.core.shader;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to define shader uniforms.
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface IProgramCallback<P extends GlProgram> {
|
|
||||||
|
|
||||||
void call(P program);
|
|
||||||
|
|
||||||
default IProgramCallback<P> andThen(IProgramCallback<P> other) {
|
|
||||||
if (other == null) return this;
|
|
||||||
|
|
||||||
return program -> {
|
|
||||||
call(program);
|
|
||||||
other.call(program);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue