diff --git a/src/main/java/com/jozufozu/flywheel/api/struct/Batched.java b/src/main/java/com/jozufozu/flywheel/api/struct/Batched.java index a61e326fd..239e088ca 100644 --- a/src/main/java/com/jozufozu/flywheel/api/struct/Batched.java +++ b/src/main/java/com/jozufozu/flywheel/api/struct/Batched.java @@ -1,11 +1,8 @@ package com.jozufozu.flywheel.api.struct; +import com.jozufozu.flywheel.core.model.ModelTransformer; + public interface Batched extends StructType { - BatchingTransformer getTransformer(); - - @Override - default Batched asBatched() { - return this; - } + void transform(S d, ModelTransformer.Params b); } diff --git a/src/main/java/com/jozufozu/flywheel/api/struct/BatchingTransformer.java b/src/main/java/com/jozufozu/flywheel/api/struct/BatchingTransformer.java deleted file mode 100644 index 06ca11419..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/struct/BatchingTransformer.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.jozufozu.flywheel.api.struct; - -import com.jozufozu.flywheel.core.model.ModelTransformer; - -@FunctionalInterface -public interface BatchingTransformer { - - void transform(S s, ModelTransformer.Params b); -} diff --git a/src/main/java/com/jozufozu/flywheel/api/struct/Instanced.java b/src/main/java/com/jozufozu/flywheel/api/struct/Instanced.java index f09ca6bff..64e95b6ba 100644 --- a/src/main/java/com/jozufozu/flywheel/api/struct/Instanced.java +++ b/src/main/java/com/jozufozu/flywheel/api/struct/Instanced.java @@ -14,8 +14,4 @@ public interface Instanced extends StructType { ResourceLocation getProgramSpec(); - @Override - default Instanced asInstanced() { - return this; - } } diff --git a/src/main/java/com/jozufozu/flywheel/api/struct/StructType.java b/src/main/java/com/jozufozu/flywheel/api/struct/StructType.java index 999161229..5d5e2985e 100644 --- a/src/main/java/com/jozufozu/flywheel/api/struct/StructType.java +++ b/src/main/java/com/jozufozu/flywheel/api/struct/StructType.java @@ -18,7 +18,4 @@ public interface StructType { */ VertexFormat format(); - Instanced asInstanced(); - - Batched asBatched(); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstancer.java index af7005abb..a13df5f17 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstancer.java @@ -2,6 +2,7 @@ package com.jozufozu.flywheel.backend.instancing; import java.util.ArrayList; import java.util.BitSet; +import java.util.function.Supplier; import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.Instancer; @@ -10,13 +11,13 @@ import com.jozufozu.flywheel.core.model.Model; public abstract class AbstractInstancer implements Instancer { - protected final StructType type; + protected final Supplier type; protected final Model modelData; protected final ArrayList data = new ArrayList<>(); protected boolean anyToRemove; - protected AbstractInstancer(StructType type, Model modelData) { + protected AbstractInstancer(Supplier type, Model modelData) { this.type = type; this.modelData = modelData; } @@ -26,7 +27,7 @@ public abstract class AbstractInstancer implements Insta */ @Override public D createInstance() { - return _add(type.create()); + return _add(type.get()); } /** diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterial.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterial.java index 18183fa6a..1b314a10a 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterial.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterial.java @@ -7,7 +7,7 @@ import java.util.function.Supplier; import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.Instancer; import com.jozufozu.flywheel.api.Material; -import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.api.struct.Batched; import com.jozufozu.flywheel.core.model.Model; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; @@ -15,9 +15,9 @@ import com.mojang.blaze3d.vertex.VertexConsumer; public class BatchedMaterial implements Material { protected final Map> models; - private final StructType type; + private final Batched type; - public BatchedMaterial(StructType type) { + public BatchedMaterial(Batched type) { this.type = type; this.models = new HashMap<>(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java index c78e3abe4..1dd50c414 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java @@ -5,6 +5,7 @@ import java.util.Map; import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.MaterialGroup; +import com.jozufozu.flywheel.api.struct.Batched; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.backend.instancing.TaskEngine; import com.jozufozu.flywheel.backend.model.DirectBufferBuilder; @@ -19,7 +20,7 @@ public class BatchedMaterialGroup implements MaterialGroup { protected final RenderType state; - private final Map, BatchedMaterial> materials = new HashMap<>(); + private final Map, BatchedMaterial> materials = new HashMap<>(); public BatchedMaterialGroup(RenderType state) { this.state = state; @@ -27,8 +28,12 @@ public class BatchedMaterialGroup implements MaterialGroup { @SuppressWarnings("unchecked") @Override - public BatchedMaterial material(StructType spec) { - return (BatchedMaterial) materials.computeIfAbsent(spec, BatchedMaterial::new); + public BatchedMaterial material(StructType type) { + if (type instanceof Batched batched) { + return (BatchedMaterial) materials.computeIfAbsent(batched, BatchedMaterial::new); + } else { + throw new ClassCastException("Cannot use type '" + type + "' with CPU instancing."); + } } public void render(PoseStack stack, MultiBufferSource source, TaskEngine pool) { diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java index e1dc909af..1d49062c9 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java @@ -49,9 +49,7 @@ public class BatchingEngine implements Engine { stack.translate(-event.camX, -event.camY, -event.camZ); - for (Map.Entry entry : layers.get(event.getLayer()).entrySet()) { - BatchedMaterialGroup group = entry.getValue(); - + for (BatchedMaterialGroup group : layers.get(event.getLayer()).values()) { group.render(stack, buffers, taskEngine); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java index 292bdddad..1c39a076d 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java @@ -1,7 +1,7 @@ package com.jozufozu.flywheel.backend.instancing.batching; import com.jozufozu.flywheel.api.InstanceData; -import com.jozufozu.flywheel.api.struct.BatchingTransformer; +import com.jozufozu.flywheel.api.struct.Batched; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.backend.instancing.AbstractInstancer; import com.jozufozu.flywheel.backend.instancing.TaskEngine; @@ -13,22 +13,17 @@ import com.mojang.blaze3d.vertex.VertexConsumer; public class CPUInstancer extends AbstractInstancer { - private final BatchingTransformer transform; + private final Batched batchingType; private final ModelTransformer sbb; private final ModelTransformer.Params defaultParams; - public CPUInstancer(StructType type, Model modelData) { - super(type, modelData); + public CPUInstancer(Batched type, Model modelData) { + super(type::create, modelData); + batchingType = type; sbb = new ModelTransformer(modelData); defaultParams = ModelTransformer.Params.defaultParams(); - transform = type.asBatched() - .getTransformer(); - - if (transform == null) { - throw new NullPointerException("Cannot batch " + type.toString()); - } } void submitTasks(PoseStack stack, TaskEngine pool, DirectVertexConsumer consumer) { @@ -56,7 +51,7 @@ public class CPUInstancer extends AbstractInstancer { ModelTransformer.Params params = defaultParams.copy(); for (D d : data.subList(from, to)) { - transform.transform(d, params); + batchingType.transform(d, params); sbb.renderInto(params, stack, buffer); @@ -67,7 +62,7 @@ public class CPUInstancer extends AbstractInstancer { void drawAll(PoseStack stack, VertexConsumer buffer) { ModelTransformer.Params params = defaultParams.copy(); for (D d : data) { - transform.transform(d, params); + batchingType.transform(d, params); sbb.renderInto(params, stack, buffer); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java index fc1480ebf..a753b0b05 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java @@ -4,6 +4,7 @@ import java.util.BitSet; import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.InstanceData; +import com.jozufozu.flywheel.api.struct.Instanced; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.api.struct.StructWriter; import com.jozufozu.flywheel.backend.Backend; @@ -23,6 +24,7 @@ public class GPUInstancer extends AbstractInstancer { private final ModelAllocator modelAllocator; private final VertexFormat instanceFormat; + private final Instanced instancedType; private IBufferedModel model; private GlVertexArray vao; @@ -34,10 +36,11 @@ public class GPUInstancer extends AbstractInstancer { protected boolean anyToUpdate; - public GPUInstancer(StructType type, Model model, ModelAllocator modelAllocator) { - super(type, model); + public GPUInstancer(Instanced type, Model model, ModelAllocator modelAllocator) { + super(type::create, model); this.modelAllocator = modelAllocator; this.instanceFormat = type.format(); + instancedType = type; } @Override @@ -152,8 +155,7 @@ public class GPUInstancer extends AbstractInstancer { try (MappedBuffer mapped = instanceVBO.getBuffer(0, glBufferSize)) { - final StructWriter writer = type.asInstanced() - .getWriter(mapped); + final StructWriter writer = instancedType.getWriter(mapped); for (int i = 0; i < size; i++) { final D element = data.get(i); @@ -176,8 +178,7 @@ public class GPUInstancer extends AbstractInstancer { instanceVBO.alloc(glBufferSize); try (MappedBuffer buffer = instanceVBO.getBuffer(0, glBufferSize)) { - StructWriter writer = type.asInstanced() - .getWriter(buffer); + StructWriter writer = instancedType.getWriter(buffer); for (D datum : data) { writer.write(datum); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterial.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterial.java index 24b569b30..a8229424b 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterial.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterial.java @@ -8,7 +8,7 @@ import com.google.common.cache.CacheBuilder; import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.Instancer; import com.jozufozu.flywheel.api.Material; -import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.api.struct.Instanced; import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.RenderWork; import com.jozufozu.flywheel.backend.model.ImmediateAllocator; @@ -25,10 +25,10 @@ public class InstancedMaterial implements Material { final ModelAllocator allocator; protected final Cache> models; - protected final StructType type; + protected final Instanced type; - public InstancedMaterial(StructType spec) { - this.type = spec; + public InstancedMaterial(Instanced type) { + this.type = type; if (Backend.getInstance().compat.onAMDWindows()) { allocator = ImmediateAllocator.INSTANCE; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java index 466c82e15..184aa3be4 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java @@ -6,6 +6,7 @@ import java.util.Map; import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.MaterialGroup; +import com.jozufozu.flywheel.api.struct.Instanced; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.backend.model.ModelPool; import com.jozufozu.flywheel.core.shader.WorldProgram; @@ -25,7 +26,7 @@ public class InstancedMaterialGroup

implements MaterialG protected final InstancingEngine

owner; protected final RenderType type; - private final Map, InstancedMaterial> materials = new HashMap<>(); + private final Map, InstancedMaterial> materials = new HashMap<>(); public InstancedMaterialGroup(InstancingEngine

owner, RenderType type) { this.owner = owner; @@ -34,8 +35,12 @@ public class InstancedMaterialGroup

implements MaterialG @SuppressWarnings("unchecked") @Override - public InstancedMaterial material(StructType spec) { - return (InstancedMaterial) materials.computeIfAbsent(spec, InstancedMaterial::new); + public InstancedMaterial material(StructType type) { + if (type instanceof Instanced instanced) { + return (InstancedMaterial) materials.computeIfAbsent(instanced, InstancedMaterial::new); + } else { + throw new ClassCastException("Cannot use type '" + type + "' with GPU instancing."); + } } public void render(Matrix4f viewProjection, double camX, double camY, double camZ) { @@ -46,7 +51,7 @@ public class InstancedMaterialGroup

implements MaterialG } protected void renderAll(Matrix4f viewProjection, double camX, double camY, double camZ) { - for (Map.Entry, InstancedMaterial> entry : materials.entrySet()) { + for (Map.Entry, InstancedMaterial> entry : materials.entrySet()) { InstancedMaterial material = entry.getValue(); if (material.nothingToRender()) continue; @@ -61,7 +66,6 @@ public class InstancedMaterialGroup

implements MaterialG } P program = owner.getProgram(entry.getKey() - .asInstanced() .getProgramSpec()).get(); program.bind(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java index 1ddc21fd5..af045697a 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java @@ -109,6 +109,7 @@ public class InstancingEngine

implements Engine { } private Stream> getGroupsToRender(@Nullable RenderLayer layer) { + // layer is null when this is called from CrumblingRenderer if (layer != null) { return layers.get(layer) .values() diff --git a/src/main/java/com/jozufozu/flywheel/backend/struct/package-info.java b/src/main/java/com/jozufozu/flywheel/backend/struct/package-info.java new file mode 100644 index 000000000..d4cbaadf2 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/struct/package-info.java @@ -0,0 +1,6 @@ +@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault +package com.jozufozu.flywheel.backend.struct; + +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.MethodsReturnNonnullByDefault; diff --git a/src/main/java/com/jozufozu/flywheel/core/WorldContext.java b/src/main/java/com/jozufozu/flywheel/core/WorldContext.java index 5271003bd..5306d605c 100644 --- a/src/main/java/com/jozufozu/flywheel/core/WorldContext.java +++ b/src/main/java/com/jozufozu/flywheel/core/WorldContext.java @@ -2,9 +2,11 @@ package com.jozufozu.flywheel.core; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.function.Supplier; import java.util.stream.Stream; +import com.jozufozu.flywheel.api.struct.Instanced; import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.ShaderContext; import com.jozufozu.flywheel.backend.pipeline.ShaderPipeline; @@ -87,8 +89,9 @@ public class WorldContext

implements ShaderContext

{ if (specStream == null) { specStream = () -> backend.allMaterials() .stream() - .map(type -> type.asInstanced() - .getProgramSpec()); + .map(t -> t instanceof Instanced i ? i : null) + .filter(Objects::nonNull) + .map(Instanced::getProgramSpec); } return new WorldContext<>(backend, name, specStream, pipeline); } diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelType.java b/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelType.java index 9527cbb1f..55bef78a8 100644 --- a/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelType.java +++ b/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelType.java @@ -1,13 +1,13 @@ package com.jozufozu.flywheel.core.materials.model; import com.jozufozu.flywheel.api.struct.Batched; -import com.jozufozu.flywheel.api.struct.BatchingTransformer; import com.jozufozu.flywheel.api.struct.Instanced; import com.jozufozu.flywheel.api.struct.StructWriter; import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.core.Programs; +import com.jozufozu.flywheel.core.model.ModelTransformer; import net.minecraft.resources.ResourceLocation; @@ -34,11 +34,9 @@ public class ModelType implements Instanced, Batched { } @Override - public BatchingTransformer getTransformer() { - return (d, b) -> { - b.transform(d.model, d.normal) - .color(d.r, d.g, d.b, d.a) - .light(d.getPackedLight()); - }; + public void transform(ModelData d, ModelTransformer.Params b) { + b.transform(d.model, d.normal) + .color(d.r, d.g, d.b, d.a) + .light(d.getPackedLight()); } } diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedType.java b/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedType.java index c5625bca0..2bd2195ae 100644 --- a/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedType.java +++ b/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedType.java @@ -1,13 +1,13 @@ package com.jozufozu.flywheel.core.materials.oriented; import com.jozufozu.flywheel.api.struct.Batched; -import com.jozufozu.flywheel.api.struct.BatchingTransformer; import com.jozufozu.flywheel.api.struct.Instanced; import com.jozufozu.flywheel.api.struct.StructWriter; import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.core.Programs; +import com.jozufozu.flywheel.core.model.ModelTransformer; import com.mojang.math.Quaternion; import net.minecraft.resources.ResourceLocation; @@ -35,13 +35,11 @@ public class OrientedType implements Instanced, Batched getTransformer() { - return (d, sbb) -> { - sbb.light(d.getPackedLight()) - .color(d.r, d.g, d.b, d.a) - .translate(d.posX + d.pivotX, d.posY + d.pivotY, d.posZ + d.pivotZ) - .multiply(new Quaternion(d.qX, d.qY, d.qZ, d.qW)) - .translate(-d.pivotX, -d.pivotY, -d.pivotZ); - }; + public void transform(OrientedData d, ModelTransformer.Params b) { + b.light(d.getPackedLight()) + .color(d.r, d.g, d.b, d.a) + .translate(d.posX + d.pivotX, d.posY + d.pivotY, d.posZ + d.pivotZ) + .multiply(new Quaternion(d.qX, d.qY, d.qZ, d.qW)) + .translate(-d.pivotX, -d.pivotY, -d.pivotZ); } }