mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-28 16:06:28 +01:00
Merge branch '1.17/dev' into 1.18/dev
This commit is contained in:
commit
fd0343c48b
26 changed files with 388 additions and 90 deletions
|
@ -0,0 +1,39 @@
|
|||
package com.jozufozu.flywheel.backend.instancing;
|
||||
|
||||
import com.jozufozu.flywheel.backend.struct.BatchingTransformer;
|
||||
import com.jozufozu.flywheel.backend.struct.StructType;
|
||||
import com.jozufozu.flywheel.core.model.IModel;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
|
||||
public class CPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
||||
|
||||
private final BatchingTransformer<D> renderer;
|
||||
|
||||
public CPUInstancer(StructType<D> type, IModel modelData) {
|
||||
super(type, modelData);
|
||||
|
||||
renderer = type.asBatched()
|
||||
.getTransformer(modelData);
|
||||
}
|
||||
|
||||
public void drawAll(PoseStack stack, VertexConsumer buffer) {
|
||||
if (renderer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
renderSetup();
|
||||
|
||||
for (D d : data) {
|
||||
renderer.draw(d, stack, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderSetup() {
|
||||
if (anyToRemove) {
|
||||
removeDeletedInstances();
|
||||
}
|
||||
|
||||
anyToRemove = anyToUpdate = false;
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ import javax.annotation.Nullable;
|
|||
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialManagerImpl;
|
||||
import com.jozufozu.flywheel.backend.material.instancing.InstancingEngine;
|
||||
import com.jozufozu.flywheel.light.LightUpdater;
|
||||
import com.mojang.math.Vector3f;
|
||||
|
||||
|
@ -19,7 +19,7 @@ import net.minecraft.client.Camera;
|
|||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.Mth;
|
||||
|
||||
public abstract class InstanceManager<T> implements MaterialManagerImpl.OriginShiftListener {
|
||||
public abstract class InstanceManager<T> implements InstancingEngine.OriginShiftListener {
|
||||
|
||||
public final MaterialManager materialManager;
|
||||
|
||||
|
@ -33,7 +33,7 @@ public abstract class InstanceManager<T> implements MaterialManagerImpl.OriginSh
|
|||
protected int frame;
|
||||
protected int tick;
|
||||
|
||||
public InstanceManager(MaterialManagerImpl<?> materialManager) {
|
||||
public InstanceManager(MaterialManager materialManager) {
|
||||
this.materialManager = materialManager;
|
||||
this.queuedUpdates = new HashSet<>(64);
|
||||
this.queuedAdditions = new HashSet<>(64);
|
||||
|
@ -41,8 +41,6 @@ public abstract class InstanceManager<T> implements MaterialManagerImpl.OriginSh
|
|||
|
||||
this.dynamicInstances = new Object2ObjectOpenHashMap<>();
|
||||
this.tickableInstances = new Object2ObjectOpenHashMap<>();
|
||||
|
||||
materialManager.addListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,8 +2,9 @@ package com.jozufozu.flywheel.backend.instancing;
|
|||
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstanceManager;
|
||||
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialManagerImpl;
|
||||
import com.jozufozu.flywheel.backend.material.Engine;
|
||||
import com.jozufozu.flywheel.backend.material.instancing.InstancingEngine;
|
||||
import com.jozufozu.flywheel.backend.material.batching.BatchingEngine;
|
||||
import com.jozufozu.flywheel.core.Contexts;
|
||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
||||
|
@ -22,20 +23,28 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
|||
* </p>
|
||||
*/
|
||||
public class InstanceWorld {
|
||||
protected final MaterialManagerImpl<WorldProgram> materialManager;
|
||||
protected final Engine engine;
|
||||
protected final InstanceManager<Entity> entityInstanceManager;
|
||||
protected final InstanceManager<BlockEntity> tileEntityInstanceManager;
|
||||
|
||||
public InstanceWorld() {
|
||||
|
||||
// TODO: finish impl
|
||||
if (false) {
|
||||
engine = new BatchingEngine();
|
||||
entityInstanceManager = new EntityInstanceManager(engine);
|
||||
tileEntityInstanceManager = new TileInstanceManager(engine);
|
||||
} else {
|
||||
InstancingEngine<WorldProgram> manager = InstancingEngine.builder(Contexts.WORLD)
|
||||
.build();
|
||||
|
||||
materialManager = MaterialManagerImpl.builder(Contexts.WORLD)
|
||||
.build();
|
||||
entityInstanceManager = new EntityInstanceManager(materialManager);
|
||||
tileEntityInstanceManager = new TileInstanceManager(materialManager);
|
||||
}
|
||||
entityInstanceManager = new EntityInstanceManager(manager);
|
||||
tileEntityInstanceManager = new TileInstanceManager(manager);
|
||||
|
||||
public MaterialManager getMaterialManager() {
|
||||
return materialManager;
|
||||
manager.addListener(entityInstanceManager);
|
||||
manager.addListener(tileEntityInstanceManager);
|
||||
engine = manager;
|
||||
}
|
||||
}
|
||||
|
||||
public InstanceManager<Entity> getEntityInstanceManager() {
|
||||
|
@ -50,7 +59,7 @@ public class InstanceWorld {
|
|||
* Free all acquired resources and invalidate this instance world.
|
||||
*/
|
||||
public void delete() {
|
||||
materialManager.delete();
|
||||
engine.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,7 +82,7 @@ public class InstanceWorld {
|
|||
* </p>
|
||||
*/
|
||||
public void beginFrame(BeginFrameEvent event) {
|
||||
materialManager.beginFrame(event.getInfo());
|
||||
engine.beginFrame(event.getInfo());
|
||||
|
||||
tileEntityInstanceManager.beginFrame(event.getInfo());
|
||||
entityInstanceManager.beginFrame(event.getInfo());
|
||||
|
@ -99,6 +108,6 @@ public class InstanceWorld {
|
|||
* Draw the given layer.
|
||||
*/
|
||||
public void renderLayer(RenderLayerEvent event) {
|
||||
materialManager.render(event.layer, event.viewProjection, event.camX, event.camY, event.camZ);
|
||||
engine.render(event, event.buffers.bufferSource());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import com.jozufozu.flywheel.backend.Backend;
|
|||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialManagerImpl;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
@ -13,7 +13,7 @@ import net.minecraft.world.level.Level;
|
|||
|
||||
public class EntityInstanceManager extends InstanceManager<Entity> {
|
||||
|
||||
public EntityInstanceManager(MaterialManagerImpl<?> materialManager) {
|
||||
public EntityInstanceManager(MaterialManager materialManager) {
|
||||
super(materialManager);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import com.jozufozu.flywheel.backend.Backend;
|
|||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialManagerImpl;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
|
@ -13,7 +13,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
|||
|
||||
public class TileInstanceManager extends InstanceManager<BlockEntity> {
|
||||
|
||||
public TileInstanceManager(MaterialManagerImpl<?> materialManager) {
|
||||
public TileInstanceManager(MaterialManager materialManager) {
|
||||
super(materialManager);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
package com.jozufozu.flywheel.backend.material;
|
||||
|
||||
public interface Engine extends RenderDispatcher, MaterialManager {
|
||||
}
|
|
@ -11,7 +11,7 @@ public interface MaterialManager {
|
|||
* Get a material group that will render in the given layer with the given state.
|
||||
*
|
||||
* @param layer The {@link RenderLayer} you want to draw in.
|
||||
* @param state The {@link net.minecraft.client.renderer.RenderType} you need to draw with.
|
||||
* @param state The {@link RenderType} you need to draw with.
|
||||
* @return A material group whose children will
|
||||
*/
|
||||
MaterialGroup state(RenderLayer layer, RenderType state);
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package com.jozufozu.flywheel.backend.material;
|
||||
|
||||
import com.jozufozu.flywheel.backend.state.RenderLayer;
|
||||
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
||||
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
|
||||
public interface RenderDispatcher {
|
||||
/**
|
||||
* Render every model for every material.
|
||||
*
|
||||
* @param layer Which of the 3 {@link RenderLayer render layers} is being drawn?
|
||||
* @param viewProjection How do we get from camera space to clip space?
|
||||
*/
|
||||
void render(RenderLayerEvent event, MultiBufferSource buffers);
|
||||
|
||||
/**
|
||||
* Maintain the integer origin coordinate to be within a certain distance from the camera in all directions.
|
||||
* <p>
|
||||
* This prevents floating point precision issues at high coordinates.
|
||||
*/
|
||||
void beginFrame(Camera info);
|
||||
|
||||
default void delete() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.jozufozu.flywheel.backend.material.batching;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.CPUInstancer;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||
import com.jozufozu.flywheel.backend.instancing.Instancer;
|
||||
import com.jozufozu.flywheel.backend.material.Material;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialSpec;
|
||||
import com.jozufozu.flywheel.backend.struct.StructType;
|
||||
import com.jozufozu.flywheel.core.model.IModel;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
|
||||
public class BatchedMaterial<D extends InstanceData> implements Material<D> {
|
||||
|
||||
protected final Map<Object, CPUInstancer<D>> models;
|
||||
private final StructType<D> type;
|
||||
|
||||
public BatchedMaterial(MaterialSpec<D> spec) {
|
||||
type = spec.getInstanceType();
|
||||
|
||||
this.models = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instancer<D> model(Object key, Supplier<IModel> modelSupplier) {
|
||||
return models.computeIfAbsent(key, $ -> new CPUInstancer<>(type, modelSupplier.get()));
|
||||
}
|
||||
|
||||
public void render(PoseStack stack, VertexConsumer buffer) {
|
||||
for (CPUInstancer<D> instancer : models.values()) {
|
||||
instancer.drawAll(stack, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all instance data without freeing resources.
|
||||
*/
|
||||
public void clear() {
|
||||
models.values()
|
||||
.forEach(CPUInstancer::clear);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package com.jozufozu.flywheel.backend.material.batching;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialGroup;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialSpec;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
|
||||
public class BatchedMaterialGroup implements MaterialGroup {
|
||||
|
||||
protected final RenderType state;
|
||||
|
||||
private final Map<MaterialSpec<?>, BatchedMaterial<?>> materials = new HashMap<>();
|
||||
|
||||
public BatchedMaterialGroup(RenderType state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the material as defined by the given {@link MaterialSpec spec}.
|
||||
* @param spec The material you want to create instances with.
|
||||
* @param <D> The type representing the per instance data.
|
||||
* @return A
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <D extends InstanceData> BatchedMaterial<D> material(MaterialSpec<D> spec) {
|
||||
return (BatchedMaterial<D>) materials.computeIfAbsent(spec, BatchedMaterial::new);
|
||||
}
|
||||
|
||||
public void render(PoseStack stack, MultiBufferSource source) {
|
||||
VertexConsumer buffer = source.getBuffer(state);
|
||||
|
||||
for (BatchedMaterial<?> value : materials.values()) {
|
||||
value.render(stack, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
materials.values().forEach(BatchedMaterial::clear);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
materials.clear();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.jozufozu.flywheel.backend.material.batching;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.jozufozu.flywheel.backend.material.Engine;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialGroup;
|
||||
import com.jozufozu.flywheel.backend.state.RenderLayer;
|
||||
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
||||
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Vec3i;
|
||||
|
||||
public class BatchingEngine implements Engine {
|
||||
|
||||
protected BlockPos originCoordinate = BlockPos.ZERO;
|
||||
|
||||
protected final Map<RenderLayer, Map<RenderType, BatchedMaterialGroup>> layers;
|
||||
|
||||
public BatchingEngine() {
|
||||
this.layers = new EnumMap<>(RenderLayer.class);
|
||||
for (RenderLayer value : RenderLayer.values()) {
|
||||
layers.put(value, new HashMap<>());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialGroup state(RenderLayer layer, RenderType state) {
|
||||
return layers.get(layer).computeIfAbsent(state, BatchedMaterialGroup::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3i getOriginCoordinate() {
|
||||
return originCoordinate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderLayerEvent event, MultiBufferSource buffers) {
|
||||
for (Map.Entry<RenderType, BatchedMaterialGroup> entry : layers.get(event.getLayer()).entrySet()) {
|
||||
BatchedMaterialGroup group = entry.getValue();
|
||||
|
||||
group.render(event.stack, buffers);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginFrame(Camera info) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||
package com.jozufozu.flywheel.backend.material.batching;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.backend.material;
|
||||
package com.jozufozu.flywheel.backend.material.instancing;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Supplier;
|
||||
|
@ -9,6 +9,8 @@ import com.jozufozu.flywheel.backend.RenderWork;
|
|||
import com.jozufozu.flywheel.backend.instancing.GPUInstancer;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||
import com.jozufozu.flywheel.backend.instancing.Instancer;
|
||||
import com.jozufozu.flywheel.backend.material.Material;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialSpec;
|
||||
import com.jozufozu.flywheel.backend.model.ModelPool;
|
||||
import com.jozufozu.flywheel.backend.struct.StructType;
|
||||
import com.jozufozu.flywheel.core.model.IModel;
|
||||
|
@ -17,13 +19,13 @@ import com.jozufozu.flywheel.core.model.IModel;
|
|||
* A collection of Instancers that all have the same format.
|
||||
* @param <D>
|
||||
*/
|
||||
public class MaterialImpl<D extends InstanceData> implements Material<D> {
|
||||
public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
||||
|
||||
final ModelPool modelPool;
|
||||
protected final Cache<Object, GPUInstancer<D>> models;
|
||||
protected final StructType<D> type;
|
||||
|
||||
public MaterialImpl(MaterialSpec<D> spec) {
|
||||
public InstancedMaterial(MaterialSpec<D> spec) {
|
||||
this.type = spec.getInstanceType();
|
||||
|
||||
modelPool = new ModelPool(spec.getModelFormat(), 64);
|
|
@ -1,10 +1,12 @@
|
|||
package com.jozufozu.flywheel.backend.material;
|
||||
package com.jozufozu.flywheel.backend.material.instancing;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialGroup;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialSpec;
|
||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||
import com.jozufozu.flywheel.util.TextureBinder;
|
||||
import com.mojang.math.Matrix4f;
|
||||
|
@ -17,15 +19,15 @@ import net.minecraft.client.renderer.RenderType;
|
|||
* The children of a material group will all be rendered at the same time.
|
||||
* No guarantees are made about the order of draw calls.
|
||||
*/
|
||||
public class MaterialGroupImpl<P extends WorldProgram> implements MaterialGroup {
|
||||
public class InstancedMaterialGroup<P extends WorldProgram> implements MaterialGroup {
|
||||
|
||||
protected final MaterialManagerImpl<P> owner;
|
||||
protected final InstancingEngine<P> owner;
|
||||
|
||||
protected final ArrayList<MaterialRenderer<P>> renderers = new ArrayList<>();
|
||||
protected final ArrayList<InstancedMaterialRenderer<P>> renderers = new ArrayList<>();
|
||||
|
||||
private final Map<MaterialSpec<?>, MaterialImpl<?>> materials = new HashMap<>();
|
||||
private final Map<MaterialSpec<?>, InstancedMaterial<?>> materials = new HashMap<>();
|
||||
|
||||
public MaterialGroupImpl(MaterialManagerImpl<P> owner) {
|
||||
public InstancedMaterialGroup(InstancingEngine<P> owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
|
@ -37,14 +39,14 @@ public class MaterialGroupImpl<P extends WorldProgram> implements MaterialGroup
|
|||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <D extends InstanceData> MaterialImpl<D> material(MaterialSpec<D> spec) {
|
||||
return (MaterialImpl<D>) materials.computeIfAbsent(spec, this::createInstanceMaterial);
|
||||
public <D extends InstanceData> InstancedMaterial<D> material(MaterialSpec<D> spec) {
|
||||
return (InstancedMaterial<D>) materials.computeIfAbsent(spec, this::createInstanceMaterial);
|
||||
}
|
||||
|
||||
public void render(RenderType type, Matrix4f viewProjection, double camX, double camY, double camZ) {
|
||||
type.setupRenderState();
|
||||
TextureBinder.bindActiveTextures();
|
||||
for (MaterialRenderer<P> renderer : renderers) {
|
||||
for (InstancedMaterialRenderer<P> renderer : renderers) {
|
||||
renderer.render(viewProjection, camX, camY, camZ);
|
||||
}
|
||||
type.clearRenderState();
|
||||
|
@ -55,21 +57,21 @@ public class MaterialGroupImpl<P extends WorldProgram> implements MaterialGroup
|
|||
}
|
||||
|
||||
public void clear() {
|
||||
materials.values().forEach(MaterialImpl::clear);
|
||||
materials.values().forEach(InstancedMaterial::clear);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
materials.values()
|
||||
.forEach(MaterialImpl::delete);
|
||||
.forEach(InstancedMaterial::delete);
|
||||
|
||||
materials.clear();
|
||||
renderers.clear();
|
||||
}
|
||||
|
||||
private MaterialImpl<?> createInstanceMaterial(MaterialSpec<?> type) {
|
||||
MaterialImpl<?> material = new MaterialImpl<>(type);
|
||||
private InstancedMaterial<?> createInstanceMaterial(MaterialSpec<?> type) {
|
||||
InstancedMaterial<?> material = new InstancedMaterial<>(type);
|
||||
|
||||
this.renderers.add(new MaterialRenderer<>(owner.getProgram(type.getProgramName()), material, this::setup));
|
||||
this.renderers.add(new InstancedMaterialRenderer<>(owner.getProgram(type.getProgramName()), material, this::setup));
|
||||
|
||||
return material;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.backend.material;
|
||||
package com.jozufozu.flywheel.backend.material.instancing;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Consumer;
|
||||
|
@ -8,14 +8,14 @@ import com.jozufozu.flywheel.backend.instancing.GPUInstancer;
|
|||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||
import com.mojang.math.Matrix4f;
|
||||
|
||||
public class MaterialRenderer<P extends WorldProgram> {
|
||||
public class InstancedMaterialRenderer<P extends WorldProgram> {
|
||||
|
||||
protected final Supplier<P> program;
|
||||
protected final MaterialImpl<?> material;
|
||||
protected final InstancedMaterial<?> material;
|
||||
|
||||
protected final Consumer<P> setupFunc;
|
||||
|
||||
public MaterialRenderer(Supplier<P> programSupplier, MaterialImpl<?> material, Consumer<P> setupFunc) {
|
||||
public InstancedMaterialRenderer(Supplier<P> programSupplier, InstancedMaterial<?> material, Consumer<P> setupFunc) {
|
||||
this.program = programSupplier;
|
||||
this.material = material;
|
||||
this.setupFunc = setupFunc;
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.backend.material;
|
||||
package com.jozufozu.flywheel.backend.material.instancing;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
|
@ -7,20 +7,24 @@ import java.util.function.Supplier;
|
|||
|
||||
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||
import com.jozufozu.flywheel.backend.material.Engine;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialGroup;
|
||||
import com.jozufozu.flywheel.backend.state.RenderLayer;
|
||||
import com.jozufozu.flywheel.core.WorldContext;
|
||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
||||
import com.jozufozu.flywheel.util.WeakHashSet;
|
||||
import com.mojang.math.Matrix4f;
|
||||
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
|
||||
public class MaterialManagerImpl<P extends WorldProgram> implements MaterialManager {
|
||||
public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||
|
||||
public static int MAX_ORIGIN_DISTANCE = 100;
|
||||
|
||||
|
@ -30,19 +34,19 @@ public class MaterialManagerImpl<P extends WorldProgram> implements MaterialMana
|
|||
protected final GroupFactory<P> groupFactory;
|
||||
protected final boolean ignoreOriginCoordinate;
|
||||
|
||||
protected final Map<RenderLayer, Map<RenderType, MaterialGroupImpl<P>>> layers;
|
||||
protected final Map<RenderLayer, Map<RenderType, InstancedMaterialGroup<P>>> layers;
|
||||
|
||||
private final WeakHashSet<OriginShiftListener> listeners;
|
||||
|
||||
public MaterialManagerImpl(WorldContext<P> context) {
|
||||
this(context, MaterialGroupImpl::new, false);
|
||||
public InstancingEngine(WorldContext<P> context) {
|
||||
this(context, InstancedMaterialGroup::new, false);
|
||||
}
|
||||
|
||||
public static <P extends WorldProgram> Builder<P> builder(WorldContext<P> context) {
|
||||
return new Builder<>(context);
|
||||
}
|
||||
|
||||
public MaterialManagerImpl(WorldContext<P> context, GroupFactory<P> groupFactory, boolean ignoreOriginCoordinate) {
|
||||
public InstancingEngine(WorldContext<P> context, GroupFactory<P> groupFactory, boolean ignoreOriginCoordinate) {
|
||||
this.context = context;
|
||||
this.ignoreOriginCoordinate = ignoreOriginCoordinate;
|
||||
|
||||
|
@ -69,10 +73,13 @@ public class MaterialManagerImpl<P extends WorldProgram> implements MaterialMana
|
|||
|
||||
/**
|
||||
* Render every model for every material.
|
||||
* @param layer Which of the 3 {@link RenderLayer render layers} 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) {
|
||||
@Override
|
||||
public void render(RenderLayerEvent event, MultiBufferSource buffers) {
|
||||
double camX = event.camX;
|
||||
double camY = event.camY;
|
||||
double camZ = event.camZ;
|
||||
Matrix4f viewProjection = event.viewProjection;
|
||||
if (!ignoreOriginCoordinate) {
|
||||
camX -= originCoordinate.getX();
|
||||
camY -= originCoordinate.getY();
|
||||
|
@ -85,9 +92,9 @@ public class MaterialManagerImpl<P extends WorldProgram> implements MaterialMana
|
|||
viewProjection = translate;
|
||||
}
|
||||
|
||||
for (Map.Entry<RenderType, MaterialGroupImpl<P>> entry : layers.get(layer).entrySet()) {
|
||||
for (Map.Entry<RenderType, InstancedMaterialGroup<P>> entry : layers.get(event.getLayer()).entrySet()) {
|
||||
RenderType state = entry.getKey();
|
||||
MaterialGroupImpl<P> group = entry.getValue();
|
||||
InstancedMaterialGroup<P> group = entry.getValue();
|
||||
|
||||
group.render(state, viewProjection, camX, camY, camZ);
|
||||
}
|
||||
|
@ -97,10 +104,11 @@ public class MaterialManagerImpl<P extends WorldProgram> implements MaterialMana
|
|||
GlVertexArray.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
for (Map<RenderType, MaterialGroupImpl<P>> groups : layers.values()) {
|
||||
for (Map<RenderType, InstancedMaterialGroup<P>> groups : layers.values()) {
|
||||
|
||||
groups.values().forEach(MaterialGroupImpl::delete);
|
||||
groups.values().forEach(InstancedMaterialGroup::delete);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,6 +130,7 @@ public class MaterialManagerImpl<P extends WorldProgram> implements MaterialMana
|
|||
*
|
||||
* This prevents floating point precision issues at high coordinates.
|
||||
*/
|
||||
@Override
|
||||
public void beginFrame(Camera info) {
|
||||
int cX = Mth.floor(info.getPosition().x);
|
||||
int cY = Mth.floor(info.getPosition().y);
|
||||
|
@ -135,8 +144,8 @@ public class MaterialManagerImpl<P extends WorldProgram> implements MaterialMana
|
|||
|
||||
originCoordinate = new BlockPos(cX, cY, cZ);
|
||||
|
||||
for (Map<RenderType, MaterialGroupImpl<P>> groups : layers.values()) {
|
||||
groups.values().forEach(MaterialGroupImpl::clear);
|
||||
for (Map<RenderType, InstancedMaterialGroup<P>> groups : layers.values()) {
|
||||
groups.values().forEach(InstancedMaterialGroup::clear);
|
||||
}
|
||||
|
||||
listeners.forEach(OriginShiftListener::onOriginShift);
|
||||
|
@ -150,12 +159,12 @@ public class MaterialManagerImpl<P extends WorldProgram> implements MaterialMana
|
|||
|
||||
@FunctionalInterface
|
||||
public interface GroupFactory<P extends WorldProgram> {
|
||||
MaterialGroupImpl<P> create(MaterialManagerImpl<P> materialManager);
|
||||
InstancedMaterialGroup<P> create(InstancingEngine<P> materialManager);
|
||||
}
|
||||
|
||||
public static class Builder<P extends WorldProgram> {
|
||||
protected final WorldContext<P> context;
|
||||
protected GroupFactory<P> groupFactory = MaterialGroupImpl::new;
|
||||
protected GroupFactory<P> groupFactory = InstancedMaterialGroup::new;
|
||||
protected boolean ignoreOriginCoordinate;
|
||||
|
||||
public Builder(WorldContext<P> context) {
|
||||
|
@ -172,8 +181,8 @@ public class MaterialManagerImpl<P extends WorldProgram> implements MaterialMana
|
|||
return this;
|
||||
}
|
||||
|
||||
public MaterialManagerImpl<P> build() {
|
||||
return new MaterialManagerImpl<>(context, groupFactory, ignoreOriginCoordinate);
|
||||
public InstancingEngine<P> build() {
|
||||
return new InstancingEngine<>(context, groupFactory, ignoreOriginCoordinate);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.jozufozu.flywheel.backend.struct;
|
||||
|
||||
import com.jozufozu.flywheel.core.model.IModel;
|
||||
|
||||
public interface Batched<S> extends StructType<S> {
|
||||
|
||||
BatchingTransformer<S> getTransformer(IModel model);
|
||||
|
||||
@Override
|
||||
default Batched<S> asBatched() {
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.jozufozu.flywheel.backend.struct;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
|
||||
public abstract class BatchingTransformer<S> {
|
||||
|
||||
public void draw(S s, PoseStack stack, VertexConsumer consumer) {
|
||||
|
||||
}
|
||||
}
|
|
@ -19,4 +19,6 @@ public interface StructType<S> {
|
|||
VertexFormat format();
|
||||
|
||||
Writeable<S> asWriteable();
|
||||
|
||||
Batched<S> asBatched();
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.jozufozu.flywheel.core.crumbling;
|
||||
|
||||
import com.jozufozu.flywheel.backend.material.MaterialGroupImpl;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialManagerImpl;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialRenderer;
|
||||
import com.jozufozu.flywheel.backend.material.instancing.InstancedMaterialGroup;
|
||||
import com.jozufozu.flywheel.backend.material.instancing.InstancingEngine;
|
||||
import com.jozufozu.flywheel.backend.material.instancing.InstancedMaterialRenderer;
|
||||
import com.jozufozu.flywheel.core.atlas.AtlasInfo;
|
||||
import com.jozufozu.flywheel.core.atlas.SheetData;
|
||||
import com.jozufozu.flywheel.util.RenderTextures;
|
||||
|
@ -13,12 +13,12 @@ import com.mojang.math.Matrix4f;
|
|||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class CrumblingGroup<P extends CrumblingProgram> extends MaterialGroupImpl<P> {
|
||||
public class CrumblingGroup<P extends CrumblingProgram> extends InstancedMaterialGroup<P> {
|
||||
|
||||
private int width;
|
||||
private int height;
|
||||
|
||||
public CrumblingGroup(MaterialManagerImpl<P> owner) {
|
||||
public CrumblingGroup(InstancingEngine<P> owner) {
|
||||
super(owner);
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ public class CrumblingGroup<P extends CrumblingProgram> extends MaterialGroupImp
|
|||
RenderSystem.setShaderTexture(4, breakingTex);
|
||||
|
||||
TextureBinder.bindActiveTextures();
|
||||
for (MaterialRenderer<P> renderer : renderers) {
|
||||
for (InstancedMaterialRenderer<P> renderer : renderers) {
|
||||
renderer.render(viewProjection, camX, camY, camZ);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package com.jozufozu.flywheel.core.crumbling;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialManagerImpl;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
||||
public class CrumblingInstanceManager extends TileInstanceManager {
|
||||
|
||||
public CrumblingInstanceManager(MaterialManagerImpl<?> materialManager) {
|
||||
public CrumblingInstanceManager(MaterialManager materialManager) {
|
||||
super(materialManager);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,17 +6,15 @@ import java.util.SortedSet;
|
|||
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
||||
import com.jozufozu.flywheel.backend.gl.error.GlError;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialManagerImpl;
|
||||
import com.jozufozu.flywheel.backend.state.RenderLayer;
|
||||
import com.jozufozu.flywheel.backend.material.instancing.InstancingEngine;
|
||||
import com.jozufozu.flywheel.core.Contexts;
|
||||
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
||||
import com.jozufozu.flywheel.mixin.LevelRendererAccessor;
|
||||
import com.jozufozu.flywheel.util.Lazy;
|
||||
import com.jozufozu.flywheel.util.Pair;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.math.Matrix4f;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
|
@ -55,17 +53,17 @@ public class CrumblingRenderer {
|
|||
INVALIDATOR = state.getSecond();
|
||||
}
|
||||
|
||||
public static void renderBreaking(ClientLevel world, Matrix4f viewProjection, double cameraX, double cameraY, double cameraZ) {
|
||||
public static void renderBreaking(RenderLayerEvent event) {
|
||||
if (!Backend.getInstance()
|
||||
.canUseInstancing(world)) return;
|
||||
.canUseInstancing(event.getWorld())) return;
|
||||
|
||||
Int2ObjectMap<List<BlockEntity>> activeStages = getActiveStageTiles(world);
|
||||
Int2ObjectMap<List<BlockEntity>> activeStages = getActiveStageTiles(event.getWorld());
|
||||
|
||||
if (activeStages.isEmpty()) return;
|
||||
|
||||
State state = STATE.get();
|
||||
InstanceManager<BlockEntity> instanceManager = state.instanceManager;
|
||||
MaterialManagerImpl<CrumblingProgram> materials = state.materialManager;
|
||||
InstancingEngine<CrumblingProgram> materials = state.materialManager;
|
||||
|
||||
TextureManager textureManager = Minecraft.getInstance().getTextureManager();
|
||||
Camera info = Minecraft.getInstance().gameRenderer.getMainCamera();
|
||||
|
@ -79,7 +77,7 @@ public class CrumblingRenderer {
|
|||
|
||||
instanceManager.beginFrame(info);
|
||||
|
||||
materials.render(RenderLayer.SOLID, viewProjection, cameraX, cameraY, cameraZ);
|
||||
materials.render(event, null);
|
||||
|
||||
instanceManager.invalidate();
|
||||
}
|
||||
|
@ -133,14 +131,15 @@ public class CrumblingRenderer {
|
|||
}
|
||||
|
||||
private static class State {
|
||||
private final MaterialManagerImpl<CrumblingProgram> materialManager;
|
||||
private final InstancingEngine<CrumblingProgram> materialManager;
|
||||
private final InstanceManager<BlockEntity> instanceManager;
|
||||
|
||||
private State() {
|
||||
materialManager = MaterialManagerImpl.builder(Contexts.CRUMBLING)
|
||||
materialManager = InstancingEngine.builder(Contexts.CRUMBLING)
|
||||
.setGroupFactory(CrumblingGroup::new)
|
||||
.build();
|
||||
instanceManager = new CrumblingInstanceManager(materialManager);
|
||||
materialManager.addListener(instanceManager);
|
||||
}
|
||||
|
||||
private void kill() {
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package com.jozufozu.flywheel.core.materials.model;
|
||||
|
||||
import com.jozufozu.flywheel.backend.struct.BatchingTransformer;
|
||||
import com.jozufozu.flywheel.core.model.IModel;
|
||||
|
||||
public class ModelTransformer extends BatchingTransformer<ModelData> {
|
||||
public ModelTransformer(IModel model) {
|
||||
|
||||
|
||||
//model.buffer();
|
||||
}
|
||||
}
|
|
@ -2,12 +2,15 @@ package com.jozufozu.flywheel.core.materials.model;
|
|||
|
||||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||
import com.jozufozu.flywheel.backend.struct.Batched;
|
||||
import com.jozufozu.flywheel.backend.struct.BatchingTransformer;
|
||||
import com.jozufozu.flywheel.backend.struct.StructWriter;
|
||||
import com.jozufozu.flywheel.backend.struct.Writeable;
|
||||
import com.jozufozu.flywheel.core.Formats;
|
||||
import com.jozufozu.flywheel.core.materials.model.writer.UnsafeModelWriter;
|
||||
import com.jozufozu.flywheel.core.model.IModel;
|
||||
|
||||
public class ModelType implements Writeable<ModelData> {
|
||||
public class ModelType implements Writeable<ModelData>, Batched<ModelData> {
|
||||
|
||||
@Override
|
||||
public ModelData create() {
|
||||
|
@ -23,4 +26,9 @@ public class ModelType implements Writeable<ModelData> {
|
|||
public StructWriter<ModelData> getWriter(VecBuffer backing) {
|
||||
return new UnsafeModelWriter(backing, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BatchingTransformer<ModelData> getTransformer(IModel model) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,15 @@ package com.jozufozu.flywheel.core.materials.oriented;
|
|||
|
||||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||
import com.jozufozu.flywheel.backend.struct.Batched;
|
||||
import com.jozufozu.flywheel.backend.struct.BatchingTransformer;
|
||||
import com.jozufozu.flywheel.backend.struct.StructWriter;
|
||||
import com.jozufozu.flywheel.backend.struct.Writeable;
|
||||
import com.jozufozu.flywheel.core.Formats;
|
||||
import com.jozufozu.flywheel.core.materials.oriented.writer.UnsafeOrientedWriter;
|
||||
import com.jozufozu.flywheel.core.model.IModel;
|
||||
|
||||
public class OrientedType implements Writeable<OrientedData> {
|
||||
public class OrientedType implements Writeable<OrientedData>, Batched<OrientedData> {
|
||||
|
||||
@Override
|
||||
public OrientedData create() {
|
||||
|
@ -23,4 +26,9 @@ public class OrientedType implements Writeable<OrientedData> {
|
|||
public StructWriter<OrientedData> getWriter(VecBuffer backing) {
|
||||
return new UnsafeOrientedWriter(backing, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BatchingTransformer<OrientedData> getTransformer(IModel model) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,13 +82,9 @@ public class RenderHooksMixin {
|
|||
if (!Backend.getInstance()
|
||||
.available()) return;
|
||||
|
||||
Matrix4f view = stack.last()
|
||||
.pose();
|
||||
Matrix4f viewProjection = view.copy();
|
||||
viewProjection.multiplyBackward(RenderSystem.getProjectionMatrix());
|
||||
|
||||
Vec3 cameraPos = info.getPosition();
|
||||
CrumblingRenderer.renderBreaking(level, viewProjection, cameraPos.x, cameraPos.y, cameraPos.z);
|
||||
|
||||
CrumblingRenderer.renderBreaking(new RenderLayerEvent(level, null, stack, null, cameraPos.x, cameraPos.y, cameraPos.z));
|
||||
|
||||
if (!OptifineHandler.usingShaders()) GL20.glUseProgram(0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue