blockEntities;
@@ -148,4 +148,8 @@ public class InstanceWorld {
.forEach(entities::add);
}
+ @Override
+ public void close() {
+ delete();
+ }
}
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..65ea1cab7 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
@@ -13,9 +13,7 @@ import com.jozufozu.flywheel.backend.instancing.InstanceManager;
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.util.FlwUtil;
-import com.mojang.blaze3d.platform.Lighting;
import com.mojang.blaze3d.vertex.PoseStack;
-import com.mojang.math.Matrix4f;
import net.minecraft.client.Camera;
import net.minecraft.client.multiplayer.ClientLevel;
@@ -68,19 +66,11 @@ 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;
}
- // FIXME: this probably breaks some vanilla stuff but it works much better for flywheel
- Matrix4f mat = new Matrix4f();
- mat.setIdentity();
- if (context.level().effects().constantAmbientLight()) {
- Lighting.setupNetherLevel(mat);
- } else {
- Lighting.setupLevel(mat);
- }
-
batchTracker.endBatch();
}
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..4e2cd4fc9 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
@@ -2,28 +2,35 @@ package com.jozufozu.flywheel.backend.instancing.batching;
import java.nio.ByteBuffer;
-import org.lwjgl.system.MemoryUtil;
-
-import com.mojang.blaze3d.platform.MemoryTracker;
+import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
+import com.jozufozu.flywheel.api.vertex.VertexListProvider;
+import com.jozufozu.flywheel.backend.memory.MemoryBlock;
+import com.jozufozu.flywheel.core.vertex.VertexListProviderRegistry;
+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 MemoryBlock memory;
+ private ByteBuffer buffer;
- private ByteBuffer backingBuffer;
private int expectedVertices;
- private long ptr;
public DrawBuffer(RenderType parent) {
this.parent = parent;
- formatInfo = new VertexFormatInfo(parent.format());
+ format = parent.format();
+ stride = format.getVertexSize();
+ provider = VertexListProviderRegistry.getOrInfer(format);
}
/**
@@ -33,29 +40,32 @@ public class DrawBuffer {
*/
public void prepare(int vertexCount) {
if (expectedVertices != 0) {
- throw new IllegalStateException("Already drawing");
+ throw new IllegalStateException("Already drawing!");
}
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);
- } else if (byteSize > backingBuffer.capacity()) {
- backingBuffer = MemoryTracker.resize(backingBuffer, byteSize);
+ if (memory == null) {
+ memory = MemoryBlock.malloc(byteSize);
+ buffer = memory.asBuffer();
+ } else if (byteSize > memory.size()) {
+ memory = memory.realloc(byteSize);
+ buffer = memory.asBuffer();
}
- backingBuffer.clear();
- ptr = MemoryUtil.memAddress(backingBuffer);
- MemoryUtil.memSet(ptr, 0, byteSize);
+ memory.clear();
}
- 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(memory.ptr() + startVertex * stride);
+ vertexList.setVertexCount(vertexCount);
+ return vertexList;
}
/**
@@ -63,7 +73,8 @@ public class DrawBuffer {
* @param bufferBuilder The buffer builder to inject into.
*/
public void inject(BufferBuilderExtension bufferBuilder) {
- bufferBuilder.flywheel$injectForRender(backingBuffer, formatInfo.format, expectedVertices);
+ buffer.clear();
+ bufferBuilder.flywheel$injectForRender(buffer, format, expectedVertices);
}
public int getVertexCount() {
@@ -78,11 +89,16 @@ public class DrawBuffer {
}
/**
- * Reset the draw buffer to have no vertices.
+ * Reset the draw buffer to have no vertices.
*
* Does not clear the backing buffer.
*/
public void reset() {
this.expectedVertices = 0;
}
+
+ public void free() {
+ buffer = null;
+ memory.free();
+ }
}
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..bb1fb6185 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
@@ -5,9 +5,8 @@ import java.util.List;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
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,80 +48,50 @@ 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();
- VertexList meshReader = mesh.getReader();
- @SuppressWarnings("unchecked")
- StructType.VertexTransformer structVertexTransformer = (VertexTransformer) instancer.type.getVertexTransformer();
+ int meshVertexCount = mesh.getVertexCount();
+ vertexList.setVertexCount(meshVertexCount);
+
+ StructType.VertexTransformer structVertexTransformer = instancer.type.getVertexTransformer();
for (D d : list) {
- vertexList.setRange(startVertex, meshVertexCount);
-
- writeMesh(vertexList, meshReader);
+ mesh.write(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);
+ applyPoseStack(vertexList, stack);
}
- // 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) {
+ private static void applyPoseStack(MutableVertexList vertexList, PoseStack stack) {
Vector4f pos = new Vector4f();
Vector3f normal = new Vector3f();
Matrix4f modelMatrix = stack.last().pose();
- Matrix3f normalMatrix;
- if (applyNormalMatrix) {
- normalMatrix = stack.last().normal();
- } else {
- normalMatrix = null;
- }
+ Matrix3f normalMatrix = stack.last().normal();
for (int i = 0; i < vertexList.getVertexCount(); i++) {
pos.set(
@@ -136,18 +105,16 @@ public class TransformSet {
vertexList.y(i, pos.y());
vertexList.z(i, pos.z());
- if (applyNormalMatrix) {
- normal.set(
- vertexList.normalX(i),
- vertexList.normalY(i),
- vertexList.normalZ(i)
- );
- normal.transform(normalMatrix);
- normal.normalize();
- vertexList.normalX(i, normal.x());
- vertexList.normalY(i, normal.y());
- vertexList.normalZ(i, normal.z());
- }
+ normal.set(
+ vertexList.normalX(i),
+ vertexList.normalY(i),
+ vertexList.normalZ(i)
+ );
+ normal.transform(normalMatrix);
+ normal.normalize();
+ vertexList.normalX(i, normal.x());
+ vertexList.normalY(i, normal.y());
+ vertexList.normalZ(i, normal.z());
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java
index a46ce4f7c..7689ca9a2 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java
@@ -10,8 +10,8 @@ import com.jozufozu.flywheel.api.instancer.InstancerFactory;
import com.jozufozu.flywheel.api.instancer.InstancerManager;
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
import com.jozufozu.flywheel.core.structs.StructTypes;
-import com.jozufozu.flywheel.core.structs.model.TransformedPart;
import com.jozufozu.flywheel.core.structs.oriented.OrientedPart;
+import com.jozufozu.flywheel.core.structs.transformed.TransformedPart;
import com.jozufozu.flywheel.util.box.GridAlignedBB;
import com.jozufozu.flywheel.util.box.ImmutableBox;
import com.jozufozu.flywheel.util.joml.FrustumIntersection;
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectMeshPool.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectMeshPool.java
index 1ae8f1722..367e4ffdb 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectMeshPool.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectMeshPool.java
@@ -13,6 +13,7 @@ import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.instancing.instancing.ElementBuffer;
+import com.jozufozu.flywheel.backend.memory.MemoryBlock;
import com.jozufozu.flywheel.core.model.Mesh;
public class IndirectMeshPool {
@@ -23,7 +24,7 @@ public class IndirectMeshPool {
final VertexType vertexType;
final int vbo;
- private final ByteBuffer clientStorage;
+ private final MemoryBlock clientStorage;
private boolean dirty;
@@ -35,7 +36,7 @@ public class IndirectMeshPool {
vbo = glCreateBuffers();
var byteCapacity = type.byteOffset(vertexCapacity);
glNamedBufferStorage(vbo, byteCapacity, GL_DYNAMIC_STORAGE_BIT);
- clientStorage = MemoryUtil.memAlloc(byteCapacity);
+ clientStorage = MemoryBlock.malloc(byteCapacity);
}
/**
@@ -65,24 +66,25 @@ public class IndirectMeshPool {
}
dirty = false;
+ final long ptr = clientStorage.ptr();
+
int byteIndex = 0;
int baseVertex = 0;
for (BufferedMesh model : meshList) {
model.byteIndex = byteIndex;
model.baseVertex = baseVertex;
- model.buffer(clientStorage);
+ model.buffer(ptr);
byteIndex += model.getByteSize();
baseVertex += model.mesh.getVertexCount();
}
- clientStorage.rewind();
-
- glNamedBufferSubData(vbo, 0, clientStorage);
+ nglNamedBufferSubData(vbo, 0, byteIndex, ptr);
}
public void delete() {
+ clientStorage.free();
glDeleteBuffers(vbo);
meshes.clear();
meshList.clear();
@@ -101,10 +103,8 @@ public class IndirectMeshPool {
vertexCount = mesh.getVertexCount();
}
- private void buffer(ByteBuffer buffer) {
- var writer = IndirectMeshPool.this.vertexType.createWriter(buffer);
- writer.seek(this.byteIndex);
- writer.writeVertexList(this.mesh.getReader());
+ private void buffer(long ptr) {
+ this.mesh.write(ptr + byteIndex);
}
public int getByteSize() {
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 bcc39f82e..a2fc2da05 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
@@ -6,12 +6,12 @@ import java.util.Set;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.struct.StructType;
+import com.jozufozu.flywheel.api.struct.StructWriter;
import com.jozufozu.flywheel.backend.gl.array.GlVertexArray;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferUsage;
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
-import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer;
import com.jozufozu.flywheel.backend.instancing.AbstractInstancer;
import com.jozufozu.flywheel.core.layout.BufferLayout;
@@ -42,7 +42,7 @@ public class GPUInstancer extends AbstractInstancer
public void init() {
if (vbo != null) return;
- vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER, GlBufferUsage.DYNAMIC_DRAW);
+ vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER, GlBufferUsage.DYNAMIC_DRAW);
vbo.setGrowthMargin(instanceFormat.getStride() * 16);
}
@@ -88,7 +88,16 @@ public class GPUInstancer extends AbstractInstancer
buf.clear(clearStart, clearLength);
if (size > 0) {
- writeChangedUnchecked(structType.getWriter(buf.unwrap()));
+ final long ptr = buf.getPtr();
+ final long stride = structType.getLayout().getStride();
+ final StructWriter writer = structType.getWriter();
+
+ for (int i = 0; i < size; i++) {
+ final D element = data.get(i);
+ if (element.checkDirtyAndClear()) {
+ writer.write(ptr + i * stride, element);
+ }
+ }
}
} catch (Exception e) {
Flywheel.LOGGER.error("Error updating GPUInstancer:", e);
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 0438ac71d..919e863d7 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
@@ -1,6 +1,5 @@
package com.jozufozu.flywheel.backend.instancing.instancing;
-import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -18,7 +17,7 @@ import com.jozufozu.flywheel.backend.gl.array.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.buffer.MappedGlBuffer;
+import com.jozufozu.flywheel.core.layout.BufferLayout;
import com.jozufozu.flywheel.core.model.Mesh;
import com.jozufozu.flywheel.core.vertex.Formats;
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
@@ -27,7 +26,7 @@ public class MeshPool {
private static MeshPool allocator;
- static MeshPool getInstance() {
+ public static MeshPool getInstance() {
if (allocator == null) {
allocator = new MeshPool();
}
@@ -58,7 +57,7 @@ public class MeshPool {
* Create a new mesh pool.
*/
public MeshPool() {
- vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER);
+ vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER);
vbo.setGrowthMargin(2048);
}
@@ -71,9 +70,8 @@ public class MeshPool {
*/
public BufferedMesh alloc(Mesh mesh) {
return meshes.computeIfAbsent(mesh, m -> {
- // FIXME: culling experiments fixing everything to Formats.BLOCK
- BufferedMesh bufferedModel = new BufferedMesh(Formats.BLOCK, m, byteSize, vertexCount);
- byteSize += bufferedModel.getByteSize();
+ BufferedMesh bufferedModel = new BufferedMesh(m, byteSize, vertexCount);
+ byteSize += m.size();
vertexCount += bufferedModel.mesh.getVertexCount();
allBuffered.add(bufferedModel);
pendingUpload.add(bufferedModel);
@@ -147,7 +145,7 @@ public class MeshPool {
private void uploadAll() {
try (MappedBuffer mapped = vbo.map()) {
- ByteBuffer buffer = mapped.unwrap();
+ long ptr = mapped.getPtr();
int byteIndex = 0;
int baseVertex = 0;
@@ -155,26 +153,26 @@ public class MeshPool {
model.byteIndex = byteIndex;
model.baseVertex = baseVertex;
- model.buffer(buffer);
+ model.buffer(ptr);
byteIndex += model.getByteSize();
baseVertex += model.mesh.getVertexCount();
}
} catch (Exception e) {
- Flywheel.LOGGER.error("Error uploading pooled models:", e);
+ Flywheel.LOGGER.error("Error uploading pooled meshes:", e);
}
}
private void uploadPending() {
try (MappedBuffer mapped = vbo.map()) {
- ByteBuffer buffer = mapped.unwrap();
+ long buffer = mapped.getPtr();
for (BufferedMesh model : pendingUpload) {
model.buffer(buffer);
}
pendingUpload.clear();
} catch (Exception e) {
- Flywheel.LOGGER.error("Error uploading pooled models:", e);
+ Flywheel.LOGGER.error("Error uploading pooled meshes:", e);
}
}
@@ -207,14 +205,6 @@ public class MeshPool {
this.type = mesh.getVertexType();
}
- public BufferedMesh(VertexType type, Mesh mesh, long byteIndex, int baseVertex) {
- this.mesh = mesh;
- this.byteIndex = byteIndex;
- this.baseVertex = baseVertex;
- this.ebo = mesh.createEBO();
- this.type = type;
- }
-
public void drawCall(GlVertexArray vao) {
drawInstances(vao, 1);
}
@@ -228,7 +218,7 @@ public class MeshPool {
}
private boolean hasAnythingToRender() {
- return mesh.getVertexCount() <= 0 || isDeleted();
+ return mesh.isEmpty() || isDeleted();
}
private void draw(int instanceCount) {
@@ -258,10 +248,8 @@ public class MeshPool {
this.deleted = true;
}
- private void buffer(ByteBuffer buffer) {
- var writer = type.createWriter(buffer);
- writer.seek(this.byteIndex);
- writer.writeVertexList(this.mesh.getReader());
+ private void buffer(long ptr) {
+ this.mesh.write(ptr + byteIndex);
this.boundTo.clear();
this.gpuResident = true;
diff --git a/src/main/java/com/jozufozu/flywheel/backend/memory/FlwMemoryTracker.java b/src/main/java/com/jozufozu/flywheel/backend/memory/FlwMemoryTracker.java
new file mode 100644
index 000000000..165b441f3
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/backend/memory/FlwMemoryTracker.java
@@ -0,0 +1,111 @@
+package com.jozufozu.flywheel.backend.memory;
+
+import java.lang.ref.Cleaner;
+import java.nio.ByteBuffer;
+
+import org.lwjgl.system.MemoryUtil;
+
+public class FlwMemoryTracker {
+ static final Cleaner CLEANER = Cleaner.create();
+
+ private static long cpuMemory = 0;
+ private static long gpuMemory = 0;
+
+ public static long malloc(long size) {
+ long ptr = MemoryUtil.nmemAlloc(size);
+ if (ptr == MemoryUtil.NULL) {
+ throw new OutOfMemoryError("Failed to allocate " + size + " bytes");
+ }
+ return ptr;
+ }
+
+ /**
+ * @deprecated Use {@link MemoryBlock#malloc(long)} or {@link MemoryBlock#mallocTracked(long)} and
+ * {@link MemoryBlock#asBuffer()} instead. This method should only be used if specifically a {@linkplain ByteBuffer} is needed and it is
+ * short-lived.
+ */
+ @Deprecated
+ public static ByteBuffer mallocBuffer(int size) {
+ ByteBuffer buffer = MemoryUtil.memByteBuffer(malloc(size), size);
+ _allocCPUMemory(buffer.capacity());
+ return buffer;
+ }
+
+ public static long calloc(long num, long size) {
+ long ptr = MemoryUtil.nmemCalloc(num, size);
+ if (ptr == MemoryUtil.NULL) {
+ throw new OutOfMemoryError("Failed to allocate " + num + " elements of size " + size + " bytes");
+ }
+ return ptr;
+ }
+
+ /**
+ * @deprecated Use {@link MemoryBlock#calloc(long, long)} or {@link MemoryBlock#callocTracked(long, long)} and
+ * {@link MemoryBlock#asBuffer()} instead. This method should only be used if specifically a {@linkplain ByteBuffer} is needed and it is
+ * short-lived.
+ */
+ @Deprecated
+ public static ByteBuffer callocBuffer(int num, int size) {
+ ByteBuffer buffer = MemoryUtil.memByteBuffer(calloc(num, size), num * size);
+ _allocCPUMemory(buffer.capacity());
+ return buffer;
+ }
+
+ public static long realloc(long ptr, long size) {
+ ptr = MemoryUtil.nmemRealloc(ptr, size);
+ if (ptr == MemoryUtil.NULL) {
+ throw new OutOfMemoryError("Failed to reallocate " + size + " bytes for address 0x" + Long.toHexString(ptr));
+ }
+ return ptr;
+ }
+
+ /**
+ * @deprecated Use {@link MemoryBlock#realloc(long)} or {@link MemoryBlock#reallocTracked(long)} instead. This method
+ * should only be used if specifically a {@linkplain ByteBuffer} is needed and it is short-lived.
+ */
+ @Deprecated
+ public static ByteBuffer reallocBuffer(ByteBuffer buffer, int size) {
+ ByteBuffer newBuffer = MemoryUtil.memByteBuffer(realloc(MemoryUtil.memAddress(buffer), size), size);
+ _freeCPUMemory(buffer.capacity());
+ _allocCPUMemory(newBuffer.capacity());
+ return newBuffer;
+ }
+
+ public static void free(long ptr) {
+ MemoryUtil.nmemFree(ptr);
+ }
+
+ /**
+ * @deprecated Use {@link MemoryBlock#free} instead. This method should only be used if specifically a {@linkplain ByteBuffer} is needed and
+ * it is short-lived.
+ */
+ @Deprecated
+ public static void freeBuffer(ByteBuffer buffer) {
+ free(MemoryUtil.memAddress(buffer));
+ _freeCPUMemory(buffer.capacity());
+ }
+
+ public static void _allocCPUMemory(long size) {
+ cpuMemory += size;
+ }
+
+ public static void _freeCPUMemory(long size) {
+ cpuMemory -= size;
+ }
+
+ public static void _allocGPUMemory(long size) {
+ gpuMemory += size;
+ }
+
+ public static void _freeGPUMemory(long size) {
+ gpuMemory -= size;
+ }
+
+ public static long getCPUMemory() {
+ return cpuMemory;
+ }
+
+ public static long getGPUMemory() {
+ return gpuMemory;
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/memory/MemoryBlock.java b/src/main/java/com/jozufozu/flywheel/backend/memory/MemoryBlock.java
new file mode 100644
index 000000000..1b28bdbe2
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/backend/memory/MemoryBlock.java
@@ -0,0 +1,43 @@
+package com.jozufozu.flywheel.backend.memory;
+
+import java.nio.ByteBuffer;
+
+public sealed interface MemoryBlock permits MemoryBlockImpl {
+ long ptr();
+
+ long size();
+
+ boolean isFreed();
+
+ boolean isTracked();
+
+ void copyTo(long ptr, long bytes);
+
+ void copyTo(long ptr);
+
+ void clear();
+
+ ByteBuffer asBuffer();
+
+ MemoryBlock realloc(long size);
+
+ MemoryBlock reallocTracked(long size);
+
+ void free();
+
+ static MemoryBlock malloc(long size) {
+ return MemoryBlockImpl.mallocBlock(size);
+ }
+
+ static MemoryBlock mallocTracked(long size) {
+ return TrackedMemoryBlockImpl.mallocBlockTracked(size);
+ }
+
+ static MemoryBlock calloc(long num, long size) {
+ return MemoryBlockImpl.callocBlock(num, size);
+ }
+
+ static MemoryBlock callocTracked(long num, long size) {
+ return TrackedMemoryBlockImpl.callocBlockTracked(num, size);
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/memory/MemoryBlockImpl.java b/src/main/java/com/jozufozu/flywheel/backend/memory/MemoryBlockImpl.java
new file mode 100644
index 000000000..d37b61ded
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/backend/memory/MemoryBlockImpl.java
@@ -0,0 +1,100 @@
+package com.jozufozu.flywheel.backend.memory;
+
+import java.nio.ByteBuffer;
+
+import org.lwjgl.system.MemoryUtil;
+
+sealed class MemoryBlockImpl implements MemoryBlock permits TrackedMemoryBlockImpl {
+ final long ptr;
+ final long size;
+
+ boolean freed;
+
+ MemoryBlockImpl(long ptr, long size) {
+ this.ptr = ptr;
+ this.size = size;
+ }
+
+ @Override
+ public long ptr() {
+ return ptr;
+ }
+
+ @Override
+ public long size() {
+ return size;
+ }
+
+ @Override
+ public boolean isFreed() {
+ return freed;
+ }
+
+ @Override
+ public boolean isTracked() {
+ return false;
+ }
+
+ @Override
+ public void copyTo(long ptr, long bytes) {
+ MemoryUtil.memCopy(this.ptr, ptr, bytes);
+ }
+
+ @Override
+ public void copyTo(long ptr) {
+ copyTo(ptr, size);
+ }
+
+ @Override
+ public void clear() {
+ MemoryUtil.memSet(ptr, 0, size);
+ }
+
+ @Override
+ public ByteBuffer asBuffer() {
+ int intSize = (int) size;
+ if (intSize != size) {
+ throw new UnsupportedOperationException("Cannot create buffer with long capacity!");
+ }
+ return MemoryUtil.memByteBuffer(ptr, intSize);
+ }
+
+ void freeInner() {
+ FlwMemoryTracker._freeCPUMemory(size);
+ freed = true;
+ }
+
+ @Override
+ public MemoryBlock realloc(long size) {
+ MemoryBlock block = new MemoryBlockImpl(FlwMemoryTracker.realloc(ptr, size), size);
+ FlwMemoryTracker._allocCPUMemory(block.size());
+ freeInner();
+ return block;
+ }
+
+ @Override
+ public MemoryBlock reallocTracked(long size) {
+ MemoryBlock block = new TrackedMemoryBlockImpl(FlwMemoryTracker.realloc(ptr, size), size, FlwMemoryTracker.CLEANER);
+ FlwMemoryTracker._allocCPUMemory(block.size());
+ freeInner();
+ return block;
+ }
+
+ @Override
+ public void free() {
+ FlwMemoryTracker.free(ptr);
+ freeInner();
+ }
+
+ static MemoryBlock mallocBlock(long size) {
+ MemoryBlock block = new MemoryBlockImpl(FlwMemoryTracker.malloc(size), size);
+ FlwMemoryTracker._allocCPUMemory(block.size());
+ return block;
+ }
+
+ static MemoryBlock callocBlock(long num, long size) {
+ MemoryBlock block = new MemoryBlockImpl(FlwMemoryTracker.calloc(num, size), num * size);
+ FlwMemoryTracker._allocCPUMemory(block.size());
+ return block;
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/memory/TrackedMemoryBlockImpl.java b/src/main/java/com/jozufozu/flywheel/backend/memory/TrackedMemoryBlockImpl.java
new file mode 100644
index 000000000..57b7730c5
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/backend/memory/TrackedMemoryBlockImpl.java
@@ -0,0 +1,58 @@
+package com.jozufozu.flywheel.backend.memory;
+
+import java.lang.ref.Cleaner;
+
+final class TrackedMemoryBlockImpl extends MemoryBlockImpl {
+ final CleaningAction cleaningAction;
+ final Cleaner.Cleanable cleanable;
+
+ TrackedMemoryBlockImpl(long ptr, long size, Cleaner cleaner) {
+ super(ptr, size);
+ cleaningAction = new CleaningAction(ptr, size);
+ cleanable = cleaner.register(this, cleaningAction);
+ }
+
+ @Override
+ public boolean isTracked() {
+ return true;
+ }
+
+ @Override
+ void freeInner() {
+ super.freeInner();
+ cleaningAction.freed = true;
+ cleanable.clean();
+ }
+
+ static MemoryBlock mallocBlockTracked(long size) {
+ MemoryBlock block = new TrackedMemoryBlockImpl(FlwMemoryTracker.malloc(size), size, FlwMemoryTracker.CLEANER);
+ FlwMemoryTracker._allocCPUMemory(block.size());
+ return block;
+ }
+
+ static MemoryBlock callocBlockTracked(long num, long size) {
+ MemoryBlock block = new TrackedMemoryBlockImpl(FlwMemoryTracker.calloc(num, size), num * size, FlwMemoryTracker.CLEANER);
+ FlwMemoryTracker._allocCPUMemory(block.size());
+ return block;
+ }
+
+ static class CleaningAction implements Runnable {
+ final long ptr;
+ final long size;
+
+ boolean freed;
+
+ CleaningAction(long ptr, long size) {
+ this.ptr = ptr;
+ this.size = size;
+ }
+
+ @Override
+ public void run() {
+ if (!freed) {
+ FlwMemoryTracker.free(ptr);
+ FlwMemoryTracker._freeCPUMemory(size);
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/struct/BufferWriter.java b/src/main/java/com/jozufozu/flywheel/backend/struct/BufferWriter.java
deleted file mode 100644
index 49ce4969d..000000000
--- a/src/main/java/com/jozufozu/flywheel/backend/struct/BufferWriter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.jozufozu.flywheel.backend.struct;
-
-import java.nio.ByteBuffer;
-
-import com.jozufozu.flywheel.api.instancer.InstancedPart;
-import com.jozufozu.flywheel.api.struct.StructType;
-import com.jozufozu.flywheel.api.struct.StructWriter;
-
-public abstract class BufferWriter implements StructWriter {
- protected final ByteBuffer backingBuffer;
-
- protected final int stride;
-
- protected BufferWriter(StructType structType, ByteBuffer byteBuffer) {
- this.backingBuffer = byteBuffer;
-
- this.stride = structType.getLayout().getStride();
- }
-
- @Override
- public final void write(S struct) {
- writeInternal(struct);
- advance();
- }
-
- /**
- * Advances the write pointer forward by the stride of one vertex.
- * This will always be called after a struct is written, implementors need not call it themselves.
- *
- * @see #write
- */
- protected abstract void advance();
-
- protected abstract void writeInternal(S s);
-
- @Override
- public void seek(int pos) {
- backingBuffer.position(pos * stride);
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/struct/UnsafeBufferWriter.java b/src/main/java/com/jozufozu/flywheel/backend/struct/UnsafeBufferWriter.java
deleted file mode 100644
index 7aa852de1..000000000
--- a/src/main/java/com/jozufozu/flywheel/backend/struct/UnsafeBufferWriter.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.jozufozu.flywheel.backend.struct;
-
-import java.nio.ByteBuffer;
-
-import org.lwjgl.system.MemoryUtil;
-
-import com.jozufozu.flywheel.api.instancer.InstancedPart;
-import com.jozufozu.flywheel.api.struct.StructType;
-
-/**
- * This class copied/adapted from jellysquid's
- *
- * An unsafe {@link BufferWriter} implementation which uses direct memory operations to enable fast blitting of
- * data into memory buffers. Only available on JVMs which support {@link sun.misc.Unsafe}, but generally produces much
- * better optimized code than other implementations. The implementation does not check for invalid memory accesses,
- * meaning that errors can corrupt process memory.
- */
-public abstract class UnsafeBufferWriter extends BufferWriter {
- /**
- * The write pointer into the buffer storage. This is advanced by the stride every time
- * {@link UnsafeBufferWriter#advance()} is called.
- */
- protected long writePointer;
-
- protected UnsafeBufferWriter(StructType structType, ByteBuffer byteBuffer) {
- super(structType, byteBuffer);
-
- acquireWritePointer();
- }
-
- @Override
- public void seek(int pos) {
- super.seek(pos);
- acquireWritePointer();
- }
-
- @Override
- protected void advance() {
- this.writePointer += this.stride;
- }
-
- private void acquireWritePointer() {
- this.writePointer = MemoryUtil.memAddress(this.backingBuffer, this.backingBuffer.position());
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java b/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java
index c3282c2ae..7280641fa 100644
--- a/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java
+++ b/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java
@@ -3,13 +3,14 @@ package com.jozufozu.flywheel.core;
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
import static org.lwjgl.opengl.GL11.glDrawArrays;
+import org.lwjgl.system.MemoryUtil;
+
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
import com.jozufozu.flywheel.backend.gl.array.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.buffer.MappedGlBuffer;
import com.jozufozu.flywheel.core.layout.BufferLayout;
import com.jozufozu.flywheel.core.layout.CommonItems;
import com.jozufozu.flywheel.util.Lazy;
@@ -34,13 +35,14 @@ public class FullscreenQuad {
private FullscreenQuad() {
try (var restoreState = GlStateTracker.getRestoreState()) {
- vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER);
+ vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER);
vbo.ensureCapacity(bufferSize);
try (MappedBuffer buffer = vbo.map()) {
+ var ptr = buffer.getPtr();
- buffer.unwrap()
- .asFloatBuffer()
- .put(vertices);
+ for (var i = 0; i < vertices.length; i++) {
+ MemoryUtil.memPutFloat(ptr + i * Float.BYTES, vertices[i]);
+ }
} catch (Exception e) {
Flywheel.LOGGER.error("Could not create fullscreen quad.", e);
diff --git a/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java b/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java
index 0b2477214..71e9d27ce 100644
--- a/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java
+++ b/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java
@@ -1,15 +1,13 @@
package com.jozufozu.flywheel.core;
-import java.nio.ByteBuffer;
-
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.backend.gl.GlNumericType;
+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.backend.instancing.instancing.ElementBuffer;
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
@@ -34,11 +32,11 @@ public class QuadConverter {
return INSTANCE;
}
- private final MappedGlBuffer ebo;
+ private final GlBuffer ebo;
private int quadCapacity;
public QuadConverter() {
- this.ebo = new MappedGlBuffer(GlBufferType.ELEMENT_ARRAY_BUFFER);
+ this.ebo = new GlBuffer(GlBufferType.ELEMENT_ARRAY_BUFFER);
this.quadCapacity = 0;
}
@@ -49,9 +47,7 @@ public class QuadConverter {
ebo.ensureCapacity((long) indexCount * GlNumericType.UINT.getByteWidth());
try (MappedBuffer map = ebo.map()) {
- ByteBuffer indices = map.unwrap();
-
- fillBuffer(indices, quads);
+ fillBuffer(map.getPtr(), quads);
}
ebo.unbind();
@@ -66,32 +62,18 @@ public class QuadConverter {
this.quadCapacity = 0;
}
- private void fillBuffer(ByteBuffer indices, int quads) {
- long addr = MemoryUtil.memAddress(indices);
+ private void fillBuffer(long addr, int quads) {
int numVertices = 4 * quads;
int baseVertex = 0;
while (baseVertex < numVertices) {
- // writeQuadIndices(indices, baseVertex);
- writeQuadIndicesUnsafe(addr, baseVertex);
+ writeQuadIndices(addr, baseVertex);
baseVertex += 4;
addr += 6 * 4;
}
- // ((Buffer) indices).flip();
}
- private void writeQuadIndices(ByteBuffer indices, int baseVertex) {
- // triangle a
- indices.putInt(baseVertex);
- indices.putInt(baseVertex + 1);
- indices.putInt(baseVertex + 2);
- // triangle b
- indices.putInt(baseVertex);
- indices.putInt(baseVertex + 2);
- indices.putInt(baseVertex + 3);
- }
-
- private void writeQuadIndicesUnsafe(long addr, int baseVertex) {
+ private void writeQuadIndices(long addr, int baseVertex) {
// triangle a
MemoryUtil.memPutInt(addr, baseVertex);
MemoryUtil.memPutInt(addr + 4, baseVertex + 1);
@@ -102,7 +84,7 @@ public class QuadConverter {
MemoryUtil.memPutInt(addr + 20, baseVertex + 3);
}
- // make sure this gets reset first so it has a chance to repopulate
+ // make sure this gets reset first, so it has a chance to repopulate
public static void onRendererReload(ReloadRenderersEvent event) {
if (INSTANCE != null) {
INSTANCE.delete();
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 91620e819..b381d859b 100644
--- a/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java
+++ b/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java
@@ -2,74 +2,86 @@ package com.jozufozu.flywheel.core.hardcoded;
import java.util.List;
-import org.jetbrains.annotations.NotNull;
-import org.lwjgl.system.MemoryStack;
-
-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.backend.memory.MemoryBlock;
import com.jozufozu.flywheel.core.model.Mesh;
import com.jozufozu.flywheel.core.model.ModelUtil;
import com.jozufozu.flywheel.core.vertex.Formats;
import com.jozufozu.flywheel.core.vertex.PosTexNormalVertex;
-import com.jozufozu.flywheel.core.vertex.PosTexNormalWriterUnsafe;
import com.jozufozu.flywheel.util.joml.Vector4f;
import com.jozufozu.flywheel.util.joml.Vector4fc;
public class ModelPart implements Mesh {
-
- private final int vertices;
+ private final int vertexCount;
+ private final MemoryBlock contents;
+ private final ReusableVertexList vertexList;
private final String name;
- private final VertexList reader;
- private final @NotNull Vector4f boundingSphere;
+ private final Vector4f boundingSphere;
public ModelPart(List cuboids, String name) {
this.name = name;
- {
- int vertices = 0;
- for (PartBuilder.CuboidBuilder cuboid : cuboids) {
- vertices += cuboid.vertices();
- }
- this.vertices = vertices;
+ this.vertexCount = countVertices(cuboids);
+
+ contents = MemoryBlock.malloc(size());
+ long ptr = contents.ptr();
+ VertexWriter writer = new VertexWriterImpl(ptr);
+ for (PartBuilder.CuboidBuilder cuboid : cuboids) {
+ cuboid.write(writer);
}
- try (var stack = MemoryStack.stackPush()) {
- PosTexNormalWriterUnsafe writer = getVertexType().createWriter(stack.malloc(size()));
- for (PartBuilder.CuboidBuilder cuboid : cuboids) {
- cuboid.buffer(writer);
- }
+ vertexList = getVertexType().createVertexList();
+ vertexList.ptr(ptr);
+ vertexList.setVertexCount(vertexCount);
- reader = writer.intoReader(this.vertices);
- }
-
- boundingSphere = ModelUtil.computeBoundingSphere(reader);
+ boundingSphere = ModelUtil.computeBoundingSphere(vertexList);
}
public static PartBuilder builder(String name, int sizeU, int sizeV) {
return new PartBuilder(name, sizeU, sizeV);
}
- @Override
- public String name() {
- return name;
- }
-
- @Override
- public int getVertexCount() {
- return vertices;
- }
-
- @Override
- public VertexList getReader() {
- return reader;
- }
-
@Override
public PosTexNormalVertex getVertexType() {
return Formats.POS_TEX_NORMAL;
}
+ @Override
+ public int getVertexCount() {
+ return vertexCount;
+ }
+
+ @Override
+ public void write(long ptr) {
+ contents.copyTo(ptr);
+ }
+
+ @Override
+ public void write(MutableVertexList dst) {
+ vertexList.writeAll(dst);
+ }
+
+ @Override
+ public void close() {
+ contents.free();
+ }
+
+ @Override
+ public String name() {
+ return name;
+ }
+
@Override
public Vector4fc getBoundingSphere() {
return boundingSphere;
}
+
+ private static int countVertices(List cuboids) {
+ int vertices = 0;
+ for (PartBuilder.CuboidBuilder cuboid : cuboids) {
+ vertices += cuboid.vertices();
+ }
+ return vertices;
+ }
}
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 dcc7ffa8f..9a120f6b6 100644
--- a/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java
+++ b/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java
@@ -1,71 +1,56 @@
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;
import com.jozufozu.flywheel.util.joml.Vector4fc;
/**
- * A mesh that can be rendered by flywheel.
- *
- *
- * It is expected that the following assertion will not fail:
- *
- *
- * {@code
- * Mesh mesh = ...;
- * VecBuffer into = ...;
- *
- * int initial = VecBuffer.unwrap().position();
- *
- * mesh.buffer(into);
- *
- * int final = VecBuffer.unwrap().position();
- *
- * assert mesh.size() == final - initial;
- * }
+ * A holder for arbitrary vertex data that can be written to memory or a vertex list.
*/
public interface Mesh {
- /**
- * A name uniquely identifying this model.
- */
- String name();
-
VertexType getVertexType();
- VertexList getReader();
-
Vector4fc getBoundingSphere();
/**
- * @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());
}
/**
- * Create an element buffer object that indexes the vertices of this model.
+ * Write this mesh into memory. The written data will use the format defined by {@link #getVertexType()} and the amount of
+ * bytes written will be the same as the return value of {@link #size()}.
+ * @param ptr The address to which data is written to.
+ */
+ void write(long ptr);
+
+ /**
+ * Write this mesh into a vertex list. Vertices with index {@literal <}0 or {@literal >=}{@link #getVertexCount()} will not be
+ * modified.
+ * @param vertexList The vertex list to which data is written to.
+ */
+ void write(MutableVertexList vertexList);
+
+ /**
+ * 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.
@@ -79,9 +64,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/Model.java b/src/main/java/com/jozufozu/flywheel/core/model/Model.java
index e0d247387..092c4a3cd 100644
--- a/src/main/java/com/jozufozu/flywheel/core/model/Model.java
+++ b/src/main/java/com/jozufozu/flywheel/core/model/Model.java
@@ -7,6 +7,8 @@ import com.jozufozu.flywheel.api.material.Material;
public interface Model {
Map getMeshes();
+ void delete();
+
default int getVertexCount() {
int size = 0;
for (Mesh mesh : getMeshes().values()) {
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 fe3041287..103f05634 100644
--- a/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java
+++ b/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java
@@ -5,16 +5,23 @@ import java.nio.ByteBuffer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.lwjgl.system.MemoryUtil;
import com.dreizak.miniball.highdim.Miniball;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.material.Material;
+import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
import com.jozufozu.flywheel.api.vertex.VertexList;
+import com.jozufozu.flywheel.api.vertex.VertexType;
+import com.jozufozu.flywheel.backend.memory.MemoryBlock;
import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.vertex.Formats;
import com.jozufozu.flywheel.util.joml.Vector4f;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
+import com.jozufozu.flywheel.core.vertex.VertexListProviderRegistry;
+import com.mojang.blaze3d.vertex.BufferBuilder.DrawState;
+import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.Minecraft;
@@ -46,15 +53,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();
+ MemoryBlock dst = MemoryBlock.malloc(src.capacity());
+ long srcPtr = MemoryUtil.memAddress(src);
+ long dstPtr = dst.ptr();
- 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/Models.java b/src/main/java/com/jozufozu/flywheel/core/model/Models.java
index 4891a3cd6..d327abc34 100644
--- a/src/main/java/com/jozufozu/flywheel/core/model/Models.java
+++ b/src/main/java/com/jozufozu/flywheel/core/model/Models.java
@@ -1,5 +1,6 @@
package com.jozufozu.flywheel.core.model;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -41,8 +42,16 @@ public class Models {
}
public static void onReload(ReloadRenderersEvent event) {
+ deleteAll(BLOCK_STATE.values());
+ deleteAll(PARTIAL.values());
+ deleteAll(PARTIAL_DIR.values());
+
BLOCK_STATE.clear();
PARTIAL.clear();
PARTIAL_DIR.clear();
}
+
+ private static void deleteAll(Collection values) {
+ values.forEach(Model::delete);
+ }
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/model/SimpleLazyModel.java b/src/main/java/com/jozufozu/flywheel/core/model/SimpleLazyModel.java
index 7933854d2..3af609e4f 100644
--- a/src/main/java/com/jozufozu/flywheel/core/model/SimpleLazyModel.java
+++ b/src/main/java/com/jozufozu/flywheel/core/model/SimpleLazyModel.java
@@ -28,6 +28,11 @@ public class SimpleLazyModel implements Model {
return ImmutableMap.of(material, supplier.get());
}
+ @Override
+ public void delete() {
+ supplier.ifPresent(Mesh::close);
+ }
+
public int getVertexCount() {
return supplier.map(Mesh::getVertexCount)
.orElse(0);
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 e5808067f..95ce7d8bf 100644
--- a/src/main/java/com/jozufozu/flywheel/core/model/SimpleMesh.java
+++ b/src/main/java/com/jozufozu/flywheel/core/model/SimpleMesh.java
@@ -1,27 +1,37 @@
package com.jozufozu.flywheel.core.model;
-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.api.vertex.VertexType;
+import com.jozufozu.flywheel.backend.memory.MemoryBlock;
import com.jozufozu.flywheel.util.joml.Vector4f;
import com.jozufozu.flywheel.util.joml.Vector4fc;
public class SimpleMesh implements Mesh {
- private final VertexList reader;
private final VertexType vertexType;
+ private final int vertexCount;
+ private final MemoryBlock contents;
+ private final ReusableVertexList vertexList;
private final String name;
private final Vector4f boundingSphere;
- public SimpleMesh(VertexList reader, VertexType vertexType, String name) {
- this.reader = reader;
+ public SimpleMesh(VertexType vertexType, MemoryBlock contents, String name) {
this.vertexType = vertexType;
+ this.contents = contents;
this.name = name;
- boundingSphere = ModelUtil.computeBoundingSphere(reader);
- }
+ int bytes = (int) contents.size();
+ int stride = vertexType.getStride();
+ if (bytes % stride != 0) {
+ throw new IllegalArgumentException("MemoryBlock contains non-whole amount of vertices!");
+ }
+ vertexCount = bytes / stride;
- @Override
- public String name() {
- return name;
+ vertexList = getVertexType().createVertexList();
+ vertexList.ptr(contents.ptr());
+ vertexList.setVertexCount(vertexCount);
+
+ boundingSphere = ModelUtil.computeBoundingSphere(vertexList);
}
@Override
@@ -30,8 +40,28 @@ public class SimpleMesh implements Mesh {
}
@Override
- public VertexList getReader() {
- return reader;
+ public int getVertexCount() {
+ return vertexCount;
+ }
+
+ @Override
+ public void write(long ptr) {
+ contents.copyTo(ptr);
+ }
+
+ @Override
+ public void write(MutableVertexList dst) {
+ vertexList.writeAll(dst);
+ }
+
+ @Override
+ public void close() {
+ contents.free();
+ }
+
+ @Override
+ public String name() {
+ return name;
}
@Override
diff --git a/src/main/java/com/jozufozu/flywheel/core/model/TessellatedModel.java b/src/main/java/com/jozufozu/flywheel/core/model/TessellatedModel.java
index 0f987bb71..d1986dc6e 100644
--- a/src/main/java/com/jozufozu/flywheel/core/model/TessellatedModel.java
+++ b/src/main/java/com/jozufozu/flywheel/core/model/TessellatedModel.java
@@ -19,6 +19,12 @@ public class TessellatedModel implements Model {
return meshes;
}
+ @Override
+ public void delete() {
+ meshes.values()
+ .forEach(Mesh::close);
+ }
+
public boolean isShadeSeparated() {
return shadeSeparated;
}
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..b86ec43f7 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
@@ -4,6 +4,8 @@ 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.backend.memory.MemoryBlock;
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;
@@ -28,9 +30,10 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.data.IModelData;
public class BakedModelBuilder {
+ private static final int STARTING_CAPACITY = 64;
+
private final BakedModel bakedModel;
private boolean shadeSeparated = true;
- private VertexFormat vertexFormat;
private BlockAndTintGetter renderWorld;
private BlockState blockState;
private PoseStack poseStack;
@@ -46,11 +49,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 +78,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;
}
@@ -103,29 +98,31 @@ public class BakedModelBuilder {
if (shadeSeparated) {
ShadeSeparatedBufferFactory bufferFactory = (renderType, shaded) -> {
- BufferBuilder buffer = new BufferBuilder(64);
- buffer.begin(VertexFormat.Mode.QUADS, vertexFormat);
+ BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY);
+ 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);
+ BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY);
+ 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..b69549c6c 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
@@ -4,6 +4,8 @@ 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.backend.memory.MemoryBlock;
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;
@@ -26,9 +28,10 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.data.IModelData;
public class BlockModelBuilder {
+ private static final int STARTING_CAPACITY = 64;
+
private final BlockState state;
private boolean shadeSeparated = true;
- private VertexFormat vertexFormat;
private BlockAndTintGetter renderWorld;
private PoseStack poseStack;
private IModelData modelData;
@@ -43,11 +46,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 +70,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;
}
@@ -92,29 +87,31 @@ public class BlockModelBuilder {
if (shadeSeparated) {
ShadeSeparatedBufferFactory bufferFactory = (renderType, shaded) -> {
- BufferBuilder buffer = new BufferBuilder(64);
- buffer.begin(VertexFormat.Mode.QUADS, vertexFormat);
+ BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY);
+ 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);
+ BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY);
+ 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..dd0342e5f 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
@@ -7,6 +7,8 @@ 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.backend.memory.MemoryBlock;
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;
@@ -29,6 +31,8 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp
import net.minecraftforge.client.model.data.IModelData;
public class MultiBlockModelBuilder {
+ private static final int STARTING_CAPACITY = 1024;
+
private final Collection blocks;
private boolean shadeSeparated = true;
private VertexFormat vertexFormat;
@@ -46,11 +50,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;
@@ -95,29 +94,31 @@ public class MultiBlockModelBuilder {
if (shadeSeparated) {
ShadeSeparatedBufferFactory bufferFactory = (renderType, shaded) -> {
- BufferBuilder buffer = new BufferBuilder(1024);
- buffer.begin(VertexFormat.Mode.QUADS, vertexFormat);
+ BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY);
+ 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);
+ BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY);
+ 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/structs/ColoredLitWriter.java b/src/main/java/com/jozufozu/flywheel/core/structs/ColoredLitWriter.java
new file mode 100644
index 000000000..dcd23aca0
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/core/structs/ColoredLitWriter.java
@@ -0,0 +1,17 @@
+package com.jozufozu.flywheel.core.structs;
+
+import org.lwjgl.system.MemoryUtil;
+
+import com.jozufozu.flywheel.api.struct.StructWriter;
+
+public abstract class ColoredLitWriter implements StructWriter {
+ @Override
+ public void write(long ptr, D d) {
+ MemoryUtil.memPutByte(ptr, d.blockLight);
+ MemoryUtil.memPutByte(ptr + 1, d.skyLight);
+ MemoryUtil.memPutByte(ptr + 2, d.r);
+ MemoryUtil.memPutByte(ptr + 3, d.g);
+ MemoryUtil.memPutByte(ptr + 4, d.b);
+ MemoryUtil.memPutByte(ptr + 5, d.a);
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/ColoredLitWriterUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/structs/ColoredLitWriterUnsafe.java
deleted file mode 100644
index 985fc7046..000000000
--- a/src/main/java/com/jozufozu/flywheel/core/structs/ColoredLitWriterUnsafe.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.jozufozu.flywheel.core.structs;
-
-import java.nio.ByteBuffer;
-
-import org.lwjgl.system.MemoryUtil;
-
-import com.jozufozu.flywheel.api.struct.StructType;
-import com.jozufozu.flywheel.backend.struct.UnsafeBufferWriter;
-
-public abstract class ColoredLitWriterUnsafe extends UnsafeBufferWriter {
-
- public ColoredLitWriterUnsafe(StructType structType, ByteBuffer byteBuffer) {
- super(structType, byteBuffer);
- }
-
- @Override
- protected void writeInternal(D d) {
- long ptr = writePointer;
- MemoryUtil.memPutByte(ptr, d.blockLight);
- MemoryUtil.memPutByte(ptr + 1, d.skyLight);
- MemoryUtil.memPutByte(ptr + 2, d.r);
- MemoryUtil.memPutByte(ptr + 3, d.g);
- MemoryUtil.memPutByte(ptr + 4, d.b);
- MemoryUtil.memPutByte(ptr + 5, d.a);
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/StructTypes.java b/src/main/java/com/jozufozu/flywheel/core/structs/StructTypes.java
index 96015bf27..597a2a43c 100644
--- a/src/main/java/com/jozufozu/flywheel/core/structs/StructTypes.java
+++ b/src/main/java/com/jozufozu/flywheel/core/structs/StructTypes.java
@@ -2,10 +2,10 @@ package com.jozufozu.flywheel.core.structs;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.core.ComponentRegistry;
-import com.jozufozu.flywheel.core.structs.model.TransformedPart;
-import com.jozufozu.flywheel.core.structs.model.TransformedType;
import com.jozufozu.flywheel.core.structs.oriented.OrientedPart;
import com.jozufozu.flywheel.core.structs.oriented.OrientedType;
+import com.jozufozu.flywheel.core.structs.transformed.TransformedPart;
+import com.jozufozu.flywheel.core.structs.transformed.TransformedType;
public class StructTypes {
public static final StructType TRANSFORMED = ComponentRegistry.register(new TransformedType());
diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/model/TransformedWriterUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/structs/model/TransformedWriterUnsafe.java
deleted file mode 100644
index 9aab8c48b..000000000
--- a/src/main/java/com/jozufozu/flywheel/core/structs/model/TransformedWriterUnsafe.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.jozufozu.flywheel.core.structs.model;
-
-import java.nio.ByteBuffer;
-
-import com.jozufozu.flywheel.api.struct.StructType;
-import com.jozufozu.flywheel.core.structs.ColoredLitWriterUnsafe;
-import com.jozufozu.flywheel.util.extension.MatrixExtension;
-
-public class TransformedWriterUnsafe extends ColoredLitWriterUnsafe {
-
- public TransformedWriterUnsafe(StructType structType, ByteBuffer byteBuffer) {
- super(structType, byteBuffer);
- }
-
- @Override
- protected void writeInternal(TransformedPart d) {
- super.writeInternal(d);
- long ptr = writePointer + 6;
-
- ((MatrixExtension) (Object) d.model).flywheel$writeUnsafe(ptr);
- ((MatrixExtension) (Object) d.normal).flywheel$writeUnsafe(ptr + 4 * 16);
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/model/package-info.java b/src/main/java/com/jozufozu/flywheel/core/structs/model/package-info.java
deleted file mode 100644
index 759c3a038..000000000
--- a/src/main/java/com/jozufozu/flywheel/core/structs/model/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
-package com.jozufozu.flywheel.core.structs.model;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-
-import net.minecraft.MethodsReturnNonnullByDefault;
diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedType.java b/src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedType.java
index 5bf956fa1..039fdd1e5 100644
--- a/src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedType.java
+++ b/src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedType.java
@@ -1,8 +1,5 @@
package com.jozufozu.flywheel.core.structs.oriented;
-import java.nio.ByteBuffer;
-
-import com.jozufozu.flywheel.api.struct.StorageBufferWriter;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.api.struct.StructWriter;
import com.jozufozu.flywheel.core.Components;
@@ -33,8 +30,8 @@ public class OrientedType implements StructType {
}
@Override
- public StructWriter getWriter(ByteBuffer backing) {
- return new OrientedWriterUnsafe(this, backing);
+ public StructWriter getWriter() {
+ return OrientedWriter.INSTANCE;
}
@Override
@@ -53,7 +50,7 @@ public class OrientedType implements StructType {
}
@Override
- public VertexTransformer extends OrientedPart> getVertexTransformer() {
+ public VertexTransformer getVertexTransformer() {
return (vertexList, struct, level) -> {
Vector4f pos = new Vector4f();
Vector3f normal = new Vector3f();
diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedWriterUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedWriter.java
similarity index 54%
rename from src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedWriterUnsafe.java
rename to src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedWriter.java
index fb03c4d1e..8aa99cef4 100644
--- a/src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedWriterUnsafe.java
+++ b/src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedWriter.java
@@ -1,21 +1,15 @@
package com.jozufozu.flywheel.core.structs.oriented;
-import java.nio.ByteBuffer;
-
import org.lwjgl.system.MemoryUtil;
-import com.jozufozu.flywheel.api.struct.StructType;
-import com.jozufozu.flywheel.core.structs.ColoredLitWriterUnsafe;
+import com.jozufozu.flywheel.core.structs.ColoredLitWriter;
-public class OrientedWriterUnsafe extends ColoredLitWriterUnsafe {
- public OrientedWriterUnsafe(StructType structType, ByteBuffer byteBuffer) {
- super(structType, byteBuffer);
- }
+public class OrientedWriter extends ColoredLitWriter {
+ public static final OrientedWriter INSTANCE = new OrientedWriter();
@Override
- protected void writeInternal(OrientedPart d) {
- long ptr = writePointer;
- super.writeInternal(d);
+ public void write(long ptr, OrientedPart d) {
+ super.write(ptr, d);
MemoryUtil.memPutFloat(ptr + 6, d.posX);
MemoryUtil.memPutFloat(ptr + 10, d.posY);
diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/model/TransformedPart.java b/src/main/java/com/jozufozu/flywheel/core/structs/transformed/TransformedPart.java
similarity index 97%
rename from src/main/java/com/jozufozu/flywheel/core/structs/model/TransformedPart.java
rename to src/main/java/com/jozufozu/flywheel/core/structs/transformed/TransformedPart.java
index 865f5bccd..215bfd913 100644
--- a/src/main/java/com/jozufozu/flywheel/core/structs/model/TransformedPart.java
+++ b/src/main/java/com/jozufozu/flywheel/core/structs/transformed/TransformedPart.java
@@ -1,4 +1,4 @@
-package com.jozufozu.flywheel.core.structs.model;
+package com.jozufozu.flywheel.core.structs.transformed;
import com.jozufozu.flywheel.core.structs.ColoredLitPart;
import com.jozufozu.flywheel.core.structs.StructTypes;
diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/model/TransformedStorageWriter.java b/src/main/java/com/jozufozu/flywheel/core/structs/transformed/TransformedStorageWriter.java
similarity index 94%
rename from src/main/java/com/jozufozu/flywheel/core/structs/model/TransformedStorageWriter.java
rename to src/main/java/com/jozufozu/flywheel/core/structs/transformed/TransformedStorageWriter.java
index 70619bdd1..1f05a3e1d 100644
--- a/src/main/java/com/jozufozu/flywheel/core/structs/model/TransformedStorageWriter.java
+++ b/src/main/java/com/jozufozu/flywheel/core/structs/transformed/TransformedStorageWriter.java
@@ -1,4 +1,4 @@
-package com.jozufozu.flywheel.core.structs.model;
+package com.jozufozu.flywheel.core.structs.transformed;
import org.lwjgl.system.MemoryUtil;
diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/model/TransformedType.java b/src/main/java/com/jozufozu/flywheel/core/structs/transformed/TransformedType.java
similarity index 88%
rename from src/main/java/com/jozufozu/flywheel/core/structs/model/TransformedType.java
rename to src/main/java/com/jozufozu/flywheel/core/structs/transformed/TransformedType.java
index 86b727125..aa6ba75d9 100644
--- a/src/main/java/com/jozufozu/flywheel/core/structs/model/TransformedType.java
+++ b/src/main/java/com/jozufozu/flywheel/core/structs/transformed/TransformedType.java
@@ -1,6 +1,4 @@
-package com.jozufozu.flywheel.core.structs.model;
-
-import java.nio.ByteBuffer;
+package com.jozufozu.flywheel.core.structs.transformed;
import com.jozufozu.flywheel.api.struct.StorageBufferWriter;
import com.jozufozu.flywheel.api.struct.StructType;
@@ -30,8 +28,8 @@ public class TransformedType implements StructType {
}
@Override
- public StructWriter getWriter(ByteBuffer backing) {
- return new TransformedWriterUnsafe(this, backing);
+ public StructWriter getWriter() {
+ return TransformedWriter.INSTANCE;
}
@Override
@@ -50,7 +48,7 @@ public class TransformedType implements StructType {
}
@Override
- public VertexTransformer extends TransformedPart> getVertexTransformer() {
+ public VertexTransformer getVertexTransformer() {
return (vertexList, struct, level) -> {
Vector4f pos = new Vector4f();
Vector3f normal = new Vector3f();
diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/transformed/TransformedWriter.java b/src/main/java/com/jozufozu/flywheel/core/structs/transformed/TransformedWriter.java
new file mode 100644
index 000000000..c6d4383ca
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/core/structs/transformed/TransformedWriter.java
@@ -0,0 +1,17 @@
+package com.jozufozu.flywheel.core.structs.transformed;
+
+import com.jozufozu.flywheel.core.structs.ColoredLitWriter;
+import com.jozufozu.flywheel.util.extension.MatrixExtension;
+
+public class TransformedWriter extends ColoredLitWriter {
+ public static final TransformedWriter INSTANCE = new TransformedWriter();
+
+ @Override
+ public void write(long ptr, TransformedPart d) {
+ super.write(ptr, d);
+ ptr += 6;
+
+ ((MatrixExtension) (Object) d.model).flywheel$writeUnsafe(ptr);
+ ((MatrixExtension) (Object) d.normal).flywheel$writeUnsafe(ptr + 4 * 16);
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/transformed/TransformedWriterUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/structs/transformed/TransformedWriterUnsafe.java
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/main/java/com/jozufozu/flywheel/backend/struct/package-info.java b/src/main/java/com/jozufozu/flywheel/core/structs/transformed/package-info.java
similarity index 75%
rename from src/main/java/com/jozufozu/flywheel/backend/struct/package-info.java
rename to src/main/java/com/jozufozu/flywheel/core/structs/transformed/package-info.java
index d4cbaadf2..2ca2a5ed4 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/struct/package-info.java
+++ b/src/main/java/com/jozufozu/flywheel/core/structs/transformed/package-info.java
@@ -1,5 +1,5 @@
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
-package com.jozufozu.flywheel.backend.struct;
+package com.jozufozu.flywheel.core.structs.transformed;
import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/src/main/java/com/jozufozu/flywheel/core/uniform/FogProvider.java b/src/main/java/com/jozufozu/flywheel/core/uniform/FogProvider.java
index 76579490e..05cfdc8b3 100644
--- a/src/main/java/com/jozufozu/flywheel/core/uniform/FogProvider.java
+++ b/src/main/java/com/jozufozu/flywheel/core/uniform/FogProvider.java
@@ -9,22 +9,18 @@ import com.mojang.blaze3d.systems.RenderSystem;
public class FogProvider extends UniformProvider {
-
-
@Override
public int getActualByteSize() {
return 16 + 8 + 4;
}
public void update() {
- if (buffer == null) {
+ if (ptr == MemoryUtil.NULL) {
return;
}
var color = RenderSystem.getShaderFogColor();
- long ptr = MemoryUtil.memAddress(buffer);
-
MemoryUtil.memPutFloat(ptr, color[0]);
MemoryUtil.memPutFloat(ptr + 4, color[1]);
MemoryUtil.memPutFloat(ptr + 8, color[2]);
diff --git a/src/main/java/com/jozufozu/flywheel/core/uniform/FrustumProvider.java b/src/main/java/com/jozufozu/flywheel/core/uniform/FrustumProvider.java
index 9070a7eae..4082a3a0c 100644
--- a/src/main/java/com/jozufozu/flywheel/core/uniform/FrustumProvider.java
+++ b/src/main/java/com/jozufozu/flywheel/core/uniform/FrustumProvider.java
@@ -37,7 +37,7 @@ public class FrustumProvider extends UniformProvider {
}
public void update(RenderContext context) {
- if (buffer == null) {
+ if (ptr == MemoryUtil.NULL) {
return;
}
@@ -51,8 +51,6 @@ public class FrustumProvider extends UniformProvider {
var shiftedCuller = RenderContext.createCuller(context.viewProjection(), -camX, -camY, -camZ);
- long ptr = MemoryUtil.memAddress(buffer);
-
shiftedCuller.getJozuPackedPlanes(ptr);
notifier.signalChanged();
diff --git a/src/main/java/com/jozufozu/flywheel/core/uniform/UniformBuffer.java b/src/main/java/com/jozufozu/flywheel/core/uniform/UniformBuffer.java
index e20db4a78..e3ecee4ab 100644
--- a/src/main/java/com/jozufozu/flywheel/core/uniform/UniformBuffer.java
+++ b/src/main/java/com/jozufozu/flywheel/core/uniform/UniformBuffer.java
@@ -1,20 +1,18 @@
package com.jozufozu.flywheel.core.uniform;
-import java.nio.ByteBuffer;
import java.util.BitSet;
import java.util.Collection;
import java.util.List;
import org.lwjgl.opengl.GL32;
-import org.lwjgl.system.MemoryUtil;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.api.uniform.UniformProvider;
+import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
-import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer;
+import com.jozufozu.flywheel.backend.memory.MemoryBlock;
import com.jozufozu.flywheel.core.ComponentRegistry;
import com.jozufozu.flywheel.util.RenderMath;
-import com.mojang.blaze3d.platform.MemoryTracker;
public class UniformBuffer {
@@ -33,13 +31,13 @@ public class UniformBuffer {
return instance;
}
- private final MappedGlBuffer buffer;
- private final ByteBuffer data;
+ private final GlBuffer buffer;
+ private final MemoryBlock data;
private final BitSet changedBytes;
private UniformBuffer() {
- buffer = new MappedGlBuffer(GlBufferType.UNIFORM_BUFFER);
+ buffer = new GlBuffer(GlBufferType.UNIFORM_BUFFER);
Collection providers = ComponentRegistry.getAllUniformProviders();
@@ -57,7 +55,7 @@ public class UniformBuffer {
allocatedProviders = builder.build();
- data = MemoryTracker.create(totalBytes);
+ data = MemoryBlock.mallocTracked(totalBytes);
changedBytes = new BitSet(totalBytes);
for (Allocated p : allocatedProviders) {
@@ -112,8 +110,8 @@ public class UniformBuffer {
changedBytes.set(offset, offset + size);
}
- private void updatePtr(ByteBuffer bufferBase) {
- provider.updatePtr(MemoryUtil.memSlice(bufferBase, offset, size), this);
+ private void updatePtr(MemoryBlock bufferBase) {
+ provider.updatePtr(bufferBase.ptr() + offset, this);
}
public UniformProvider provider() {
diff --git a/src/main/java/com/jozufozu/flywheel/core/uniform/ViewProvider.java b/src/main/java/com/jozufozu/flywheel/core/uniform/ViewProvider.java
index 65ffb4077..3c8448744 100644
--- a/src/main/java/com/jozufozu/flywheel/core/uniform/ViewProvider.java
+++ b/src/main/java/com/jozufozu/flywheel/core/uniform/ViewProvider.java
@@ -31,7 +31,7 @@ public class ViewProvider extends UniformProvider {
}
public void update(RenderContext context) {
- if (buffer == null) {
+ if (ptr == MemoryUtil.NULL) {
return;
}
@@ -52,8 +52,6 @@ public class ViewProvider extends UniformProvider {
var vp = context.viewProjection().copy();
vp.multiplyWithTranslation(-camX, -camY, -camZ);
- long ptr = MemoryUtil.memAddress(buffer);
-
MatrixExtension.writeUnsafe(vp, ptr);
MemoryUtil.memPutFloat(ptr + 64, camX);
MemoryUtil.memPutFloat(ptr + 68, camY);
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);
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java b/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java
index 1310235f7..793f519ca 100644
--- a/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java
+++ b/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java
@@ -4,9 +4,10 @@ import java.util.ArrayList;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.backend.Backend;
-import com.jozufozu.flywheel.backend.FlywheelMemory;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
+import com.jozufozu.flywheel.backend.memory.FlwMemoryTracker;
import com.jozufozu.flywheel.light.LightUpdater;
+import com.jozufozu.flywheel.util.StringUtil;
import com.jozufozu.flywheel.util.WorldAttached;
import net.minecraft.client.Minecraft;
@@ -24,10 +25,7 @@ public class ForgeEvents {
InstancedRenderDispatcher.getDebugString(debug);
- // TODO: compress into one line
- debug.add("Memory used:");
- debug.add("GPU: " + FlywheelMemory.getGPUMemory());
- debug.add("CPU: " + FlywheelMemory.getCPUMemory());
+ debug.add("Memory Usage: CPU: " + StringUtil.formatBytes(FlwMemoryTracker.getCPUMemory()) + ", GPU: " + StringUtil.formatBytes(FlwMemoryTracker.getGPUMemory()));
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/light/GPULightVolume.java b/src/main/java/com/jozufozu/flywheel/light/GPULightVolume.java
index 673670973..233b84504 100644
--- a/src/main/java/com/jozufozu/flywheel/light/GPULightVolume.java
+++ b/src/main/java/com/jozufozu/flywheel/light/GPULightVolume.java
@@ -73,7 +73,7 @@ public class GPULightVolume extends LightVolume {
public void bind() {
// just in case something goes wrong, or we accidentally call this before this volume is properly disposed of.
- if (lightData == null || lightData.capacity() == 0) return;
+ if (lightData == null || lightData.size() == 0) return;
textureUnit.makeActive();
glTexture.bind();
@@ -93,7 +93,7 @@ public class GPULightVolume extends LightVolume {
int sizeY = box.sizeY();
int sizeZ = box.sizeZ();
- glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, sizeX, sizeY, sizeZ, GL30.GL_RG, GL_UNSIGNED_BYTE, lightData);
+ glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, sizeX, sizeY, sizeZ, GL30.GL_RG, GL_UNSIGNED_BYTE, lightData.ptr());
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4 is the default
bufferDirty = false;
diff --git a/src/main/java/com/jozufozu/flywheel/light/LightVolume.java b/src/main/java/com/jozufozu/flywheel/light/LightVolume.java
index 31245dea9..ef1dc4f88 100644
--- a/src/main/java/com/jozufozu/flywheel/light/LightVolume.java
+++ b/src/main/java/com/jozufozu/flywheel/light/LightVolume.java
@@ -1,9 +1,8 @@
package com.jozufozu.flywheel.light;
-import java.nio.ByteBuffer;
-
import org.lwjgl.system.MemoryUtil;
+import com.jozufozu.flywheel.backend.memory.MemoryBlock;
import com.jozufozu.flywheel.util.box.GridAlignedBB;
import com.jozufozu.flywheel.util.box.ImmutableBox;
@@ -15,13 +14,53 @@ public class LightVolume implements ImmutableBox, LightListener {
protected final BlockAndTintGetter level;
protected final GridAlignedBB box = new GridAlignedBB();
- protected ByteBuffer lightData;
+ protected MemoryBlock lightData;
public LightVolume(BlockAndTintGetter level, ImmutableBox sampleVolume) {
this.level = level;
this.setBox(sampleVolume);
- this.lightData = MemoryUtil.memAlloc(this.box.volume() * 2);
+ this.lightData = MemoryBlock.malloc(this.box.volume() * 2);
+ }
+
+ @Override
+ public ImmutableBox getVolume() {
+ return box;
+ }
+
+ @Override
+ public int getMinX() {
+ return box.getMinX();
+ }
+
+ @Override
+ public int getMinY() {
+ return box.getMinY();
+ }
+
+ @Override
+ public int getMinZ() {
+ return box.getMinZ();
+ }
+
+ @Override
+ public int getMaxX() {
+ return box.getMaxX();
+ }
+
+ @Override
+ public int getMaxY() {
+ return box.getMaxY();
+ }
+
+ @Override
+ public int getMaxZ() {
+ return box.getMaxZ();
+ }
+
+ @Override
+ public boolean isListenerInvalid() {
+ return lightData == null;
}
protected void setBox(ImmutableBox box) {
@@ -30,47 +69,143 @@ public class LightVolume implements ImmutableBox, LightListener {
public short getPackedLight(int x, int y, int z) {
if (box.contains(x, y, z)) {
- return lightData.getShort(worldPosToBufferIndex(x, y, z));
+ return MemoryUtil.memGetShort(worldPosToPtr(x, y, z));
} else {
return 0;
}
}
- public int getMinX() {
- return box.getMinX();
- }
-
- public int getMinY() {
- return box.getMinY();
- }
-
- public int getMinZ() {
- return box.getMinZ();
- }
-
- public int getMaxX() {
- return box.getMaxX();
- }
-
- public int getMaxY() {
- return box.getMaxY();
- }
-
- public int getMaxZ() {
- return box.getMaxZ();
- }
-
public void move(ImmutableBox newSampleVolume) {
if (lightData == null) return;
setBox(newSampleVolume);
int neededCapacity = box.volume() * 2;
- if (neededCapacity > lightData.capacity()) {
- lightData = MemoryUtil.memRealloc(lightData, neededCapacity);
+ if (neededCapacity > lightData.size()) {
+ lightData = lightData.realloc(neededCapacity);
}
initialize();
}
+ /**
+ * Completely (re)populate this volume with block and sky lighting data.
+ * This is expensive and should be avoided.
+ */
+ public void initialize() {
+ if (lightData == null) return;
+
+ copyLight(getVolume());
+ markDirty();
+ }
+
+ protected void markDirty() {
+ // noop
+ }
+
+ public void delete() {
+ lightData.free();
+ lightData = null;
+ }
+
+ /**
+ * Copy all light from the world into this volume.
+ *
+ * @param worldVolume the region in the world to copy data from.
+ */
+ public void copyLight(ImmutableBox worldVolume) {
+ BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
+
+ int xShift = box.getMinX();
+ int yShift = box.getMinY();
+ int zShift = box.getMinZ();
+
+ worldVolume.forEachContained((x, y, z) -> {
+ pos.set(x, y, z);
+
+ int block = this.level.getBrightness(LightLayer.BLOCK, pos);
+ int sky = this.level.getBrightness(LightLayer.SKY, pos);
+
+ writeLight(x - xShift, y - yShift, z - zShift, block, sky);
+ });
+ }
+
+ protected void writeLight(int x, int y, int z, int block, int sky) {
+ byte b = (byte) ((block & 0xF) << 4);
+ byte s = (byte) ((sky & 0xF) << 4);
+
+ long ptr = boxPosToPtr(x, y, z);
+ MemoryUtil.memPutByte(ptr, b);
+ MemoryUtil.memPutByte(ptr + 1, s);
+ }
+
+ /**
+ * Copy block light from the world into this volume.
+ *
+ * @param worldVolume the region in the world to copy data from.
+ */
+ public void copyBlock(ImmutableBox worldVolume) {
+ var pos = new BlockPos.MutableBlockPos();
+
+ int xShift = box.getMinX();
+ int yShift = box.getMinY();
+ int zShift = box.getMinZ();
+
+ worldVolume.forEachContained((x, y, z) -> {
+ int light = this.level.getBrightness(LightLayer.BLOCK, pos.set(x, y, z));
+
+ writeBlock(x - xShift, y - yShift, z - zShift, light);
+ });
+ }
+
+ protected void writeBlock(int x, int y, int z, int block) {
+ byte b = (byte) ((block & 0xF) << 4);
+
+ MemoryUtil.memPutByte(boxPosToPtr(x, y, z), b);
+ }
+
+ /**
+ * Copy sky light from the world into this volume.
+ *
+ * @param worldVolume the region in the world to copy data from.
+ */
+ public void copySky(ImmutableBox worldVolume) {
+ var pos = new BlockPos.MutableBlockPos();
+
+ int xShift = box.getMinX();
+ int yShift = box.getMinY();
+ int zShift = box.getMinZ();
+
+ worldVolume.forEachContained((x, y, z) -> {
+ int light = this.level.getBrightness(LightLayer.SKY, pos.set(x, y, z));
+
+ writeSky(x - xShift, y - yShift, z - zShift, light);
+ });
+ }
+
+ protected void writeSky(int x, int y, int z, int sky) {
+ byte s = (byte) ((sky & 0xF) << 4);
+
+ MemoryUtil.memPutByte(boxPosToPtr(x, y, z) + 1, s);
+ }
+
+ protected long worldPosToPtr(int x, int y, int z) {
+ return lightData.ptr() + worldPosToPtrOffset(x, y, z);
+ }
+
+ protected long boxPosToPtr(int x, int y, int z) {
+ return lightData.ptr() + boxPosToPtrOffset(x, y, z);
+ }
+
+ protected int worldPosToPtrOffset(int x, int y, int z) {
+ x -= box.getMinX();
+ y -= box.getMinY();
+ z -= box.getMinZ();
+ return boxPosToPtrOffset(x, y, z);
+ }
+
+ protected int boxPosToPtrOffset(int x, int y, int z) {
+ return (x + box.sizeX() * (y + z * box.sizeY())) * 2;
+ }
+
@Override
public void onLightUpdate(LightLayer type, ImmutableBox changedVolume) {
if (lightData == null) return;
@@ -96,126 +231,4 @@ public class LightVolume implements ImmutableBox, LightListener {
markDirty();
}
- /**
- * Completely (re)populate this volume with block and sky lighting data.
- * This is expensive and should be avoided.
- */
- public void initialize() {
- if (lightData == null) return;
-
- copyLight(getVolume());
- markDirty();
- }
-
- /**
- * Copy block light from the world into this volume.
- *
- * @param worldVolume the region in the world to copy data from.
- */
- public void copyBlock(ImmutableBox worldVolume) {
- var pos = new BlockPos.MutableBlockPos();
-
- int xShift = box.getMinX();
- int yShift = box.getMinY();
- int zShift = box.getMinZ();
-
- worldVolume.forEachContained((x, y, z) -> {
- int light = this.level.getBrightness(LightLayer.BLOCK, pos.set(x, y, z));
-
- writeBlock(x - xShift, y - yShift, z - zShift, light);
- });
- }
-
- /**
- * Copy sky light from the world into this volume.
- *
- * @param worldVolume the region in the world to copy data from.
- */
- public void copySky(ImmutableBox worldVolume) {
- var pos = new BlockPos.MutableBlockPos();
-
- int xShift = box.getMinX();
- int yShift = box.getMinY();
- int zShift = box.getMinZ();
-
- worldVolume.forEachContained((x, y, z) -> {
- int light = this.level.getBrightness(LightLayer.SKY, pos.set(x, y, z));
-
- writeSky(x - xShift, y - yShift, z - zShift, light);
- });
- }
-
- /**
- * Copy all light from the world into this volume.
- *
- * @param worldVolume the region in the world to copy data from.
- */
- public void copyLight(ImmutableBox worldVolume) {
- BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
-
- int xShift = box.getMinX();
- int yShift = box.getMinY();
- int zShift = box.getMinZ();
-
- worldVolume.forEachContained((x, y, z) -> {
- pos.set(x, y, z);
-
- int block = this.level.getBrightness(LightLayer.BLOCK, pos);
- int sky = this.level.getBrightness(LightLayer.SKY, pos);
-
- writeLight(x - xShift, y - yShift, z - zShift, block, sky);
- });
- }
-
- public void delete() {
- MemoryUtil.memFree(lightData);
- lightData = null;
- }
-
- protected void markDirty() {
- // noop
- }
-
- protected void writeLight(int x, int y, int z, int block, int sky) {
- byte b = (byte) ((block & 0xF) << 4);
- byte s = (byte) ((sky & 0xF) << 4);
-
- int i = boxPosToBufferIndex(x, y, z);
- lightData.put(i, b);
- lightData.put(i + 1, s);
- }
-
- protected void writeBlock(int x, int y, int z, int block) {
- byte b = (byte) ((block & 0xF) << 4);
-
- lightData.put(boxPosToBufferIndex(x, y, z), b);
- }
-
- protected void writeSky(int x, int y, int z, int sky) {
- byte b = (byte) ((sky & 0xF) << 4);
-
- lightData.put(boxPosToBufferIndex(x, y, z) + 1, b);
- }
-
- protected int worldPosToBufferIndex(int x, int y, int z) {
- x -= box.getMinX();
- y -= box.getMinY();
- z -= box.getMinZ();
- return boxPosToBufferIndex(x, y, z);
- }
-
- protected int boxPosToBufferIndex(int x, int y, int z) {
- return (x + box.sizeX() * (y + z * box.sizeY())) * 2;
- }
-
- @Override
- public ImmutableBox getVolume() {
- return box;
- }
-
- @Override
- public boolean isListenerInvalid() {
- return lightData == null;
- }
-
}
diff --git a/src/main/java/com/jozufozu/flywheel/util/StringUtil.java b/src/main/java/com/jozufozu/flywheel/util/StringUtil.java
index 054bf0f43..7af4a9c5f 100644
--- a/src/main/java/com/jozufozu/flywheel/util/StringUtil.java
+++ b/src/main/java/com/jozufozu/flywheel/util/StringUtil.java
@@ -15,19 +15,33 @@ import java.util.stream.Collectors;
import org.lwjgl.system.MemoryUtil;
+import com.jozufozu.flywheel.backend.memory.FlwMemoryTracker;
+
public class StringUtil {
- private static final NumberFormat timeFormat = new DecimalFormat("#0.000");
+ private static final NumberFormat THREE_DECIMAL_PLACES = new DecimalFormat("#0.000");
+
+ public static String formatBytes(long bytes) {
+ if (bytes < 1024) {
+ return bytes + " B";
+ } else if (bytes < 1024 * 1024) {
+ return THREE_DECIMAL_PLACES.format(bytes / 1024f) + " KiB";
+ } else if (bytes < 1024 * 1024 * 1024) {
+ return THREE_DECIMAL_PLACES.format(bytes / 1024f / 1024f) + " MiB";
+ } else {
+ return THREE_DECIMAL_PLACES.format(bytes / 1024f / 1024f / 1024f) + " GiB";
+ }
+ }
public static String formatTime(long ns) {
if (ns < 1000) {
return ns + " ns";
} else if (ns < 1000000) {
- return timeFormat.format(ns / 1000.) + " μs";
+ return THREE_DECIMAL_PLACES.format(ns / 1000f) + " μs";
} else if (ns < 1000000000) {
- return timeFormat.format(ns / 1000000.) + " ms";
+ return THREE_DECIMAL_PLACES.format(ns / 1000000f) + " ms";
} else {
- return timeFormat.format(ns / 1000000000.) + " s";
+ return THREE_DECIMAL_PLACES.format(ns / 1000000000f) + " s";
}
}
@@ -56,11 +70,11 @@ public class StringUtil {
((Buffer) bytebuffer).rewind();
return MemoryUtil.memASCII(bytebuffer, i);
} catch (IOException ignored) {
+ //
} finally {
if (bytebuffer != null) {
- MemoryUtil.memFree(bytebuffer);
+ FlwMemoryTracker.freeBuffer(bytebuffer);
}
-
}
return null;
@@ -75,12 +89,12 @@ public class StringUtil {
}
private static ByteBuffer readInputStream(InputStream is) throws IOException {
- ByteBuffer bytebuffer = MemoryUtil.memAlloc(8192);
+ ByteBuffer bytebuffer = FlwMemoryTracker.mallocBuffer(8192);
ReadableByteChannel readablebytechannel = Channels.newChannel(is);
while (readablebytechannel.read(bytebuffer) != -1) {
if (bytebuffer.remaining() == 0) {
- bytebuffer = MemoryUtil.memRealloc(bytebuffer, bytebuffer.capacity() * 2);
+ bytebuffer = FlwMemoryTracker.reallocBuffer(bytebuffer, bytebuffer.capacity() * 2);
}
}
return bytebuffer;
@@ -88,7 +102,7 @@ public class StringUtil {
private static ByteBuffer readFileInputStream(FileInputStream fileinputstream) throws IOException {
FileChannel filechannel = fileinputstream.getChannel();
- ByteBuffer bytebuffer = MemoryUtil.memAlloc((int) filechannel.size() + 1);
+ ByteBuffer bytebuffer = FlwMemoryTracker.mallocBuffer((int) filechannel.size() + 1);
while (filechannel.read(bytebuffer) != -1) {
}
diff --git a/src/main/java/com/jozufozu/flywheel/util/WorldAttached.java b/src/main/java/com/jozufozu/flywheel/util/WorldAttached.java
index cb41e9fd1..93b79a310 100644
--- a/src/main/java/com/jozufozu/flywheel/util/WorldAttached.java
+++ b/src/main/java/com/jozufozu/flywheel/util/WorldAttached.java
@@ -36,7 +36,16 @@ public class WorldAttached {
i.remove();
} else {
// Prevent leaks
- map.remove(world);
+ Object attached = map.remove(world);
+
+ // No, *really* prevent leaks
+ if (attached instanceof AutoCloseable closeable) {
+ try {
+ closeable.close();
+ } catch (Exception ignored) {
+
+ }
+ }
}
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java
index 39e6650fb..0089766d2 100644
--- a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java
+++ b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java
@@ -15,8 +15,8 @@ import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
import com.jozufozu.flywheel.core.model.SimpleLazyModel;
import com.jozufozu.flywheel.core.structs.StructTypes;
-import com.jozufozu.flywheel.core.structs.model.TransformedPart;
import com.jozufozu.flywheel.core.structs.oriented.OrientedPart;
+import com.jozufozu.flywheel.core.structs.transformed.TransformedPart;
import com.jozufozu.flywheel.util.AnimationTickHolder;
import com.mojang.math.Quaternion;
import com.mojang.math.Vector3f;
diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java
index e12f6d37e..d1ae67501 100644
--- a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java
+++ b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java
@@ -12,7 +12,7 @@ import com.jozufozu.flywheel.core.model.Mesh;
import com.jozufozu.flywheel.core.model.Models;
import com.jozufozu.flywheel.core.model.SimpleLazyModel;
import com.jozufozu.flywheel.core.structs.StructTypes;
-import com.jozufozu.flywheel.core.structs.model.TransformedPart;
+import com.jozufozu.flywheel.core.structs.transformed.TransformedPart;
import com.jozufozu.flywheel.util.AnimationTickHolder;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java
index cc9aadb8a..cfe63f41d 100644
--- a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java
+++ b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java
@@ -12,7 +12,7 @@ import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
import com.jozufozu.flywheel.core.model.SimpleLazyModel;
import com.jozufozu.flywheel.core.structs.StructTypes;
-import com.jozufozu.flywheel.core.structs.model.TransformedPart;
+import com.jozufozu.flywheel.core.structs.transformed.TransformedPart;
import com.jozufozu.flywheel.util.AnimationTickHolder;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/effect/ExampleEffect.java b/src/main/java/com/jozufozu/flywheel/vanilla/effect/ExampleEffect.java
index d7f362424..60cfa49fa 100644
--- a/src/main/java/com/jozufozu/flywheel/vanilla/effect/ExampleEffect.java
+++ b/src/main/java/com/jozufozu/flywheel/vanilla/effect/ExampleEffect.java
@@ -13,7 +13,7 @@ import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.backend.instancing.effect.Effect;
import com.jozufozu.flywheel.core.model.Models;
import com.jozufozu.flywheel.core.structs.StructTypes;
-import com.jozufozu.flywheel.core.structs.model.TransformedPart;
+import com.jozufozu.flywheel.core.structs.transformed.TransformedPart;
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
import com.jozufozu.flywheel.util.AnimationTickHolder;
import com.jozufozu.flywheel.util.box.GridAlignedBB;