mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-27 07:26:48 +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
38418b2f91
commit
fd96df1abe
7 changed files with 62 additions and 69 deletions
|
@ -30,7 +30,7 @@ import net.minecraftforge.fml.common.Mod;
|
|||
@Mod.EventBusSubscriber(Dist.CLIENT)
|
||||
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<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.state.IRenderState;
|
||||
import com.jozufozu.flywheel.core.shader.IProgramCallback;
|
||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.util.math.vector.Matrix4f;
|
||||
|
||||
public class MaterialGroup<P extends WorldProgram> {
|
||||
|
@ -26,12 +24,16 @@ public class MaterialGroup<P extends WorldProgram> {
|
|||
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) {
|
||||
renderer.render(viewProjection, camX, camY, camZ, callback);
|
||||
renderer.render(viewProjection, camX, camY, camZ);
|
||||
}
|
||||
}
|
||||
|
||||
public void setup(P program) {
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <D extends InstanceData> InstanceMaterial<D> material(MaterialSpec<D> spec) {
|
||||
return (InstanceMaterial<D>) materials.computeIfAbsent(spec, this::createInstanceMaterial);
|
||||
|
@ -40,7 +42,7 @@ public class MaterialGroup<P extends WorldProgram> {
|
|||
private InstanceMaterial<?> createInstanceMaterial(MaterialSpec<?> 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;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.jozufozu.flywheel.backend.material;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
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.materials.ModelData;
|
||||
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.util.WeakHashSet;
|
||||
|
||||
|
@ -29,23 +29,32 @@ public class MaterialManager<P extends WorldProgram> {
|
|||
|
||||
public static int MAX_ORIGIN_DISTANCE = 100;
|
||||
|
||||
protected BlockPos originCoordinate = BlockPos.ZERO;
|
||||
|
||||
protected final WorldContext<P> context;
|
||||
protected GroupFactory<P> groupFactory;
|
||||
protected boolean ignoreOriginCoordinate;
|
||||
protected final GroupFactory<P> groupFactory;
|
||||
protected final boolean ignoreOriginCoordinate;
|
||||
|
||||
protected final Map<RenderLayer, Map<IRenderState, MaterialGroup<P>>> layers;
|
||||
|
||||
protected BlockPos originCoordinate = BlockPos.ZERO;
|
||||
|
||||
private final WeakHashSet<OriginShiftListener> listeners;
|
||||
|
||||
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.ignoreOriginCoordinate = ignoreOriginCoordinate;
|
||||
|
||||
this.layers = new HashMap<>();
|
||||
this.listeners = new WeakHashSet<>();
|
||||
this.groupFactory = MaterialGroup::new;
|
||||
this.groupFactory = groupFactory;
|
||||
|
||||
this.layers = new EnumMap<>(RenderLayer.class);
|
||||
for (RenderLayer value : RenderLayer.values()) {
|
||||
layers.put(value, new HashMap<>());
|
||||
}
|
||||
|
@ -53,20 +62,10 @@ public class MaterialManager<P extends WorldProgram> {
|
|||
|
||||
/**
|
||||
* 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?
|
||||
*/
|
||||
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) {
|
||||
camX -= originCoordinate.getX();
|
||||
camY -= originCoordinate.getY();
|
||||
|
@ -84,7 +83,7 @@ public class MaterialManager<P extends WorldProgram> {
|
|||
MaterialGroup<P> group = entry.getValue();
|
||||
|
||||
state.bind();
|
||||
group.render(viewProjection, camX, camY, camZ, callback);
|
||||
group.render(viewProjection, camX, camY, camZ);
|
||||
state.unbind();
|
||||
}
|
||||
}
|
||||
|
@ -148,16 +147,6 @@ public class MaterialManager<P extends WorldProgram> {
|
|||
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() {
|
||||
return originCoordinate;
|
||||
}
|
||||
|
@ -200,4 +189,28 @@ public class MaterialManager<P extends WorldProgram> {
|
|||
public interface GroupFactory<P extends WorldProgram> {
|
||||
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;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.Instancer;
|
||||
import com.jozufozu.flywheel.core.shader.IProgramCallback;
|
||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||
|
||||
import net.minecraft.util.math.vector.Matrix4f;
|
||||
|
@ -13,12 +13,15 @@ public class MaterialRenderer<P extends WorldProgram> {
|
|||
protected final Supplier<P> program;
|
||||
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.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;
|
||||
|
||||
P program = this.program.get();
|
||||
|
@ -27,7 +30,7 @@ public class MaterialRenderer<P extends WorldProgram> {
|
|||
program.uploadViewProjection(viewProjection);
|
||||
program.uploadCameraPos(camX, camY, camZ);
|
||||
|
||||
if (setup != null) setup.call(program);
|
||||
setupFunc.accept(program);
|
||||
|
||||
material.forEachInstancer(Instancer::render);
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
package com.jozufozu.flywheel.core.crumbling;
|
||||
|
||||
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.MaterialManager;
|
||||
import com.jozufozu.flywheel.backend.state.IRenderState;
|
||||
import com.jozufozu.flywheel.core.atlas.AtlasInfo;
|
||||
import com.jozufozu.flywheel.core.atlas.SheetData;
|
||||
import com.jozufozu.flywheel.core.shader.IProgramCallback;
|
||||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.vector.Matrix4f;
|
||||
|
||||
public class CrumblingGroup<P extends CrumblingProgram> extends MaterialGroup<P> {
|
||||
|
||||
|
@ -32,11 +30,7 @@ public class CrumblingGroup<P extends CrumblingProgram> extends MaterialGroup<P>
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(Matrix4f viewProjection, double camX, double camY, double camZ, IProgramCallback<P> callback) {
|
||||
super.render(viewProjection, camX, camY, camZ, ((IProgramCallback<P>) this::setup).andThen(callback));
|
||||
}
|
||||
|
||||
private void setup(P p) {
|
||||
public void setup(P p) {
|
||||
p.setAtlasSize(width, height);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,7 +148,9 @@ public class CrumblingRenderer {
|
|||
private final InstanceManager<TileEntity> instanceManager;
|
||||
|
||||
private State() {
|
||||
materialManager = new MaterialManager<>(Contexts.CRUMBLING).setGroupFactory(CrumblingGroup::new);
|
||||
materialManager = MaterialManager.builder(Contexts.CRUMBLING)
|
||||
.setGroupFactory(CrumblingGroup::new)
|
||||
.build();
|
||||
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