From 6913a3444306b21dadb060beb9c9fefd0235b802 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Tue, 9 Aug 2022 11:25:26 -0700 Subject: [PATCH] Vertex format refactor - Use memCopy for instanced mesh buffering - Remove VertexWriter - Add VertexListProvider - Add VertexListProviderRegistry to allow vanilla VertexFormats to create VertexLists - Add ReusableVertexList that allows setting the pointer and vertex count --- .../api/vertex/ReusableVertexList.java | 11 + .../flywheel/api/vertex/VertexList.java | 31 +++ .../api/vertex/VertexListProvider.java | 5 + .../flywheel/api/vertex/VertexType.java | 22 +- .../flywheel/api/vertex/VertexWriter.java | 15 -- .../instancing/batching/BatchingEngine.java | 1 + .../instancing/batching/DrawBuffer.java | 27 ++- .../batching/MutableVertexListImpl.java | 206 ----------------- .../instancing/batching/TransformSet.java | 52 ++--- .../instancing/instancing/MeshPool.java | 6 +- .../flywheel/core/hardcoded/ModelPart.java | 57 +++-- .../flywheel/core/hardcoded/PartBuilder.java | 40 ++-- .../flywheel/core/hardcoded/VertexWriter.java | 5 + .../core/hardcoded/VertexWriterImpl.java | 27 +++ .../flywheel/core/layout/CommonItems.java | 37 ++- .../flywheel/core/layout/PrimitiveItem.java | 10 - .../jozufozu/flywheel/core/model/Mesh.java | 37 ++- .../flywheel/core/model/ModelUtil.java | 36 ++- .../flywheel/core/model/SimpleMesh.java | 55 ++++- .../model/buffering/BakedModelBuilder.java | 23 +- .../model/buffering/BlockModelBuilder.java | 23 +- .../buffering/MultiBlockModelBuilder.java | 19 +- .../core/vertex/AbstractVertexList.java | 59 ++--- .../flywheel/core/vertex/BlockVertex.java | 18 +- .../flywheel/core/vertex/BlockVertexList.java | 120 +++++++--- .../core/vertex/BlockVertexListUnsafe.java | 91 -------- .../core/vertex/BlockWriterUnsafe.java | 56 ----- .../vertex/InferredVertexFormatInfo.java} | 8 +- .../core/vertex/InferredVertexListImpl.java | 214 ++++++++++++++++++ .../InferredVertexListProviderImpl.java | 20 ++ .../core/vertex/PosTexNormalVertex.java | 18 +- .../core/vertex/PosTexNormalVertexList.java | 154 +++++++++++++ .../vertex/PosTexNormalVertexListUnsafe.java | 90 -------- .../core/vertex/PosTexNormalWriterUnsafe.java | 44 ---- .../core/vertex/TrackedVertexList.java | 41 ---- .../vertex/VertexListProviderRegistry.java | 55 +++++ .../core/vertex/VertexWriterUnsafe.java | 33 --- 37 files changed, 877 insertions(+), 889 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/api/vertex/ReusableVertexList.java create mode 100644 src/main/java/com/jozufozu/flywheel/api/vertex/VertexListProvider.java delete mode 100644 src/main/java/com/jozufozu/flywheel/api/vertex/VertexWriter.java delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/batching/MutableVertexListImpl.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/hardcoded/VertexWriter.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/hardcoded/VertexWriterImpl.java delete mode 100644 src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java delete mode 100644 src/main/java/com/jozufozu/flywheel/core/vertex/BlockWriterUnsafe.java rename src/main/java/com/jozufozu/flywheel/{backend/instancing/batching/VertexFormatInfo.java => core/vertex/InferredVertexFormatInfo.java} (88%) create mode 100644 src/main/java/com/jozufozu/flywheel/core/vertex/InferredVertexListImpl.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/vertex/InferredVertexListProviderImpl.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexList.java delete mode 100644 src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java delete mode 100644 src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalWriterUnsafe.java delete mode 100644 src/main/java/com/jozufozu/flywheel/core/vertex/TrackedVertexList.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/vertex/VertexListProviderRegistry.java delete mode 100644 src/main/java/com/jozufozu/flywheel/core/vertex/VertexWriterUnsafe.java diff --git a/src/main/java/com/jozufozu/flywheel/api/vertex/ReusableVertexList.java b/src/main/java/com/jozufozu/flywheel/api/vertex/ReusableVertexList.java new file mode 100644 index 000000000..c4f9c4b70 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/vertex/ReusableVertexList.java @@ -0,0 +1,11 @@ +package com.jozufozu.flywheel.api.vertex; + +public interface ReusableVertexList extends MutableVertexList { + long ptr(); + + void ptr(long ptr); + + void shiftPtr(int vertices); + + void setVertexCount(int vertexCount); +} 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 519ef671f..ec47c17c8 100644 --- a/src/main/java/com/jozufozu/flywheel/api/vertex/VertexList.java +++ b/src/main/java/com/jozufozu/flywheel/api/vertex/VertexList.java @@ -42,6 +42,37 @@ public interface VertexList { float normalZ(int index); + default void write(MutableVertexList dst, int srcIndex, int dstIndex) { + dst.x(dstIndex, x(srcIndex)); + dst.y(dstIndex, y(srcIndex)); + dst.z(dstIndex, z(srcIndex)); + + dst.r(dstIndex, r(srcIndex)); + dst.g(dstIndex, g(srcIndex)); + dst.b(dstIndex, b(srcIndex)); + dst.a(dstIndex, a(srcIndex)); + + dst.u(dstIndex, u(srcIndex)); + dst.v(dstIndex, v(srcIndex)); + + dst.overlay(dstIndex, overlay(srcIndex)); + dst.light(dstIndex, light(srcIndex)); + + dst.normalX(dstIndex, normalX(srcIndex)); + dst.normalY(dstIndex, normalY(srcIndex)); + dst.normalZ(dstIndex, normalZ(srcIndex)); + } + + default void write(MutableVertexList dst, int srcStartIndex, int dstStartIndex, int vertexCount) { + for (int i = 0; i < vertexCount; i++) { + write(dst, srcStartIndex + i, dstStartIndex + i); + } + } + + default void writeAll(MutableVertexList dst) { + write(dst, 0, 0, getVertexCount()); + } + int getVertexCount(); default boolean isEmpty() { diff --git a/src/main/java/com/jozufozu/flywheel/api/vertex/VertexListProvider.java b/src/main/java/com/jozufozu/flywheel/api/vertex/VertexListProvider.java new file mode 100644 index 000000000..a200e03ad --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/vertex/VertexListProvider.java @@ -0,0 +1,5 @@ +package com.jozufozu.flywheel.api.vertex; + +public interface VertexListProvider { + ReusableVertexList createVertexList(); +} diff --git a/src/main/java/com/jozufozu/flywheel/api/vertex/VertexType.java b/src/main/java/com/jozufozu/flywheel/api/vertex/VertexType.java index 1ae89d406..72dab420d 100644 --- a/src/main/java/com/jozufozu/flywheel/api/vertex/VertexType.java +++ b/src/main/java/com/jozufozu/flywheel/api/vertex/VertexType.java @@ -1,38 +1,18 @@ package com.jozufozu.flywheel.api.vertex; -import java.nio.ByteBuffer; - import com.jozufozu.flywheel.core.layout.BufferLayout; import com.jozufozu.flywheel.core.source.FileResolution; /** * A vertex type containing metadata about a specific vertex layout. */ -public interface VertexType { +public interface VertexType extends VertexListProvider { /** * The layout of this type of vertex when buffered. */ BufferLayout getLayout(); - /** - * Create a writer backed by the given ByteBuffer. - * - *

- * Implementors are encouraged to override the return type for ergonomics. - *

- */ - VertexWriter createWriter(ByteBuffer buffer); - - /** - * Create a view of the given ByteBuffer as if it were already filled with vertices. - * - *

- * Implementors are encouraged to override the return type for ergonomics. - *

- */ - VertexList createReader(ByteBuffer buffer, int vertexCount); - FileResolution getLayoutShader(); default int getStride() { diff --git a/src/main/java/com/jozufozu/flywheel/api/vertex/VertexWriter.java b/src/main/java/com/jozufozu/flywheel/api/vertex/VertexWriter.java deleted file mode 100644 index a16f0eec5..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/vertex/VertexWriter.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.jozufozu.flywheel.api.vertex; - -public interface VertexWriter { - void writeVertex(VertexList list, int index); - - void seek(long offset); - - VertexList intoReader(int vertices); - - default void writeVertexList(VertexList list) { - for (int i = 0; i < list.getVertexCount(); i++) { - this.writeVertex(list, i); - } - } -} 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 00fb68cd6..1d68c6617 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 @@ -68,6 +68,7 @@ public class BatchingEngine implements Engine { @Override public void renderStage(TaskEngine taskEngine, RenderContext context, RenderStage stage) { // FIXME: properly support material stages + // This also breaks block outlines on batched block entities if (stage != RenderStage.AFTER_FINAL_END_BATCH) { return; } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/DrawBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/DrawBuffer.java index e583f85e1..50a099bae 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/DrawBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/DrawBuffer.java @@ -4,18 +4,24 @@ import java.nio.ByteBuffer; import org.lwjgl.system.MemoryUtil; +import com.jozufozu.flywheel.api.vertex.ReusableVertexList; +import com.jozufozu.flywheel.api.vertex.VertexListProvider; +import com.jozufozu.flywheel.core.vertex.VertexListProviderRegistry; import com.mojang.blaze3d.platform.MemoryTracker; +import com.mojang.blaze3d.vertex.VertexFormat; import net.minecraft.client.renderer.RenderType; /** - * A byte buffer that can be used to draw vertices through multiple {@link MutableVertexListImpl}s. + * A byte buffer that can be used to draw vertices through multiple {@link ReusableVertexList}s. * * The number of vertices needs to be known ahead of time. */ public class DrawBuffer { private final RenderType parent; - private final VertexFormatInfo formatInfo; + private final VertexFormat format; + private final int stride; + private final VertexListProvider provider; private ByteBuffer backingBuffer; private int expectedVertices; @@ -23,7 +29,9 @@ public class DrawBuffer { public DrawBuffer(RenderType parent) { this.parent = parent; - formatInfo = new VertexFormatInfo(parent.format()); + format = parent.format(); + stride = format.getVertexSize(); + provider = VertexListProviderRegistry.getOrInfer(format); } /** @@ -39,9 +47,9 @@ public class DrawBuffer { this.expectedVertices = vertexCount; // Add one extra vertex to uphold the vanilla assumption that BufferBuilders have at least - // enough buffer space for one more vertex. Sodium checks for this extra space when popNextBuffer + // enough buffer space for one more vertex. Rubidium checks for this extra space when popNextBuffer // is called and reallocates the buffer if there is not space for one more vertex. - int byteSize = formatInfo.stride * (vertexCount + 1); + int byteSize = stride * (vertexCount + 1); if (backingBuffer == null) { backingBuffer = MemoryTracker.create(byteSize); @@ -54,8 +62,11 @@ public class DrawBuffer { MemoryUtil.memSet(ptr, 0, byteSize); } - public MutableVertexListImpl slice(int startVertex, int vertexCount) { - return new MutableVertexListImpl(ptr + startVertex * formatInfo.stride, formatInfo, vertexCount); + public ReusableVertexList slice(int startVertex, int vertexCount) { + ReusableVertexList vertexList = provider.createVertexList(); + vertexList.ptr(ptr + startVertex * stride); + vertexList.setVertexCount(vertexCount); + return vertexList; } /** @@ -63,7 +74,7 @@ public class DrawBuffer { * @param bufferBuilder The buffer builder to inject into. */ public void inject(BufferBuilderExtension bufferBuilder) { - bufferBuilder.flywheel$injectForRender(backingBuffer, formatInfo.format, expectedVertices); + bufferBuilder.flywheel$injectForRender(backingBuffer, format, expectedVertices); } public int getVertexCount() { diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/MutableVertexListImpl.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/MutableVertexListImpl.java deleted file mode 100644 index 410da67af..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/MutableVertexListImpl.java +++ /dev/null @@ -1,206 +0,0 @@ -package com.jozufozu.flywheel.backend.instancing.batching; - -import org.lwjgl.system.MemoryUtil; - -import com.jozufozu.flywheel.api.vertex.MutableVertexList; -import com.jozufozu.flywheel.util.RenderMath; - -public class MutableVertexListImpl extends VertexFormatInfo implements MutableVertexList { - private final long anchorPtr; - private final int totalVertexCount; - - private long ptr; - private int vertexCount; - - public MutableVertexListImpl(long ptr, VertexFormatInfo formatInfo, int vertexCount) { - super(formatInfo); - - anchorPtr = ptr; - totalVertexCount = vertexCount; - - setFullRange(); - } - - public void setRange(int startVertex, int vertexCount) { - ptr = anchorPtr + startVertex * stride; - this.vertexCount = vertexCount; - } - - public void setFullRange() { - ptr = anchorPtr; - vertexCount = totalVertexCount; - } - - @Override - public float x(int index) { - if (positionOffset < 0) return 0; - return MemoryUtil.memGetFloat(ptr + index * stride + positionOffset); - } - - @Override - public float y(int index) { - if (positionOffset < 0) return 0; - return MemoryUtil.memGetFloat(ptr + index * stride + positionOffset + 4); - } - - @Override - public float z(int index) { - if (positionOffset < 0) return 0; - return MemoryUtil.memGetFloat(ptr + index * stride + positionOffset + 8); - } - - @Override - public byte r(int index) { - if (colorOffset < 0) return 0; - return MemoryUtil.memGetByte(ptr + index * stride + colorOffset); - } - - @Override - public byte g(int index) { - if (colorOffset < 0) return 0; - return MemoryUtil.memGetByte(ptr + index * stride + colorOffset + 1); - } - - @Override - public byte b(int index) { - if (colorOffset < 0) return 0; - return MemoryUtil.memGetByte(ptr + index * stride + colorOffset + 2); - } - - @Override - public byte a(int index) { - if (colorOffset < 0) return 0; - return MemoryUtil.memGetByte(ptr + index * stride + colorOffset + 3); - } - - @Override - public float u(int index) { - if (textureOffset < 0) return 0; - return MemoryUtil.memGetFloat(ptr + index * stride + textureOffset); - } - - @Override - public float v(int index) { - if (textureOffset < 0) return 0; - return MemoryUtil.memGetFloat(ptr + index * stride + textureOffset + 4); - } - - @Override - public int overlay(int index) { - if (overlayOffset < 0) return 0; - return MemoryUtil.memGetInt(ptr + index * stride + overlayOffset); - } - - @Override - public int light(int index) { - if (lightOffset < 0) return 0; - return MemoryUtil.memGetInt(ptr + index * stride + lightOffset); - } - - @Override - public float normalX(int index) { - if (normalOffset < 0) return 0; - return RenderMath.f(MemoryUtil.memGetByte(ptr + index * stride + normalOffset)); - } - - @Override - public float normalY(int index) { - if (normalOffset < 0) return 0; - return RenderMath.f(MemoryUtil.memGetByte(ptr + index * stride + normalOffset + 1)); - } - - @Override - public float normalZ(int index) { - if (normalOffset < 0) return 0; - return RenderMath.f(MemoryUtil.memGetByte(ptr + index * stride + normalOffset + 2)); - } - - @Override - public int getVertexCount() { - return vertexCount; - } - - @Override - public void x(int index, float x) { - if (positionOffset < 0) return; - MemoryUtil.memPutFloat(ptr + index * stride + positionOffset, x); - } - - @Override - public void y(int index, float y) { - if (positionOffset < 0) return; - MemoryUtil.memPutFloat(ptr + index * stride + positionOffset + 4, y); - } - - @Override - public void z(int index, float z) { - if (positionOffset < 0) return; - MemoryUtil.memPutFloat(ptr + index * stride + positionOffset + 8, z); - } - - @Override - public void r(int index, byte r) { - if (colorOffset < 0) return; - MemoryUtil.memPutByte(ptr + index * stride + colorOffset, r); - } - - @Override - public void g(int index, byte g) { - if (colorOffset < 0) return; - MemoryUtil.memPutByte(ptr + index * stride + colorOffset + 1, g); - } - - @Override - public void b(int index, byte b) { - if (colorOffset < 0) return; - MemoryUtil.memPutByte(ptr + index * stride + colorOffset + 2, b); - } - - @Override - public void a(int index, byte a) { - if (colorOffset < 0) return; - MemoryUtil.memPutByte(ptr + index * stride + colorOffset + 3, a); - } - - @Override - public void u(int index, float u) { - if (textureOffset < 0) return; - MemoryUtil.memPutFloat(ptr + index * stride + textureOffset, u); - } - - @Override - public void v(int index, float v) { - if (textureOffset < 0) return; - MemoryUtil.memPutFloat(ptr + index * stride + textureOffset + 4, v); - } - - @Override - public void overlay(int index, int overlay) { - if (overlayOffset < 0) return; - MemoryUtil.memPutInt(ptr + index * stride + overlayOffset, overlay); - } - - @Override - public void light(int index, int light) { - if (lightOffset < 0) return; - MemoryUtil.memPutInt(ptr + index * stride + lightOffset, light); - } - - @Override - public void normalX(int index, float normalX) { - if (normalOffset < 0) return; - MemoryUtil.memPutByte(ptr + index * stride + normalOffset, RenderMath.nb(normalX)); - } - - @Override - public void normalY(int index, float normalY) { - if (normalOffset < 0) return; - MemoryUtil.memPutByte(ptr + index * stride + normalOffset + 1, RenderMath.nb(normalY)); - } - - @Override - public void normalZ(int index, float normalZ) { - if (normalOffset < 0) return; - MemoryUtil.memPutByte(ptr + index * stride + normalOffset + 2, RenderMath.nb(normalZ)); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/TransformSet.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/TransformSet.java index 642fea29f..4dc4a1bef 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/TransformSet.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/TransformSet.java @@ -7,7 +7,7 @@ import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.api.struct.StructType.VertexTransformer; import com.jozufozu.flywheel.api.vertex.MutableVertexList; -import com.jozufozu.flywheel.api.vertex.VertexList; +import com.jozufozu.flywheel.api.vertex.ReusableVertexList; import com.jozufozu.flywheel.backend.instancing.TaskEngine; import com.jozufozu.flywheel.core.model.Mesh; import com.mojang.blaze3d.vertex.PoseStack; @@ -49,69 +49,45 @@ public class TransformSet { int start = Math.max(instances, 0); int vertexCount = mesh.getVertexCount() * (end - start); - MutableVertexListImpl sub = buffer.slice(startVertex, vertexCount); + ReusableVertexList sub = buffer.slice(startVertex, vertexCount); startVertex += vertexCount; pool.submit(() -> drawRange(sub, start, end, stack, level)); } } - private void drawRange(MutableVertexListImpl vertexList, int from, int to, PoseStack stack, ClientLevel level) { + private void drawRange(ReusableVertexList vertexList, int from, int to, PoseStack stack, ClientLevel level) { drawList(vertexList, instancer.getRange(from, to), stack, level); } - void drawAll(MutableVertexListImpl vertexList, PoseStack stack, ClientLevel level) { + void drawAll(ReusableVertexList vertexList, PoseStack stack, ClientLevel level) { drawList(vertexList, instancer.getAll(), stack, level); } - private void drawList(MutableVertexListImpl vertexList, List list, PoseStack stack, ClientLevel level) { - int startVertex = 0; - int meshVertexCount = mesh.getVertexCount(); + private void drawList(ReusableVertexList vertexList, List list, PoseStack stack, ClientLevel level) { + long anchorPtr = vertexList.ptr(); + int totalVertexCount = vertexList.getVertexCount(); + + int meshVertexCount = mesh.getVertexCount(); + vertexList.setVertexCount(meshVertexCount); - VertexList meshReader = mesh.getReader(); @SuppressWarnings("unchecked") StructType.VertexTransformer structVertexTransformer = (VertexTransformer) instancer.type.getVertexTransformer(); for (D d : list) { - vertexList.setRange(startVertex, meshVertexCount); - - writeMesh(vertexList, meshReader); + mesh.writeInto(vertexList); structVertexTransformer.transform(vertexList, d, level); - startVertex += meshVertexCount; + vertexList.shiftPtr(meshVertexCount); } - vertexList.setFullRange(); + vertexList.ptr(anchorPtr); + vertexList.setVertexCount(totalVertexCount); material.getVertexTransformer().transform(vertexList, level); applyPoseStack(vertexList, stack, false); } - // TODO: remove this - // The VertexWriter API and VertexFormat conversion needs to be rewritten to make this unnecessary - private static void writeMesh(MutableVertexList vertexList, VertexList meshReader) { - for (int i = 0; i < meshReader.getVertexCount(); i++) { - vertexList.x(i, meshReader.x(i)); - vertexList.y(i, meshReader.y(i)); - vertexList.z(i, meshReader.z(i)); - - vertexList.r(i, meshReader.r(i)); - vertexList.g(i, meshReader.g(i)); - vertexList.b(i, meshReader.b(i)); - vertexList.a(i, meshReader.a(i)); - - vertexList.u(i, meshReader.u(i)); - vertexList.v(i, meshReader.v(i)); - - vertexList.overlay(i, meshReader.overlay(i)); - vertexList.light(i, meshReader.light(i)); - - vertexList.normalX(i, meshReader.normalX(i)); - vertexList.normalY(i, meshReader.normalY(i)); - vertexList.normalZ(i, meshReader.normalZ(i)); - } - } - private static void applyPoseStack(MutableVertexList vertexList, PoseStack stack, boolean applyNormalMatrix) { Vector4f pos = new Vector4f(); Vector3f normal = new Vector3f(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/MeshPool.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/MeshPool.java index 145f90ec3..39a0b4a48 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/MeshPool.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/MeshPool.java @@ -152,7 +152,7 @@ public class MeshPool { } } catch (Exception e) { - Flywheel.LOGGER.error("Error uploading pooled models:", e); + Flywheel.LOGGER.error("Error uploading pooled meshes:", e); } } @@ -164,7 +164,7 @@ public class MeshPool { } pendingUpload.clear(); } catch (Exception e) { - Flywheel.LOGGER.error("Error uploading pooled models:", e); + Flywheel.LOGGER.error("Error uploading pooled meshes:", e); } } @@ -209,7 +209,7 @@ public class MeshPool { } private boolean hasAnythingToRender() { - return mesh.getVertexCount() <= 0 || isDeleted(); + return mesh.isEmpty() || isDeleted(); } private void draw(int instanceCount) { 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 b639d64e0..7369df882 100644 --- a/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java +++ b/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java @@ -1,20 +1,22 @@ package com.jozufozu.flywheel.core.hardcoded; +import java.nio.ByteBuffer; import java.util.List; -import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; -import com.jozufozu.flywheel.api.vertex.VertexList; +import com.jozufozu.flywheel.api.vertex.MutableVertexList; +import com.jozufozu.flywheel.api.vertex.ReusableVertexList; import com.jozufozu.flywheel.core.model.Mesh; import com.jozufozu.flywheel.core.vertex.Formats; import com.jozufozu.flywheel.core.vertex.PosTexNormalVertex; -import com.jozufozu.flywheel.core.vertex.PosTexNormalWriterUnsafe; +import com.mojang.blaze3d.platform.MemoryTracker; public class ModelPart implements Mesh { - - private final int vertices; + private final int vertexCount; + private final ByteBuffer contents; + private final ReusableVertexList vertexList; private final String name; - private final VertexList reader; public ModelPart(List cuboids, String name) { this.name = name; @@ -24,17 +26,19 @@ public class ModelPart implements Mesh { for (PartBuilder.CuboidBuilder cuboid : cuboids) { vertices += cuboid.vertices(); } - this.vertices = vertices; + this.vertexCount = vertices; } - try (var stack = MemoryStack.stackPush()) { - PosTexNormalWriterUnsafe writer = getVertexType().createWriter(stack.malloc(size())); - for (PartBuilder.CuboidBuilder cuboid : cuboids) { - cuboid.buffer(writer); - } - - reader = writer.intoReader(this.vertices); + contents = MemoryTracker.create(size()); + long ptr = MemoryUtil.memAddress(contents); + VertexWriter writer = new VertexWriterImpl(ptr); + for (PartBuilder.CuboidBuilder cuboid : cuboids) { + cuboid.write(writer); } + + vertexList = getVertexType().createVertexList(); + vertexList.ptr(ptr); + vertexList.setVertexCount(vertexCount); } public static PartBuilder builder(String name, int sizeU, int sizeV) { @@ -42,22 +46,33 @@ public class ModelPart implements Mesh { } @Override - public String name() { - return name; + public PosTexNormalVertex getVertexType() { + return Formats.POS_TEX_NORMAL; } @Override public int getVertexCount() { - return vertices; + return vertexCount; } @Override - public VertexList getReader() { - return reader; + public void writeInto(ByteBuffer buffer, long byteIndex) { + buffer.position((int) byteIndex); + MemoryUtil.memCopy(contents, buffer); } @Override - public PosTexNormalVertex getVertexType() { - return Formats.POS_TEX_NORMAL; + public void writeInto(MutableVertexList dst) { + vertexList.writeAll(dst); + } + + @Override + public void close() { + MemoryUtil.memFree(contents); + } + + @Override + public String name() { + return name; } } diff --git a/src/main/java/com/jozufozu/flywheel/core/hardcoded/PartBuilder.java b/src/main/java/com/jozufozu/flywheel/core/hardcoded/PartBuilder.java index 3747fbe62..945607a47 100644 --- a/src/main/java/com/jozufozu/flywheel/core/hardcoded/PartBuilder.java +++ b/src/main/java/com/jozufozu/flywheel/core/hardcoded/PartBuilder.java @@ -5,7 +5,6 @@ import java.util.EnumSet; import java.util.List; import java.util.Set; -import com.jozufozu.flywheel.core.vertex.PosTexNormalWriterUnsafe; import com.mojang.math.Matrix3f; import com.mojang.math.Quaternion; import com.mojang.math.Vector3f; @@ -160,8 +159,7 @@ public class PartBuilder { return visibleFaces.size() * 4; } - public void buffer(PosTexNormalWriterUnsafe buffer) { - + public void write(VertexWriter writer) { float sizeX = posX2 - posX1; float sizeY = posY2 - posY1; float sizeZ = posZ2 - posZ1; @@ -219,28 +217,27 @@ public class PartBuilder { float f12 = getV((float)textureOffsetV + sizeZ + sizeY); if (invertYZ) { - quad(buffer, new Vector3f[]{hlh, llh, lll, hll}, f6, f11, f7, f10, down); - quad(buffer, new Vector3f[]{hhl, lhl, lhh, hhh}, f5, f10, f6, f11, up); - quad(buffer, new Vector3f[]{lll, llh, lhh, lhl}, f5, f12, f4, f11, west); - quad(buffer, new Vector3f[]{hll, lll, lhl, hhl}, f9, f12, f8, f11, north); - quad(buffer, new Vector3f[]{hlh, hll, hhl, hhh}, f8, f12, f6, f11, east); - quad(buffer, new Vector3f[]{llh, hlh, hhh, lhh}, f6, f12, f5, f11, south); + quad(writer, new Vector3f[]{hlh, llh, lll, hll}, f6, f11, f7, f10, down); + quad(writer, new Vector3f[]{hhl, lhl, lhh, hhh}, f5, f10, f6, f11, up); + quad(writer, new Vector3f[]{lll, llh, lhh, lhl}, f5, f12, f4, f11, west); + quad(writer, new Vector3f[]{hll, lll, lhl, hhl}, f9, f12, f8, f11, north); + quad(writer, new Vector3f[]{hlh, hll, hhl, hhh}, f8, f12, f6, f11, east); + quad(writer, new Vector3f[]{llh, hlh, hhh, lhh}, f6, f12, f5, f11, south); } else { - quad(buffer, new Vector3f[]{hlh, llh, lll, hll}, f5, f10, f6, f11, down); - quad(buffer, new Vector3f[]{hhl, lhl, lhh, hhh}, f6, f11, f7, f10, up); - quad(buffer, new Vector3f[]{lll, llh, lhh, lhl}, f4, f11, f5, f12, west); - quad(buffer, new Vector3f[]{hll, lll, lhl, hhl}, f5, f11, f6, f12, north); - quad(buffer, new Vector3f[]{hlh, hll, hhl, hhh}, f6, f11, f8, f12, east); - quad(buffer, new Vector3f[]{llh, hlh, hhh, lhh}, f8, f11, f9, f12, south); + quad(writer, new Vector3f[]{hlh, llh, lll, hll}, f5, f10, f6, f11, down); + quad(writer, new Vector3f[]{hhl, lhl, lhh, hhh}, f6, f11, f7, f10, up); + quad(writer, new Vector3f[]{lll, llh, lhh, lhl}, f4, f11, f5, f12, west); + quad(writer, new Vector3f[]{hll, lll, lhl, hhl}, f5, f11, f6, f12, north); + quad(writer, new Vector3f[]{hlh, hll, hhl, hhh}, f6, f11, f8, f12, east); + quad(writer, new Vector3f[]{llh, hlh, hhh, lhh}, f8, f11, f9, f12, south); } } - public void quad(PosTexNormalWriterUnsafe buffer, Vector3f[] vertices, float minU, float minV, float maxU, float maxV, Vector3f normal) { - buffer.putVertex(vertices[0].x(), vertices[0].y(), vertices[0].z(), normal.x(), normal.y(), normal.z(), maxU, minV); - buffer.putVertex(vertices[1].x(), vertices[1].y(), vertices[1].z(), normal.x(), normal.y(), normal.z(), minU, minV); - buffer.putVertex(vertices[2].x(), vertices[2].y(), vertices[2].z(), normal.x(), normal.y(), normal.z(), minU, maxV); - buffer.putVertex(vertices[3].x(), vertices[3].y(), vertices[3].z(), normal.x(), normal.y(), normal.z(), maxU, maxV); - + public void quad(VertexWriter writer, Vector3f[] vertices, float minU, float minV, float maxU, float maxV, Vector3f normal) { + writer.putVertex(vertices[0].x(), vertices[0].y(), vertices[0].z(), maxU, minV, normal.x(), normal.y(), normal.z()); + writer.putVertex(vertices[1].x(), vertices[1].y(), vertices[1].z(), minU, minV, normal.x(), normal.y(), normal.z()); + writer.putVertex(vertices[2].x(), vertices[2].y(), vertices[2].z(), minU, maxV, normal.x(), normal.y(), normal.z()); + writer.putVertex(vertices[3].x(), vertices[3].y(), vertices[3].z(), maxU, maxV, normal.x(), normal.y(), normal.z()); } public float getU(float u) { @@ -258,5 +255,4 @@ public class PartBuilder { } } - } diff --git a/src/main/java/com/jozufozu/flywheel/core/hardcoded/VertexWriter.java b/src/main/java/com/jozufozu/flywheel/core/hardcoded/VertexWriter.java new file mode 100644 index 000000000..7e031c58b --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/hardcoded/VertexWriter.java @@ -0,0 +1,5 @@ +package com.jozufozu.flywheel.core.hardcoded; + +public interface VertexWriter { + void putVertex(float x, float y, float z, float u, float v, float nX, float nY, float nZ); +} diff --git a/src/main/java/com/jozufozu/flywheel/core/hardcoded/VertexWriterImpl.java b/src/main/java/com/jozufozu/flywheel/core/hardcoded/VertexWriterImpl.java new file mode 100644 index 000000000..3b8b617cd --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/hardcoded/VertexWriterImpl.java @@ -0,0 +1,27 @@ +package com.jozufozu.flywheel.core.hardcoded; + +import org.lwjgl.system.MemoryUtil; + +import com.jozufozu.flywheel.util.RenderMath; + +public class VertexWriterImpl implements VertexWriter { + private long ptr; + + public VertexWriterImpl(long ptr) { + this.ptr = ptr; + } + + @Override + public void putVertex(float x, float y, float z, float u, float v, float nX, float nY, float nZ) { + MemoryUtil.memPutFloat(ptr, x); + MemoryUtil.memPutFloat(ptr + 4, y); + MemoryUtil.memPutFloat(ptr + 8, z); + MemoryUtil.memPutFloat(ptr + 12, u); + MemoryUtil.memPutFloat(ptr + 16, v); + MemoryUtil.memPutByte(ptr + 20, RenderMath.nb(nX)); + MemoryUtil.memPutByte(ptr + 21, RenderMath.nb(nY)); + MemoryUtil.memPutByte(ptr + 22, RenderMath.nb(nZ)); + + ptr += 23; + } +} 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 e8d51f557..488d16489 100644 --- a/src/main/java/com/jozufozu/flywheel/core/layout/CommonItems.java +++ b/src/main/java/com/jozufozu/flywheel/core/layout/CommonItems.java @@ -1,26 +1,39 @@ package com.jozufozu.flywheel.core.layout; import com.jozufozu.flywheel.backend.gl.GlNumericType; +import com.jozufozu.flywheel.backend.gl.array.VertexAttributeF; import com.jozufozu.flywheel.backend.gl.array.VertexAttributeI; public class CommonItems { - public static final PrimitiveItem VEC4 = new PrimitiveItem(GlNumericType.FLOAT, 4); - public static final PrimitiveItem VEC3 = new PrimitiveItem(GlNumericType.FLOAT, 3); - public static final PrimitiveItem VEC2 = new PrimitiveItem(GlNumericType.FLOAT, 2); - public static final PrimitiveItem FLOAT = new PrimitiveItem(GlNumericType.FLOAT, 1); + public static final PrimitiveItem VEC4 = primitiveF(GlNumericType.FLOAT, 4); + public static final PrimitiveItem VEC3 = primitiveF(GlNumericType.FLOAT, 3); + public static final PrimitiveItem VEC2 = primitiveF(GlNumericType.FLOAT, 2); + public static final PrimitiveItem FLOAT = primitiveF(GlNumericType.FLOAT, 1); - public static final PrimitiveItem QUATERNION = new PrimitiveItem(GlNumericType.FLOAT, 4); - public static final PrimitiveItem NORMAL = new PrimitiveItem(GlNumericType.BYTE, 3, true); - public static final PrimitiveItem UV = new PrimitiveItem(GlNumericType.FLOAT, 2); + public static final PrimitiveItem QUATERNION = primitiveF(GlNumericType.FLOAT, 4); + public static final PrimitiveItem NORMAL = primitiveF(GlNumericType.BYTE, 3, true); + public static final PrimitiveItem UV = primitiveF(GlNumericType.FLOAT, 2); - public static final PrimitiveItem RGBA = new PrimitiveItem(GlNumericType.UBYTE, 4, true); - public static final PrimitiveItem RGB = new PrimitiveItem(GlNumericType.UBYTE, 3, true); - public static final PrimitiveItem LIGHT = new PrimitiveItem(new VertexAttributeI(GlNumericType.UBYTE, 2)); - public static final PrimitiveItem LIGHT_SHORT = new PrimitiveItem(new VertexAttributeI(GlNumericType.USHORT, 2)); + public static final PrimitiveItem RGBA = primitiveF(GlNumericType.UBYTE, 4, true); + public static final PrimitiveItem RGB = primitiveF(GlNumericType.UBYTE, 3, true); + public static final PrimitiveItem LIGHT = primitiveI(GlNumericType.UBYTE, 2); + public static final PrimitiveItem LIGHT_SHORT = primitiveI(GlNumericType.USHORT, 2); - public static final PrimitiveItem NORMALIZED_BYTE = new PrimitiveItem(GlNumericType.BYTE, 1, true); + public static final PrimitiveItem NORMALIZED_BYTE = primitiveF(GlNumericType.BYTE, 1, true); public static final MatrixItem MAT3 = new MatrixItem(3, 3); public static final MatrixItem MAT4 = new MatrixItem(4, 4); + + private static PrimitiveItem primitiveF(GlNumericType type, int count, boolean normalized) { + return new PrimitiveItem(new VertexAttributeF(type, count, normalized)); + } + + private static PrimitiveItem primitiveF(GlNumericType type, int count) { + return primitiveF(type, count, false); + } + + private static PrimitiveItem primitiveI(GlNumericType type, int count) { + return new PrimitiveItem(new VertexAttributeI(type, count)); + } } 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 bc6423e17..d26fc4a16 100644 --- a/src/main/java/com/jozufozu/flywheel/core/layout/PrimitiveItem.java +++ b/src/main/java/com/jozufozu/flywheel/core/layout/PrimitiveItem.java @@ -2,22 +2,12 @@ package com.jozufozu.flywheel.core.layout; import java.util.function.Consumer; -import com.jozufozu.flywheel.backend.gl.GlNumericType; import com.jozufozu.flywheel.backend.gl.array.VertexAttribute; -import com.jozufozu.flywheel.backend.gl.array.VertexAttributeF; public class PrimitiveItem implements LayoutItem { private final VertexAttribute attribute; - public PrimitiveItem(GlNumericType type, int count) { - this(type, count, false); - } - - public PrimitiveItem(GlNumericType type, int count, boolean normalized) { - this(new VertexAttributeF(type, count, normalized)); - } - public PrimitiveItem(VertexAttribute attribute) { this.attribute = attribute; } diff --git a/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java b/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java index c382211c7..f09c5ec58 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java @@ -2,9 +2,8 @@ package com.jozufozu.flywheel.core.model; import java.nio.ByteBuffer; -import com.jozufozu.flywheel.api.vertex.VertexList; +import com.jozufozu.flywheel.api.vertex.MutableVertexList; import com.jozufozu.flywheel.api.vertex.VertexType; -import com.jozufozu.flywheel.api.vertex.VertexWriter; import com.jozufozu.flywheel.backend.instancing.instancing.ElementBuffer; import com.jozufozu.flywheel.core.QuadConverter; @@ -30,39 +29,34 @@ import com.jozufozu.flywheel.core.QuadConverter; */ public interface Mesh { - /** - * A name uniquely identifying this model. - */ - String name(); - VertexType getVertexType(); - VertexList getReader(); - /** - * @return The number of vertices the model has. + * @return The number of vertices this mesh has. */ - default int getVertexCount() { - return getReader().getVertexCount(); - } + int getVertexCount(); /** * Is there nothing to render? * @return true if there are no vertices. */ default boolean isEmpty() { - return getReader().isEmpty(); + return getVertexCount() == 0; } /** - * The size in bytes that this model's data takes up. + * The size in bytes that this mesh's data takes up. */ default int size() { return getVertexType().byteOffset(getVertexCount()); } + void writeInto(ByteBuffer buffer, long byteIndex); + + void writeInto(MutableVertexList vertexList); + /** - * Create an element buffer object that indexes the vertices of this model. + * Create an element buffer object that indexes the vertices of this mesh. * *

* Very often models in minecraft are made up of sequential quads, which is a very predictable pattern. @@ -76,9 +70,10 @@ public interface Mesh { .quads2Tris(getVertexCount() / 4); } - default void writeInto(ByteBuffer buffer, long byteIndex) { - VertexWriter writer = getVertexType().createWriter(buffer); - writer.seek(byteIndex); - writer.writeVertexList(getReader()); - } + void close(); + + /** + * A name uniquely identifying this mesh. + */ + String name(); } diff --git a/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java b/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java index b74a35989..dfcd1435a 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java @@ -4,14 +4,18 @@ import java.lang.reflect.Field; import java.nio.ByteBuffer; import org.jetbrains.annotations.Nullable; +import org.lwjgl.system.MemoryUtil; import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.material.Material; -import com.jozufozu.flywheel.api.vertex.VertexList; +import com.jozufozu.flywheel.api.vertex.ReusableVertexList; +import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.core.Materials; import com.jozufozu.flywheel.core.vertex.Formats; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.jozufozu.flywheel.core.vertex.VertexListProviderRegistry; +import com.mojang.blaze3d.platform.MemoryTracker; +import com.mojang.blaze3d.vertex.BufferBuilder.DrawState; +import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.datafixers.util.Pair; import net.minecraft.client.Minecraft; @@ -43,15 +47,27 @@ public class ModelUtil { return dispatcher; } - public static VertexList createVertexList(BufferBuilder bufferBuilder) { - Pair pair = bufferBuilder.popNextBuffer(); - BufferBuilder.DrawState drawState = pair.getFirst(); + public static Pair convertBlockBuffer(Pair pair) { + DrawState drawState = pair.getFirst(); + int vertexCount = drawState.vertexCount(); + VertexFormat srcFormat = drawState.format(); + VertexType dstVertexType = Formats.BLOCK; - if (drawState.format() != DefaultVertexFormat.BLOCK) { - throw new RuntimeException("Cannot use BufferBuilder with " + drawState.format()); - } + ByteBuffer src = pair.getSecond(); + ByteBuffer dst = MemoryTracker.create(src.capacity()); + long srcPtr = MemoryUtil.memAddress(src); + long dstPtr = MemoryUtil.memAddress(dst); - return Formats.BLOCK.createReader(pair.getSecond(), drawState.vertexCount()); + ReusableVertexList srcList = VertexListProviderRegistry.getOrInfer(srcFormat).createVertexList(); + ReusableVertexList dstList = dstVertexType.createVertexList(); + srcList.ptr(srcPtr); + dstList.ptr(dstPtr); + srcList.setVertexCount(vertexCount); + dstList.setVertexCount(vertexCount); + + srcList.writeAll(dstList); + + return Pair.of(dstVertexType, dst); } @Nullable diff --git a/src/main/java/com/jozufozu/flywheel/core/model/SimpleMesh.java b/src/main/java/com/jozufozu/flywheel/core/model/SimpleMesh.java index 55f76ef44..f95423005 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/SimpleMesh.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/SimpleMesh.java @@ -1,22 +1,36 @@ package com.jozufozu.flywheel.core.model; -import com.jozufozu.flywheel.api.vertex.VertexList; +import java.nio.ByteBuffer; + +import org.lwjgl.system.MemoryUtil; + +import com.jozufozu.flywheel.api.vertex.MutableVertexList; +import com.jozufozu.flywheel.api.vertex.ReusableVertexList; import com.jozufozu.flywheel.api.vertex.VertexType; public class SimpleMesh implements Mesh { - private final VertexList reader; private final VertexType vertexType; + private final int vertexCount; + private final ByteBuffer contents; + private final ReusableVertexList vertexList; private final String name; - public SimpleMesh(VertexList reader, VertexType vertexType, String name) { - this.reader = reader; + public SimpleMesh(VertexType vertexType, ByteBuffer contents, String name) { this.vertexType = vertexType; + this.contents = contents; this.name = name; - } - @Override - public String name() { - return name; + contents.clear(); + int bytes = contents.remaining(); + int stride = vertexType.getStride(); + if (bytes % stride != 0) { + throw new IllegalArgumentException("Buffer contains non-whole amount of vertices!"); + } + vertexCount = bytes / stride; + + vertexList = getVertexType().createVertexList(); + vertexList.ptr(MemoryUtil.memAddress(contents)); + vertexList.setVertexCount(vertexCount); } @Override @@ -25,8 +39,29 @@ public class SimpleMesh implements Mesh { } @Override - public VertexList getReader() { - return reader; + public int getVertexCount() { + return vertexCount; + } + + @Override + public void writeInto(ByteBuffer buffer, long byteIndex) { + buffer.position((int) byteIndex); + MemoryUtil.memCopy(contents, buffer); + } + + @Override + public void writeInto(MutableVertexList dst) { + vertexList.writeAll(dst); + } + + @Override + public void close() { + MemoryUtil.memFree(contents); + } + + @Override + public String name() { + return name; } @Override diff --git a/src/main/java/com/jozufozu/flywheel/core/model/buffering/BakedModelBuilder.java b/src/main/java/com/jozufozu/flywheel/core/model/buffering/BakedModelBuilder.java index 7393ac14b..d7c138d00 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/buffering/BakedModelBuilder.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/buffering/BakedModelBuilder.java @@ -1,9 +1,11 @@ package com.jozufozu.flywheel.core.model.buffering; +import java.nio.ByteBuffer; import java.util.function.BiFunction; import com.google.common.collect.ImmutableMap; import com.jozufozu.flywheel.api.material.Material; +import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.core.model.Mesh; import com.jozufozu.flywheel.core.model.ModelUtil; import com.jozufozu.flywheel.core.model.SimpleMesh; @@ -12,13 +14,13 @@ import com.jozufozu.flywheel.core.model.buffering.ModelBufferingUtil.BufferFacto import com.jozufozu.flywheel.core.model.buffering.ModelBufferingUtil.ResultConsumer; import com.jozufozu.flywheel.core.model.buffering.ModelBufferingUtil.ShadeSeparatedBufferFactory; import com.jozufozu.flywheel.core.model.buffering.ModelBufferingUtil.ShadeSeparatedResultConsumer; -import com.jozufozu.flywheel.core.vertex.Formats; import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; import com.jozufozu.flywheel.core.virtual.VirtualEmptyModelData; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexFormat; +import com.mojang.datafixers.util.Pair; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.resources.model.BakedModel; @@ -30,7 +32,6 @@ import net.minecraftforge.client.model.data.IModelData; public class BakedModelBuilder { private final BakedModel bakedModel; private boolean shadeSeparated = true; - private VertexFormat vertexFormat; private BlockAndTintGetter renderWorld; private BlockState blockState; private PoseStack poseStack; @@ -46,11 +47,6 @@ public class BakedModelBuilder { return this; } - public BakedModelBuilder vertexFormat(VertexFormat vertexFormat) { - this.vertexFormat = vertexFormat; - return this; - } - public BakedModelBuilder renderWorld(BlockAndTintGetter renderWorld) { this.renderWorld = renderWorld; return this; @@ -80,9 +76,6 @@ public class BakedModelBuilder { public TessellatedModel build() { ModelBufferingObjects objects = ModelBufferingObjects.THREAD_LOCAL.get(); - if (vertexFormat == null) { - vertexFormat = DefaultVertexFormat.BLOCK; - } if (renderWorld == null) { renderWorld = VirtualEmptyBlockGetter.INSTANCE; } @@ -104,28 +97,30 @@ public class BakedModelBuilder { if (shadeSeparated) { ShadeSeparatedBufferFactory bufferFactory = (renderType, shaded) -> { BufferBuilder buffer = new BufferBuilder(64); - buffer.begin(VertexFormat.Mode.QUADS, vertexFormat); + buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); return buffer; }; ShadeSeparatedResultConsumer resultConsumer = (renderType, shaded, buffer) -> { buffer.end(); Material material = materialFunc.apply(renderType, shaded); if (material != null) { - meshMapBuilder.put(material, new SimpleMesh(ModelUtil.createVertexList(buffer), Formats.BLOCK, "bakedModel=" + bakedModel.toString() + ",renderType=" + renderType.toString() + ",shaded=" + shaded)); + Pair pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer()); + meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "bakedModel=" + bakedModel.toString() + ",renderType=" + renderType.toString() + ",shaded=" + shaded)); } }; ModelBufferingUtil.bufferSingleShadeSeparated(ModelUtil.VANILLA_RENDERER.getModelRenderer(), renderWorld, bakedModel, blockState, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelData, resultConsumer); } else { BufferFactory bufferFactory = (renderType) -> { BufferBuilder buffer = new BufferBuilder(64); - buffer.begin(VertexFormat.Mode.QUADS, vertexFormat); + buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); return buffer; }; ResultConsumer resultConsumer = (renderType, buffer) -> { buffer.end(); Material material = materialFunc.apply(renderType, false); if (material != null) { - meshMapBuilder.put(material, new SimpleMesh(ModelUtil.createVertexList(buffer), Formats.BLOCK, "bakedModel=" + bakedModel.toString() + ",renderType=" + renderType.toString())); + Pair pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer()); + meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "bakedModel=" + bakedModel.toString() + ",renderType=" + renderType.toString())); } }; ModelBufferingUtil.bufferSingle(ModelUtil.VANILLA_RENDERER.getModelRenderer(), renderWorld, bakedModel, blockState, poseStack, bufferFactory, objects.bufferWrapper, objects.random, modelData, resultConsumer); diff --git a/src/main/java/com/jozufozu/flywheel/core/model/buffering/BlockModelBuilder.java b/src/main/java/com/jozufozu/flywheel/core/model/buffering/BlockModelBuilder.java index 022e948b9..f5d0c485e 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/buffering/BlockModelBuilder.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/buffering/BlockModelBuilder.java @@ -1,9 +1,11 @@ package com.jozufozu.flywheel.core.model.buffering; +import java.nio.ByteBuffer; import java.util.function.BiFunction; import com.google.common.collect.ImmutableMap; import com.jozufozu.flywheel.api.material.Material; +import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.core.model.Mesh; import com.jozufozu.flywheel.core.model.ModelUtil; import com.jozufozu.flywheel.core.model.SimpleMesh; @@ -12,13 +14,13 @@ import com.jozufozu.flywheel.core.model.buffering.ModelBufferingUtil.BufferFacto import com.jozufozu.flywheel.core.model.buffering.ModelBufferingUtil.ResultConsumer; import com.jozufozu.flywheel.core.model.buffering.ModelBufferingUtil.ShadeSeparatedBufferFactory; import com.jozufozu.flywheel.core.model.buffering.ModelBufferingUtil.ShadeSeparatedResultConsumer; -import com.jozufozu.flywheel.core.vertex.Formats; import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; import com.jozufozu.flywheel.core.virtual.VirtualEmptyModelData; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexFormat; +import com.mojang.datafixers.util.Pair; import net.minecraft.client.renderer.RenderType; import net.minecraft.world.level.BlockAndTintGetter; @@ -28,7 +30,6 @@ import net.minecraftforge.client.model.data.IModelData; public class BlockModelBuilder { private final BlockState state; private boolean shadeSeparated = true; - private VertexFormat vertexFormat; private BlockAndTintGetter renderWorld; private PoseStack poseStack; private IModelData modelData; @@ -43,11 +44,6 @@ public class BlockModelBuilder { return this; } - public BlockModelBuilder vertexFormat(VertexFormat vertexFormat) { - this.vertexFormat = vertexFormat; - return this; - } - public BlockModelBuilder renderWorld(BlockAndTintGetter renderWorld) { this.renderWorld = renderWorld; return this; @@ -72,9 +68,6 @@ public class BlockModelBuilder { public TessellatedModel build() { ModelBufferingObjects objects = ModelBufferingObjects.THREAD_LOCAL.get(); - if (vertexFormat == null) { - vertexFormat = DefaultVertexFormat.BLOCK; - } if (renderWorld == null) { renderWorld = VirtualEmptyBlockGetter.INSTANCE; } @@ -93,28 +86,30 @@ public class BlockModelBuilder { if (shadeSeparated) { ShadeSeparatedBufferFactory bufferFactory = (renderType, shaded) -> { BufferBuilder buffer = new BufferBuilder(64); - buffer.begin(VertexFormat.Mode.QUADS, vertexFormat); + buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); return buffer; }; ShadeSeparatedResultConsumer resultConsumer = (renderType, shaded, buffer) -> { buffer.end(); Material material = materialFunc.apply(renderType, shaded); if (material != null) { - meshMapBuilder.put(material, new SimpleMesh(ModelUtil.createVertexList(buffer), Formats.BLOCK, "state=" + state.toString() + ",renderType=" + renderType.toString() + ",shaded=" + shaded)); + Pair pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer()); + meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "state=" + state.toString() + ",renderType=" + renderType.toString() + ",shaded=" + shaded)); } }; ModelBufferingUtil.bufferBlockShadeSeparated(ModelUtil.VANILLA_RENDERER, renderWorld, state, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelData, resultConsumer); } else { BufferFactory bufferFactory = (renderType) -> { BufferBuilder buffer = new BufferBuilder(64); - buffer.begin(VertexFormat.Mode.QUADS, vertexFormat); + buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); return buffer; }; ResultConsumer resultConsumer = (renderType, buffer) -> { buffer.end(); Material material = materialFunc.apply(renderType, false); if (material != null) { - meshMapBuilder.put(material, new SimpleMesh(ModelUtil.createVertexList(buffer), Formats.BLOCK, "state=" + state.toString() + ",renderType=" + renderType.toString())); + Pair pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer()); + meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "state=" + state.toString() + ",renderType=" + renderType.toString())); } }; ModelBufferingUtil.bufferBlock(ModelUtil.VANILLA_RENDERER, renderWorld, state, poseStack, bufferFactory, objects.bufferWrapper, objects.random, modelData, resultConsumer); diff --git a/src/main/java/com/jozufozu/flywheel/core/model/buffering/MultiBlockModelBuilder.java b/src/main/java/com/jozufozu/flywheel/core/model/buffering/MultiBlockModelBuilder.java index 33acbcdab..c951acfbd 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/buffering/MultiBlockModelBuilder.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/buffering/MultiBlockModelBuilder.java @@ -1,5 +1,6 @@ package com.jozufozu.flywheel.core.model.buffering; +import java.nio.ByteBuffer; import java.util.Collection; import java.util.Collections; import java.util.Map; @@ -7,6 +8,7 @@ import java.util.function.BiFunction; import com.google.common.collect.ImmutableMap; import com.jozufozu.flywheel.api.material.Material; +import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.core.model.Mesh; import com.jozufozu.flywheel.core.model.ModelUtil; import com.jozufozu.flywheel.core.model.SimpleMesh; @@ -15,12 +17,12 @@ import com.jozufozu.flywheel.core.model.buffering.ModelBufferingUtil.BufferFacto import com.jozufozu.flywheel.core.model.buffering.ModelBufferingUtil.ResultConsumer; import com.jozufozu.flywheel.core.model.buffering.ModelBufferingUtil.ShadeSeparatedBufferFactory; import com.jozufozu.flywheel.core.model.buffering.ModelBufferingUtil.ShadeSeparatedResultConsumer; -import com.jozufozu.flywheel.core.vertex.Formats; import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexFormat; +import com.mojang.datafixers.util.Pair; import net.minecraft.client.renderer.RenderType; import net.minecraft.core.BlockPos; @@ -46,11 +48,6 @@ public class MultiBlockModelBuilder { return this; } - public MultiBlockModelBuilder vertexFormat(VertexFormat vertexFormat) { - this.vertexFormat = vertexFormat; - return this; - } - public MultiBlockModelBuilder renderWorld(BlockAndTintGetter renderWorld) { this.renderWorld = renderWorld; return this; @@ -96,28 +93,30 @@ public class MultiBlockModelBuilder { if (shadeSeparated) { ShadeSeparatedBufferFactory bufferFactory = (renderType, shaded) -> { BufferBuilder buffer = new BufferBuilder(1024); - buffer.begin(VertexFormat.Mode.QUADS, vertexFormat); + buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); return buffer; }; ShadeSeparatedResultConsumer resultConsumer = (renderType, shaded, buffer) -> { buffer.end(); Material material = materialFunc.apply(renderType, shaded); if (material != null) { - meshMapBuilder.put(material, new SimpleMesh(ModelUtil.createVertexList(buffer), Formats.BLOCK, "renderType=" + renderType.toString() + ",shaded=" + shaded)); + Pair pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer()); + meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "renderType=" + renderType.toString() + ",shaded=" + shaded)); } }; ModelBufferingUtil.bufferMultiBlockShadeSeparated(blocks, ModelUtil.VANILLA_RENDERER, renderWorld, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelDataMap, resultConsumer); } else { BufferFactory bufferFactory = (renderType) -> { BufferBuilder buffer = new BufferBuilder(1024); - buffer.begin(VertexFormat.Mode.QUADS, vertexFormat); + buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); return buffer; }; ResultConsumer resultConsumer = (renderType, buffer) -> { buffer.end(); Material material = materialFunc.apply(renderType, false); if (material != null) { - meshMapBuilder.put(material, new SimpleMesh(ModelUtil.createVertexList(buffer), Formats.BLOCK, "renderType=" + renderType.toString())); + Pair pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer()); + meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "renderType=" + renderType.toString())); } }; ModelBufferingUtil.bufferMultiBlock(blocks, ModelUtil.VANILLA_RENDERER, renderWorld, poseStack, bufferFactory, objects.bufferWrapper, objects.random, modelDataMap, resultConsumer); diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java b/src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java index a68e0c943..d1524cac2 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java @@ -1,49 +1,28 @@ package com.jozufozu.flywheel.core.vertex; -import java.nio.Buffer; -import java.nio.ByteBuffer; +import com.jozufozu.flywheel.api.vertex.ReusableVertexList; -import org.lwjgl.system.MemoryUtil; - -import com.jozufozu.flywheel.api.vertex.VertexList; -import com.mojang.blaze3d.platform.MemoryTracker; -import com.mojang.blaze3d.vertex.BufferBuilder; - -public abstract class AbstractVertexList implements VertexList, AutoCloseable { - - protected final ByteBuffer contents; - protected final long base; - protected final int vertexCount; - - protected AbstractVertexList(ByteBuffer copyFrom, int vertexCount) { - this.contents = MemoryTracker.create(copyFrom.capacity()); - this.vertexCount = vertexCount; - this.base = MemoryUtil.memAddress(this.contents); - init(copyFrom); - } - - public AbstractVertexList(BufferBuilder builder) { - var pair = builder.popNextBuffer(); - ByteBuffer copyFrom = pair.getSecond(); - this.contents = MemoryTracker.create(copyFrom.capacity()); - this.vertexCount = pair.getFirst().vertexCount(); - this.base = MemoryUtil.memAddress(this.contents); - init(copyFrom); - } - - private void init(ByteBuffer copyFrom) { - this.contents.order(copyFrom.order()); - this.contents.put(copyFrom); - ((Buffer) this.contents).flip(); - } - - @Override - public void close() { - MemoryUtil.memFree(contents); - } +public abstract class AbstractVertexList implements ReusableVertexList { + protected long ptr; + protected int vertexCount; @Override public int getVertexCount() { return vertexCount; } + + @Override + public void setVertexCount(int vertexCount) { + this.vertexCount = vertexCount; + } + + @Override + public long ptr() { + return ptr; + } + + @Override + public void ptr(long ptr) { + this.ptr = ptr; + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java index 9f37d06b8..e916d5ce3 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java @@ -1,7 +1,5 @@ package com.jozufozu.flywheel.core.vertex; -import java.nio.ByteBuffer; - import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.core.Components; import com.jozufozu.flywheel.core.layout.BufferLayout; @@ -9,7 +7,6 @@ import com.jozufozu.flywheel.core.layout.CommonItems; import com.jozufozu.flywheel.core.source.FileResolution; public class BlockVertex implements VertexType { - public static final BufferLayout FORMAT = BufferLayout.builder() .addItems(CommonItems.VEC3, CommonItems.RGBA, @@ -24,18 +21,13 @@ public class BlockVertex implements VertexType { return FORMAT; } - @Override - public BlockWriterUnsafe createWriter(ByteBuffer buffer) { - return new BlockWriterUnsafe(this, buffer); - } - - @Override - public BlockVertexListUnsafe createReader(ByteBuffer buffer, int vertexCount) { - return new BlockVertexListUnsafe(buffer, vertexCount); - } - @Override public FileResolution getLayoutShader() { return Components.Files.BLOCK_LAYOUT; } + + @Override + public BlockVertexList createVertexList() { + return new BlockVertexList(); + } } 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 a0423246a..ecfa8f277 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java @@ -1,72 +1,61 @@ package com.jozufozu.flywheel.core.vertex; +import org.lwjgl.system.MemoryUtil; + import com.jozufozu.flywheel.util.RenderMath; -import com.mojang.blaze3d.vertex.BufferBuilder; import net.minecraft.client.renderer.texture.OverlayTexture; public class BlockVertexList extends AbstractVertexList { + protected static final int STRIDE = 32; - private final int stride; - - public BlockVertexList(BufferBuilder builder) { - super(builder); - this.stride = builder.getVertexFormat() - .getVertexSize(); - } - - @Override - public boolean isEmpty() { - return vertexCount == 0; - } - - private int vertIdx(int vertexIndex) { - return vertexIndex * stride; + protected long idxPtr(int index) { + return ptr + index * STRIDE; } @Override public float x(int index) { - return contents.getFloat(vertIdx(index)); + return MemoryUtil.memGetFloat(idxPtr(index)); } @Override public float y(int index) { - return contents.getFloat(vertIdx(index) + 4); + return MemoryUtil.memGetFloat(idxPtr(index) + 4); } @Override public float z(int index) { - return contents.getFloat(vertIdx(index) + 8); + return MemoryUtil.memGetFloat(idxPtr(index) + 8); } @Override public byte r(int index) { - return contents.get(vertIdx(index) + 12); + return MemoryUtil.memGetByte(idxPtr(index) + 12); } @Override public byte g(int index) { - return contents.get(vertIdx(index) + 13); + return MemoryUtil.memGetByte(idxPtr(index) + 13); } @Override public byte b(int index) { - return contents.get(vertIdx(index) + 14); + return MemoryUtil.memGetByte(idxPtr(index) + 14); } @Override public byte a(int index) { - return contents.get(vertIdx(index) + 15); + return MemoryUtil.memGetByte(idxPtr(index) + 15); } @Override public float u(int index) { - return contents.getFloat(vertIdx(index) + 16); + return MemoryUtil.memGetFloat(idxPtr(index) + 16); } @Override public float v(int index) { - return contents.getFloat(vertIdx(index) + 20); + return MemoryUtil.memGetFloat(idxPtr(index) + 20); } @Override @@ -76,22 +65,95 @@ public class BlockVertexList extends AbstractVertexList { @Override public int light(int index) { - return contents.getInt(vertIdx(index) + 24); + return MemoryUtil.memGetInt(idxPtr(index) + 24) << 4; } @Override public float normalX(int index) { - return RenderMath.f(contents.get(vertIdx(index) + 28)); + return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + 28)); } @Override public float normalY(int index) { - return RenderMath.f(contents.get(vertIdx(index) + 29)); + return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + 29)); } @Override public float normalZ(int index) { - return RenderMath.f(contents.get(vertIdx(index) + 30)); + return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + 30)); } + @Override + public void x(int index, float x) { + MemoryUtil.memPutFloat(idxPtr(index), x); + } + + @Override + public void y(int index, float y) { + MemoryUtil.memPutFloat(idxPtr(index) + 4, y); + } + + @Override + public void z(int index, float z) { + MemoryUtil.memPutFloat(idxPtr(index) + 8, z); + } + + @Override + public void r(int index, byte r) { + MemoryUtil.memPutByte(idxPtr(index) + 12, r); + } + + @Override + public void g(int index, byte g) { + MemoryUtil.memPutByte(idxPtr(index) + 13, g); + } + + @Override + public void b(int index, byte b) { + MemoryUtil.memPutByte(idxPtr(index) + 14, b); + } + + @Override + public void a(int index, byte a) { + MemoryUtil.memPutByte(idxPtr(index) + 15, a); + } + + @Override + public void u(int index, float u) { + MemoryUtil.memPutFloat(idxPtr(index) + 16, u); + } + + @Override + public void v(int index, float v) { + MemoryUtil.memPutFloat(idxPtr(index) + 20, v); + } + + @Override + public void overlay(int index, int overlay) { + } + + @Override + public void light(int index, int light) { + MemoryUtil.memPutInt(idxPtr(index) + 24, light >> 4); + } + + @Override + public void normalX(int index, float normalX) { + MemoryUtil.memPutByte(idxPtr(index) + 28, RenderMath.nb(normalX)); + } + + @Override + public void normalY(int index, float normalY) { + MemoryUtil.memPutByte(idxPtr(index) + 29, RenderMath.nb(normalY)); + } + + @Override + public void normalZ(int index, float normalZ) { + MemoryUtil.memPutByte(idxPtr(index) + 30, RenderMath.nb(normalZ)); + } + + @Override + public void shiftPtr(int vertices) { + ptr += vertices * STRIDE; + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java deleted file mode 100644 index 2b272f76e..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.jozufozu.flywheel.core.vertex; - -import java.nio.ByteBuffer; - -import org.lwjgl.system.MemoryUtil; - -import com.jozufozu.flywheel.util.RenderMath; - -import net.minecraft.client.renderer.texture.OverlayTexture; - -public class BlockVertexListUnsafe extends AbstractVertexList { - - public BlockVertexListUnsafe(ByteBuffer copyFrom, int vertexCount) { - super(copyFrom, vertexCount); - } - - private long ptr(long index) { - return base + index * 32; - } - - @Override - public float x(int index) { - return MemoryUtil.memGetFloat(ptr(index)); - } - - @Override - public float y(int index) { - return MemoryUtil.memGetFloat(ptr(index) + 4); - } - - @Override - public float z(int index) { - return MemoryUtil.memGetFloat(ptr(index) + 8); - } - - @Override - public byte r(int index) { - return MemoryUtil.memGetByte(ptr(index) + 12); - } - - @Override - public byte g(int index) { - return MemoryUtil.memGetByte(ptr(index) + 13); - } - - @Override - public byte b(int index) { - return MemoryUtil.memGetByte(ptr(index) + 14); - } - - @Override - public byte a(int index) { - return MemoryUtil.memGetByte(ptr(index) + 15); - } - - @Override - public float u(int index) { - return MemoryUtil.memGetFloat(ptr(index) + 16); - } - - @Override - public float v(int index) { - return MemoryUtil.memGetFloat(ptr(index) + 20); - } - - @Override - public int overlay(int index) { - return OverlayTexture.NO_OVERLAY; - } - - @Override - public int light(int index) { - return MemoryUtil.memGetInt(ptr(index) + 24); - } - - @Override - public float normalX(int index) { - return RenderMath.f(MemoryUtil.memGetByte(ptr(index) + 28)); - } - - @Override - public float normalY(int index) { - return RenderMath.f(MemoryUtil.memGetByte(ptr(index) + 29)); - } - - @Override - public float normalZ(int index) { - return RenderMath.f(MemoryUtil.memGetByte(ptr(index) + 30)); - } - -} diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockWriterUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockWriterUnsafe.java deleted file mode 100644 index 556e352d9..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockWriterUnsafe.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.jozufozu.flywheel.core.vertex; - -import java.nio.ByteBuffer; - -import org.lwjgl.system.MemoryUtil; - -import com.jozufozu.flywheel.api.vertex.VertexList; -import com.jozufozu.flywheel.util.RenderMath; - -public class BlockWriterUnsafe extends VertexWriterUnsafe { - - public BlockWriterUnsafe(BlockVertex type, ByteBuffer buffer) { - super(type, buffer); - } - - @Override - public void writeVertex(VertexList list, int i) { - float x = list.x(i); - float y = list.y(i); - float z = list.z(i); - - float xN = list.normalX(i); - float yN = list.normalY(i); - float zN = list.normalZ(i); - - float u = list.u(i); - float v = list.v(i); - - byte r = list.r(i); - byte g = list.g(i); - byte b = list.b(i); - byte a = list.a(i); - - int light = list.light(i); - - putVertex(x, y, z, u, v, r, g, b, a, light, xN, yN, zN); - } - - public void putVertex(float x, float y, float z, float u, float v, byte r, byte g, byte b, byte a, int light, float nX, float nY, float nZ) { - MemoryUtil.memPutFloat(ptr, x); - MemoryUtil.memPutFloat(ptr + 4, y); - MemoryUtil.memPutFloat(ptr + 8, z); - MemoryUtil.memPutByte(ptr + 12, r); - MemoryUtil.memPutByte(ptr + 13, g); - MemoryUtil.memPutByte(ptr + 14, b); - MemoryUtil.memPutByte(ptr + 15, a); - MemoryUtil.memPutFloat(ptr + 16, u); - MemoryUtil.memPutFloat(ptr + 20, v); - MemoryUtil.memPutInt(ptr + 24, (light >> 4) & 0xF000F); - MemoryUtil.memPutByte(ptr + 28, RenderMath.nb(nX)); - MemoryUtil.memPutByte(ptr + 29, RenderMath.nb(nY)); - MemoryUtil.memPutByte(ptr + 30, RenderMath.nb(nZ)); - - ptr += 32; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/VertexFormatInfo.java b/src/main/java/com/jozufozu/flywheel/core/vertex/InferredVertexFormatInfo.java similarity index 88% rename from src/main/java/com/jozufozu/flywheel/backend/instancing/batching/VertexFormatInfo.java rename to src/main/java/com/jozufozu/flywheel/core/vertex/InferredVertexFormatInfo.java index 35f273508..c47cb837e 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/VertexFormatInfo.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/InferredVertexFormatInfo.java @@ -1,9 +1,9 @@ -package com.jozufozu.flywheel.backend.instancing.batching; +package com.jozufozu.flywheel.core.vertex; import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormatElement; -public class VertexFormatInfo { +public class InferredVertexFormatInfo { public final VertexFormat format; public final int stride; @@ -14,7 +14,7 @@ public class VertexFormatInfo { public final int lightOffset; public final int normalOffset; - public VertexFormatInfo(VertexFormat format) { + public InferredVertexFormatInfo(VertexFormat format) { this.format = format; stride = format.getVertexSize(); @@ -51,7 +51,7 @@ public class VertexFormatInfo { this.normalOffset = normalOffset; } - protected VertexFormatInfo(VertexFormatInfo formatInfo) { + protected InferredVertexFormatInfo(InferredVertexFormatInfo formatInfo) { format = formatInfo.format; stride = formatInfo.stride; positionOffset = formatInfo.positionOffset; diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/InferredVertexListImpl.java b/src/main/java/com/jozufozu/flywheel/core/vertex/InferredVertexListImpl.java new file mode 100644 index 000000000..c074e37bf --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/InferredVertexListImpl.java @@ -0,0 +1,214 @@ +package com.jozufozu.flywheel.core.vertex; + +import org.lwjgl.system.MemoryUtil; + +import com.jozufozu.flywheel.api.vertex.ReusableVertexList; +import com.jozufozu.flywheel.util.RenderMath; + +import net.minecraft.client.renderer.texture.OverlayTexture; + +public final class InferredVertexListImpl extends InferredVertexFormatInfo implements ReusableVertexList { + private long ptr; + private int vertexCount; + + public InferredVertexListImpl(InferredVertexFormatInfo formatInfo) { + super(formatInfo); + } + + private long idxPtr(int index) { + return ptr + index * stride; + } + + @Override + public float x(int index) { + if (positionOffset < 0) return 0; + return MemoryUtil.memGetFloat(idxPtr(index) + positionOffset); + } + + @Override + public float y(int index) { + if (positionOffset < 0) return 0; + return MemoryUtil.memGetFloat(idxPtr(index) + positionOffset + 4); + } + + @Override + public float z(int index) { + if (positionOffset < 0) return 0; + return MemoryUtil.memGetFloat(idxPtr(index) + positionOffset + 8); + } + + @Override + public byte r(int index) { + if (colorOffset < 0) return 0; + return MemoryUtil.memGetByte(idxPtr(index) + colorOffset); + } + + @Override + public byte g(int index) { + if (colorOffset < 0) return 0; + return MemoryUtil.memGetByte(idxPtr(index) + colorOffset + 1); + } + + @Override + public byte b(int index) { + if (colorOffset < 0) return 0; + return MemoryUtil.memGetByte(idxPtr(index) + colorOffset + 2); + } + + @Override + public byte a(int index) { + if (colorOffset < 0) return 0; + return MemoryUtil.memGetByte(idxPtr(index) + colorOffset + 3); + } + + @Override + public float u(int index) { + if (textureOffset < 0) return 0; + return MemoryUtil.memGetFloat(idxPtr(index) + textureOffset); + } + + @Override + public float v(int index) { + if (textureOffset < 0) return 0; + return MemoryUtil.memGetFloat(idxPtr(index) + textureOffset + 4); + } + + @Override + public int overlay(int index) { + if (overlayOffset < 0) return OverlayTexture.NO_OVERLAY; + return MemoryUtil.memGetInt(idxPtr(index) + overlayOffset); + } + + @Override + public int light(int index) { + if (lightOffset < 0) return 0; + return MemoryUtil.memGetInt(idxPtr(index) + lightOffset); + } + + @Override + public float normalX(int index) { + if (normalOffset < 0) return 0; + return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + normalOffset)); + } + + @Override + public float normalY(int index) { + if (normalOffset < 0) return 0; + return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + normalOffset + 1)); + } + + @Override + public float normalZ(int index) { + if (normalOffset < 0) return 0; + return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + normalOffset + 2)); + } + + @Override + public void x(int index, float x) { + if (positionOffset < 0) return; + MemoryUtil.memPutFloat(idxPtr(index) + positionOffset, x); + } + + @Override + public void y(int index, float y) { + if (positionOffset < 0) return; + MemoryUtil.memPutFloat(idxPtr(index) + positionOffset + 4, y); + } + + @Override + public void z(int index, float z) { + if (positionOffset < 0) return; + MemoryUtil.memPutFloat(idxPtr(index) + positionOffset + 8, z); + } + + @Override + public void r(int index, byte r) { + if (colorOffset < 0) return; + MemoryUtil.memPutByte(idxPtr(index) + colorOffset, r); + } + + @Override + public void g(int index, byte g) { + if (colorOffset < 0) return; + MemoryUtil.memPutByte(idxPtr(index) + colorOffset + 1, g); + } + + @Override + public void b(int index, byte b) { + if (colorOffset < 0) return; + MemoryUtil.memPutByte(idxPtr(index) + colorOffset + 2, b); + } + + @Override + public void a(int index, byte a) { + if (colorOffset < 0) return; + MemoryUtil.memPutByte(idxPtr(index) + colorOffset + 3, a); + } + + @Override + public void u(int index, float u) { + if (textureOffset < 0) return; + MemoryUtil.memPutFloat(idxPtr(index) + textureOffset, u); + } + + @Override + public void v(int index, float v) { + if (textureOffset < 0) return; + MemoryUtil.memPutFloat(idxPtr(index) + textureOffset + 4, v); + } + + @Override + public void overlay(int index, int overlay) { + if (overlayOffset < 0) return; + MemoryUtil.memPutInt(idxPtr(index) + overlayOffset, overlay); + } + + @Override + public void light(int index, int light) { + if (lightOffset < 0) return; + MemoryUtil.memPutInt(idxPtr(index) + lightOffset, light); + } + + @Override + public void normalX(int index, float normalX) { + if (normalOffset < 0) return; + MemoryUtil.memPutByte(idxPtr(index) + normalOffset, RenderMath.nb(normalX)); + } + + @Override + public void normalY(int index, float normalY) { + if (normalOffset < 0) return; + MemoryUtil.memPutByte(idxPtr(index) + normalOffset + 1, RenderMath.nb(normalY)); + } + + @Override + public void normalZ(int index, float normalZ) { + if (normalOffset < 0) return; + MemoryUtil.memPutByte(idxPtr(index) + normalOffset + 2, RenderMath.nb(normalZ)); + } + + @Override + public int getVertexCount() { + return vertexCount; + } + + @Override + public long ptr() { + return ptr; + } + + @Override + public void ptr(long ptr) { + this.ptr = ptr; + } + + @Override + public void shiftPtr(int vertices) { + ptr += vertices * stride; + } + + @Override + public void setVertexCount(int vertexCount) { + this.vertexCount = vertexCount; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/InferredVertexListProviderImpl.java b/src/main/java/com/jozufozu/flywheel/core/vertex/InferredVertexListProviderImpl.java new file mode 100644 index 000000000..fd976aa6b --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/InferredVertexListProviderImpl.java @@ -0,0 +1,20 @@ +package com.jozufozu.flywheel.core.vertex; + +import com.jozufozu.flywheel.api.vertex.ReusableVertexList; +import com.jozufozu.flywheel.api.vertex.VertexListProvider; +import com.mojang.blaze3d.vertex.VertexFormat; + +public class InferredVertexListProviderImpl implements VertexListProvider { + private final VertexFormat format; + private final InferredVertexFormatInfo formatInfo; + + public InferredVertexListProviderImpl(VertexFormat format) { + this.format = format; + formatInfo = new InferredVertexFormatInfo(format); + } + + @Override + public ReusableVertexList createVertexList() { + return new InferredVertexListImpl(formatInfo); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertex.java b/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertex.java index 2c115041c..131bfc6e6 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertex.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertex.java @@ -1,7 +1,5 @@ package com.jozufozu.flywheel.core.vertex; -import java.nio.ByteBuffer; - import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.core.Components; import com.jozufozu.flywheel.core.layout.BufferLayout; @@ -9,7 +7,6 @@ import com.jozufozu.flywheel.core.layout.CommonItems; import com.jozufozu.flywheel.core.source.FileResolution; public class PosTexNormalVertex implements VertexType { - public static final BufferLayout FORMAT = BufferLayout.builder() .addItems(CommonItems.VEC3, CommonItems.UV, CommonItems.NORMAL) .build(); @@ -19,18 +16,13 @@ public class PosTexNormalVertex implements VertexType { return FORMAT; } - @Override - public PosTexNormalWriterUnsafe createWriter(ByteBuffer buffer) { - return new PosTexNormalWriterUnsafe(this, buffer); - } - - @Override - public PosTexNormalVertexListUnsafe createReader(ByteBuffer buffer, int vertexCount) { - return new PosTexNormalVertexListUnsafe(buffer, vertexCount); - } - @Override public FileResolution getLayoutShader() { return Components.Files.POS_TEX_NORMAL_LAYOUT; } + + @Override + public PosTexNormalVertexList createVertexList() { + return new PosTexNormalVertexList(); + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexList.java b/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexList.java new file mode 100644 index 000000000..4ac841c04 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexList.java @@ -0,0 +1,154 @@ +package com.jozufozu.flywheel.core.vertex; + +import org.lwjgl.system.MemoryUtil; + +import com.jozufozu.flywheel.util.RenderMath; + +import net.minecraft.client.renderer.texture.OverlayTexture; + +public class PosTexNormalVertexList extends AbstractVertexList { + protected static final int STRIDE = 23; + + protected long idxPtr(long idx) { + return ptr + idx * STRIDE; + } + + @Override + public float x(int index) { + return MemoryUtil.memGetFloat(idxPtr(index)); + } + + @Override + public float y(int index) { + return MemoryUtil.memGetFloat(idxPtr(index) + 4); + } + + @Override + public float z(int index) { + return MemoryUtil.memGetFloat(idxPtr(index) + 8); + } + + @Override + public byte r(int index) { + return (byte) 0xFF; + } + + @Override + public byte g(int index) { + return (byte) 0xFF; + } + + @Override + public byte b(int index) { + return (byte) 0xFF; + } + + @Override + public byte a(int index) { + return (byte) 0xFF; + } + + @Override + public float u(int index) { + return MemoryUtil.memGetFloat(idxPtr(index) + 12); + } + + @Override + public float v(int index) { + return MemoryUtil.memGetFloat(idxPtr(index) + 16); + } + + @Override + public int overlay(int index) { + return OverlayTexture.NO_OVERLAY; + } + + @Override + public int light(int index) { + return 0; + } + + @Override + public float normalX(int index) { + return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + 20)); + } + + @Override + public float normalY(int index) { + return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + 21)); + } + + @Override + public float normalZ(int index) { + return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + 22)); + } + + @Override + public void x(int index, float x) { + MemoryUtil.memPutFloat(idxPtr(index), x); + } + + @Override + public void y(int index, float y) { + MemoryUtil.memPutFloat(idxPtr(index) + 4, y); + } + + @Override + public void z(int index, float z) { + MemoryUtil.memPutFloat(idxPtr(index) + 8, z); + } + + @Override + public void r(int index, byte r) { + } + + @Override + public void g(int index, byte g) { + } + + @Override + public void b(int index, byte b) { + } + + @Override + public void a(int index, byte a) { + } + + @Override + public void u(int index, float u) { + MemoryUtil.memPutFloat(idxPtr(index) + 12, u); + } + + @Override + public void v(int index, float v) { + MemoryUtil.memPutFloat(idxPtr(index) + 16, v); + } + + @Override + public void overlay(int index, int overlay) { + } + + @Override + public void light(int index, int light) { + } + + @Override + public void normalX(int index, float normalX) { + MemoryUtil.memPutByte(idxPtr(index) + 20, RenderMath.nb(normalX)); + } + + @Override + public void normalY(int index, float normalY) { + MemoryUtil.memPutByte(idxPtr(index) + 21, RenderMath.nb(normalY)); + } + + @Override + public void normalZ(int index, float normalZ) { + MemoryUtil.memPutByte(idxPtr(index) + 22, RenderMath.nb(normalZ)); + } + + @Override + public void shiftPtr(int vertices) { + ptr += vertices * STRIDE; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java deleted file mode 100644 index df1091a97..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.jozufozu.flywheel.core.vertex; - -import java.nio.ByteBuffer; - -import org.lwjgl.system.MemoryUtil; - -import com.jozufozu.flywheel.util.RenderMath; - -import net.minecraft.client.renderer.texture.OverlayTexture; - -public class PosTexNormalVertexListUnsafe extends AbstractVertexList { - - public PosTexNormalVertexListUnsafe(ByteBuffer copyFrom, int vertexCount) { - super(copyFrom, vertexCount); - } - - private long ptr(long idx) { - return base + idx * 23; - } - - @Override - public float x(int index) { - return MemoryUtil.memGetFloat(ptr(index)); - } - - @Override - public float y(int index) { - return MemoryUtil.memGetFloat(ptr(index) + 4); - } - - @Override - public float z(int index) { - return MemoryUtil.memGetFloat(ptr(index) + 8); - } - - @Override - public byte r(int index) { - return (byte) 0xFF; - } - - @Override - public byte g(int index) { - return (byte) 0xFF; - } - - @Override - public byte b(int index) { - return (byte) 0xFF; - } - - @Override - public byte a(int index) { - return (byte) 0xFF; - } - - @Override - public float u(int index) { - return MemoryUtil.memGetFloat(ptr(index) + 12); - } - - @Override - public float v(int index) { - return MemoryUtil.memGetFloat(ptr(index) + 16); - } - - @Override - public int overlay(int index) { - return OverlayTexture.NO_OVERLAY; - } - - @Override - public int light(int index) { - return 0; - } - - @Override - public float normalX(int index) { - return RenderMath.f(MemoryUtil.memGetByte(ptr(index) + 20)); - } - - @Override - public float normalY(int index) { - return RenderMath.f(MemoryUtil.memGetByte(ptr(index) + 21)); - } - - @Override - public float normalZ(int index) { - return RenderMath.f(MemoryUtil.memGetByte(ptr(index) + 22)); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalWriterUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalWriterUnsafe.java deleted file mode 100644 index 7e97962bc..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalWriterUnsafe.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.jozufozu.flywheel.core.vertex; - -import java.nio.ByteBuffer; - -import org.lwjgl.system.MemoryUtil; - -import com.jozufozu.flywheel.api.vertex.VertexList; -import com.jozufozu.flywheel.util.RenderMath; - -public class PosTexNormalWriterUnsafe extends VertexWriterUnsafe { - - public PosTexNormalWriterUnsafe(PosTexNormalVertex type, ByteBuffer buffer) { - super(type, buffer); - } - - @Override - public void writeVertex(VertexList list, int i) { - float x = list.x(i); - float y = list.y(i); - float z = list.z(i); - - float u = list.u(i); - float v = list.v(i); - - float xN = list.normalX(i); - float yN = list.normalY(i); - float zN = list.normalZ(i); - - putVertex(x, y, z, xN, yN, zN, u, v); - } - - public void putVertex(float x, float y, float z, float nX, float nY, float nZ, float u, float v) { - MemoryUtil.memPutFloat(ptr, x); - MemoryUtil.memPutFloat(ptr + 4, y); - MemoryUtil.memPutFloat(ptr + 8, z); - MemoryUtil.memPutFloat(ptr + 12, u); - MemoryUtil.memPutFloat(ptr + 16, v); - MemoryUtil.memPutByte(ptr + 20, RenderMath.nb(nX)); - MemoryUtil.memPutByte(ptr + 21, RenderMath.nb(nY)); - MemoryUtil.memPutByte(ptr + 22, RenderMath.nb(nZ)); - - ptr += 23; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/TrackedVertexList.java b/src/main/java/com/jozufozu/flywheel/core/vertex/TrackedVertexList.java deleted file mode 100644 index 00cb24eec..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/TrackedVertexList.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.jozufozu.flywheel.core.vertex; - -import java.lang.ref.Cleaner; -import java.nio.Buffer; -import java.nio.ByteBuffer; - -import org.lwjgl.system.MemoryUtil; - -import com.jozufozu.flywheel.api.vertex.VertexList; -import com.jozufozu.flywheel.backend.FlywheelMemory; -import com.mojang.blaze3d.platform.MemoryTracker; - -public abstract class TrackedVertexList implements VertexList, AutoCloseable { - - protected final ByteBuffer contents; - protected final long base; - protected final int vertexCount; - private final Cleaner.Cleanable cleanable; - - protected TrackedVertexList(ByteBuffer copyFrom, int vertexCount) { - this.contents = MemoryTracker.create(copyFrom.capacity()); - this.contents.order(copyFrom.order()); - this.contents.put(copyFrom); - ((Buffer) this.contents).flip(); - - this.cleanable = FlywheelMemory.track(this, this.contents); - - this.base = MemoryUtil.memAddress(this.contents); - this.vertexCount = vertexCount; - } - - @Override - public void close() { - cleanable.clean(); - } - - @Override - public int getVertexCount() { - return vertexCount; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/VertexListProviderRegistry.java b/src/main/java/com/jozufozu/flywheel/core/vertex/VertexListProviderRegistry.java new file mode 100644 index 000000000..3a597d8db --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/VertexListProviderRegistry.java @@ -0,0 +1,55 @@ +package com.jozufozu.flywheel.core.vertex; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.jetbrains.annotations.Nullable; + +import com.jozufozu.flywheel.api.vertex.VertexListProvider; +import com.mojang.blaze3d.vertex.VertexFormat; + +public class VertexListProviderRegistry { + private static final Map HOLDERS = new ConcurrentHashMap<>(); + + private static Holder getOrCreateHolder(VertexFormat format) { + return HOLDERS.computeIfAbsent(format, Holder::new); + } + + public static void register(VertexFormat format, VertexListProvider provider) { + getOrCreateHolder(format).registeredProvider = provider; + } + + @Nullable + public static VertexListProvider get(VertexFormat format) { + return getOrCreateHolder(format).get(); + } + + public static VertexListProvider getOrInfer(VertexFormat format) { + return getOrCreateHolder(format).getOrInfer(); + } + + private static class Holder { + public final VertexFormat format; + public VertexListProvider registeredProvider; + public VertexListProvider inferredProvider; + + public Holder(VertexFormat format) { + this.format = format; + } + + @Nullable + public VertexListProvider get() { + return registeredProvider; + } + + public VertexListProvider getOrInfer() { + if (registeredProvider != null) { + return registeredProvider; + } + if (inferredProvider == null) { + inferredProvider = new InferredVertexListProviderImpl(format); + } + return inferredProvider; + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/VertexWriterUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/vertex/VertexWriterUnsafe.java deleted file mode 100644 index f4f31c7d0..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/VertexWriterUnsafe.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.jozufozu.flywheel.core.vertex; - -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.api.vertex.VertexWriter; - -public abstract class VertexWriterUnsafe implements VertexWriter { - - public final V type; - protected final ByteBuffer buffer; - protected long ptr; - - protected VertexWriterUnsafe(V type, ByteBuffer buffer) { - this.type = type; - this.buffer = buffer; - this.ptr = MemoryUtil.memAddress(buffer); - } - - @Override - public void seek(long offset) { - buffer.position((int) offset); - ptr = MemoryUtil.memAddress(buffer); - } - - @Override - public VertexList intoReader(int vertices) { - return type.createReader(buffer, vertices); - } -}