diff --git a/src/main/java/com/jozufozu/flywheel/api/Material.java b/src/main/java/com/jozufozu/flywheel/api/Material.java index 345c3e3ed..7ac7b64a2 100644 --- a/src/main/java/com/jozufozu/flywheel/api/Material.java +++ b/src/main/java/com/jozufozu/flywheel/api/Material.java @@ -1,6 +1,6 @@ package com.jozufozu.flywheel.api; -import com.jozufozu.flywheel.core.ModelSupplier; +import com.jozufozu.flywheel.core.model.ModelSupplier; public interface Material { diff --git a/src/main/java/com/jozufozu/flywheel/api/vertex/VertexList.java b/src/main/java/com/jozufozu/flywheel/api/vertex/VertexList.java index 939f42731..46edc536d 100644 --- a/src/main/java/com/jozufozu/flywheel/api/vertex/VertexList.java +++ b/src/main/java/com/jozufozu/flywheel/api/vertex/VertexList.java @@ -38,6 +38,8 @@ public interface VertexList { int getVertexCount(); + VertexType getVertexType(); + default boolean isEmpty() { return getVertexCount() == 0; } diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java b/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java index 8f511b9cb..f5f54047b 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java @@ -3,66 +3,123 @@ package com.jozufozu.flywheel.backend.gl; import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL32; +import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; +import com.jozufozu.flywheel.backend.gl.versioned.GlCompat; import com.jozufozu.flywheel.core.layout.BufferLayout; -import com.jozufozu.flywheel.core.layout.LayoutItem; import com.mojang.blaze3d.platform.GlStateManager; +@SuppressWarnings("MismatchedReadAndWriteOfArray") public class GlVertexArray extends GlObject { - private final boolean[] arrays = new boolean[GL32.glGetInteger(GL32.GL_MAX_VERTEX_ATTRIBS)]; + private static final int MAX_ATTRIBS = GL32.glGetInteger(GL32.GL_MAX_VERTEX_ATTRIBS); + + /** + * Whether each attribute is enabled. + */ + private final boolean[] enabled = new boolean[MAX_ATTRIBS]; + /** + * Each attribute's divisor. + */ + private final int[] divisors = new int[MAX_ATTRIBS]; + + /** + * The VBO to which each attribute is bound. + */ + private final int[] targets = new int[MAX_ATTRIBS]; + + /** + * Each attribute's data type. + */ + private final VertexAttribute[] attributes = new VertexAttribute[MAX_ATTRIBS]; + + /** + * Each attribute's offset. + */ + private final int[] offsets = new int[MAX_ATTRIBS]; + + /** + * Each attribute's stride. + */ + private final int[] strides = new int[MAX_ATTRIBS]; + public GlVertexArray() { setHandle(GlStateManager._glGenVertexArrays()); } - public static void bind(int vao) { - GlStateManager._glBindVertexArray(vao); + public void bind() { + if (!isBound()) { + GlStateManager._glBindVertexArray(handle()); + } } - public void bind() { - bind(handle()); + public boolean isBound() { + return handle() == GlStateTracker.getVertexArray(); } public static void unbind() { GlStateManager._glBindVertexArray(0); } + public void bindAttributes(int startIndex, BufferLayout type) { + int boundBuffer = GlStateTracker.getBuffer(GlBufferType.ARRAY_BUFFER); + + bind(); + int i = startIndex; + int offset = 0; + final int stride = type.getStride(); + + for (VertexAttribute attribute : type.getAttributes()) { + targets[i] = boundBuffer; + attributes[i] = attribute; + offsets[i] = offset; + strides[i] = stride; + + GL20.glVertexAttribPointer(i++, attribute.size(), attribute.type().getGlEnum(), attribute.normalized(), stride, offset); + + offset += attribute.getByteWidth(); + } + } + public void enableArrays(int count) { + bind(); + for (int i = 0; i < count; i++) { enable(i); } } public void disableArrays(int count) { + bind(); + for (int i = 0; i < count; i++) { disable(i); } } private void enable(int i) { - if (!arrays[i]) { + if (!enabled[i]) { GL20.glEnableVertexAttribArray(i); - arrays[i] = true; + enabled[i] = true; } } private void disable(int i) { - if (arrays[i]) { + if (enabled[i]) { GL20.glDisableVertexAttribArray(i); - arrays[i] = false; - } - } - - public void bindAttributes(int startIndex, BufferLayout type) { - int offset = 0; - for (LayoutItem spec : type.getLayoutItems()) { - spec.vertexAttribPointer(type.getStride(), startIndex, offset); - startIndex += spec.attributeCount(); - offset += spec.size(); + enabled[i] = false; } } protected void deleteInternal(int handle) { GlStateManager._glDeleteVertexArrays(handle); } + + public void setAttributeDivisor(int index, int divisor) { + if (divisors[index] != divisor) { + bind(); + GlCompat.getInstance().instancedArrays.vertexAttribDivisor(index, divisor); + divisors[index] = divisor; + } + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/VertexAttribute.java b/src/main/java/com/jozufozu/flywheel/backend/gl/VertexAttribute.java new file mode 100644 index 000000000..be1394e9e --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/VertexAttribute.java @@ -0,0 +1,15 @@ +package com.jozufozu.flywheel.backend.gl; + +/** + * A bindable attribute in a vertex array. + * + * @param size The number of components in the attribute, e.g. 3 for a vec3. + * @param type The type of the attribute, e.g. GL_FLOAT. + * @param normalized Whether the data is normalized. + */ +public record VertexAttribute(int size, GlNumericType type, boolean normalized) { + + public int getByteWidth() { + return size * type.getByteWidth(); + } +} 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 5389ca60e..c018c1bc6 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstancer.java @@ -6,19 +6,17 @@ import java.util.function.Supplier; import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.Instancer; -import com.jozufozu.flywheel.core.ModelSupplier; +import com.jozufozu.flywheel.core.model.ModelSupplier; public abstract class AbstractInstancer implements Instancer { protected final Supplier factory; - protected final ModelSupplier modelData; protected final ArrayList data = new ArrayList<>(); protected boolean anyToRemove; - protected AbstractInstancer(Supplier factory, ModelSupplier modelData) { + protected AbstractInstancer(Supplier factory) { this.factory = factory; - this.modelData = modelData; } /** @@ -58,18 +56,10 @@ public abstract class AbstractInstancer implements Insta anyToRemove = true; } - public int getModelVertexCount() { - return modelData.getVertexCount(); - } - public int getInstanceCount() { return data.size(); } - public int getVertexCount() { - return getModelVertexCount() * getInstanceCount(); - } - protected void removeDeletedInstances() { // Figure out which elements are to be removed. final int oldSize = this.data.size(); @@ -117,6 +107,6 @@ public abstract class AbstractInstancer implements Insta @Override public String toString() { - return "Instancer[" + modelData + ']'; + return "Instancer[" + getInstanceCount() + ']'; } } 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 5456c2995..af0fff2cf 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,8 @@ import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.Instancer; import com.jozufozu.flywheel.api.Material; import com.jozufozu.flywheel.api.struct.Batched; -import com.jozufozu.flywheel.core.ModelSupplier; +import com.jozufozu.flywheel.core.BasicModelSupplier; +import com.jozufozu.flywheel.core.model.ModelSupplier; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; @@ -24,7 +25,7 @@ public class BatchedMaterial implements Material { @Override public Instancer model(ModelSupplier modelKey) { - return models.computeIfAbsent(modelKey, k -> new CPUInstancer<>(type, k)); + return models.computeIfAbsent(modelKey, k -> new CPUInstancer<>(type)); } public void setupAndRenderInto(PoseStack stack, VertexConsumer buffer) { 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 14b2cd212..5895377c4 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 @@ -39,27 +39,27 @@ public class BatchedMaterialGroup implements MaterialGroup { public void render(PoseStack stack, BatchDrawingTracker source, TaskEngine pool) { - vertexCount = 0; - instanceCount = 0; - for (BatchedMaterial material : materials.values()) { - for (CPUInstancer instancer : material.models.values()) { - instancer.setup(); - vertexCount += instancer.getVertexCount(); - instanceCount += instancer.getInstanceCount(); - } - } - - DirectVertexConsumer consumer = source.getDirectConsumer(state, vertexCount); - - // avoids rendering garbage, but doesn't fix the issue of some instances not being buffered - consumer.memSetZero(); - - for (BatchedMaterial material : materials.values()) { - for (CPUInstancer instancer : material.models.values()) { - instancer.sbb.context.outputColorDiffuse = !consumer.hasOverlay() && !OptifineHandler.isUsingShaders(); - instancer.submitTasks(stack, pool, consumer); - } - } +// vertexCount = 0; +// instanceCount = 0; +// for (BatchedMaterial material : materials.values()) { +// for (CPUInstancer instancer : material.models.values()) { +// instancer.setup(); +// vertexCount += instancer.getVertexCount(); +// instanceCount += instancer.getInstanceCount(); +// } +// } +// +// DirectVertexConsumer consumer = source.getDirectConsumer(state, vertexCount); +// +// // avoids rendering garbage, but doesn't fix the issue of some instances not being buffered +// consumer.memSetZero(); +// +// for (BatchedMaterial material : materials.values()) { +// for (CPUInstancer instancer : material.models.values()) { +// instancer.sbb.context.outputColorDiffuse = !consumer.hasOverlay() && !OptifineHandler.isUsingShaders(); +// instancer.submitTasks(stack, pool, consumer); +// } +// } } public void clear() { 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 fa47dee00..967c6c19a 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 @@ -5,68 +5,67 @@ import com.jozufozu.flywheel.api.struct.Batched; import com.jozufozu.flywheel.backend.instancing.AbstractInstancer; import com.jozufozu.flywheel.backend.instancing.TaskEngine; import com.jozufozu.flywheel.backend.model.DirectVertexConsumer; -import com.jozufozu.flywheel.core.ModelSupplier; -import com.jozufozu.flywheel.core.model.ModelTransformer; +import com.jozufozu.flywheel.core.BasicModelSupplier; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; public class CPUInstancer extends AbstractInstancer { - private final Batched batchingType; +// private final Batched batchingType; +// +// final ModelTransformer sbb; - final ModelTransformer sbb; - - public CPUInstancer(Batched type, ModelSupplier modelData) { - super(type::create, modelData); - batchingType = type; - - sbb = new ModelTransformer(modelData.get()); + public CPUInstancer(Batched type) { + super(type::create); +// batchingType = type; +// +// sbb = new ModelTransformer(modelData.get()); } void submitTasks(PoseStack stack, TaskEngine pool, DirectVertexConsumer consumer) { - int instances = getInstanceCount(); - - while (instances > 0) { - int end = instances; - instances -= 512; - int start = Math.max(instances, 0); - - int verts = getModelVertexCount() * (end - start); - - DirectVertexConsumer sub = consumer.split(verts); - - pool.submit(() -> drawRange(stack, sub, start, end)); - } +// int instances = getInstanceCount(); +// +// while (instances > 0) { +// int end = instances; +// instances -= 512; +// int start = Math.max(instances, 0); +// +// int verts = getModelVertexCount() * (end - start); +// +// DirectVertexConsumer sub = consumer.split(verts); +// +// pool.submit(() -> drawRange(stack, sub, start, end)); +// } } private void drawRange(PoseStack stack, VertexConsumer buffer, int from, int to) { - ModelTransformer.Params params = new ModelTransformer.Params(); - - for (D d : data.subList(from, to)) { - params.loadDefault(); - - batchingType.transform(d, params); - - sbb.renderInto(params, stack, buffer); - } +// ModelTransformer.Params params = new ModelTransformer.Params(); +// +// for (D d : data.subList(from, to)) { +// params.loadDefault(); +// +// batchingType.transform(d, params); +// +// sbb.renderInto(params, stack, buffer); +// } } void drawAll(PoseStack stack, VertexConsumer buffer) { - ModelTransformer.Params params = new ModelTransformer.Params(); - for (D d : data) { - params.loadDefault(); - - batchingType.transform(d, params); - - sbb.renderInto(params, stack, buffer); - } +// ModelTransformer.Params params = new ModelTransformer.Params(); +// for (D d : data) { +// params.loadDefault(); +// +// batchingType.transform(d, params); +// +// sbb.renderInto(params, stack, buffer); +// } } void setup() { - if (anyToRemove) { - data.removeIf(InstanceData::isRemoved); - anyToRemove = false; - } +// if (anyToRemove) { +// data.removeIf(InstanceData::isRemoved); +// anyToRemove = false; +// } } @Override 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 75b9505c6..99c7c8b74 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 @@ -1,45 +1,31 @@ package com.jozufozu.flywheel.backend.instancing.instancing; -import java.util.Collections; -import java.util.Map; - import org.lwjgl.system.MemoryUtil; -import com.google.common.collect.ImmutableMap; import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.struct.Instanced; import com.jozufozu.flywheel.api.struct.StructWriter; -import com.jozufozu.flywheel.backend.gl.GlStateTracker; import com.jozufozu.flywheel.backend.gl.GlVertexArray; import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; -import com.jozufozu.flywheel.backend.gl.versioned.GlCompat; import com.jozufozu.flywheel.backend.instancing.AbstractInstancer; -import com.jozufozu.flywheel.backend.model.BufferedModel; -import com.jozufozu.flywheel.backend.model.ModelAllocator; -import com.jozufozu.flywheel.core.ModelSupplier; import com.jozufozu.flywheel.core.layout.BufferLayout; -import net.minecraft.client.renderer.RenderType; - public class GPUInstancer extends AbstractInstancer { - private final BufferLayout instanceFormat; - private final Instanced instancedType; + final BufferLayout instanceFormat; + final Instanced instancedType; - private BufferedModel model; - private GlVertexArray vao; - private GlBuffer instanceVBO; - private int glInstanceCount = 0; - private boolean deleted; - private boolean initialized; + GlBuffer vbo; + int attributeBaseIndex; + int glInstanceCount = 0; - protected boolean anyToUpdate; + boolean anyToUpdate; - public GPUInstancer(Instanced type, ModelSupplier model) { - super(type::create, model); + public GPUInstancer(Instanced type) { + super(type::create); this.instanceFormat = type.getLayout(); instancedType = type; } @@ -49,72 +35,24 @@ public class GPUInstancer extends AbstractInstancer { anyToUpdate = true; } - public void render() { - if (invalid()) return; + public void init() { + if (vbo != null) return; - vao.bind(); - - renderSetup(); - - if (glInstanceCount > 0) { - model.drawInstances(glInstanceCount); - } - - // persistent mapping sync point - instanceVBO.doneForThisFrame(); - } - - private boolean invalid() { - return deleted || model == null; - } - - public Map init(ModelAllocator modelAllocator) { - if (isInitialized()) return Collections.emptyMap(); - - initialized = true; - - instanceVBO = GlBuffer.requestPersistent(GlBufferType.ARRAY_BUFFER); - instanceVBO.setGrowthMargin(instanceFormat.getStride() * 16); - - vao = new GlVertexArray(); - - model = modelAllocator.alloc(modelData.get(), vao); - - vao.bind(); - vao.enableArrays(model.getAttributeCount() + instanceFormat.getAttributeCount()); - - return ImmutableMap.of(modelData.getRenderType(), this::render); - } - - public boolean isInitialized() { - return initialized; + vbo = GlBuffer.requestPersistent(GlBufferType.ARRAY_BUFFER); + vbo.setGrowthMargin(instanceFormat.getStride() * 16); } public boolean isEmpty() { return !anyToUpdate && !anyToRemove && glInstanceCount == 0; } - /** - * Free acquired resources. All other Instancer methods are undefined behavior after calling delete. - */ - public void delete() { - if (invalid()) return; - - deleted = true; - - model.delete(); - - instanceVBO.delete(); - vao.delete(); - } - - protected void renderSetup() { + void renderSetup(GlVertexArray vao) { if (anyToRemove) { removeDeletedInstances(); } - instanceVBO.bind(); - if (!realloc()) { + vbo.bind(); + if (!realloc(vao)) { if (anyToRemove) { clearBufferTail(); @@ -127,7 +65,7 @@ public class GPUInstancer extends AbstractInstancer { glInstanceCount = data.size(); } - instanceVBO.unbind(); + vbo.unbind(); anyToRemove = anyToUpdate = false; } @@ -135,9 +73,9 @@ public class GPUInstancer extends AbstractInstancer { private void clearBufferTail() { int size = data.size(); final int offset = size * instanceFormat.getStride(); - final long length = instanceVBO.getCapacity() - offset; + final long length = vbo.getCapacity() - offset; if (length > 0) { - try (MappedBuffer buf = instanceVBO.getBuffer(offset, length)) { + try (MappedBuffer buf = vbo.getBuffer(offset, length)) { MemoryUtil.memSet(MemoryUtil.memAddress(buf.unwrap()), 0, length); } catch (Exception e) { Flywheel.LOGGER.error("Error clearing buffer tail:", e); @@ -150,7 +88,7 @@ public class GPUInstancer extends AbstractInstancer { if (size <= 0) return; - try (MappedBuffer mapped = instanceVBO.getBuffer()) { + try (MappedBuffer mapped = vbo.getBuffer()) { final StructWriter writer = instancedType.getWriter(mapped); @@ -172,13 +110,13 @@ public class GPUInstancer extends AbstractInstancer { } } - private boolean realloc() { + private boolean realloc(GlVertexArray vao) { int size = this.data.size(); int stride = instanceFormat.getStride(); int requiredSize = size * stride; - if (instanceVBO.ensureCapacity(requiredSize)) { + if (vbo.ensureCapacity(requiredSize)) { - try (MappedBuffer buffer = instanceVBO.getBuffer()) { + try (MappedBuffer buffer = vbo.getBuffer()) { StructWriter writer = instancedType.getWriter(buffer); for (D datum : data) { writer.write(datum); @@ -189,19 +127,18 @@ public class GPUInstancer extends AbstractInstancer { glInstanceCount = size; - bindInstanceAttributes(); + bindInstanceAttributes(vao); return true; } return false; } - private void bindInstanceAttributes() { - int attributeBaseIndex = model.getAttributeCount(); + private void bindInstanceAttributes(GlVertexArray vao) { vao.bindAttributes(attributeBaseIndex, instanceFormat); for (int i = 0; i < instanceFormat.getAttributeCount(); i++) { - GlCompat.getInstance().instancedArrays.vertexAttribDivisor(attributeBaseIndex + i, 1); + vao.setAttributeDivisor(attributeBaseIndex + i, 1); } } } 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 054e478b7..3e3b3e3a8 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 @@ -12,8 +12,8 @@ import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.Instancer; import com.jozufozu.flywheel.api.Material; import com.jozufozu.flywheel.api.struct.Instanced; -import com.jozufozu.flywheel.backend.model.ModelAllocator; -import com.jozufozu.flywheel.core.ModelSupplier; +import com.jozufozu.flywheel.backend.model.MeshAllocator; +import com.jozufozu.flywheel.core.model.ModelSupplier; import net.minecraft.client.renderer.RenderType; @@ -23,10 +23,10 @@ import net.minecraft.client.renderer.RenderType; */ public class InstancedMaterial implements Material { - protected final Map> models = new HashMap<>(); + protected final Map> models = new HashMap<>(); protected final Instanced type; - protected final List> uninitialized = new ArrayList<>(); + protected final List> uninitialized = new ArrayList<>(); protected final Multimap renderables = ArrayListMultimap.create(); @@ -36,29 +36,32 @@ public class InstancedMaterial implements Material { @Override public Instancer model(ModelSupplier modelKey) { - return models.computeIfAbsent(modelKey, k -> { - GPUInstancer instancer = new GPUInstancer<>(type, modelKey); - uninitialized.add(instancer); - return instancer; - }); + return models.computeIfAbsent(modelKey, this::createInstancer).instancer; } public int getInstanceCount() { - return models.values().stream().mapToInt(GPUInstancer::getInstanceCount).sum(); + return models.values() + .stream() + .map(InstancedModel::getInstancer) + .mapToInt(GPUInstancer::getInstanceCount) + .sum(); } public int getVertexCount() { - return models.values().stream().mapToInt(GPUInstancer::getVertexCount).sum(); + return models.values() + .stream() + .mapToInt(InstancedModel::getVertexCount) + .sum(); } public boolean nothingToRender() { return models.size() > 0 && models.values() .stream() - .allMatch(GPUInstancer::isEmpty); + .allMatch(InstancedModel::isEmpty); } public void delete() { - models.values().forEach(GPUInstancer::delete); + models.values().forEach(InstancedModel::delete); models.clear(); renderables.clear(); } @@ -68,16 +71,15 @@ public class InstancedMaterial implements Material { */ public void clear() { models.values() + .stream() + .map(InstancedModel::getInstancer) .forEach(GPUInstancer::clear); } - public Collection> getAllInstancers() { - return models.values(); - } + public void init(MeshAllocator allocator) { + for (var instanced : uninitialized) { - public void init(ModelAllocator allocator) { - for (GPUInstancer instancer : uninitialized) { - var map = instancer.init(allocator); + var map = instanced.init(allocator); map.forEach((type, renderable) -> renderables.get(type).add(renderable)); } @@ -91,4 +93,10 @@ public class InstancedMaterial implements Material { public boolean anythingToRender(RenderType type) { return renderables.get(type).size() > 0; } + + private InstancedModel createInstancer(ModelSupplier model) { + var instancer = new InstancedModel<>(new GPUInstancer<>(type), model); + uninitialized.add(instancer); + return instancer; + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedModel.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedModel.java new file mode 100644 index 000000000..845f7e4cb --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedModel.java @@ -0,0 +1,89 @@ +package com.jozufozu.flywheel.backend.instancing.instancing; + +import java.util.Map; + +import javax.annotation.Nullable; + +import com.google.common.collect.ImmutableMap; +import com.jozufozu.flywheel.api.InstanceData; +import com.jozufozu.flywheel.backend.gl.GlVertexArray; +import com.jozufozu.flywheel.backend.model.BufferedModel; +import com.jozufozu.flywheel.backend.model.MeshAllocator; +import com.jozufozu.flywheel.core.model.ModelSupplier; + +import net.minecraft.client.renderer.RenderType; + +public class InstancedModel { + + GPUInstancer instancer; + ModelSupplier model; + + @Nullable + private BufferedModel bufferedMesh; + @Nullable + private GlVertexArray vao; + + public InstancedModel(GPUInstancer instancer, ModelSupplier model) { + this.instancer = instancer; + this.model = model; + } + + public Map init(MeshAllocator allocator) { + instancer.init(); + + vao = new GlVertexArray(); + + bufferedMesh = allocator.alloc(model.get(), vao); + instancer.attributeBaseIndex = bufferedMesh.getAttributeCount(); + vao.enableArrays(bufferedMesh.getAttributeCount() + instancer.instanceFormat.getAttributeCount()); + + return ImmutableMap.of(RenderType.solid(), this::render); + } + + public void render() { + if (invalid()) return; + + vao.bind(); + + instancer.renderSetup(vao); + + if (instancer.glInstanceCount > 0) { + bufferedMesh.drawInstances(instancer.glInstanceCount); + } + + // persistent mapping sync point + instancer.vbo.doneForThisFrame(); + } + + private boolean invalid() { + return instancer.vbo == null || bufferedMesh == null || vao == null; + } + + public GPUInstancer getInstancer() { + return instancer; + } + + public ModelSupplier getModel() { + return model; + } + + public int getVertexCount() { + return model.getVertexCount() * instancer.glInstanceCount; + } + + public boolean isEmpty() { + return instancer.isEmpty(); + } + + public void delete() { + if (invalid()) return; + + vao.delete(); + bufferedMesh.delete(); + instancer.vbo.delete(); + + vao = null; + bufferedMesh = null; + instancer.vbo = null; + } +} 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 1d62940a9..6af4b7add 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 @@ -1,6 +1,5 @@ package com.jozufozu.flywheel.backend.instancing.instancing; -import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -9,9 +8,6 @@ import java.util.Set; import javax.annotation.Nonnull; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Multimap; -import com.google.common.collect.Multimaps; import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.struct.Instanced; import com.jozufozu.flywheel.api.struct.StructType; @@ -19,8 +15,8 @@ import com.jozufozu.flywheel.backend.gl.versioned.GlCompat; import com.jozufozu.flywheel.backend.instancing.Engine; import com.jozufozu.flywheel.backend.instancing.TaskEngine; import com.jozufozu.flywheel.backend.model.FallbackAllocator; -import com.jozufozu.flywheel.backend.model.ModelAllocator; -import com.jozufozu.flywheel.backend.model.ModelPool; +import com.jozufozu.flywheel.backend.model.MeshAllocator; +import com.jozufozu.flywheel.backend.model.MeshPool; import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.core.RenderContext; import com.jozufozu.flywheel.core.RenderTypeRegistry; @@ -45,7 +41,7 @@ public class InstancingEngine

implements Engine { protected BlockPos originCoordinate = BlockPos.ZERO; protected final ProgramCompiler

context; - private ModelAllocator allocator; + private MeshAllocator allocator; protected final Map, InstancedMaterial> materials = new HashMap<>(); @@ -169,7 +165,7 @@ public class InstancingEngine

implements Engine { public void beginFrame(Camera info) { checkOriginDistance(info); - ModelAllocator allocator = getModelAllocator(); + MeshAllocator allocator = getModelAllocator(); for (InstancedMaterial material : materials.values()) { material.init(allocator); @@ -177,7 +173,7 @@ public class InstancingEngine

implements Engine { toRender.addAll(material.renderables.keySet()); } - if (allocator instanceof ModelPool pool) { + if (allocator instanceof MeshPool pool) { // ...and then flush the model arena in case anything was marked for upload pool.flush(); } @@ -215,19 +211,19 @@ public class InstancingEngine

implements Engine { info.add("Origin: " + originCoordinate.getX() + ", " + originCoordinate.getY() + ", " + originCoordinate.getZ()); } - private ModelAllocator getModelAllocator() { + private MeshAllocator getModelAllocator() { if (allocator == null) { allocator = createAllocator(); } return this.allocator; } - private static ModelAllocator createAllocator() { + private static MeshAllocator createAllocator() { if (GlCompat.getInstance() .onAMDWindows()) { return FallbackAllocator.INSTANCE; } else { - return new ModelPool(Formats.POS_TEX_NORMAL); + return new MeshPool(Formats.POS_TEX_NORMAL); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java b/src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java index f190aa103..c4d47bdbd 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java @@ -1,17 +1,17 @@ package com.jozufozu.flywheel.backend.model; import com.jozufozu.flywheel.backend.gl.GlVertexArray; -import com.jozufozu.flywheel.core.model.Model; +import com.jozufozu.flywheel.core.model.Mesh; public class ArrayModelRenderer { - private final Model model; + private final Mesh mesh; protected GlVertexArray vao; protected BufferedModel vbo; protected boolean initialized; - public ArrayModelRenderer(Model model) { - this.model = model; + public ArrayModelRenderer(Mesh mesh) { + this.mesh = mesh; } /** @@ -29,14 +29,12 @@ public class ArrayModelRenderer { protected void init() { initialized = true; - if (model.empty()) return; + if (mesh.empty()) return; - this.vbo = new IndexedModel(model); + this.vbo = new IndexedModel(mesh); vao = new GlVertexArray(); - vao.bind(); - // bind the model's vbo to our vao this.vbo.setupState(vao); diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/FallbackAllocator.java b/src/main/java/com/jozufozu/flywheel/backend/model/FallbackAllocator.java index a06593ed3..1f276016a 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/FallbackAllocator.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/FallbackAllocator.java @@ -1,15 +1,14 @@ package com.jozufozu.flywheel.backend.model; import com.jozufozu.flywheel.backend.gl.GlVertexArray; -import com.jozufozu.flywheel.core.model.Model; +import com.jozufozu.flywheel.core.model.Mesh; -public enum FallbackAllocator implements ModelAllocator { +public enum FallbackAllocator implements MeshAllocator { INSTANCE; @Override - public BufferedModel alloc(Model model, GlVertexArray vao) { - IndexedModel out = new IndexedModel(model); - vao.bind(); + public BufferedModel alloc(Mesh mesh, GlVertexArray vao) { + IndexedModel out = new IndexedModel(mesh); out.setupState(vao); return out; } diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java b/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java index 2add47260..d2129ad09 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java @@ -11,7 +11,7 @@ import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer; -import com.jozufozu.flywheel.core.model.Model; +import com.jozufozu.flywheel.core.model.Mesh; /** * An indexed triangle model. Just what the driver ordered. @@ -20,32 +20,32 @@ import com.jozufozu.flywheel.core.model.Model; */ public class IndexedModel implements BufferedModel { - protected final Model model; + protected final Mesh mesh; protected final GlPrimitive primitiveMode; protected ElementBuffer ebo; protected GlBuffer vbo; protected boolean deleted; - public IndexedModel(Model model) { - this.model = model; + public IndexedModel(Mesh mesh) { + this.mesh = mesh; this.primitiveMode = GlPrimitive.TRIANGLES; vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER); vbo.bind(); // allocate the buffer on the gpu - vbo.ensureCapacity(model.size()); + vbo.ensureCapacity(mesh.size()); // mirror it in system memory, so we can write to it, and upload our model. try (MappedBuffer buffer = vbo.getBuffer()) { - model.writeInto(buffer.unwrap()); + mesh.writeInto(buffer.unwrap()); } catch (Exception e) { - Flywheel.LOGGER.error(String.format("Error uploading model '%s':", model.name()), e); + Flywheel.LOGGER.error(String.format("Error uploading model '%s':", mesh.name()), e); } vbo.unbind(); - this.ebo = model.createEBO(); + this.ebo = mesh.createEBO(); } /** @@ -81,11 +81,11 @@ public class IndexedModel implements BufferedModel { @Override public VertexType getType() { - return model.getType(); + return mesh.getType(); } public int getVertexCount() { - return model.vertexCount(); + return mesh.vertexCount(); } public void delete() { diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/ModelAllocator.java b/src/main/java/com/jozufozu/flywheel/backend/model/MeshAllocator.java similarity index 66% rename from src/main/java/com/jozufozu/flywheel/backend/model/ModelAllocator.java rename to src/main/java/com/jozufozu/flywheel/backend/model/MeshAllocator.java index ee3ca81b8..371b80fbf 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/ModelAllocator.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/MeshAllocator.java @@ -1,17 +1,17 @@ package com.jozufozu.flywheel.backend.model; import com.jozufozu.flywheel.backend.gl.GlVertexArray; -import com.jozufozu.flywheel.core.model.Model; +import com.jozufozu.flywheel.core.model.Mesh; -public interface ModelAllocator { +public interface MeshAllocator { /** * Allocate a model. * - * @param model The model to allocate. + * @param mesh The model to allocate. * @param vao The vertex array object to attach the model to. * @return A handle to the allocated model. */ - BufferedModel alloc(Model model, GlVertexArray vao); + BufferedModel alloc(Mesh mesh, GlVertexArray vao); @FunctionalInterface interface Callback { diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java b/src/main/java/com/jozufozu/flywheel/backend/model/MeshPool.java similarity index 86% rename from src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java rename to src/main/java/com/jozufozu/flywheel/backend/model/MeshPool.java index 223ccc034..70fb5acbd 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/MeshPool.java @@ -14,9 +14,9 @@ import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer; -import com.jozufozu.flywheel.core.model.Model; +import com.jozufozu.flywheel.core.model.Mesh; -public class ModelPool implements ModelAllocator { +public class MeshPool implements MeshAllocator { protected final VertexType vertexType; @@ -36,7 +36,7 @@ public class ModelPool implements ModelAllocator { * * @param vertexType The vertex type of the models that will be stored in the pool. */ - public ModelPool(VertexType vertexType) { + public MeshPool(VertexType vertexType) { this.vertexType = vertexType; int stride = vertexType.getStride(); @@ -49,14 +49,14 @@ public class ModelPool implements ModelAllocator { /** * Allocate a model in the arena. * - * @param model The model to allocate. + * @param mesh The model to allocate. * @param vao The vertex array object to attach the model to. * @return A handle to the allocated model. */ @Override - public PooledModel alloc(Model model, GlVertexArray vao) { - PooledModel bufferedModel = new PooledModel(vao, model, vertices); - vertices += model.vertexCount(); + public PooledModel alloc(Mesh mesh, GlVertexArray vao) { + PooledModel bufferedModel = new PooledModel(vao, mesh, vertices); + vertices += mesh.vertexCount(); models.add(bufferedModel); pendingUpload.add(bufferedModel); @@ -94,7 +94,7 @@ public class ModelPool implements ModelAllocator { model.first = vertices; - vertices += model.getVertexCount(); + vertices += model.mesh.vertexCount(); } this.vertices = vertices; @@ -120,7 +120,7 @@ public class ModelPool implements ModelAllocator { model.buffer(writer); - vertices += model.getVertexCount(); + vertices += model.mesh.vertexCount(); } } catch (Exception e) { @@ -153,31 +153,31 @@ public class ModelPool implements ModelAllocator { private final ElementBuffer ebo; private final GlVertexArray vao; - private final Model model; + private final Mesh mesh; private int first; private boolean deleted; - public PooledModel(GlVertexArray vao, Model model, int first) { + public PooledModel(GlVertexArray vao, Mesh mesh, int first) { this.vao = vao; - this.model = model; + this.mesh = mesh; this.first = first; - ebo = model.createEBO(); + ebo = mesh.createEBO(); } @Override public VertexType getType() { - return ModelPool.this.vertexType; + return MeshPool.this.vertexType; } @Override public int getVertexCount() { - return model.vertexCount(); + return mesh.vertexCount(); } @Override public void setupState(GlVertexArray vao) { - vao.bind(); + vbo.bind(); vao.enableArrays(getAttributeCount()); vao.bindAttributes(0, vertexType.getLayout()); } @@ -212,9 +212,8 @@ public class ModelPool implements ModelAllocator { private void buffer(VertexWriter writer) { writer.seekToVertex(first); - writer.writeVertexList(model.getReader()); + writer.writeVertexList(mesh.getReader()); - vao.bind(); setupState(vao); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java b/src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java index 54dccbd28..100fbf9d7 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java @@ -12,30 +12,30 @@ import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer; -import com.jozufozu.flywheel.core.model.Model; +import com.jozufozu.flywheel.core.model.Mesh; public class VBOModel implements BufferedModel { - protected final Model model; + protected final Mesh mesh; protected final GlPrimitive primitiveMode; protected GlBuffer vbo; protected boolean deleted; - public VBOModel(GlPrimitive primitiveMode, Model model) { - this.model = model; + public VBOModel(GlPrimitive primitiveMode, Mesh mesh) { + this.mesh = mesh; this.primitiveMode = primitiveMode; vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER); vbo.bind(); // allocate the buffer on the gpu - vbo.ensureCapacity(model.size()); + vbo.ensureCapacity(mesh.size()); // mirror it in system memory, so we can write to it, and upload our model. try (MappedBuffer buffer = vbo.getBuffer()) { - model.writeInto(buffer.unwrap()); + mesh.writeInto(buffer.unwrap()); } catch (Exception e) { - Flywheel.LOGGER.error(String.format("Error uploading model '%s':", model.name()), e); + Flywheel.LOGGER.error(String.format("Error uploading model '%s':", mesh.name()), e); } vbo.unbind(); @@ -47,11 +47,11 @@ public class VBOModel implements BufferedModel { @Override public VertexType getType() { - return model.getType(); + return mesh.getType(); } public int getVertexCount() { - return model.vertexCount(); + return mesh.vertexCount(); } /** @@ -64,7 +64,7 @@ public class VBOModel implements BufferedModel { } public void drawCall() { - glDrawArrays(primitiveMode.glEnum, 0, getVertexCount()); + glDrawArrays(primitiveMode.glEnum, 0, mesh.vertexCount()); } /** @@ -73,7 +73,7 @@ public class VBOModel implements BufferedModel { public void drawInstances(int instanceCount) { if (!valid()) return; - GL31.glDrawArraysInstanced(primitiveMode.glEnum, 0, getVertexCount(), instanceCount); + GL31.glDrawArraysInstanced(primitiveMode.glEnum, 0, mesh.vertexCount(), instanceCount); } public void delete() { diff --git a/src/main/java/com/jozufozu/flywheel/core/BasicModelSupplier.java b/src/main/java/com/jozufozu/flywheel/core/BasicModelSupplier.java new file mode 100644 index 000000000..b7c66e0cb --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/BasicModelSupplier.java @@ -0,0 +1,55 @@ +package com.jozufozu.flywheel.core; + +import javax.annotation.Nonnull; + +import com.jozufozu.flywheel.core.model.Mesh; +import com.jozufozu.flywheel.core.model.ModelSupplier; +import com.jozufozu.flywheel.util.Lazy; +import com.jozufozu.flywheel.util.NonNullSupplier; + +import net.minecraft.client.renderer.RenderType; + +public class BasicModelSupplier implements ModelSupplier { + + private RenderType renderType; + private final Lazy supplier; + + public BasicModelSupplier(NonNullSupplier supplier) { + this(supplier, RenderType.solid()); + } + + public BasicModelSupplier(NonNullSupplier supplier, RenderType renderType) { + this.supplier = Lazy.of(supplier); + this.renderType = renderType; + } + + public BasicModelSupplier setCutout() { + return setRenderType(RenderType.cutoutMipped()); + } + + public BasicModelSupplier setRenderType(@Nonnull RenderType renderType) { + this.renderType = renderType; + return this; + } + + @Override + public Mesh get() { + return supplier.get(); + } + + @Nonnull + public RenderType getRenderType() { + return renderType; + } + + public int getVertexCount() { + return supplier.map(Mesh::vertexCount) + .orElse(0); + } + + @Override + public String toString() { + return "ModelSupplier{" + supplier.map(Mesh::name) + .orElse("Uninitialized") + '}'; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java b/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java index fbabefe94..4a0034507 100644 --- a/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java +++ b/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java @@ -42,7 +42,7 @@ public class FullscreenQuad { vao = new GlVertexArray(); vao.bind(); - glEnableVertexAttribArray(0); + vao.enableArrays(1); glVertexAttribPointer(0, 4, GlNumericType.FLOAT.getGlEnum(), false, 4 * 4, 0); diff --git a/src/main/java/com/jozufozu/flywheel/core/ModelSupplier.java b/src/main/java/com/jozufozu/flywheel/core/ModelSupplier.java deleted file mode 100644 index 9fb787a4b..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/ModelSupplier.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.jozufozu.flywheel.core; - -import javax.annotation.Nonnull; - -import com.jozufozu.flywheel.core.model.Model; -import com.jozufozu.flywheel.util.Lazy; -import com.jozufozu.flywheel.util.NonNullSupplier; - -import net.minecraft.client.renderer.RenderType; - -public class ModelSupplier extends Lazy { - - private RenderType renderType; - - public ModelSupplier(NonNullSupplier supplier) { - this(supplier, RenderType.solid()); - } - - public ModelSupplier(NonNullSupplier supplier, RenderType renderType) { - super(supplier); - this.renderType = renderType; - } - - public ModelSupplier setCutout() { - return setRenderType(RenderType.cutoutMipped()); - } - - public ModelSupplier setRenderType(@Nonnull RenderType renderType) { - this.renderType = renderType; - return this; - } - - @Nonnull - public RenderType getRenderType() { - return renderType; - } - - public int getVertexCount() { - return map(Model::vertexCount).orElse(0); - } - - @Override - public String toString() { - return "ModelSupplier{" + map(Model::name).orElse("Uninitialized") + '}'; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/core/Models.java b/src/main/java/com/jozufozu/flywheel/core/Models.java index da92ba1f7..063453a7e 100644 --- a/src/main/java/com/jozufozu/flywheel/core/Models.java +++ b/src/main/java/com/jozufozu/flywheel/core/Models.java @@ -2,36 +2,33 @@ package com.jozufozu.flywheel.core; import java.util.HashMap; import java.util.Map; -import java.util.function.Function; import java.util.function.Supplier; -import com.jozufozu.flywheel.core.model.BlockModel; +import com.jozufozu.flywheel.core.model.BlockMesh; import com.jozufozu.flywheel.core.model.ModelUtil; import com.jozufozu.flywheel.event.ReloadRenderersEvent; import com.jozufozu.flywheel.util.Pair; import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.Util; import net.minecraft.core.Direction; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; public class Models { - public static ModelSupplier block(BlockState state) { - return BLOCK_STATE.computeIfAbsent(state, it -> new ModelSupplier(() -> new BlockModel(it))); + public static BasicModelSupplier block(BlockState state) { + return BLOCK_STATE.computeIfAbsent(state, it -> new BasicModelSupplier(() -> new BlockMesh(it))); } - public static ModelSupplier partial(PartialModel partial) { - return PARTIAL.computeIfAbsent(partial, it -> new ModelSupplier(() -> new BlockModel(it))); + public static BasicModelSupplier partial(PartialModel partial) { + return PARTIAL.computeIfAbsent(partial, it -> new BasicModelSupplier(() -> new BlockMesh(it))); } - public static ModelSupplier partial(PartialModel partial, Direction dir) { + public static BasicModelSupplier partial(PartialModel partial, Direction dir) { return partial(partial, dir, () -> ModelUtil.rotateToFace(dir)); } - public static ModelSupplier partial(PartialModel partial, Direction dir, Supplier modelTransform) { - return PARTIAL_DIR.computeIfAbsent(Pair.of(dir, partial), $ -> new ModelSupplier(() -> new BlockModel(partial, modelTransform.get()))); + public static BasicModelSupplier partial(PartialModel partial, Direction dir, Supplier modelTransform) { + return PARTIAL_DIR.computeIfAbsent(Pair.of(dir, partial), $ -> new BasicModelSupplier(() -> new BlockMesh(partial, modelTransform.get()))); } public static void onReload(ReloadRenderersEvent ignored) { @@ -40,8 +37,8 @@ public class Models { PARTIAL_DIR.clear(); } - private static final Map BLOCK_STATE = new HashMap<>(); - private static final Map PARTIAL = new HashMap<>(); - private static final Map, ModelSupplier> PARTIAL_DIR = new HashMap<>(); + private static final Map BLOCK_STATE = new HashMap<>(); + private static final Map PARTIAL = new HashMap<>(); + private static final Map, BasicModelSupplier> PARTIAL_DIR = new HashMap<>(); } diff --git a/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java b/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java index 67bdeb798..e946c3a33 100644 --- a/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java +++ b/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java @@ -3,12 +3,14 @@ package com.jozufozu.flywheel.core.hardcoded; import java.util.List; import com.jozufozu.flywheel.api.vertex.VertexList; +import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.core.Formats; -import com.jozufozu.flywheel.core.model.Model; +import com.jozufozu.flywheel.core.model.Mesh; +import com.jozufozu.flywheel.core.vertex.PosTexNormalVertex; import com.jozufozu.flywheel.core.vertex.PosTexNormalWriterUnsafe; import com.mojang.blaze3d.platform.MemoryTracker; -public class ModelPart implements Model { +public class ModelPart implements Mesh { private final int vertices; private final String name; @@ -25,7 +27,7 @@ public class ModelPart implements Model { this.vertices = vertices; } - PosTexNormalWriterUnsafe writer = Formats.POS_TEX_NORMAL.createWriter(MemoryTracker.create(size())); + PosTexNormalWriterUnsafe writer = getType().createWriter(MemoryTracker.create(size())); for (PartBuilder.CuboidBuilder cuboid : cuboids) { cuboid.buffer(writer); } @@ -51,4 +53,9 @@ public class ModelPart implements Model { public VertexList getReader() { return reader; } + + @Override + public PosTexNormalVertex getType() { + return Formats.POS_TEX_NORMAL; + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/layout/BufferLayout.java b/src/main/java/com/jozufozu/flywheel/core/layout/BufferLayout.java index ecdde9ea3..3e8ae1a0e 100644 --- a/src/main/java/com/jozufozu/flywheel/core/layout/BufferLayout.java +++ b/src/main/java/com/jozufozu/flywheel/core/layout/BufferLayout.java @@ -1,9 +1,11 @@ package com.jozufozu.flywheel.core.layout; +import java.util.Collection; import java.util.List; import com.google.common.collect.ImmutableList; import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.backend.gl.VertexAttribute; /** * Classic Vertex Format struct with a clever name. @@ -17,29 +19,29 @@ import com.jozufozu.flywheel.api.vertex.VertexType; */ public class BufferLayout { - private final List allAttributes; + private final List attributes; - private final int numAttributes; private final int stride; - public BufferLayout(List allAttributes) { - this.allAttributes = allAttributes; + public BufferLayout(List layoutItems) { - int numAttributes = 0, stride = 0; - for (LayoutItem spec : allAttributes) { - numAttributes += spec.attributeCount(); - stride += spec.size(); + ImmutableList.Builder attributes = ImmutableList.builder(); + + stride = calculateStride(layoutItems); + + for (LayoutItem item : layoutItems) { + item.provideAttributes(attributes::add); } - this.numAttributes = numAttributes; - this.stride = stride; + + this.attributes = attributes.build(); } - public List getLayoutItems() { - return allAttributes; + public Collection getAttributes() { + return attributes; } public int getAttributeCount() { - return numAttributes; + return attributes.size(); } public int getStride() { @@ -50,6 +52,14 @@ public class BufferLayout { return new Builder(); } + private static int calculateStride(List layoutItems) { + int stride = 0; + for (LayoutItem spec : layoutItems) { + stride += spec.getByteWidth(); + } + return stride; + } + public static class Builder { private final ImmutableList.Builder allItems; @@ -66,4 +76,5 @@ public class BufferLayout { return new BufferLayout(allItems.build()); } } + } diff --git a/src/main/java/com/jozufozu/flywheel/core/layout/CommonItems.java b/src/main/java/com/jozufozu/flywheel/core/layout/CommonItems.java index 232879964..5cae77a0f 100644 --- a/src/main/java/com/jozufozu/flywheel/core/layout/CommonItems.java +++ b/src/main/java/com/jozufozu/flywheel/core/layout/CommonItems.java @@ -21,4 +21,6 @@ public class CommonItems { public static final PrimitiveItem NORMALIZED_BYTE = new PrimitiveItem(GlNumericType.BYTE, 1, true); public static final LayoutItem PADDING_BYTE = new Padding(1); + public static final MatrixItem MAT3 = new MatrixItem(3, 3); + public static final MatrixItem MAT4 = new MatrixItem(4, 4); } diff --git a/src/main/java/com/jozufozu/flywheel/core/layout/LayoutItem.java b/src/main/java/com/jozufozu/flywheel/core/layout/LayoutItem.java index cc0f6fabe..69d2ed978 100644 --- a/src/main/java/com/jozufozu/flywheel/core/layout/LayoutItem.java +++ b/src/main/java/com/jozufozu/flywheel/core/layout/LayoutItem.java @@ -1,10 +1,13 @@ package com.jozufozu.flywheel.core.layout; +import java.util.function.Consumer; + +import com.jozufozu.flywheel.backend.gl.VertexAttribute; + public interface LayoutItem { - void vertexAttribPointer(int stride, int index, int offset); + void provideAttributes(Consumer consumer); - int size(); + int getByteWidth(); - int attributeCount(); } diff --git a/src/main/java/com/jozufozu/flywheel/core/layout/MatrixItem.java b/src/main/java/com/jozufozu/flywheel/core/layout/MatrixItem.java new file mode 100644 index 000000000..fbcd53a53 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/layout/MatrixItem.java @@ -0,0 +1,22 @@ +package com.jozufozu.flywheel.core.layout; + +import java.util.function.Consumer; + +import com.jozufozu.flywheel.backend.gl.GlNumericType; +import com.jozufozu.flywheel.backend.gl.VertexAttribute; + +public record MatrixItem(int rows, int cols) implements LayoutItem { + + @Override + public void provideAttributes(Consumer consumer) { + for (int i = 0; i < rows; i++) { + consumer.accept(new VertexAttribute(cols, GlNumericType.FLOAT, false)); + } + } + + @Override + public int getByteWidth() { + return GlNumericType.FLOAT.getByteWidth() * rows * cols; + } + +} diff --git a/src/main/java/com/jozufozu/flywheel/core/layout/MatrixItems.java b/src/main/java/com/jozufozu/flywheel/core/layout/MatrixItems.java deleted file mode 100644 index 1ca6f2fec..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/layout/MatrixItems.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.jozufozu.flywheel.core.layout; - -import org.lwjgl.opengl.GL20; - -import com.jozufozu.flywheel.backend.gl.GlNumericType; - -public enum MatrixItems implements LayoutItem { - MAT3(3, 3), - MAT4(4, 4), - ; - - private final int rows; - private final int cols; - - MatrixItems(int rows, int cols) { - this.rows = rows; - this.cols = cols; - } - - @Override - public void vertexAttribPointer(int stride, int index, int offset) { - for (int i = 0; i < rows; i++) { - long attribPointer = offset + (long) i * cols * GlNumericType.FLOAT.getByteWidth(); - GL20.glVertexAttribPointer(index + i, cols, GlNumericType.FLOAT.getGlEnum(), false, stride, attribPointer); - } - } - - @Override - public int size() { - return GlNumericType.FLOAT.getByteWidth() * rows * cols; - } - - @Override - public int attributeCount() { - return rows; - } - -} diff --git a/src/main/java/com/jozufozu/flywheel/core/layout/Padding.java b/src/main/java/com/jozufozu/flywheel/core/layout/Padding.java index 7b3abbed3..033752cfc 100644 --- a/src/main/java/com/jozufozu/flywheel/core/layout/Padding.java +++ b/src/main/java/com/jozufozu/flywheel/core/layout/Padding.java @@ -1,20 +1,19 @@ package com.jozufozu.flywheel.core.layout; +import java.util.function.Consumer; + +import com.jozufozu.flywheel.backend.gl.VertexAttribute; + record Padding(int bytes) implements LayoutItem { @Override - public void vertexAttribPointer(int stride, int index, int offset) { + public void provideAttributes(Consumer consumer) { } @Override - public int size() { + public int getByteWidth() { return bytes; } - @Override - public int attributeCount() { - return 0; - } - } diff --git a/src/main/java/com/jozufozu/flywheel/core/layout/PrimitiveItem.java b/src/main/java/com/jozufozu/flywheel/core/layout/PrimitiveItem.java index c7c1bd6c0..323ac2c6f 100644 --- a/src/main/java/com/jozufozu/flywheel/core/layout/PrimitiveItem.java +++ b/src/main/java/com/jozufozu/flywheel/core/layout/PrimitiveItem.java @@ -1,42 +1,30 @@ package com.jozufozu.flywheel.core.layout; -import org.lwjgl.opengl.GL20; +import java.util.function.Consumer; import com.jozufozu.flywheel.backend.gl.GlNumericType; +import com.jozufozu.flywheel.backend.gl.VertexAttribute; public class PrimitiveItem implements LayoutItem { - private final GlNumericType type; - private final int count; - private final int size; - private final int attributeCount; - private final boolean normalized; + private final VertexAttribute attribute; public PrimitiveItem(GlNumericType type, int count) { this(type, count, false); } public PrimitiveItem(GlNumericType type, int count, boolean normalized) { - this.type = type; - this.count = count; - this.size = type.getByteWidth() * count; - this.attributeCount = (this.size + 15) / 16; // ceiling division. GLSL vertex attributes can only be 16 bytes wide - this.normalized = normalized; + attribute = new VertexAttribute(count, type, normalized); } @Override - public void vertexAttribPointer(int stride, int index, int offset) { - GL20.glVertexAttribPointer(index, count, type.getGlEnum(), normalized, stride, offset); + public void provideAttributes(Consumer consumer) { + consumer.accept(attribute); } @Override - public int size() { - return size; - } - - @Override - public int attributeCount() { - return attributeCount; + public int getByteWidth() { + return attribute.getByteWidth(); } } 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 67172a308..8e26cee70 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 @@ -7,7 +7,6 @@ import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; import com.jozufozu.flywheel.core.Programs; import com.jozufozu.flywheel.core.layout.BufferLayout; import com.jozufozu.flywheel.core.layout.CommonItems; -import com.jozufozu.flywheel.core.layout.MatrixItems; import com.jozufozu.flywheel.core.model.ModelTransformer; import net.minecraft.resources.ResourceLocation; @@ -16,7 +15,7 @@ public class ModelType implements Instanced, Batched { public static final BufferLayout FORMAT = BufferLayout.builder() .addItems(CommonItems.LIGHT, CommonItems.RGBA) - .addItems(MatrixItems.MAT4, MatrixItems.MAT3) + .addItems(CommonItems.MAT4, CommonItems.MAT3) .build(); @Override diff --git a/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java b/src/main/java/com/jozufozu/flywheel/core/model/BlockMesh.java similarity index 68% rename from src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java rename to src/main/java/com/jozufozu/flywheel/core/model/BlockMesh.java index f6ee05f73..c5f21bef6 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/BlockMesh.java @@ -12,43 +12,43 @@ import net.minecraft.world.level.block.state.BlockState; /** * A model of a single block. */ -public class BlockModel implements Model { +public class BlockMesh implements Mesh { private static final PoseStack IDENTITY = new PoseStack(); private final VertexList reader; private final String name; - public BlockModel(BlockState state) { + public BlockMesh(BlockState state) { this(Minecraft.getInstance() .getBlockRenderer() .getBlockModel(state), state); } - public BlockModel(BakedModel model, BlockState referenceState) { + public BlockMesh(BakedModel model, BlockState referenceState) { this(model, referenceState, IDENTITY); } - public BlockModel(PartialModel model) { + public BlockMesh(PartialModel model) { this(model, IDENTITY); } - public BlockModel(PartialModel model, PoseStack ms) { + public BlockMesh(PartialModel model, PoseStack ms) { this(ModelUtil.bakedModel(model.get()) .withPoseStack(ms), model.getName()); } - public BlockModel(BakedModel model, BlockState referenceState, PoseStack ms) { + public BlockMesh(BakedModel model, BlockState referenceState, PoseStack ms) { this(ModelUtil.bakedModel(model) .withReferenceState(referenceState) .withPoseStack(ms), referenceState.toString()); } - public BlockModel(Bufferable builder, String name) { + public BlockMesh(Bufferable builder, String name) { this(Formats.BLOCK.createReader(builder.build()), name); } - public BlockModel(VertexList reader, String name) { + public BlockMesh(VertexList reader, String name) { this.reader = reader; this.name = name; } @@ -58,13 +58,13 @@ public class BlockModel implements Model { return name; } - @Override - public int vertexCount() { - return reader.getVertexCount(); - } - @Override public VertexList getReader() { return reader; } + + @Override + public String toString() { + return "BlockMesh{" + "name='" + name + "',type='" + reader.getVertexType() + "}"; + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/model/Model.java b/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java similarity index 93% rename from src/main/java/com/jozufozu/flywheel/core/model/Model.java rename to src/main/java/com/jozufozu/flywheel/core/model/Mesh.java index eacfd3394..f0b843f7d 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/Model.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java @@ -5,7 +5,6 @@ import java.nio.ByteBuffer; import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.model.ElementBuffer; -import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.core.QuadConverter; /** @@ -28,7 +27,7 @@ import com.jozufozu.flywheel.core.QuadConverter; * assert model.size() == final - initial; * } */ -public interface Model { +public interface Mesh { /** * A name uniquely identifying this model. @@ -40,10 +39,12 @@ public interface Model { /** * @return The number of vertices the model has. */ - int vertexCount(); + default int vertexCount() { + return getReader().getVertexCount(); + } default VertexType getType() { - return Formats.POS_TEX_NORMAL; + return getReader().getVertexType(); } /** diff --git a/src/main/java/com/jozufozu/flywheel/core/model/ModelSupplier.java b/src/main/java/com/jozufozu/flywheel/core/model/ModelSupplier.java new file mode 100644 index 000000000..82ea5d76c --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/model/ModelSupplier.java @@ -0,0 +1,8 @@ +package com.jozufozu.flywheel.core.model; + +public interface ModelSupplier { + + Mesh get(); + + int getVertexCount(); +} diff --git a/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java b/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java index 52e542ec7..819ede8e2 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java @@ -20,15 +20,15 @@ import net.minecraft.util.Mth; public class ModelTransformer { - private final Model model; + private final Mesh mesh; private final VertexList reader; private final IntPredicate shadedPredicate; public final Context context = new Context(); - public ModelTransformer(Model model) { - this.model = model; - reader = model.getReader(); + public ModelTransformer(Mesh mesh) { + this.mesh = mesh; + reader = mesh.getReader(); if (reader instanceof ShadedVertexList shaded) { shadedPredicate = shaded::isShaded; } else { @@ -128,7 +128,7 @@ public class ModelTransformer { @Override public String toString() { - return "ModelTransformer[" + model + ']'; + return "ModelTransformer[" + mesh + ']'; } public static int transformColor(byte component, float scale) { diff --git a/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java b/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java index 75f4fdc10..86e4da233 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java @@ -76,4 +76,8 @@ public final class WorldModelBuilder implements Bufferable { this.poseStack = poseStack; return this; } + + public BlockMesh finish() { + return new BlockMesh(this, "name"); + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java index eaac02cee..d746896ea 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java @@ -4,6 +4,8 @@ import java.nio.ByteBuffer; import com.jozufozu.flywheel.api.vertex.ShadedVertexList; import com.jozufozu.flywheel.api.vertex.VertexList; +import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder; import com.jozufozu.flywheel.util.RenderMath; import com.mojang.blaze3d.vertex.BufferBuilder; @@ -106,6 +108,11 @@ public class BlockVertexList implements VertexList { return vertexCount; } + @Override + public VertexType getVertexType() { + return Formats.BLOCK; + } + public static class Shaded extends BlockVertexList implements ShadedVertexList { private final int unshadedStartVertex; diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java index 0993f29e5..bd96c4bfb 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java @@ -6,6 +6,8 @@ import org.lwjgl.system.MemoryUtil; import com.jozufozu.flywheel.api.vertex.ShadedVertexList; import com.jozufozu.flywheel.api.vertex.VertexList; +import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.util.RenderMath; public class BlockVertexListUnsafe implements VertexList { @@ -99,6 +101,11 @@ public class BlockVertexListUnsafe implements VertexList { return vertexCount; } + @Override + public VertexType getVertexType() { + return Formats.BLOCK; + } + public static class Shaded extends BlockVertexListUnsafe implements ShadedVertexList { private final int unshadedStartVertex; diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java index 70d4a72ee..49eddde63 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java @@ -5,6 +5,8 @@ import java.nio.ByteBuffer; import org.lwjgl.system.MemoryUtil; import com.jozufozu.flywheel.api.vertex.VertexList; +import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.util.RenderMath; public class PosTexNormalVertexListUnsafe implements VertexList { @@ -92,4 +94,9 @@ public class PosTexNormalVertexListUnsafe implements VertexList { public int getVertexCount() { return vertexCount; } + + @Override + public VertexType getVertexType() { + return Formats.POS_TEX_NORMAL; + } } diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java index 415feec67..92430d074 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java @@ -6,7 +6,7 @@ import com.jozufozu.flywheel.api.MaterialManager; import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; import com.jozufozu.flywheel.core.Materials; -import com.jozufozu.flywheel.core.ModelSupplier; +import com.jozufozu.flywheel.core.BasicModelSupplier; import com.jozufozu.flywheel.core.hardcoded.ModelPart; import com.jozufozu.flywheel.core.materials.oriented.OrientedData; import com.jozufozu.flywheel.util.AnimationTickHolder; @@ -20,7 +20,7 @@ import net.minecraft.world.level.block.entity.BellBlockEntity; public class BellInstance extends BlockEntityInstance implements DynamicInstance { - private static final ModelSupplier MODEL = new ModelSupplier(BellInstance::createBellModel, RenderType.cutoutMipped()); + private static final BasicModelSupplier MODEL = new BasicModelSupplier(BellInstance::createBellModel, RenderType.cutoutMipped()); private final OrientedData bell; diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java index 08dc5502c..e7678ab6c 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java @@ -9,7 +9,7 @@ import com.jozufozu.flywheel.api.MaterialManager; import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; import com.jozufozu.flywheel.core.Materials; -import com.jozufozu.flywheel.core.ModelSupplier; +import com.jozufozu.flywheel.core.BasicModelSupplier; import com.jozufozu.flywheel.core.hardcoded.ModelPart; import com.jozufozu.flywheel.core.materials.model.ModelData; import com.jozufozu.flywheel.core.materials.oriented.OrientedData; @@ -19,7 +19,6 @@ import com.mojang.math.Vector3f; import it.unimi.dsi.fastutil.floats.Float2FloatFunction; import net.minecraft.Util; -import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.Sheets; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.Material; @@ -34,8 +33,8 @@ import net.minecraft.world.level.block.state.properties.ChestType; public class ChestInstance extends BlockEntityInstance implements DynamicInstance { - private static final BiFunction LID = Util.memoize((type, mat) -> new ModelSupplier(() -> createLidModel(type, mat.sprite()), Sheets.chestSheet())); - private static final BiFunction BASE = Util.memoize((type, mat) -> new ModelSupplier(() -> createBaseModel(type, mat.sprite()), Sheets.chestSheet())); + private static final BiFunction LID = Util.memoize((type, mat) -> new BasicModelSupplier(() -> createLidModel(type, mat.sprite()), Sheets.chestSheet())); + private static final BiFunction BASE = Util.memoize((type, mat) -> new BasicModelSupplier(() -> createBaseModel(type, mat.sprite()), Sheets.chestSheet())); private final OrientedData body; private final ModelData lid; diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java index 3111a8844..0e7aec4e2 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java @@ -2,17 +2,16 @@ package com.jozufozu.flywheel.vanilla; import javax.annotation.Nonnull; -import com.jozufozu.flywheel.api.Material; import com.jozufozu.flywheel.api.MaterialManager; import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance; import com.jozufozu.flywheel.core.Materials; -import com.jozufozu.flywheel.core.ModelSupplier; +import com.jozufozu.flywheel.core.BasicModelSupplier; import com.jozufozu.flywheel.core.Models; import com.jozufozu.flywheel.core.hardcoded.ModelPart; import com.jozufozu.flywheel.core.materials.model.ModelData; -import com.jozufozu.flywheel.core.model.Model; +import com.jozufozu.flywheel.core.model.Mesh; import com.jozufozu.flywheel.util.AnimationTickHolder; import com.jozufozu.flywheel.util.transform.TransformStack; import com.mojang.blaze3d.vertex.PoseStack; @@ -30,7 +29,7 @@ import net.minecraft.world.phys.Vec3; public class MinecartInstance extends EntityInstance implements DynamicInstance, TickableInstance { private static final ResourceLocation MINECART_LOCATION = new ResourceLocation("textures/entity/minecart.png"); - private static final ModelSupplier MODEL = new ModelSupplier(MinecartInstance::getBodyModel, RenderType.entitySolid(MINECART_LOCATION)); + private static final BasicModelSupplier MODEL = new BasicModelSupplier(MinecartInstance::getBodyModel, RenderType.entitySolid(MINECART_LOCATION)); private final PoseStack stack = new PoseStack(); @@ -160,7 +159,7 @@ public class MinecartInstance extends EntityInstance } @Nonnull - private static Model getBodyModel() { + private static Mesh getBodyModel() { int y = -3; return ModelPart.builder("minecart", 64, 32) .cuboid().invertYZ().start(-10, -8, -y).size(20, 16, 2).textureOffset(0, 10).rotateZ((float) Math.PI).rotateX(((float)Math.PI / 2F)).endCuboid() diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java index 833f1acd5..91fe7e959 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java @@ -6,7 +6,7 @@ import com.jozufozu.flywheel.api.MaterialManager; import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; import com.jozufozu.flywheel.core.Materials; -import com.jozufozu.flywheel.core.ModelSupplier; +import com.jozufozu.flywheel.core.BasicModelSupplier; import com.jozufozu.flywheel.core.hardcoded.ModelPart; import com.jozufozu.flywheel.core.materials.model.ModelData; import com.jozufozu.flywheel.util.AnimationTickHolder; @@ -26,8 +26,8 @@ import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity; public class ShulkerBoxInstance extends BlockEntityInstance implements DynamicInstance { - private static final Function BASE = Util.memoize(it -> new ModelSupplier(() -> makeBaseModel(it), RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET))); - private static final Function LID = Util.memoize(it -> new ModelSupplier(() -> makeLidModel(it), RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET))); + private static final Function BASE = Util.memoize(it -> new BasicModelSupplier(() -> makeBaseModel(it), RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET))); + private static final Function LID = Util.memoize(it -> new BasicModelSupplier(() -> makeLidModel(it), RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET))); private final TextureAtlasSprite texture;