From 9b39ba6c32bf03f4acafd1c3047f902b0491533e Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Sun, 14 Aug 2022 21:42:44 -0700 Subject: [PATCH] Hazardous light - BatchingEngine no longer resets the light matrices - Fix flw_constantAmbientLight always being 0 - Move code from FlwMemoryTracker#*Block methods into MemoryBlockImpl and TrackedMemoryBlockImpl - Convert LightVolume to use MemoryBlock - Add FlwMemoryTracker#callocBuffer - Add javadoc to deprecated FlwMemoryTracker#*Buffer methods - Update Mesh javadoc - Organize imports --- .../flywheel/api/material/Material.java | 2 +- .../flywheel/api/struct/StructType.java | 2 +- .../flywheel/api/uniform/UniformProvider.java | 2 - .../backend/gl/array/GlVertexArray.java | 2 +- .../flywheel/backend/gl/buffer/GlBuffer.java | 8 +- .../instancing/batching/BatchingEngine.java | 11 - .../instancing/batching/TransformSet.java | 33 +- .../instancing/instancing/GPUInstancer.java | 2 +- .../instancing/instancing/MeshPool.java | 2 +- .../backend/memory/FlwMemoryTracker.java | 66 ++-- .../flywheel/backend/memory/MemoryBlock.java | 14 +- .../backend/memory/MemoryBlockImpl.java | 31 +- .../memory/TrackedMemoryBlockImpl.java | 23 +- .../flywheel/core/FullscreenQuad.java | 2 +- .../jozufozu/flywheel/core/QuadConverter.java | 2 +- .../jozufozu/flywheel/core/model/Mesh.java | 29 +- .../model/buffering/BakedModelBuilder.java | 6 +- .../model/buffering/BlockModelBuilder.java | 6 +- .../buffering/MultiBlockModelBuilder.java | 6 +- .../flywheel/core/uniform/UniformBuffer.java | 3 +- .../flywheel/core/uniform/ViewProvider.java | 2 +- .../flywheel/light/GPULightVolume.java | 4 +- .../jozufozu/flywheel/light/LightVolume.java | 320 +++++++++--------- .../jozufozu/flywheel/util/StringUtil.java | 6 +- 24 files changed, 288 insertions(+), 296 deletions(-) diff --git a/src/main/java/com/jozufozu/flywheel/api/material/Material.java b/src/main/java/com/jozufozu/flywheel/api/material/Material.java index a93091d89..dc0db130f 100644 --- a/src/main/java/com/jozufozu/flywheel/api/material/Material.java +++ b/src/main/java/com/jozufozu/flywheel/api/material/Material.java @@ -22,7 +22,7 @@ public interface Material { VertexTransformer getVertexTransformer(); - public interface VertexTransformer { + interface VertexTransformer { void transform(MutableVertexList vertexList, ClientLevel level); } } diff --git a/src/main/java/com/jozufozu/flywheel/api/struct/StructType.java b/src/main/java/com/jozufozu/flywheel/api/struct/StructType.java index 7bdeab3a0..ef14279de 100644 --- a/src/main/java/com/jozufozu/flywheel/api/struct/StructType.java +++ b/src/main/java/com/jozufozu/flywheel/api/struct/StructType.java @@ -29,7 +29,7 @@ public interface StructType { VertexTransformer getVertexTransformer(); - public interface VertexTransformer { + interface VertexTransformer { void transform(MutableVertexList vertexList, S struct, ClientLevel level); } diff --git a/src/main/java/com/jozufozu/flywheel/api/uniform/UniformProvider.java b/src/main/java/com/jozufozu/flywheel/api/uniform/UniformProvider.java index 62890b521..982be51be 100644 --- a/src/main/java/com/jozufozu/flywheel/api/uniform/UniformProvider.java +++ b/src/main/java/com/jozufozu/flywheel/api/uniform/UniformProvider.java @@ -1,7 +1,5 @@ package com.jozufozu.flywheel.api.uniform; -import java.nio.ByteBuffer; - import com.jozufozu.flywheel.core.source.FileResolution; public abstract class UniformProvider { diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/array/GlVertexArray.java b/src/main/java/com/jozufozu/flywheel/backend/gl/array/GlVertexArray.java index 69efb178f..3abf7a7d0 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/array/GlVertexArray.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/array/GlVertexArray.java @@ -5,8 +5,8 @@ import org.lwjgl.opengl.GL32; import com.jozufozu.flywheel.backend.gl.GlObject; import com.jozufozu.flywheel.backend.gl.GlStateTracker; -import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; import com.jozufozu.flywheel.backend.gl.versioned.GlCompat; import com.jozufozu.flywheel.core.layout.BufferLayout; import com.mojang.blaze3d.platform.GlStateManager; diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBuffer.java index edfff94d3..ef8eaa6df 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBuffer.java @@ -1,6 +1,12 @@ package com.jozufozu.flywheel.backend.gl.buffer; -import static org.lwjgl.opengl.GL32.*; +import static org.lwjgl.opengl.GL15.glBufferData; +import static org.lwjgl.opengl.GL15.glDeleteBuffers; +import static org.lwjgl.opengl.GL15.glGenBuffers; +import static org.lwjgl.opengl.GL15.nglBufferData; +import static org.lwjgl.opengl.GL30.GL_MAP_WRITE_BIT; +import static org.lwjgl.opengl.GL30.nglMapBufferRange; +import static org.lwjgl.opengl.GL31.glCopyBufferSubData; import org.lwjgl.system.MemoryUtil; 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 1d68c6617..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; @@ -73,15 +71,6 @@ public class BatchingEngine implements Engine { 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/TransformSet.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/TransformSet.java index 8b27d389d..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 @@ -83,20 +83,15 @@ public class TransformSet { vertexList.ptr(anchorPtr); vertexList.setVertexCount(totalVertexCount); material.getVertexTransformer().transform(vertexList, level); - applyPoseStack(vertexList, stack, false); + applyPoseStack(vertexList, stack); } - 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( @@ -110,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/instancing/GPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java index cfce702fb..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 @@ -8,10 +8,10 @@ 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.GlBuffer; import com.jozufozu.flywheel.backend.instancing.AbstractInstancer; import com.jozufozu.flywheel.core.layout.BufferLayout; 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 c43a49fc9..f23b647d1 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 @@ -14,9 +14,9 @@ import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.gl.GlPrimitive; 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.GlBuffer; import com.jozufozu.flywheel.core.layout.BufferLayout; import com.jozufozu.flywheel.core.model.Mesh; import com.jozufozu.flywheel.event.ReloadRenderersEvent; diff --git a/src/main/java/com/jozufozu/flywheel/backend/memory/FlwMemoryTracker.java b/src/main/java/com/jozufozu/flywheel/backend/memory/FlwMemoryTracker.java index 80d1c486b..165b441f3 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/memory/FlwMemoryTracker.java +++ b/src/main/java/com/jozufozu/flywheel/backend/memory/FlwMemoryTracker.java @@ -6,7 +6,7 @@ import java.nio.ByteBuffer; import org.lwjgl.system.MemoryUtil; public class FlwMemoryTracker { - private static final Cleaner CLEANER = Cleaner.create(); + static final Cleaner CLEANER = Cleaner.create(); private static long cpuMemory = 0; private static long gpuMemory = 0; @@ -19,18 +19,11 @@ public class FlwMemoryTracker { return ptr; } - public static MemoryBlock mallocBlock(long size) { - MemoryBlock block = new MemoryBlockImpl(malloc(size), size); - _allocCPUMemory(block.size()); - return block; - } - - public static MemoryBlock mallocBlockTracked(long size) { - MemoryBlock block = new TrackedMemoryBlockImpl(malloc(size), size, CLEANER); - _allocCPUMemory(block.size()); - return block; - } - + /** + * @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); @@ -46,16 +39,16 @@ public class FlwMemoryTracker { return ptr; } - public static MemoryBlock callocBlock(long num, long size) { - MemoryBlock block = new MemoryBlockImpl(calloc(num, size), num * size); - _allocCPUMemory(block.size()); - return block; - } - - public static MemoryBlock callocBlockTracked(long num, long size) { - MemoryBlock block = new TrackedMemoryBlockImpl(calloc(num, size), num * size, CLEANER); - _allocCPUMemory(block.size()); - return block; + /** + * @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) { @@ -66,20 +59,10 @@ public class FlwMemoryTracker { return ptr; } - public static MemoryBlock reallocBlock(MemoryBlock block, long size) { - MemoryBlock newBlock = new MemoryBlockImpl(realloc(block.ptr(), size), size); - _freeCPUMemory(block.size()); - _allocCPUMemory(newBlock.size()); - return newBlock; - } - - public static MemoryBlock reallocBlockTracked(MemoryBlock block, long size) { - MemoryBlock newBlock = new TrackedMemoryBlockImpl(realloc(block.ptr(), size), size, CLEANER); - _freeCPUMemory(block.size()); - _allocCPUMemory(newBlock.size()); - return newBlock; - } - + /** + * @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); @@ -92,11 +75,10 @@ public class FlwMemoryTracker { MemoryUtil.nmemFree(ptr); } - public static void freeBlock(MemoryBlock block) { - free(block.ptr()); - _freeCPUMemory(block.size()); - } - + /** + * @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)); diff --git a/src/main/java/com/jozufozu/flywheel/backend/memory/MemoryBlock.java b/src/main/java/com/jozufozu/flywheel/backend/memory/MemoryBlock.java index 9b6ad2cea..1b28bdbe2 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/memory/MemoryBlock.java +++ b/src/main/java/com/jozufozu/flywheel/backend/memory/MemoryBlock.java @@ -26,18 +26,18 @@ public sealed interface MemoryBlock permits MemoryBlockImpl { void free(); static MemoryBlock malloc(long size) { - return FlwMemoryTracker.mallocBlock(size); - } - - static MemoryBlock calloc(long num, long size) { - return FlwMemoryTracker.callocBlock(num, size); + return MemoryBlockImpl.mallocBlock(size); } static MemoryBlock mallocTracked(long size) { - return FlwMemoryTracker.mallocBlockTracked(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 FlwMemoryTracker.callocBlockTracked(num, 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 index a3fb15a60..d37b61ded 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/memory/MemoryBlockImpl.java +++ b/src/main/java/com/jozufozu/flywheel/backend/memory/MemoryBlockImpl.java @@ -59,23 +59,42 @@ sealed class MemoryBlockImpl implements MemoryBlock permits TrackedMemoryBlockIm return MemoryUtil.memByteBuffer(ptr, intSize); } + void freeInner() { + FlwMemoryTracker._freeCPUMemory(size); + freed = true; + } + @Override public MemoryBlock realloc(long size) { - MemoryBlock block = FlwMemoryTracker.reallocBlock(this, size); - freed = true; + MemoryBlock block = new MemoryBlockImpl(FlwMemoryTracker.realloc(ptr, size), size); + FlwMemoryTracker._allocCPUMemory(block.size()); + freeInner(); return block; } @Override public MemoryBlock reallocTracked(long size) { - MemoryBlock block = FlwMemoryTracker.reallocBlockTracked(this, size); - freed = true; + MemoryBlock block = new TrackedMemoryBlockImpl(FlwMemoryTracker.realloc(ptr, size), size, FlwMemoryTracker.CLEANER); + FlwMemoryTracker._allocCPUMemory(block.size()); + freeInner(); return block; } @Override public void free() { - FlwMemoryTracker.freeBlock(this); - freed = true; + 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 index a37ba3590..57b7730c5 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/memory/TrackedMemoryBlockImpl.java +++ b/src/main/java/com/jozufozu/flywheel/backend/memory/TrackedMemoryBlockImpl.java @@ -17,32 +17,25 @@ final class TrackedMemoryBlockImpl extends MemoryBlockImpl { return true; } + @Override void freeInner() { - freed = true; + super.freeInner(); cleaningAction.freed = true; cleanable.clean(); } - @Override - public MemoryBlock realloc(long size) { - MemoryBlock block = FlwMemoryTracker.reallocBlock(this, size); - freeInner(); + static MemoryBlock mallocBlockTracked(long size) { + MemoryBlock block = new TrackedMemoryBlockImpl(FlwMemoryTracker.malloc(size), size, FlwMemoryTracker.CLEANER); + FlwMemoryTracker._allocCPUMemory(block.size()); return block; } - @Override - public MemoryBlock reallocTracked(long size) { - MemoryBlock block = FlwMemoryTracker.reallocBlockTracked(this, size); - freeInner(); + 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; } - @Override - public void free() { - FlwMemoryTracker.freeBlock(this); - freeInner(); - } - static class CleaningAction implements Runnable { final long ptr; final long size; diff --git a/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java b/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java index 79b49df58..7280641fa 100644 --- a/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java +++ b/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java @@ -8,9 +8,9 @@ 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.GlBuffer; import com.jozufozu.flywheel.core.layout.BufferLayout; import com.jozufozu.flywheel.core.layout.CommonItems; import com.jozufozu.flywheel.util.Lazy; diff --git a/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java b/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java index 93427f829..71e9d27ce 100644 --- a/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java +++ b/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java @@ -5,9 +5,9 @@ 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.GlBuffer; import com.jozufozu.flywheel.backend.instancing.instancing.ElementBuffer; import com.jozufozu.flywheel.event.ReloadRenderersEvent; 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 a1a4f10c2..ecf138451 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java @@ -6,24 +6,7 @@ import com.jozufozu.flywheel.backend.instancing.instancing.ElementBuffer; import com.jozufozu.flywheel.core.QuadConverter; /** - * 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 { @@ -49,8 +32,18 @@ public interface Mesh { return getVertexType().byteOffset(getVertexCount()); } + /** + * 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); /** 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 e0ca37b16..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 @@ -30,6 +30,8 @@ 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 BlockAndTintGetter renderWorld; @@ -96,7 +98,7 @@ public class BakedModelBuilder { if (shadeSeparated) { ShadeSeparatedBufferFactory bufferFactory = (renderType, shaded) -> { - BufferBuilder buffer = new BufferBuilder(64); + BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY); buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); return buffer; }; @@ -111,7 +113,7 @@ public class BakedModelBuilder { 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); + BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY); buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); return buffer; }; 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 84686aa74..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 @@ -28,6 +28,8 @@ 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 BlockAndTintGetter renderWorld; @@ -85,7 +87,7 @@ public class BlockModelBuilder { if (shadeSeparated) { ShadeSeparatedBufferFactory bufferFactory = (renderType, shaded) -> { - BufferBuilder buffer = new BufferBuilder(64); + BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY); buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); return buffer; }; @@ -100,7 +102,7 @@ public class BlockModelBuilder { ModelBufferingUtil.bufferBlockShadeSeparated(ModelUtil.VANILLA_RENDERER, renderWorld, state, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelData, resultConsumer); } else { BufferFactory bufferFactory = (renderType) -> { - BufferBuilder buffer = new BufferBuilder(64); + BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY); buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); return buffer; }; 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 b329a46c6..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 @@ -31,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; @@ -92,7 +94,7 @@ public class MultiBlockModelBuilder { if (shadeSeparated) { ShadeSeparatedBufferFactory bufferFactory = (renderType, shaded) -> { - BufferBuilder buffer = new BufferBuilder(1024); + BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY); buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); return buffer; }; @@ -107,7 +109,7 @@ public class MultiBlockModelBuilder { ModelBufferingUtil.bufferMultiBlockShadeSeparated(blocks, ModelUtil.VANILLA_RENDERER, renderWorld, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelDataMap, resultConsumer); } else { BufferFactory bufferFactory = (renderType) -> { - BufferBuilder buffer = new BufferBuilder(1024); + BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY); buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); return buffer; }; 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 e1c88b815..39ce69a94 100644 --- a/src/main/java/com/jozufozu/flywheel/core/uniform/UniformBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/core/uniform/UniformBuffer.java @@ -5,12 +5,11 @@ 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.GlBufferType; import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; import com.jozufozu.flywheel.backend.memory.MemoryBlock; import com.jozufozu.flywheel.core.ComponentRegistry; import com.jozufozu.flywheel.util.RenderMath; 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 437b5cdcd..5a785ec70 100644 --- a/src/main/java/com/jozufozu/flywheel/core/uniform/ViewProvider.java +++ b/src/main/java/com/jozufozu/flywheel/core/uniform/ViewProvider.java @@ -56,7 +56,7 @@ public class ViewProvider extends UniformProvider { MemoryUtil.memPutFloat(ptr + 64, camX); MemoryUtil.memPutFloat(ptr + 68, camY); MemoryUtil.memPutFloat(ptr + 72, camZ); - MemoryUtil.memPutInt(ptr + 76, constantAmbientLight); + MemoryUtil.memPutInt(ptr + 80, constantAmbientLight); notifier.signalChanged(); } 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 cf4abacb1..ef1dc4f88 100644 --- a/src/main/java/com/jozufozu/flywheel/light/LightVolume.java +++ b/src/main/java/com/jozufozu/flywheel/light/LightVolume.java @@ -1,8 +1,8 @@ package com.jozufozu.flywheel.light; -import java.nio.ByteBuffer; +import org.lwjgl.system.MemoryUtil; -import com.jozufozu.flywheel.backend.memory.FlwMemoryTracker; +import com.jozufozu.flywheel.backend.memory.MemoryBlock; import com.jozufozu.flywheel.util.box.GridAlignedBB; import com.jozufozu.flywheel.util.box.ImmutableBox; @@ -14,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 = FlwMemoryTracker.mallocBuffer(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) { @@ -29,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 = FlwMemoryTracker.reallocBuffer(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; @@ -95,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() { - FlwMemoryTracker.freeBuffer(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 cdf8c6952..7af4a9c5f 100644 --- a/src/main/java/com/jozufozu/flywheel/util/StringUtil.java +++ b/src/main/java/com/jozufozu/flywheel/util/StringUtil.java @@ -25,11 +25,11 @@ public class StringUtil { if (bytes < 1024) { return bytes + " B"; } else if (bytes < 1024 * 1024) { - return THREE_DECIMAL_PLACES.format(bytes / 1024f) + " KB"; + return THREE_DECIMAL_PLACES.format(bytes / 1024f) + " KiB"; } else if (bytes < 1024 * 1024 * 1024) { - return THREE_DECIMAL_PLACES.format(bytes / 1024f / 1024f) + " MB"; + return THREE_DECIMAL_PLACES.format(bytes / 1024f / 1024f) + " MiB"; } else { - return THREE_DECIMAL_PLACES.format(bytes / 1024f / 1024f / 1024f) + " GB"; + return THREE_DECIMAL_PLACES.format(bytes / 1024f / 1024f / 1024f) + " GiB"; } }