mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-28 16:06:28 +01:00
MaterialGroups and massive refactors
- Move material stuff to its own package - The various render functions in the material tree now bind to specific render layers - Instancers can choose which layer to use - The layers are SOLID, CUTOUT, and TRANSPARENT - More layers are likely unnecessary, but we'll see - Deprecate functions in MaterialManager in favor of more builderesque ones using MaterialGroups
This commit is contained in:
parent
fe836645aa
commit
418676a0f0
32 changed files with 432 additions and 285 deletions
|
@ -15,7 +15,7 @@ import org.lwjgl.opengl.GLCapabilities;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.versioned.GlCompat;
|
import com.jozufozu.flywheel.backend.gl.versioned.GlCompat;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
import com.jozufozu.flywheel.backend.material.MaterialSpec;
|
||||||
import com.jozufozu.flywheel.config.FlwConfig;
|
import com.jozufozu.flywheel.config.FlwConfig;
|
||||||
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
|
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||||
|
|
|
@ -5,6 +5,8 @@ import javax.annotation.Nonnull;
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
||||||
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
|
import com.jozufozu.flywheel.backend.state.RenderLayer;
|
||||||
import com.jozufozu.flywheel.core.Contexts;
|
import com.jozufozu.flywheel.core.Contexts;
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
||||||
|
@ -84,10 +86,14 @@ public class InstancedRenderDispatcher {
|
||||||
if (!Backend.getInstance()
|
if (!Backend.getInstance()
|
||||||
.canUseInstancing(world)) return;
|
.canUseInstancing(world)) return;
|
||||||
|
|
||||||
|
RenderLayer renderLayer = RenderLayer.fromRenderType(event.type);
|
||||||
|
|
||||||
|
if (renderLayer == null) return;
|
||||||
|
|
||||||
event.type.setupRenderState();
|
event.type.setupRenderState();
|
||||||
|
|
||||||
materialManagers.get(world)
|
materialManagers.get(world)
|
||||||
.render(event.type, event.viewProjection, event.camX, event.camY, event.camZ);
|
.render(renderLayer, event.viewProjection, event.camX, event.camY, event.camZ);
|
||||||
|
|
||||||
event.type.clearRenderState();
|
event.type.clearRenderState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.entity.IEntityInstanceFactory;
|
import com.jozufozu.flywheel.backend.instancing.entity.IEntityInstanceFactory;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.ITileInstanceFactory;
|
import com.jozufozu.flywheel.backend.instancing.tile.ITileInstanceFactory;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
||||||
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2BooleanLinkedOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2BooleanLinkedOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
|
import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
|
||||||
|
|
|
@ -5,12 +5,15 @@ import java.util.ArrayList;
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
|
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
|
||||||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
|
||||||
|
import com.jozufozu.flywheel.backend.material.MaterialSpec;
|
||||||
import com.jozufozu.flywheel.backend.model.BufferedModel;
|
import com.jozufozu.flywheel.backend.model.BufferedModel;
|
||||||
import com.jozufozu.flywheel.util.AttribUtil;
|
import com.jozufozu.flywheel.util.AttribUtil;
|
||||||
|
|
||||||
|
@ -20,7 +23,7 @@ public class Instancer<D extends InstanceData> {
|
||||||
|
|
||||||
public final Supplier<Vector3i> originCoordinate;
|
public final Supplier<Vector3i> originCoordinate;
|
||||||
|
|
||||||
protected Supplier<BufferedModel> gen;
|
protected final Supplier<BufferedModel> gen;
|
||||||
protected BufferedModel model;
|
protected BufferedModel model;
|
||||||
|
|
||||||
protected final VertexFormat instanceFormat;
|
protected final VertexFormat instanceFormat;
|
||||||
|
@ -30,6 +33,7 @@ public class Instancer<D extends InstanceData> {
|
||||||
protected int glBufferSize = -1;
|
protected int glBufferSize = -1;
|
||||||
protected int glInstanceCount = 0;
|
protected int glInstanceCount = 0;
|
||||||
private boolean deleted;
|
private boolean deleted;
|
||||||
|
private boolean initialized;
|
||||||
|
|
||||||
protected final ArrayList<D> data = new ArrayList<>();
|
protected final ArrayList<D> data = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -69,7 +73,7 @@ public class Instancer<D extends InstanceData> {
|
||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
model = gen.get();
|
model = gen.get();
|
||||||
gen = null;
|
initialized = true;
|
||||||
|
|
||||||
if (model.getVertexCount() <= 0)
|
if (model.getVertexCount() <= 0)
|
||||||
throw new IllegalArgumentException("Refusing to instance a model with no vertices.");
|
throw new IllegalArgumentException("Refusing to instance a model with no vertices.");
|
||||||
|
@ -90,7 +94,7 @@ public class Instancer<D extends InstanceData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInitialized() {
|
public boolean isInitialized() {
|
||||||
return gen != null;
|
return initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
|
|
|
@ -1,161 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.state.IRenderState;
|
|
||||||
import com.jozufozu.flywheel.backend.state.TextureRenderState;
|
|
||||||
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;
|
|
||||||
|
|
||||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.inventory.container.PlayerContainer;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
|
||||||
import net.minecraft.util.math.vector.Vector3i;
|
|
||||||
|
|
||||||
// TODO: 0.2 block atlas should not be a special case
|
|
||||||
public class MaterialManager<P extends WorldProgram> {
|
|
||||||
|
|
||||||
public static int MAX_ORIGIN_DISTANCE = 100;
|
|
||||||
|
|
||||||
protected final WorldContext<P> context;
|
|
||||||
|
|
||||||
protected final Map<IRenderState, ArrayList<MaterialRenderer<P>>> renderers;
|
|
||||||
protected final Map<IRenderState, Map<MaterialSpec<?>, InstanceMaterial<?>>> materials;
|
|
||||||
|
|
||||||
protected BlockPos originCoordinate = BlockPos.ZERO;
|
|
||||||
|
|
||||||
private final WeakHashSet<OriginShiftListener> listeners;
|
|
||||||
|
|
||||||
public MaterialManager(WorldContext<P> context) {
|
|
||||||
this.context = context;
|
|
||||||
|
|
||||||
this.materials = new HashMap<>();
|
|
||||||
this.renderers = new HashMap<>();
|
|
||||||
|
|
||||||
this.listeners = new WeakHashSet<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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?
|
|
||||||
*/
|
|
||||||
public void render(RenderType 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(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ, IProgramCallback<P> callback) {
|
|
||||||
camX -= originCoordinate.getX();
|
|
||||||
camY -= originCoordinate.getY();
|
|
||||||
camZ -= originCoordinate.getZ();
|
|
||||||
|
|
||||||
Matrix4f translate = Matrix4f.createTranslateMatrix((float) -camX, (float) -camY, (float) -camZ);
|
|
||||||
|
|
||||||
translate.multiplyBackward(viewProjection);
|
|
||||||
|
|
||||||
for (Map.Entry<IRenderState, ArrayList<MaterialRenderer<P>>> entry : renderers.entrySet()) {
|
|
||||||
entry.getKey().bind();
|
|
||||||
|
|
||||||
for (MaterialRenderer<P> materialRenderer : entry.getValue()) {
|
|
||||||
materialRenderer.render(layer, translate, camX, camY, camZ, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
entry.getKey().unbind();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete() {
|
|
||||||
materials.values()
|
|
||||||
.stream()
|
|
||||||
.flatMap(m -> m.values()
|
|
||||||
.stream())
|
|
||||||
.forEach(InstanceMaterial::delete);
|
|
||||||
|
|
||||||
materials.clear();
|
|
||||||
renderers.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public <D extends InstanceData> InstanceMaterial<D> getMaterial(MaterialSpec<D> materialType) {
|
|
||||||
return getMaterial(materialType, PlayerContainer.BLOCK_ATLAS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public <D extends InstanceData> InstanceMaterial<D> getMaterial(MaterialSpec<D> materialType, ResourceLocation texture) {
|
|
||||||
return getMaterial(materialType, TextureRenderState.get(texture));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <D extends InstanceData> InstanceMaterial<D> getMaterial(MaterialSpec<D> materialType, IRenderState state) {
|
|
||||||
return (InstanceMaterial<D>) materials.computeIfAbsent(state, $ -> new HashMap<>())
|
|
||||||
.computeIfAbsent(materialType, type -> {
|
|
||||||
InstanceMaterial<?> material = new InstanceMaterial<>(this::getOriginCoordinate, type);
|
|
||||||
|
|
||||||
this.renderers.computeIfAbsent(state, $ -> new ArrayList<>())
|
|
||||||
.add(new MaterialRenderer<>(context.getProgramSupplier(type.getProgramName()), material));
|
|
||||||
|
|
||||||
return material;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public InstanceMaterial<ModelData> getTransformMaterial() {
|
|
||||||
return getMaterial(Materials.TRANSFORMED);
|
|
||||||
}
|
|
||||||
|
|
||||||
public InstanceMaterial<OrientedData> getOrientedMaterial() {
|
|
||||||
return getMaterial(Materials.ORIENTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector3i getOriginCoordinate() {
|
|
||||||
return originCoordinate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addListener(OriginShiftListener listener) {
|
|
||||||
listeners.add(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkAndShiftOrigin(ActiveRenderInfo info) {
|
|
||||||
int cX = MathHelper.floor(info.getPosition().x);
|
|
||||||
int cY = MathHelper.floor(info.getPosition().y);
|
|
||||||
int cZ = MathHelper.floor(info.getPosition().z);
|
|
||||||
|
|
||||||
int dX = cX - originCoordinate.getX();
|
|
||||||
int dY = cY - originCoordinate.getY();
|
|
||||||
int dZ = cZ - originCoordinate.getZ();
|
|
||||||
|
|
||||||
if (Math.abs(dX) > MAX_ORIGIN_DISTANCE || Math.abs(dY) > MAX_ORIGIN_DISTANCE || Math.abs(dZ) > MAX_ORIGIN_DISTANCE) {
|
|
||||||
|
|
||||||
originCoordinate = new BlockPos(cX, cY, cZ);
|
|
||||||
|
|
||||||
materials.values()
|
|
||||||
.stream()
|
|
||||||
.flatMap(m -> m.values()
|
|
||||||
.stream())
|
|
||||||
.forEach(InstanceMaterial::clear);
|
|
||||||
|
|
||||||
listeners.forEach(OriginShiftListener::onOriginShift);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface OriginShiftListener {
|
|
||||||
void onOriginShift();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,9 +6,10 @@ import java.util.stream.Stream;
|
||||||
import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
|
import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.IInstance;
|
import com.jozufozu.flywheel.backend.instancing.IInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.ITickableInstance;
|
import com.jozufozu.flywheel.backend.instancing.ITickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceMaterial;
|
import com.jozufozu.flywheel.backend.material.InstanceMaterial;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
||||||
|
import com.jozufozu.flywheel.core.Materials;
|
||||||
import com.jozufozu.flywheel.core.materials.IFlatLight;
|
import com.jozufozu.flywheel.core.materials.IFlatLight;
|
||||||
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;
|
||||||
|
@ -120,11 +121,11 @@ public abstract class EntityInstance<E extends Entity> implements IInstance {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InstanceMaterial<ModelData> getTransformMaterial() {
|
protected InstanceMaterial<ModelData> getTransformMaterial() {
|
||||||
return materialManager.getTransformMaterial();
|
return materialManager.defaultSolid().material(Materials.TRANSFORMED);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InstanceMaterial<OrientedData> getOrientedMaterial() {
|
protected InstanceMaterial<OrientedData> getOrientedMaterial() {
|
||||||
return materialManager.getOrientedMaterial();
|
return materialManager.defaultSolid().material(Materials.ORIENTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.instancing.IInstance;
|
import com.jozufozu.flywheel.backend.instancing.IInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.entity;
|
package com.jozufozu.flywheel.backend.instancing.entity;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||||
|
package com.jozufozu.flywheel.backend.instancing;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import mcp.MethodsReturnNonnullByDefault;
|
|
@ -1,6 +1,6 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.tile;
|
package com.jozufozu.flywheel.backend.instancing.tile;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,9 @@ import java.util.stream.Stream;
|
||||||
import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
|
import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.IInstance;
|
import com.jozufozu.flywheel.backend.instancing.IInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.ITickableInstance;
|
import com.jozufozu.flywheel.backend.instancing.ITickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceMaterial;
|
import com.jozufozu.flywheel.backend.material.InstanceMaterial;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
|
import com.jozufozu.flywheel.core.Materials;
|
||||||
import com.jozufozu.flywheel.core.materials.IFlatLight;
|
import com.jozufozu.flywheel.core.materials.IFlatLight;
|
||||||
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;
|
||||||
|
@ -122,10 +123,10 @@ public abstract class TileEntityInstance<T extends TileEntity> implements IInsta
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InstanceMaterial<ModelData> getTransformMaterial() {
|
protected InstanceMaterial<ModelData> getTransformMaterial() {
|
||||||
return materialManager.getTransformMaterial();
|
return materialManager.defaultCutout().material(Materials.TRANSFORMED);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InstanceMaterial<OrientedData> getOrientedMaterial() {
|
protected InstanceMaterial<OrientedData> getOrientedMaterial() {
|
||||||
return materialManager.getOrientedMaterial();
|
return materialManager.defaultCutout().material(Materials.ORIENTED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.instancing.IInstance;
|
import com.jozufozu.flywheel.backend.instancing.IInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing;
|
package com.jozufozu.flywheel.backend.material;
|
||||||
|
|
||||||
import java.nio.Buffer;
|
import java.nio.Buffer;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
@ -15,6 +15,8 @@ import com.google.common.cache.Cache;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.jozufozu.flywheel.backend.RenderWork;
|
import com.jozufozu.flywheel.backend.RenderWork;
|
||||||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.Instancer;
|
||||||
import com.jozufozu.flywheel.backend.model.BufferedModel;
|
import com.jozufozu.flywheel.backend.model.BufferedModel;
|
||||||
import com.jozufozu.flywheel.backend.model.IndexedModel;
|
import com.jozufozu.flywheel.backend.model.IndexedModel;
|
||||||
import com.jozufozu.flywheel.core.PartialModel;
|
import com.jozufozu.flywheel.core.PartialModel;
|
||||||
|
@ -83,7 +85,7 @@ public class InstanceMaterial<D extends InstanceData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instancer<D> getModel(PartialModel partial, BlockState referenceState) {
|
public Instancer<D> getModel(PartialModel partial, BlockState referenceState) {
|
||||||
return get(partial, () -> buildModel(partial.get(), referenceState));
|
return model(partial, () -> buildModel(partial.get(), referenceState));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instancer<D> getModel(PartialModel partial, BlockState referenceState, Direction dir) {
|
public Instancer<D> getModel(PartialModel partial, BlockState referenceState, Direction dir) {
|
||||||
|
@ -91,14 +93,14 @@ public class InstanceMaterial<D extends InstanceData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instancer<D> getModel(PartialModel partial, BlockState referenceState, Direction dir, Supplier<MatrixStack> modelTransform) {
|
public Instancer<D> getModel(PartialModel partial, BlockState referenceState, Direction dir, Supplier<MatrixStack> modelTransform) {
|
||||||
return get(Pair.of(dir, partial), () -> buildModel(partial.get(), referenceState, modelTransform.get()));
|
return model(Pair.of(dir, partial), () -> buildModel(partial.get(), referenceState, modelTransform.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instancer<D> getModel(BlockState toRender) {
|
public Instancer<D> getModel(BlockState toRender) {
|
||||||
return get(toRender, () -> buildModel(toRender));
|
return model(toRender, () -> buildModel(toRender));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instancer<D> get(Object key, Supplier<BufferedModel> supplier) {
|
public Instancer<D> model(Object key, Supplier<BufferedModel> supplier) {
|
||||||
try {
|
try {
|
||||||
return models.get(key, () -> new Instancer<>(supplier, originCoordinate, spec));
|
return models.get(key, () -> new Instancer<>(supplier, originCoordinate, spec));
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.jozufozu.flywheel.backend.material;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
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> {
|
||||||
|
|
||||||
|
protected final MaterialManager<P> owner;
|
||||||
|
protected final IRenderState state;
|
||||||
|
|
||||||
|
private final ArrayList<MaterialRenderer<P>> renderers = new ArrayList<>();
|
||||||
|
|
||||||
|
private final Map<MaterialSpec<?>, InstanceMaterial<?>> materials = new HashMap<>();
|
||||||
|
|
||||||
|
public MaterialGroup(MaterialManager<P> owner, IRenderState state) {
|
||||||
|
this.owner = owner;
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render(Matrix4f viewProjection, double camX, double camY, double camZ, IProgramCallback<P> callback) {
|
||||||
|
for (MaterialRenderer<P> renderer : renderers) {
|
||||||
|
renderer.render(viewProjection, camX, camY, camZ, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <D extends InstanceData> InstanceMaterial<D> material(MaterialSpec<D> spec) {
|
||||||
|
return (InstanceMaterial<D>) materials.computeIfAbsent(spec, this::createInstanceMaterial);
|
||||||
|
}
|
||||||
|
|
||||||
|
private InstanceMaterial<?> createInstanceMaterial(MaterialSpec<?> type) {
|
||||||
|
InstanceMaterial<?> material = new InstanceMaterial<>(owner::getOriginCoordinate, type);
|
||||||
|
|
||||||
|
this.renderers.add(new MaterialRenderer<>(owner.getProgram(type.getProgramName()), material));
|
||||||
|
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
materials.values().forEach(InstanceMaterial::clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
materials.values()
|
||||||
|
.forEach(InstanceMaterial::delete);
|
||||||
|
|
||||||
|
materials.clear();
|
||||||
|
renderers.clear();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,203 @@
|
||||||
|
package com.jozufozu.flywheel.backend.material;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||||
|
import com.jozufozu.flywheel.backend.state.IRenderState;
|
||||||
|
import com.jozufozu.flywheel.backend.state.RenderLayer;
|
||||||
|
import com.jozufozu.flywheel.backend.state.TextureRenderState;
|
||||||
|
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;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.inventory.container.PlayerContainer;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
|
import net.minecraft.util.math.vector.Vector3i;
|
||||||
|
|
||||||
|
public class MaterialManager<P extends WorldProgram> {
|
||||||
|
|
||||||
|
public static int MAX_ORIGIN_DISTANCE = 100;
|
||||||
|
|
||||||
|
protected final WorldContext<P> context;
|
||||||
|
protected GroupFactory<P> groupFactory;
|
||||||
|
protected 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 = context;
|
||||||
|
|
||||||
|
this.layers = new HashMap<>();
|
||||||
|
this.listeners = new WeakHashSet<>();
|
||||||
|
this.groupFactory = MaterialGroup::new;
|
||||||
|
|
||||||
|
for (RenderLayer value : RenderLayer.values()) {
|
||||||
|
layers.put(value, new HashMap<>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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?
|
||||||
|
*/
|
||||||
|
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();
|
||||||
|
camZ -= originCoordinate.getZ();
|
||||||
|
|
||||||
|
Matrix4f translate = Matrix4f.createTranslateMatrix((float) -camX, (float) -camY, (float) -camZ);
|
||||||
|
|
||||||
|
translate.multiplyBackward(viewProjection);
|
||||||
|
|
||||||
|
viewProjection = translate;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<IRenderState, MaterialGroup<P>> entry : layers.get(layer).entrySet()) {
|
||||||
|
IRenderState state = entry.getKey();
|
||||||
|
MaterialGroup<P> group = entry.getValue();
|
||||||
|
|
||||||
|
state.bind();
|
||||||
|
group.render(viewProjection, camX, camY, camZ, callback);
|
||||||
|
state.unbind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
for (Map<IRenderState, MaterialGroup<P>> groups : layers.values()) {
|
||||||
|
|
||||||
|
groups.values().forEach(MaterialGroup::delete);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaterialGroup<P> state(RenderLayer layer, IRenderState state) {
|
||||||
|
return layers.get(layer).computeIfAbsent(state, this::createGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaterialGroup<P> solid(IRenderState state) {
|
||||||
|
return layers.get(RenderLayer.SOLID).computeIfAbsent(state, this::createGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaterialGroup<P> cutout(IRenderState state) {
|
||||||
|
return layers.get(RenderLayer.CUTOUT).computeIfAbsent(state, this::createGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaterialGroup<P> transparent(IRenderState state) {
|
||||||
|
return layers.get(RenderLayer.TRANSPARENT).computeIfAbsent(state, this::createGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaterialGroup<P> defaultSolid() {
|
||||||
|
return solid(TextureRenderState.get(PlayerContainer.BLOCK_ATLAS));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaterialGroup<P> defaultCutout() {
|
||||||
|
return cutout(TextureRenderState.get(PlayerContainer.BLOCK_ATLAS));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaterialGroup<P> defaultTransparent() {
|
||||||
|
return transparent(TextureRenderState.get(PlayerContainer.BLOCK_ATLAS));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public <D extends InstanceData> InstanceMaterial<D> getMaterial(MaterialSpec<D> materialType) {
|
||||||
|
return defaultCutout().material(materialType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public <D extends InstanceData> InstanceMaterial<D> getMaterial(MaterialSpec<D> materialType, ResourceLocation texture) {
|
||||||
|
return cutout(TextureRenderState.get(texture)).material(materialType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public InstanceMaterial<ModelData> getTransformMaterial() {
|
||||||
|
return defaultCutout().material(Materials.TRANSFORMED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public InstanceMaterial<OrientedData> getOrientedMaterial() {
|
||||||
|
return defaultCutout().material(Materials.ORIENTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Supplier<P> getProgram(ResourceLocation 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() {
|
||||||
|
return originCoordinate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addListener(OriginShiftListener listener) {
|
||||||
|
listeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkAndShiftOrigin(ActiveRenderInfo info) {
|
||||||
|
int cX = MathHelper.floor(info.getPosition().x);
|
||||||
|
int cY = MathHelper.floor(info.getPosition().y);
|
||||||
|
int cZ = MathHelper.floor(info.getPosition().z);
|
||||||
|
|
||||||
|
int dX = cX - originCoordinate.getX();
|
||||||
|
int dY = cY - originCoordinate.getY();
|
||||||
|
int dZ = cZ - originCoordinate.getZ();
|
||||||
|
|
||||||
|
if (Math.abs(dX) > MAX_ORIGIN_DISTANCE || Math.abs(dY) > MAX_ORIGIN_DISTANCE || Math.abs(dZ) > MAX_ORIGIN_DISTANCE) {
|
||||||
|
|
||||||
|
originCoordinate = new BlockPos(cX, cY, cZ);
|
||||||
|
|
||||||
|
for (Map<IRenderState, MaterialGroup<P>> groups : layers.values()) {
|
||||||
|
groups.values().forEach(MaterialGroup::clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners.forEach(OriginShiftListener::onOriginShift);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MaterialGroup<P> createGroup(IRenderState state) {
|
||||||
|
return groupFactory.create(this, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface OriginShiftListener {
|
||||||
|
void onOriginShift();
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface GroupFactory<P extends WorldProgram> {
|
||||||
|
MaterialGroup<P> create(MaterialManager<P> materialManager, IRenderState state);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,26 +1,24 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing;
|
package com.jozufozu.flywheel.backend.material;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
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.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 MaterialRenderer<P extends WorldProgram> {
|
public class MaterialRenderer<P extends WorldProgram> {
|
||||||
|
|
||||||
private final Supplier<P> program;
|
protected final Supplier<P> program;
|
||||||
private final InstanceMaterial<?> material;
|
protected final InstanceMaterial<?> material;
|
||||||
|
|
||||||
public MaterialRenderer(Supplier<P> programSupplier, InstanceMaterial<?> material) {
|
public MaterialRenderer(Supplier<P> programSupplier, InstanceMaterial<?> material) {
|
||||||
this.program = programSupplier;
|
this.program = programSupplier;
|
||||||
this.material = material;
|
this.material = material;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ, IProgramCallback<P> setup) {
|
public void render(Matrix4f viewProjection, double camX, double camY, double camZ, IProgramCallback<P> setup) {
|
||||||
if (!(layer == RenderType.cutoutMipped())) return;
|
|
||||||
|
|
||||||
if (material.nothingToRender()) return;
|
if (material.nothingToRender()) return;
|
||||||
|
|
||||||
P program = this.program.get();
|
P program = this.program.get();
|
||||||
|
@ -31,10 +29,7 @@ public class MaterialRenderer<P extends WorldProgram> {
|
||||||
|
|
||||||
if (setup != null) setup.call(program);
|
if (setup != null) setup.call(program);
|
||||||
|
|
||||||
makeRenderCalls();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void makeRenderCalls() {
|
|
||||||
material.forEachInstancer(Instancer::render);
|
material.forEachInstancer(Instancer::render);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing;
|
package com.jozufozu.flywheel.backend.material;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.IInstanceFactory;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||||
|
|
||||||
import net.minecraft.inventory.container.PlayerContainer;
|
import net.minecraft.inventory.container.PlayerContainer;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
|
@ -3,6 +3,9 @@ package com.jozufozu.flywheel.backend.state;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
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.core.shader.WorldProgram;
|
||||||
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.jozufozu.flywheel.backend.state;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
|
||||||
|
public enum RenderLayer {
|
||||||
|
SOLID,
|
||||||
|
CUTOUT,
|
||||||
|
TRANSPARENT,
|
||||||
|
;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static RenderLayer fromRenderType(RenderType type) {
|
||||||
|
if (type == RenderType.solid()) {
|
||||||
|
return SOLID;
|
||||||
|
} else if (type == RenderType.cutoutMipped()) {
|
||||||
|
return CUTOUT;
|
||||||
|
} else if (type == RenderType.translucent()) {
|
||||||
|
return TRANSPARENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package com.jozufozu.flywheel.core;
|
package com.jozufozu.flywheel.core;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
import com.jozufozu.flywheel.backend.material.MaterialSpec;
|
||||||
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.event.GatherContextEvent;
|
import com.jozufozu.flywheel.event.GatherContextEvent;
|
||||||
|
|
|
@ -12,7 +12,7 @@ import com.jozufozu.flywheel.backend.ResourceUtil;
|
||||||
import com.jozufozu.flywheel.backend.ShaderContext;
|
import com.jozufozu.flywheel.backend.ShaderContext;
|
||||||
import com.jozufozu.flywheel.backend.ShaderSources;
|
import com.jozufozu.flywheel.backend.ShaderSources;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
import com.jozufozu.flywheel.backend.material.MaterialSpec;
|
||||||
import com.jozufozu.flywheel.backend.loading.InstancedArraysTemplate;
|
import com.jozufozu.flywheel.backend.loading.InstancedArraysTemplate;
|
||||||
import com.jozufozu.flywheel.backend.loading.Program;
|
import com.jozufozu.flywheel.backend.loading.Program;
|
||||||
import com.jozufozu.flywheel.backend.loading.ProgramTemplate;
|
import com.jozufozu.flywheel.backend.loading.ProgramTemplate;
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
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.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> {
|
||||||
|
|
||||||
|
private final int width;
|
||||||
|
private final int height;
|
||||||
|
|
||||||
|
public CrumblingGroup(MaterialManager<P> owner, IRenderState state) {
|
||||||
|
super(owner, state);
|
||||||
|
|
||||||
|
ResourceLocation texture = state.getTexture(GlTextureUnit.T0);
|
||||||
|
|
||||||
|
if (texture != null) {
|
||||||
|
SheetData atlasData = AtlasInfo.getAtlasData(texture);
|
||||||
|
|
||||||
|
width = atlasData.width;
|
||||||
|
height = atlasData.height;
|
||||||
|
} else {
|
||||||
|
width = height = 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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) {
|
||||||
|
p.setAtlasSize(width, height);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package com.jozufozu.flywheel.core.crumbling;
|
package com.jozufozu.flywheel.core.crumbling;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
package com.jozufozu.flywheel.core.crumbling;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialRenderer;
|
|
||||||
import com.jozufozu.flywheel.backend.state.IRenderState;
|
|
||||||
import com.jozufozu.flywheel.core.WorldContext;
|
|
||||||
import com.jozufozu.flywheel.core.atlas.AtlasInfo;
|
|
||||||
import com.jozufozu.flywheel.core.atlas.SheetData;
|
|
||||||
import com.jozufozu.flywheel.core.shader.IProgramCallback;
|
|
||||||
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
|
||||||
|
|
||||||
public class CrumblingMaterialManager extends MaterialManager<CrumblingProgram> {
|
|
||||||
|
|
||||||
public CrumblingMaterialManager(WorldContext<CrumblingProgram> context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ, IProgramCallback<CrumblingProgram> callback) {
|
|
||||||
camX -= originCoordinate.getX();
|
|
||||||
camY -= originCoordinate.getY();
|
|
||||||
camZ -= originCoordinate.getZ();
|
|
||||||
|
|
||||||
Matrix4f translate = Matrix4f.createTranslateMatrix((float) -camX, (float) -camY, (float) -camZ);
|
|
||||||
|
|
||||||
translate.multiplyBackward(viewProjection);
|
|
||||||
|
|
||||||
for (Map.Entry<IRenderState, ArrayList<MaterialRenderer<CrumblingProgram>>> entry : renderers.entrySet()) {
|
|
||||||
IRenderState key = entry.getKey();
|
|
||||||
key.bind();
|
|
||||||
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
|
|
||||||
ResourceLocation texture = key.getTexture(GlTextureUnit.T0);
|
|
||||||
|
|
||||||
if (texture != null) {
|
|
||||||
SheetData atlasData = AtlasInfo.getAtlasData(texture);
|
|
||||||
|
|
||||||
width = atlasData.width;
|
|
||||||
height = atlasData.height;
|
|
||||||
} else {
|
|
||||||
width = height = 256;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (MaterialRenderer<CrumblingProgram> materialRenderer : entry.getValue()) {
|
|
||||||
materialRenderer.render(layer, translate, camX, camY, camZ, p -> p.setAtlasSize(width, height));
|
|
||||||
}
|
|
||||||
|
|
||||||
key.unbind();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,8 +11,10 @@ import java.util.List;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
|
import com.jozufozu.flywheel.backend.state.RenderLayer;
|
||||||
import com.jozufozu.flywheel.core.Contexts;
|
import com.jozufozu.flywheel.core.Contexts;
|
||||||
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||||
import com.jozufozu.flywheel.util.Lazy;
|
import com.jozufozu.flywheel.util.Lazy;
|
||||||
|
@ -84,9 +86,9 @@ public class CrumblingRenderer {
|
||||||
|
|
||||||
renderer.beginFrame(info);
|
renderer.beginFrame(info);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE4);
|
GlTextureUnit.T4.makeActive();
|
||||||
glBindTexture(GL_TEXTURE_2D, breaking.getId());
|
glBindTexture(GL_TEXTURE_2D, breaking.getId());
|
||||||
materials.render(RenderType.cutoutMipped(), viewProjection, cameraX, cameraY, cameraZ);
|
materials.render(RenderLayer.SOLID, viewProjection, cameraX, cameraY, cameraZ);
|
||||||
|
|
||||||
renderer.invalidate();
|
renderer.invalidate();
|
||||||
}
|
}
|
||||||
|
@ -95,7 +97,7 @@ public class CrumblingRenderer {
|
||||||
|
|
||||||
crumblingLayer.clearRenderState();
|
crumblingLayer.clearRenderState();
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
GlTextureUnit.T0.makeActive();
|
||||||
Texture breaking = textureManager.getTexture(ModelBakery.BREAKING_LOCATIONS.get(0));
|
Texture breaking = textureManager.getTexture(ModelBakery.BREAKING_LOCATIONS.get(0));
|
||||||
if (breaking != null) glBindTexture(GL_TEXTURE_2D, breaking.getId());
|
if (breaking != null) glBindTexture(GL_TEXTURE_2D, breaking.getId());
|
||||||
}
|
}
|
||||||
|
@ -146,7 +148,7 @@ public class CrumblingRenderer {
|
||||||
private final InstanceManager<TileEntity> instanceManager;
|
private final InstanceManager<TileEntity> instanceManager;
|
||||||
|
|
||||||
private State() {
|
private State() {
|
||||||
materialManager = new CrumblingMaterialManager(Contexts.CRUMBLING);
|
materialManager = new MaterialManager<>(Contexts.CRUMBLING).setGroupFactory(CrumblingGroup::new);
|
||||||
instanceManager = new CrumblingInstanceManager(materialManager);
|
instanceManager = new CrumblingInstanceManager(materialManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ public interface IProgramCallback<P extends GlProgram> {
|
||||||
void call(P program);
|
void call(P program);
|
||||||
|
|
||||||
default IProgramCallback<P> andThen(IProgramCallback<P> other) {
|
default IProgramCallback<P> andThen(IProgramCallback<P> other) {
|
||||||
|
if (other == null) return this;
|
||||||
|
|
||||||
return program -> {
|
return program -> {
|
||||||
call(program);
|
call(program);
|
||||||
other.call(program);
|
other.call(program);
|
||||||
|
|
|
@ -6,7 +6,19 @@ import net.minecraft.util.math.vector.Quaternion;
|
||||||
|
|
||||||
public class MatrixTransformStack implements TransformStack {
|
public class MatrixTransformStack implements TransformStack {
|
||||||
|
|
||||||
private final MatrixStack internal = new MatrixStack();
|
private final MatrixStack internal;
|
||||||
|
|
||||||
|
public MatrixTransformStack() {
|
||||||
|
this(new MatrixStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
public MatrixTransformStack(MatrixStack internal) {
|
||||||
|
this.internal = internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MatrixTransformStack of(MatrixStack ms) {
|
||||||
|
return new MatrixTransformStack(ms);
|
||||||
|
}
|
||||||
|
|
||||||
public MatrixStack unwrap() {
|
public MatrixStack unwrap() {
|
||||||
return internal;
|
return internal;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.jozufozu.flywheel.vanilla;
|
package com.jozufozu.flywheel.vanilla;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
|
import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
||||||
import com.jozufozu.flywheel.backend.model.BufferedModel;
|
import com.jozufozu.flywheel.backend.model.BufferedModel;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
import com.jozufozu.flywheel.core.Materials;
|
||||||
|
@ -58,8 +58,9 @@ public class BellInstance extends TileEntityInstance<BellTileEntity> implements
|
||||||
}
|
}
|
||||||
|
|
||||||
private OrientedData createBellInstance() {
|
private OrientedData createBellInstance() {
|
||||||
return materialManager.getMaterial(Materials.ORIENTED)
|
return materialManager.defaultCutout()
|
||||||
.get(tile.getType(), BellInstance::createBellModel)
|
.material(Materials.ORIENTED)
|
||||||
|
.model(tile.getType(), BellInstance::createBellModel)
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,10 @@ import java.util.Calendar;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
|
import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
||||||
import com.jozufozu.flywheel.backend.model.BufferedModel;
|
import com.jozufozu.flywheel.backend.model.BufferedModel;
|
||||||
|
import com.jozufozu.flywheel.backend.state.TextureRenderState;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
import com.jozufozu.flywheel.core.Materials;
|
||||||
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;
|
||||||
|
@ -119,15 +120,17 @@ public class ChestInstance<T extends TileEntity & IChestLid> extends TileEntityI
|
||||||
|
|
||||||
private OrientedData baseInstance() {
|
private OrientedData baseInstance() {
|
||||||
|
|
||||||
return materialManager.getMaterial(Materials.ORIENTED, renderMaterial.atlasLocation())
|
return materialManager.solid(TextureRenderState.get(renderMaterial.atlasLocation()))
|
||||||
.get("base_" + renderMaterial.texture(), this::getBaseModel)
|
.material(Materials.ORIENTED)
|
||||||
|
.model("base_" + renderMaterial.texture(), this::getBaseModel)
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelData lidInstance() {
|
private ModelData lidInstance() {
|
||||||
|
|
||||||
return materialManager.getMaterial(Materials.TRANSFORMED, renderMaterial.atlasLocation())
|
return materialManager.solid(TextureRenderState.get(renderMaterial.atlasLocation()))
|
||||||
.get("lid_" + renderMaterial.texture(), this::getLidModel)
|
.material(Materials.TRANSFORMED)
|
||||||
|
.model("lid_" + renderMaterial.texture(), this::getLidModel)
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import java.util.stream.Collectors;
|
||||||
import com.jozufozu.flywheel.backend.state.IRenderState;
|
import com.jozufozu.flywheel.backend.state.IRenderState;
|
||||||
import com.jozufozu.flywheel.backend.state.NoCullRenderState;
|
import com.jozufozu.flywheel.backend.state.NoCullRenderState;
|
||||||
import com.jozufozu.flywheel.backend.state.RenderState;
|
import com.jozufozu.flywheel.backend.state.RenderState;
|
||||||
|
import com.jozufozu.flywheel.backend.state.TextureRenderState;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.Atlases;
|
import net.minecraft.client.renderer.Atlases;
|
||||||
import net.minecraft.client.renderer.model.RenderMaterial;
|
import net.minecraft.client.renderer.model.RenderMaterial;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.jozufozu.flywheel.vanilla;
|
package com.jozufozu.flywheel.vanilla;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
|
import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
|
||||||
import com.jozufozu.flywheel.backend.model.BufferedModel;
|
import com.jozufozu.flywheel.backend.model.BufferedModel;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
import com.jozufozu.flywheel.core.Materials;
|
||||||
|
@ -88,14 +88,16 @@ public class ShulkerBoxInstance extends TileEntityInstance<ShulkerBoxTileEntity>
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelData makeBaseInstance() {
|
private ModelData makeBaseInstance() {
|
||||||
return materialManager.getMaterial(Materials.TRANSFORMED, RenderStates.SHULKER)
|
return materialManager.cutout(RenderStates.SHULKER)
|
||||||
.get("base_" + texture.getName(), this::makeBaseModel)
|
.material(Materials.TRANSFORMED)
|
||||||
|
.model("base_" + texture.getName(), this::makeBaseModel)
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelData makeLidInstance() {
|
private ModelData makeLidInstance() {
|
||||||
return materialManager.getMaterial(Materials.TRANSFORMED, RenderStates.SHULKER)
|
return materialManager.cutout(RenderStates.SHULKER)
|
||||||
.get("lid_" + texture.getName(), this::makeLidModel)
|
.material(Materials.TRANSFORMED)
|
||||||
|
.model("lid_" + texture.getName(), this::makeLidModel)
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue