From 79977aee1443fe29d4febcb51cbf437c691c3a86 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Fri, 14 May 2021 22:51:14 -0700 Subject: [PATCH 1/3] Choose between 2 different implementations of a mapped buffer - MappedBufferRange (GL30) and MappedFullBuffer (GL15) so far - Persistent mapping (optionally?) would be nice --- .../flywheel/backend/BufferedModel.java | 12 +-- .../backend/core/materials/BasicData.java | 2 +- .../backend/core/materials/ModelData.java | 2 +- .../backend/core/materials/OrientedData.java | 2 +- .../backend/gl/MappedBufferRange.java | 31 ------ .../backend/gl/{ => buffer}/GlBuffer.java | 16 +++- .../backend/gl/{ => buffer}/GlBufferType.java | 2 +- .../gl/{ => buffer}/GlBufferUsage.java | 2 +- .../backend/gl/{ => buffer}/MappedBuffer.java | 46 ++++++++- .../backend/gl/buffer/MappedBufferRange.java | 33 +++++++ .../backend/gl/buffer/MappedBufferUsage.java | 16 ++++ .../backend/gl/buffer/MappedFullBuffer.java | 21 +++++ .../backend/gl/versioned/GlCompat.java | 4 +- .../backend/gl/versioned/MapBuffer.java | 94 ------------------- .../backend/gl/versioned/MapBufferRange.java | 49 ++++++++++ .../backend/instancing/InstanceData.java | 2 +- .../backend/instancing/InstancedModel.java | 23 ++--- .../contraptions/base/KineticData.java | 2 +- .../contraptions/base/RotatingData.java | 2 +- .../components/actors/ActorData.java | 2 +- .../render/ContraptionModel.java | 12 +-- .../contraptions/relays/belt/BeltData.java | 2 +- .../content/logistics/block/FlapData.java | 2 +- .../render/effects/EffectsHandler.java | 10 +- .../render/effects/FilterSphere.java | 2 +- .../render/effects/SphereFilterProgram.java | 10 +- 26 files changed, 223 insertions(+), 178 deletions(-) delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/gl/MappedBufferRange.java rename src/main/java/com/jozufozu/flywheel/backend/gl/{ => buffer}/GlBuffer.java (61%) rename src/main/java/com/jozufozu/flywheel/backend/gl/{ => buffer}/GlBufferType.java (95%) rename src/main/java/com/jozufozu/flywheel/backend/gl/{ => buffer}/GlBufferUsage.java (90%) rename src/main/java/com/jozufozu/flywheel/backend/gl/{ => buffer}/MappedBuffer.java (62%) create mode 100644 src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBufferRange.java create mode 100644 src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBufferUsage.java create mode 100644 src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedFullBuffer.java delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/gl/versioned/MapBuffer.java create mode 100644 src/main/java/com/jozufozu/flywheel/backend/gl/versioned/MapBufferRange.java diff --git a/src/main/java/com/jozufozu/flywheel/backend/BufferedModel.java b/src/main/java/com/jozufozu/flywheel/backend/BufferedModel.java index d23d9fdd7..3f2f959a0 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/BufferedModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/BufferedModel.java @@ -3,10 +3,10 @@ package com.jozufozu.flywheel.backend; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL20; -import com.jozufozu.flywheel.backend.gl.GlBuffer; -import com.jozufozu.flywheel.backend.gl.GlBufferType; -import com.jozufozu.flywheel.backend.gl.MappedBufferRange; import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; +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.simibubi.create.foundation.render.TemplateBuffer; import net.minecraft.client.renderer.BufferBuilder; @@ -38,14 +38,14 @@ public abstract class BufferedModel extends TemplateBuffer { GL15.glBufferData(GL15.GL_ARRAY_BUFFER, invariantSize, GL15.GL_STATIC_DRAW); // mirror it in system memory so we can write to it - MappedBufferRange buffer = modelVBO.getBuffer(0, invariantSize); + MappedBuffer buffer = modelVBO.getBuffer(0, invariantSize); for (int i = 0; i < vertexCount; i++) { copyVertex(buffer, i); } - buffer.unmap(); + buffer.flush(); } - protected abstract void copyVertex(MappedBufferRange to, int index); + protected abstract void copyVertex(MappedBuffer to, int index); protected abstract VertexFormat getModelFormat(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/materials/BasicData.java b/src/main/java/com/jozufozu/flywheel/backend/core/materials/BasicData.java index 8900db4e1..9097d9ee7 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/core/materials/BasicData.java +++ b/src/main/java/com/jozufozu/flywheel/backend/core/materials/BasicData.java @@ -1,6 +1,6 @@ package com.jozufozu.flywheel.backend.core.materials; -import com.jozufozu.flywheel.backend.gl.MappedBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.instancing.InstanceData; import com.jozufozu.flywheel.backend.instancing.InstancedModel; diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/materials/ModelData.java b/src/main/java/com/jozufozu/flywheel/backend/core/materials/ModelData.java index 42e9afbfb..88475d478 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/core/materials/ModelData.java +++ b/src/main/java/com/jozufozu/flywheel/backend/core/materials/ModelData.java @@ -1,6 +1,6 @@ package com.jozufozu.flywheel.backend.core.materials; -import com.jozufozu.flywheel.backend.gl.MappedBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.instancing.InstancedModel; import com.jozufozu.flywheel.util.RenderUtil; import com.mojang.blaze3d.matrix.MatrixStack; diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/materials/OrientedData.java b/src/main/java/com/jozufozu/flywheel/backend/core/materials/OrientedData.java index 187e4f3c2..0132537c7 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/core/materials/OrientedData.java +++ b/src/main/java/com/jozufozu/flywheel/backend/core/materials/OrientedData.java @@ -1,6 +1,6 @@ package com.jozufozu.flywheel.backend.core.materials; -import com.jozufozu.flywheel.backend.gl.MappedBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.instancing.InstancedModel; import net.minecraft.util.math.BlockPos; diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/MappedBufferRange.java b/src/main/java/com/jozufozu/flywheel/backend/gl/MappedBufferRange.java deleted file mode 100644 index 6a28dfce6..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/MappedBufferRange.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.jozufozu.flywheel.backend.gl; - -import java.nio.ByteBuffer; - -import org.lwjgl.opengl.GL30; - -public class MappedBufferRange extends MappedBuffer { - - GlBuffer owner; - - public MappedBufferRange(GlBuffer buffer, ByteBuffer internal) { - super(internal); - this.owner = buffer; - } - - public static MappedBufferRange create(GlBuffer buffer, long offset, long length, int access) { - ByteBuffer byteBuffer = GL30.glMapBufferRange(buffer.type.glEnum, offset, length, access); - - return new MappedBufferRange(buffer, byteBuffer); - } - - public MappedBuffer unmap() { - GL30.glUnmapBuffer(owner.type.glEnum); - return this; - } - - @Override - public void close() throws Exception { - unmap(); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/GlBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBuffer.java similarity index 61% rename from src/main/java/com/jozufozu/flywheel/backend/gl/GlBuffer.java rename to src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBuffer.java index 6ded39c5d..c3c2da51a 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/GlBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBuffer.java @@ -1,9 +1,13 @@ -package com.jozufozu.flywheel.backend.gl; +package com.jozufozu.flywheel.backend.gl.buffer; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL30; +import com.jozufozu.flywheel.backend.Backend; +import com.jozufozu.flywheel.backend.gl.GlObject; +import com.jozufozu.flywheel.backend.gl.versioned.MapBufferRange; + public class GlBuffer extends GlObject { protected final GlBufferType type; @@ -43,8 +47,14 @@ public class GlBuffer extends GlObject { GL15.glBufferData(type.glEnum, size, usage.glEnum); } - public MappedBufferRange getBuffer(int offset, int length) { - return MappedBufferRange.create(this, offset, length, GL30.GL_MAP_WRITE_BIT); + public MappedBuffer getBuffer(int offset, int length) { + if (Backend.compat.mapBufferRange == MapBufferRange.UNSUPPORTED) { + return new MappedBufferRange(this, offset, length, GL30.GL_MAP_WRITE_BIT); + } else { + MappedFullBuffer fullBuffer = new MappedFullBuffer(this, MappedBufferUsage.WRITE_ONLY); + fullBuffer.position(offset); + return fullBuffer; + } } protected void deleteInternal(int handle) { diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/GlBufferType.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferType.java similarity index 95% rename from src/main/java/com/jozufozu/flywheel/backend/gl/GlBufferType.java rename to src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferType.java index f64caa6c3..7ba9d0073 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/GlBufferType.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferType.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.backend.gl; +package com.jozufozu.flywheel.backend.gl.buffer; import org.lwjgl.opengl.GL15C; import org.lwjgl.opengl.GL21; diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/GlBufferUsage.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferUsage.java similarity index 90% rename from src/main/java/com/jozufozu/flywheel/backend/gl/GlBufferUsage.java rename to src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferUsage.java index a2f69461c..e01f28afe 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/GlBufferUsage.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferUsage.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.backend.gl; +package com.jozufozu.flywheel.backend.gl.buffer; import org.lwjgl.opengl.GL15; diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/MappedBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java similarity index 62% rename from src/main/java/com/jozufozu/flywheel/backend/gl/MappedBuffer.java rename to src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java index 7c01fbf8e..eace56477 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/MappedBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java @@ -1,16 +1,40 @@ -package com.jozufozu.flywheel.backend.gl; +package com.jozufozu.flywheel.backend.gl.buffer; import java.nio.ByteBuffer; +import org.lwjgl.opengl.GL15; + public abstract class MappedBuffer implements AutoCloseable { - private final ByteBuffer internal; + protected boolean mapped; + protected final GlBuffer owner; + protected ByteBuffer internal; - public MappedBuffer(ByteBuffer internal) { + public MappedBuffer(GlBuffer owner) { + this.owner = owner; + } + + public void setInternal(ByteBuffer internal) { this.internal = internal; } + protected abstract void checkAndMap(); + + public void flush() { + if (mapped) { + GL15.glUnmapBuffer(owner.type.glEnum); + mapped = false; + setInternal(null); + } + } + + @Override + public void close() throws Exception { + flush(); + } + public MappedBuffer putFloatArray(float[] floats) { + checkAndMap(); internal.asFloatBuffer().put(floats); internal.position(internal.position() + floats.length * 4); @@ -18,32 +42,44 @@ public abstract class MappedBuffer implements AutoCloseable { } public MappedBuffer putByteArray(byte[] bytes) { + checkAndMap(); internal.put(bytes); return this; } + /** + * Position this buffer relative to the 0-index in GPU memory. + * + * @param p + * @return This buffer. + */ public MappedBuffer position(int p) { + checkAndMap(); internal.position(p); return this; } public MappedBuffer putFloat(float f) { + checkAndMap(); internal.putFloat(f); return this; } public MappedBuffer putInt(int i) { + checkAndMap(); internal.putInt(i); return this; } public MappedBuffer put(byte b) { + checkAndMap(); internal.put(b); return this; } public MappedBuffer putVec4(float x, float y, float z, float w) { + checkAndMap(); internal.putFloat(x); internal.putFloat(y); internal.putFloat(z); @@ -53,6 +89,7 @@ public abstract class MappedBuffer implements AutoCloseable { } public MappedBuffer putVec3(float x, float y, float z) { + checkAndMap(); internal.putFloat(x); internal.putFloat(y); internal.putFloat(z); @@ -61,6 +98,7 @@ public abstract class MappedBuffer implements AutoCloseable { } public MappedBuffer putVec2(float x, float y) { + checkAndMap(); internal.putFloat(x); internal.putFloat(y); @@ -68,6 +106,7 @@ public abstract class MappedBuffer implements AutoCloseable { } public MappedBuffer putVec3(byte x, byte y, byte z) { + checkAndMap(); internal.put(x); internal.put(y); internal.put(z); @@ -76,6 +115,7 @@ public abstract class MappedBuffer implements AutoCloseable { } public MappedBuffer putVec2(byte x, byte y) { + checkAndMap(); internal.put(x); internal.put(y); diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBufferRange.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBufferRange.java new file mode 100644 index 000000000..1ce8cdc6c --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBufferRange.java @@ -0,0 +1,33 @@ +package com.jozufozu.flywheel.backend.gl.buffer; + +import com.jozufozu.flywheel.backend.Backend; + +public class MappedBufferRange extends MappedBuffer { + + long offset, length; + int access; + + public MappedBufferRange(GlBuffer buffer, long offset, long length, int access) { + super(buffer); + this.offset = offset; + this.length = length; + this.access = access; + } + + + @Override + public MappedBuffer position(int p) { + if (p < offset || p >= offset + length) { + throw new IndexOutOfBoundsException("Index " + p + " is not mapped"); + } + return super.position(p - (int) offset); + } + + @Override + protected void checkAndMap() { + if (!mapped) { + setInternal(Backend.compat.mapBufferRange.mapBuffer(owner.type, offset, length, access)); + mapped = true; + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBufferUsage.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBufferUsage.java new file mode 100644 index 000000000..30e60a348 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBufferUsage.java @@ -0,0 +1,16 @@ +package com.jozufozu.flywheel.backend.gl.buffer; + +import org.lwjgl.opengl.GL15C; + +public enum MappedBufferUsage { + READ_ONLY(GL15C.GL_READ_ONLY), + WRITE_ONLY(GL15C.GL_WRITE_ONLY), + READ_WRITE(GL15C.GL_READ_WRITE), + ; + + int glEnum; + + MappedBufferUsage(int glEnum) { + this.glEnum = glEnum; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedFullBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedFullBuffer.java new file mode 100644 index 000000000..36ebb41d2 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedFullBuffer.java @@ -0,0 +1,21 @@ +package com.jozufozu.flywheel.backend.gl.buffer; + +import org.lwjgl.opengl.GL15; + +public class MappedFullBuffer extends MappedBuffer { + + MappedBufferUsage usage; + + public MappedFullBuffer(GlBuffer buffer, MappedBufferUsage usage) { + super(buffer); + this.usage = usage; + } + + @Override + protected void checkAndMap() { + if (!mapped) { + setInternal(GL15.glMapBuffer(owner.type.glEnum, usage.glEnum)); + mapped = true; + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/GlCompat.java b/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/GlCompat.java index 17eeecef4..fdeaa93ff 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/GlCompat.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/GlCompat.java @@ -23,7 +23,7 @@ import com.jozufozu.flywheel.backend.gl.versioned.instancing.VertexArrayObject; * most appropriate version of a feature for the current system. */ public class GlCompat { - public final MapBuffer mapBuffer; + public final MapBufferRange mapBufferRange; public final VertexArrayObject vao; public final InstancedArrays instancedArrays; @@ -34,7 +34,7 @@ public class GlCompat { public final RGPixelFormat pixelFormat; public GlCompat(GLCapabilities caps) { - mapBuffer = getLatest(MapBuffer.class, caps); + mapBufferRange = getLatest(MapBufferRange.class, caps); vao = getLatest(VertexArrayObject.class, caps); instancedArrays = getLatest(InstancedArrays.class, caps); diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/MapBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/MapBuffer.java deleted file mode 100644 index db775f7e9..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/MapBuffer.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.jozufozu.flywheel.backend.gl.versioned; - -import java.nio.ByteBuffer; -import java.util.function.Consumer; - -import org.lwjgl.opengl.ARBMapBufferRange; -import org.lwjgl.opengl.GL15; -import org.lwjgl.opengl.GL30; -import org.lwjgl.opengl.GLCapabilities; - -import com.jozufozu.flywheel.backend.gl.GlBufferType; - -public enum MapBuffer implements GlVersioned { - - GL30_RANGE { - @Override - public boolean supported(GLCapabilities caps) { - return caps.OpenGL30; - } - - public ByteBuffer mapBuffer(GlBufferType target, long offset, long length, int access) { - return GL30.glMapBufferRange(target.glEnum, offset, length, access); - } - - @Override - public void mapBuffer(GlBufferType target, int offset, int length, Consumer upload) { - ByteBuffer buffer = mapBuffer(target, offset, length, GL30.GL_MAP_WRITE_BIT); - - upload.accept(buffer); - buffer.rewind(); - - GL30.glUnmapBuffer(target.glEnum); - } - }, - ARB_RANGE { - @Override - public boolean supported(GLCapabilities caps) { - return caps.GL_ARB_map_buffer_range; - } - - public ByteBuffer mapBuffer(GlBufferType target, long offset, long length, int access) { - return ARBMapBufferRange.glMapBufferRange(target.glEnum, offset, length, access); - } - - @Override - public void mapBuffer(GlBufferType target, int offset, int length, Consumer upload) { - ByteBuffer buffer = ARBMapBufferRange.glMapBufferRange(target.glEnum, offset, length, GL30.GL_MAP_WRITE_BIT); - - upload.accept(buffer); - buffer.rewind(); - - GL30.glUnmapBuffer(target.glEnum); - } - }, - GL15_MAP { - @Override - public boolean supported(GLCapabilities caps) { - return caps.OpenGL15; - } - - @Override - public void mapBuffer(GlBufferType target, int offset, int length, Consumer upload) { - ByteBuffer buffer = GL15.glMapBuffer(target.glEnum, GL15.GL_WRITE_ONLY); - - buffer.position(offset); - upload.accept(buffer); - buffer.rewind(); - GL15.glUnmapBuffer(target.glEnum); - } - }, - UNSUPPORTED { - @Override - public boolean supported(GLCapabilities caps) { - return true; - } - - @Override - public void mapBuffer(GlBufferType target, int offset, int length, Consumer upload) { - throw new UnsupportedOperationException("glMapBuffer not supported"); - } - - @Override - public void unmapBuffer(int target) { - throw new UnsupportedOperationException("glMapBuffer not supported"); - } - }; - - - public void unmapBuffer(int target) { - GL15.glUnmapBuffer(target); - } - - public abstract void mapBuffer(GlBufferType target, int offset, int length, Consumer upload); -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/MapBufferRange.java b/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/MapBufferRange.java new file mode 100644 index 000000000..85f75bc2c --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/MapBufferRange.java @@ -0,0 +1,49 @@ +package com.jozufozu.flywheel.backend.gl.versioned; + +import java.nio.ByteBuffer; + +import org.lwjgl.opengl.ARBMapBufferRange; +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.GLCapabilities; + +import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; + +public enum MapBufferRange implements GlVersioned { + + GL30_RANGE { + @Override + public boolean supported(GLCapabilities caps) { + return caps.OpenGL30; + } + + @Override + public ByteBuffer mapBuffer(GlBufferType target, long offset, long length, int access) { + return GL30.glMapBufferRange(target.glEnum, offset, length, access); + } + }, + ARB_RANGE { + @Override + public boolean supported(GLCapabilities caps) { + return caps.GL_ARB_map_buffer_range; + } + + @Override + public ByteBuffer mapBuffer(GlBufferType target, long offset, long length, int access) { + return ARBMapBufferRange.glMapBufferRange(target.glEnum, offset, length, access); + } + }, + UNSUPPORTED { + @Override + public boolean supported(GLCapabilities caps) { + return true; + } + + @Override + public ByteBuffer mapBuffer(GlBufferType target, long offset, long length, int access) { + throw new UnsupportedOperationException("glMapBuffer not supported"); + } + }; + + + public abstract ByteBuffer mapBuffer(GlBufferType target, long offset, long length, int access); +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceData.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceData.java index 725e023f0..6776c6f56 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceData.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceData.java @@ -1,6 +1,6 @@ package com.jozufozu.flywheel.backend.instancing; -import com.jozufozu.flywheel.backend.gl.MappedBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; public abstract class InstanceData { diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedModel.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedModel.java index 0d6f970d4..57789e637 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedModel.java @@ -9,11 +9,11 @@ import org.lwjgl.opengl.GL11; import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.BufferedModel; import com.jozufozu.flywheel.backend.core.materials.ModelAttributes; -import com.jozufozu.flywheel.backend.gl.GlBuffer; -import com.jozufozu.flywheel.backend.gl.GlBufferType; import com.jozufozu.flywheel.backend.gl.GlVertexArray; -import com.jozufozu.flywheel.backend.gl.MappedBufferRange; import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; +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 net.minecraft.client.renderer.BufferBuilder; @@ -128,9 +128,9 @@ public abstract class InstancedModel extends BufferedMod final int offset = size * getInstanceFormat().getStride(); final int length = glBufferSize - offset; if (length > 0) { - MappedBufferRange buffer = instanceVBO.getBuffer(offset, length); + MappedBuffer buffer = instanceVBO.getBuffer(offset, length); buffer.putByteArray(new byte[length]); - buffer.unmap(); + buffer.flush(); } } @@ -151,14 +151,15 @@ public abstract class InstancedModel extends BufferedMod final int length = (1 + lastDirty - firstDirty) * stride; if (length > 0) { - MappedBufferRange mapped = instanceVBO.getBuffer(offset, length); + MappedBuffer mapped = instanceVBO.getBuffer(offset, length); + dirtySet.stream().forEach(i -> { final D d = data.get(i); - mapped.position(i * stride - offset); + mapped.position(i * stride); d.write(mapped); }); - mapped.unmap(); + mapped.flush(); } } @@ -185,11 +186,11 @@ public abstract class InstancedModel extends BufferedMod glBufferSize = requiredSize + stride * 16; instanceVBO.alloc(glBufferSize); - MappedBufferRange buffer = instanceVBO.getBuffer(0, glBufferSize); + MappedBuffer buffer = instanceVBO.getBuffer(0, glBufferSize); for (D datum : data) { datum.write(buffer); } - buffer.unmap(); + buffer.flush(); glInstanceCount = size; return true; @@ -232,7 +233,7 @@ public abstract class InstancedModel extends BufferedMod } @Override - protected void copyVertex(MappedBufferRange constant, int i) { + protected void copyVertex(MappedBuffer constant, int i) { constant.putFloat(getX(template, i)); constant.putFloat(getY(template, i)); constant.putFloat(getZ(template, i)); diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticData.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticData.java index 1e57ff19b..6d30b973e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticData.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticData.java @@ -1,7 +1,7 @@ package com.simibubi.create.content.contraptions.base; import com.jozufozu.flywheel.backend.core.materials.BasicData; -import com.jozufozu.flywheel.backend.gl.MappedBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.instancing.InstancedModel; import com.simibubi.create.foundation.utility.ColorHelper; diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/RotatingData.java b/src/main/java/com/simibubi/create/content/contraptions/base/RotatingData.java index 044bcd5ca..e75eec62c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/RotatingData.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/RotatingData.java @@ -1,6 +1,6 @@ package com.simibubi.create.content.contraptions.base; -import com.jozufozu.flywheel.backend.gl.MappedBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.instancing.InstancedModel; import net.minecraft.util.Direction; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorData.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorData.java index fb542eb6f..3d44c51ba 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorData.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorData.java @@ -1,6 +1,6 @@ package com.simibubi.create.content.contraptions.components.actors; -import com.jozufozu.flywheel.backend.gl.MappedBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.instancing.InstanceData; import com.jozufozu.flywheel.backend.instancing.InstancedModel; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionModel.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionModel.java index 8ae5ff8f9..6c4d90485 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionModel.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionModel.java @@ -3,11 +3,11 @@ package com.simibubi.create.content.contraptions.components.structureMovement.re import org.lwjgl.opengl.GL20; import com.jozufozu.flywheel.backend.BufferedModel; -import com.jozufozu.flywheel.backend.gl.GlBuffer; -import com.jozufozu.flywheel.backend.gl.GlBufferType; import com.jozufozu.flywheel.backend.gl.GlPrimitiveType; -import com.jozufozu.flywheel.backend.gl.MappedBufferRange; import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; +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 net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.LightTexture; @@ -57,17 +57,17 @@ public class ContraptionModel extends BufferedModel { ebo.bind(); ebo.alloc(indicesSize); - MappedBufferRange indices = ebo.getBuffer(0, indicesSize); + MappedBuffer indices = ebo.getBuffer(0, indicesSize); for (int i = 0; i < vertexCount; i++) { indices.putInt(i); } - indices.unmap(); + indices.flush(); ebo.unbind(); } @Override - protected void copyVertex(MappedBufferRange to, int vertex) { + protected void copyVertex(MappedBuffer to, int vertex) { to.putFloat(getX(template, vertex)); to.putFloat(getY(template, vertex)); to.putFloat(getZ(template, vertex)); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltData.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltData.java index cc444d47b..1d4025831 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltData.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltData.java @@ -1,6 +1,6 @@ package com.simibubi.create.content.contraptions.relays.belt; -import com.jozufozu.flywheel.backend.gl.MappedBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.instancing.InstancedModel; import com.simibubi.create.content.contraptions.base.KineticData; import com.simibubi.create.foundation.block.render.SpriteShiftEntry; diff --git a/src/main/java/com/simibubi/create/content/logistics/block/FlapData.java b/src/main/java/com/simibubi/create/content/logistics/block/FlapData.java index e75a9578e..8b51aca11 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/FlapData.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/FlapData.java @@ -1,7 +1,7 @@ package com.simibubi.create.content.logistics.block; import com.jozufozu.flywheel.backend.core.materials.IFlatLight; -import com.jozufozu.flywheel.backend.gl.MappedBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.instancing.InstanceData; import com.jozufozu.flywheel.backend.instancing.InstancedModel; diff --git a/src/main/java/com/simibubi/create/foundation/render/effects/EffectsHandler.java b/src/main/java/com/simibubi/create/foundation/render/effects/EffectsHandler.java index c3bf3c446..a2ce90c60 100644 --- a/src/main/java/com/simibubi/create/foundation/render/effects/EffectsHandler.java +++ b/src/main/java/com/simibubi/create/foundation/render/effects/EffectsHandler.java @@ -9,11 +9,11 @@ import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL30; import com.jozufozu.flywheel.backend.Backend; -import com.jozufozu.flywheel.backend.gl.GlBuffer; -import com.jozufozu.flywheel.backend.gl.GlBufferType; import com.jozufozu.flywheel.backend.gl.GlPrimitiveType; import com.jozufozu.flywheel.backend.gl.GlVertexArray; -import com.jozufozu.flywheel.backend.gl.MappedBufferRange; +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.util.RenderUtil; import com.simibubi.create.foundation.render.AllProgramSpecs; import com.simibubi.create.foundation.utility.AnimationTickHolder; @@ -81,9 +81,9 @@ public class EffectsHandler { vbo.bind(); vbo.alloc(bufferSize); - MappedBufferRange buffer = vbo.getBuffer(0, bufferSize); + MappedBuffer buffer = vbo.getBuffer(0, bufferSize); buffer.putFloatArray(vertices); - buffer.unmap(); + buffer.flush(); vao.bind(); diff --git a/src/main/java/com/simibubi/create/foundation/render/effects/FilterSphere.java b/src/main/java/com/simibubi/create/foundation/render/effects/FilterSphere.java index 30cacab69..6c9546aef 100644 --- a/src/main/java/com/simibubi/create/foundation/render/effects/FilterSphere.java +++ b/src/main/java/com/simibubi/create/foundation/render/effects/FilterSphere.java @@ -1,6 +1,6 @@ package com.simibubi.create.foundation.render.effects; -import com.jozufozu.flywheel.backend.gl.MappedBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.util.RenderUtil; import net.minecraft.util.math.vector.Matrix4f; diff --git a/src/main/java/com/simibubi/create/foundation/render/effects/SphereFilterProgram.java b/src/main/java/com/simibubi/create/foundation/render/effects/SphereFilterProgram.java index 6986182a0..c04c61c36 100644 --- a/src/main/java/com/simibubi/create/foundation/render/effects/SphereFilterProgram.java +++ b/src/main/java/com/simibubi/create/foundation/render/effects/SphereFilterProgram.java @@ -5,9 +5,9 @@ import java.util.ArrayList; import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL31; -import com.jozufozu.flywheel.backend.gl.GlBuffer; -import com.jozufozu.flywheel.backend.gl.GlBufferType; -import com.jozufozu.flywheel.backend.gl.MappedBufferRange; +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.shader.GlProgram; import net.minecraft.util.ResourceLocation; @@ -81,13 +81,13 @@ public class SphereFilterProgram extends GlProgram { public void uploadFilters(ArrayList filters) { effectsUBO.bind(GlBufferType.ARRAY_BUFFER); - MappedBufferRange buffer = effectsUBO.getBuffer(0, BUFFER_SIZE); + MappedBuffer buffer = effectsUBO.getBuffer(0, BUFFER_SIZE); buffer.putInt(filters.size()) .position(16); filters.forEach(it -> it.write(buffer)); - buffer.unmap(); + buffer.flush(); effectsUBO.unbind(GlBufferType.ARRAY_BUFFER); } From 9ff193946cb268df192db29ef28cf373ba06d83c Mon Sep 17 00:00:00 2001 From: JozsefA Date: Sat, 15 May 2021 16:41:56 -0700 Subject: [PATCH 2/3] Refactor InstancedModel to not rely on inheritance - Instead, MaterialSpecs store the information - RenderMaterials are now generic on InstanceData instead of InstancedModel - RenderMaterials are directly constructed with and store a MaterialSpec --- .../jozufozu/flywheel/backend/Backend.java | 13 +--- .../flywheel/backend/BufferedModel.java | 66 +++++++++-------- .../backend/core/materials/OrientedModel.java | 28 -------- .../core/materials/TransformedModel.java | 28 -------- .../backend/gl/buffer/MappedBuffer.java | 4 +- .../backend/instancing/InstanceFactory.java | 5 ++ .../backend/instancing/InstancedModel.java | 70 ++++++++----------- .../instancing/InstancedTileRenderer.java | 10 +-- .../backend/instancing/MaterialSpec.java | 21 +++--- .../backend/instancing/ModelFactory.java | 8 --- .../backend/instancing/RenderMaterial.java | 54 +++++--------- .../instancing/TileEntityInstance.java | 4 +- .../base/KineticTileInstance.java | 5 +- .../contraptions/base/RotatingData.java | 6 +- .../contraptions/base/RotatingModel.java | 31 -------- .../components/actors/ActorData.java | 6 +- .../components/actors/ActorModel.java | 27 ------- .../components/actors/DrillActorInstance.java | 3 +- .../actors/HarvesterActorInstance.java | 3 +- .../deployer/DeployerActorInstance.java | 3 +- .../components/flywheel/FlyWheelInstance.java | 14 ++-- .../render/ContraptionKineticRenderer.java | 5 +- .../render/ContraptionModel.java | 7 +- .../contraptions/relays/belt/BeltData.java | 6 +- .../relays/belt/BeltInstancedModel.java | 32 --------- .../relays/encased/SplitShaftInstance.java | 2 +- .../relays/gearbox/GearboxInstance.java | 2 +- .../content/logistics/block/FlapModel.java | 27 ------- .../block/mechanicalArm/ArmInstance.java | 2 +- .../block/redstone/AnalogLeverInstance.java | 3 +- .../block/SchematicannonInstance.java | 3 +- .../foundation/render/AllInstanceFormats.java | 39 +++++++++++ .../foundation/render/AllMaterialSpecs.java | 20 ++---- .../render/effects/EffectsHandler.java | 13 ++-- .../render/effects/SphereFilterProgram.java | 4 +- 35 files changed, 195 insertions(+), 379 deletions(-) delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/core/materials/OrientedModel.java delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/core/materials/TransformedModel.java create mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceFactory.java delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/ModelFactory.java delete mode 100644 src/main/java/com/simibubi/create/content/contraptions/base/RotatingModel.java delete mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorModel.java delete mode 100644 src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstancedModel.java delete mode 100644 src/main/java/com/simibubi/create/content/logistics/block/FlapModel.java create mode 100644 src/main/java/com/simibubi/create/foundation/render/AllInstanceFormats.java diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backend.java b/src/main/java/com/jozufozu/flywheel/backend/Backend.java index 83acbe955..beab8e28e 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backend.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backend.java @@ -26,10 +26,9 @@ import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec; import com.jozufozu.flywheel.backend.gl.versioned.GlCompat; import com.jozufozu.flywheel.backend.instancing.IFlywheelWorld; -import com.jozufozu.flywheel.backend.instancing.InstancedModel; +import com.jozufozu.flywheel.backend.instancing.InstanceData; import com.jozufozu.flywheel.backend.instancing.MaterialSpec; import com.jozufozu.flywheel.util.WorldAttached; -import com.simibubi.create.content.contraptions.KineticDebugger; import com.simibubi.create.foundation.config.AllConfigs; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; @@ -131,7 +130,7 @@ public class Backend { /** * Register an instancing material. */ - public static > MaterialSpec register(MaterialSpec spec) { + public static MaterialSpec register(MaterialSpec spec) { ResourceLocation name = spec.name; if (materialRegistry.containsKey(name)) { throw new IllegalStateException("Material spec '" + name + "' already registered."); @@ -275,14 +274,6 @@ public class Backend { return canUseInstancing() && isFlywheelWorld(world); } - /** - * TODO: Remove in favor of separate debug programs specified by the SpecLoader/IMultiProgram - */ - @Deprecated - public static int getDebugMode() { - return KineticDebugger.isActive() ? 1 : 0; - } - public static Collection> allMaterials() { return materialRegistry.values(); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/BufferedModel.java b/src/main/java/com/jozufozu/flywheel/backend/BufferedModel.java index 3f2f959a0..934ba2722 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/BufferedModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/BufferedModel.java @@ -13,16 +13,45 @@ import net.minecraft.client.renderer.BufferBuilder; public abstract class BufferedModel extends TemplateBuffer { + protected final VertexFormat modelFormat; protected GlBuffer modelVBO; - protected boolean removed; + private boolean initialized; // lazy init + private boolean removed; - protected BufferedModel(BufferBuilder buf) { + protected BufferedModel(VertexFormat modelFormat, BufferBuilder buf) { super(buf); - if (vertexCount > 0) init(); + this.modelFormat = modelFormat; + } + + /** + * Renders this model, checking first if there is anything to render. + */ + public final void render() { + if (vertexCount == 0 || removed) return; + + if (!initialized) { + // Lazily acquire resources in order to get around initialization order, as #getTotalShaderAttributeCount + // might depend on fields in subclasses. + init(); + initialized = true; + } + + doRender(); + } + + /** + * Set up any state and make the draw calls. + */ + protected abstract void doRender(); + + public final void delete() { + removed = true; + if (initialized) { + RenderWork.enqueue(this::deleteInternal); + } } protected void init() { - modelVBO = new GlBuffer(GlBufferType.ARRAY_BUFFER); modelVBO.bind(); @@ -31,7 +60,7 @@ public abstract class BufferedModel extends TemplateBuffer { } protected void initModel() { - int stride = getModelFormat().getStride(); + int stride = modelFormat.getStride(); int invariantSize = vertexCount * stride; // allocate the buffer on the gpu @@ -47,40 +76,17 @@ public abstract class BufferedModel extends TemplateBuffer { protected abstract void copyVertex(MappedBuffer to, int index); - protected abstract VertexFormat getModelFormat(); - protected int getTotalShaderAttributeCount() { - return getModelFormat().getShaderAttributeCount(); + return modelFormat.getShaderAttributeCount(); } - /** - * Renders this model, checking first if there is anything to render. - */ - public final void render() { - if (vertexCount == 0 || removed) return; - - doRender(); - } - - /** - * Set up any state and make the draw calls. - */ - protected abstract void doRender(); - protected void setupAttributes() { int numAttributes = getTotalShaderAttributeCount(); for (int i = 0; i <= numAttributes; i++) { GL20.glEnableVertexAttribArray(i); } - getModelFormat().vertexAttribPointers(0); - } - - public final void delete() { - removed = true; - if (vertexCount > 0) { - RenderWork.enqueue(this::deleteInternal); - } + modelFormat.vertexAttribPointers(0); } protected void deleteInternal() { diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/materials/OrientedModel.java b/src/main/java/com/jozufozu/flywheel/backend/core/materials/OrientedModel.java deleted file mode 100644 index 6c5ca0544..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/core/materials/OrientedModel.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.jozufozu.flywheel.backend.core.materials; - -import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; -import com.jozufozu.flywheel.backend.instancing.InstancedModel; -import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer; - -import net.minecraft.client.renderer.BufferBuilder; - -public class OrientedModel extends InstancedModel { - public static final VertexFormat INSTANCE_FORMAT = VertexFormat.builder() - .addAttributes(BasicAttributes.class) - .addAttributes(OrientedAttributes.class) - .build(); - - public OrientedModel(InstancedTileRenderer renderer, BufferBuilder buf) { - super(renderer, buf); - } - - @Override - protected OrientedData newInstance() { - return new OrientedData(this); - } - - @Override - protected VertexFormat getInstanceFormat() { - return INSTANCE_FORMAT; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/materials/TransformedModel.java b/src/main/java/com/jozufozu/flywheel/backend/core/materials/TransformedModel.java deleted file mode 100644 index 4d848b2e9..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/core/materials/TransformedModel.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.jozufozu.flywheel.backend.core.materials; - -import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; -import com.jozufozu.flywheel.backend.instancing.InstancedModel; -import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer; - -import net.minecraft.client.renderer.BufferBuilder; - -public class TransformedModel extends InstancedModel { - public static final VertexFormat INSTANCE_FORMAT = VertexFormat.builder() - .addAttributes(BasicAttributes.class) - .addAttributes(TransformAttributes.class) - .build(); - - public TransformedModel(InstancedTileRenderer renderer, BufferBuilder buf) { - super(renderer, buf); - } - - @Override - protected ModelData newInstance() { - return new ModelData(this); - } - - @Override - protected VertexFormat getInstanceFormat() { - return INSTANCE_FORMAT; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java index eace56477..16de2eb1e 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java @@ -20,6 +20,9 @@ public abstract class MappedBuffer implements AutoCloseable { protected abstract void checkAndMap(); + /** + * Make the changes in client memory available to the GPU. + */ public void flush() { if (mapped) { GL15.glUnmapBuffer(owner.type.glEnum); @@ -51,7 +54,6 @@ public abstract class MappedBuffer implements AutoCloseable { /** * Position this buffer relative to the 0-index in GPU memory. * - * @param p * @return This buffer. */ public MappedBuffer position(int p) { diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceFactory.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceFactory.java new file mode 100644 index 000000000..533b63af9 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceFactory.java @@ -0,0 +1,5 @@ +package com.jozufozu.flywheel.backend.instancing; + +public interface InstanceFactory { + D create(InstancedModel owner); +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedModel.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedModel.java index 57789e637..9409e4edf 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedModel.java @@ -17,11 +17,13 @@ import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import net.minecraft.client.renderer.BufferBuilder; -public abstract class InstancedModel extends BufferedModel { +public class InstancedModel extends BufferedModel { public static final VertexFormat FORMAT = VertexFormat.builder().addAttributes(ModelAttributes.class).build(); public final InstancedTileRenderer renderer; + protected final VertexFormat instanceFormat; + protected final InstanceFactory factory; protected GlVertexArray vao; protected GlBuffer instanceVBO; protected int glBufferSize = -1; @@ -32,11 +34,22 @@ public abstract class InstancedModel extends BufferedMod boolean anyToRemove; boolean anyToUpdate; - public InstancedModel(InstancedTileRenderer renderer, BufferBuilder buf) { - super(buf); + public InstancedModel(InstancedTileRenderer renderer, VertexFormat instanceFormat, InstanceFactory factory, BufferBuilder buf) { + super(FORMAT, buf); + this.factory = factory; + this.instanceFormat = instanceFormat; this.renderer = renderer; } + public synchronized D createInstance() { + D instanceData = factory.create(this); + instanceData.dirty = true; + anyToUpdate = true; + data.add(instanceData); + + return instanceData; + } + @Override protected void init() { vao = new GlVertexArray(); @@ -53,14 +66,6 @@ public abstract class InstancedModel extends BufferedMod setupAttributes(); } - public int instanceCount() { - return data.size(); - } - - public boolean isEmpty() { - return instanceCount() == 0; - } - protected void deleteInternal() { super.deleteInternal(); @@ -68,23 +73,13 @@ public abstract class InstancedModel extends BufferedMod vao.delete(); } - public synchronized D createInstance() { - D instanceData = newInstance(); - instanceData.dirty = true; - anyToUpdate = true; - data.add(instanceData); - - return instanceData; - } - - protected abstract D newInstance(); - protected void doRender() { vao.bind(); renderSetup(); if (glInstanceCount > 0) Backend.compat.drawInstanced.drawArraysInstanced(GL11.GL_QUADS, 0, vertexCount, glInstanceCount); + vao.unbind(); } @@ -115,22 +110,22 @@ public abstract class InstancedModel extends BufferedMod } private void informAttribDivisors() { - int staticAttributes = getModelFormat().getShaderAttributeCount(); - getInstanceFormat().vertexAttribPointers(staticAttributes); + int staticAttributes = modelFormat.getShaderAttributeCount(); + instanceFormat.vertexAttribPointers(staticAttributes); - for (int i = 0; i < getInstanceFormat().getShaderAttributeCount(); i++) { + for (int i = 0; i < instanceFormat.getShaderAttributeCount(); i++) { Backend.compat.instancedArrays.vertexAttribDivisor(i + staticAttributes, 1); } } private void clearBufferTail() { int size = data.size(); - final int offset = size * getInstanceFormat().getStride(); + final int offset = size * instanceFormat.getStride(); final int length = glBufferSize - offset; if (length > 0) { - MappedBuffer buffer = instanceVBO.getBuffer(offset, length); - buffer.putByteArray(new byte[length]); - buffer.flush(); + instanceVBO.getBuffer(offset, length) + .putByteArray(new byte[length]) + .flush(); } } @@ -139,7 +134,7 @@ public abstract class InstancedModel extends BufferedMod if (size <= 0) return; - final int stride = getInstanceFormat().getStride(); + final int stride = instanceFormat.getStride(); final BitSet dirtySet = getDirtyBitSet(); if (dirtySet.isEmpty()) return; @@ -180,7 +175,7 @@ public abstract class InstancedModel extends BufferedMod private boolean realloc() { int size = this.data.size(); - int stride = getInstanceFormat().getStride(); + int stride = instanceFormat.getStride(); int requiredSize = size * stride; if (requiredSize > glBufferSize) { glBufferSize = requiredSize + stride * 16; @@ -199,9 +194,7 @@ public abstract class InstancedModel extends BufferedMod } private void removeDeletedInstances() { - // figure out which elements are to be removed - // any exception thrown from the filter predicate at this stage - // will leave the collection unmodified + // Figure out which elements are to be removed. final int oldSize = this.data.size(); int removeCount = 0; final BitSet removeSet = new BitSet(oldSize); @@ -246,14 +239,7 @@ public abstract class InstancedModel extends BufferedMod constant.putFloat(getV(template, i)); } - @Override - protected VertexFormat getModelFormat() { - return FORMAT; - } - - protected abstract VertexFormat getInstanceFormat(); - protected int getTotalShaderAttributeCount() { - return getInstanceFormat().getShaderAttributeCount() + super.getTotalShaderAttributeCount(); + return instanceFormat.getShaderAttributeCount() + super.getTotalShaderAttributeCount(); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedTileRenderer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedTileRenderer.java index 61183820e..04a3646fc 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedTileRenderer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedTileRenderer.java @@ -46,7 +46,7 @@ public abstract class InstancedTileRenderer

{ materials = new HashMap<>(); for (MaterialSpec spec : Backend.allMaterials()) { - materials.put(spec, spec.create(this)); + materials.put(spec, new RenderMaterial<>(this, spec)); } queuedUpdates = ConcurrentHashMap.newKeySet(64); @@ -137,15 +137,15 @@ public abstract class InstancedTileRenderer

{ } @SuppressWarnings("unchecked") - public > RenderMaterial getMaterial(MaterialSpec materialType) { - return (RenderMaterial) materials.get(materialType); + public RenderMaterial getMaterial(MaterialSpec materialType) { + return (RenderMaterial) materials.get(materialType); } - public RenderMaterial> getTransformMaterial() { + public RenderMaterial getTransformMaterial() { return getMaterial(AllMaterialSpecs.TRANSFORMED); } - public RenderMaterial> getOrientedMaterial() { + public RenderMaterial getOrientedMaterial() { return getMaterial(AllMaterialSpecs.ORIENTED); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/MaterialSpec.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/MaterialSpec.java index 8e319f98d..565cf5d41 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/MaterialSpec.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/MaterialSpec.java @@ -1,32 +1,35 @@ package com.jozufozu.flywheel.backend.instancing; -import com.jozufozu.flywheel.backend.core.BasicProgram; +import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec; import net.minecraft.util.ResourceLocation; -public class MaterialSpec> { +public class MaterialSpec { public final ResourceLocation name; private final ProgramSpec programSpec; - private final ModelFactory modelFactory; + private final VertexFormat instanceFormat; + private final InstanceFactory instanceFactory; - public MaterialSpec(ResourceLocation name, ProgramSpec programSpec, ModelFactory modelFactory) { + public MaterialSpec(ResourceLocation name, ProgramSpec programSpec, VertexFormat instanceFormat, InstanceFactory instanceFactory) { this.name = name; this.programSpec = programSpec; - this.modelFactory = modelFactory; + this.instanceFormat = instanceFormat; + this.instanceFactory = instanceFactory; } public ProgramSpec getProgramSpec() { return programSpec; } - public ModelFactory getModelFactory() { - return modelFactory; + public VertexFormat getInstanceFormat() { + return instanceFormat; } - public

RenderMaterial create(InstancedTileRenderer

renderer) { - return new RenderMaterial<>(renderer, programSpec, modelFactory); + public InstanceFactory getInstanceFactory() { + return instanceFactory; } + } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/ModelFactory.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/ModelFactory.java deleted file mode 100644 index 74edfc7b4..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/ModelFactory.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.jozufozu.flywheel.backend.instancing; - -import net.minecraft.client.renderer.BufferBuilder; - -@FunctionalInterface -public interface ModelFactory> { - B makeModel(InstancedTileRenderer renderer, BufferBuilder buf); -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/RenderMaterial.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/RenderMaterial.java index f3994d105..7ce543169 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/RenderMaterial.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/RenderMaterial.java @@ -3,7 +3,6 @@ package com.jozufozu.flywheel.backend.instancing; import java.util.Arrays; import java.util.concurrent.ExecutionException; import java.util.function.Consumer; -import java.util.function.Predicate; import java.util.function.Supplier; import org.apache.commons.lang3.tuple.Pair; @@ -13,7 +12,6 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.jozufozu.flywheel.backend.core.BasicProgram; import com.jozufozu.flywheel.backend.core.PartialModel; -import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec; import com.jozufozu.flywheel.backend.gl.shader.ShaderCallback; import com.jozufozu.flywheel.util.RenderUtil; import com.jozufozu.flywheel.util.VirtualEmptyModelData; @@ -32,33 +30,19 @@ import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Matrix4f; -public class RenderMaterial

> { +public class RenderMaterial

{ protected final InstancedTileRenderer

renderer; - protected final Cache models; - protected final ModelFactory factory; - protected final ProgramSpec programSpec; - protected final Predicate layerPredicate; + protected final Cache> models; + protected final MaterialSpec spec; - /** - * Creates a material that renders in the default layer (CUTOUT_MIPPED) - */ - public RenderMaterial(InstancedTileRenderer

renderer, ProgramSpec programSpec, ModelFactory factory) { - this(renderer, programSpec, factory, type -> type == RenderType.getCutoutMipped()); - } - - public RenderMaterial(InstancedTileRenderer

renderer, ProgramSpec programSpec, ModelFactory factory, Predicate layerPredicate) { + public RenderMaterial(InstancedTileRenderer

renderer, MaterialSpec spec) { this.renderer = renderer; + this.spec = spec; + this.models = CacheBuilder.newBuilder() .removalListener(notification -> ((InstancedModel) notification.getValue()).delete()) .build(); - this.factory = factory; - this.programSpec = programSpec; - this.layerPredicate = layerPredicate; - } - - public boolean canRenderInLayer(RenderType layer) { - return layerPredicate.test(layer); } public void render(RenderType layer, Matrix4f projection, double camX, double camY, double camZ) { @@ -66,9 +50,9 @@ public class RenderMaterial

setup) { - if (!canRenderInLayer(layer)) return; + if (!(layer == RenderType.getCutoutMipped())) return; - P program = renderer.context.getProgram(programSpec); + P program = renderer.context.getProgram(this.spec.getProgramSpec()); program.bind(); program.uploadViewProjection(viewProjection); program.uploadCameraPos(camX, camY, camZ); @@ -87,30 +71,30 @@ public class RenderMaterial

f) { - for (MODEL model : models.asMap().values()) { + public void runOnAll(Consumer> f) { + for (InstancedModel model : models.asMap().values()) { f.accept(model); } } - public MODEL getModel(PartialModel partial, BlockState referenceState) { + public InstancedModel getModel(PartialModel partial, BlockState referenceState) { return get(partial, () -> buildModel(partial.get(), referenceState)); } - public MODEL getModel(PartialModel partial, BlockState referenceState, Direction dir) { + public InstancedModel getModel(PartialModel partial, BlockState referenceState, Direction dir) { return getModel(partial, referenceState, dir, RenderUtil.rotateToFace(dir)); } - public MODEL getModel(PartialModel partial, BlockState referenceState, Direction dir, Supplier modelTransform) { + public InstancedModel getModel(PartialModel partial, BlockState referenceState, Direction dir, Supplier modelTransform) { return get(Pair.of(dir, partial), () -> buildModel(partial.get(), referenceState, modelTransform.get())); } - public MODEL getModel(BlockState toRender) { + public InstancedModel getModel(BlockState toRender) { return get(toRender, () -> buildModel(toRender)); } - public MODEL get(Object key, Supplier supplier) { + public InstancedModel get(Object key, Supplier> supplier) { try { return models.get(key, supplier::get); } catch (ExecutionException e) { @@ -119,19 +103,19 @@ public class RenderMaterial

buildModel(BlockState renderedState) { BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher(); return buildModel(dispatcher.getModelForState(renderedState), renderedState); } - private MODEL buildModel(IBakedModel model, BlockState renderedState) { + private InstancedModel buildModel(IBakedModel model, BlockState renderedState) { return buildModel(model, renderedState, new MatrixStack()); } - private MODEL buildModel(IBakedModel model, BlockState referenceState, MatrixStack ms) { + private InstancedModel buildModel(IBakedModel model, BlockState referenceState, MatrixStack ms) { BufferBuilder builder = getBufferBuilder(model, referenceState, ms); - return factory.makeModel(renderer, builder); + return new InstancedModel<>(renderer, spec.getInstanceFormat(), spec.getInstanceFactory(), builder); } private static final Direction[] dirs; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/TileEntityInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/TileEntityInstance.java index bec358be7..bc7e8f4d2 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/TileEntityInstance.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/TileEntityInstance.java @@ -117,11 +117,11 @@ public abstract class TileEntityInstance implements IInsta models.forEach(model -> model.setBlockLight(block).setSkyLight(sky)); } - protected RenderMaterial> getTransformMaterial() { + protected RenderMaterial getTransformMaterial() { return renderer.getTransformMaterial(); } - protected RenderMaterial> getOrientedMaterial() { + protected RenderMaterial getOrientedMaterial() { return renderer.getOrientedMaterial(); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java index 5bf761651..3525e9417 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java @@ -1,6 +1,5 @@ package com.simibubi.create.content.contraptions.base; -import com.jozufozu.flywheel.backend.instancing.InstancedModel; import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer; import com.jozufozu.flywheel.backend.instancing.RenderMaterial; import com.jozufozu.flywheel.backend.instancing.TileEntityInstance; @@ -85,9 +84,9 @@ public abstract class KineticTileInstance extends T return shaft(getRotationAxis()); } - protected final RenderMaterial> getRotatingMaterial() { + protected final RenderMaterial getRotatingMaterial() { return renderer.getMaterial(AllMaterialSpecs.ROTATING); - } + } public static BlockState shaft(Direction.Axis axis) { return AllBlocks.SHAFT.getDefaultState() diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/RotatingData.java b/src/main/java/com/simibubi/create/content/contraptions/base/RotatingData.java index e75eec62c..ef59d938e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/RotatingData.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/RotatingData.java @@ -11,9 +11,9 @@ public class RotatingData extends KineticData { private byte rotationAxisY; private byte rotationAxisZ; - protected RotatingData(InstancedModel owner) { - super(owner); - } + public RotatingData(InstancedModel owner) { + super(owner); + } public RotatingData setRotationAxis(Direction.Axis axis) { Direction orientation = Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis); diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/RotatingModel.java b/src/main/java/com/simibubi/create/content/contraptions/base/RotatingModel.java deleted file mode 100644 index 5eaadbc5a..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/base/RotatingModel.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.simibubi.create.content.contraptions.base; - -import com.jozufozu.flywheel.backend.core.materials.BasicAttributes; -import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; -import com.jozufozu.flywheel.backend.instancing.InstancedModel; -import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer; - -import net.minecraft.client.renderer.BufferBuilder; - -public class RotatingModel extends InstancedModel { - public static VertexFormat FORMAT = VertexFormat.builder() - .addAttributes(BasicAttributes.class) - .addAttributes(KineticAttributes.class) - .addAttributes(RotatingAttributes.class) - .build(); - - public RotatingModel(InstancedTileRenderer renderer, BufferBuilder buf) { - super(renderer, buf); - } - - @Override - protected RotatingData newInstance() { - return new RotatingData(this); - } - - @Override - protected VertexFormat getInstanceFormat() { - return FORMAT; - } - -} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorData.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorData.java index 3d44c51ba..0d993e316 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorData.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorData.java @@ -28,9 +28,9 @@ public class ActorData extends InstanceData { private float speed; - protected ActorData(InstancedModel owner) { - super(owner); - } + public ActorData(InstancedModel owner) { + super(owner); + } public ActorData setPosition(BlockPos pos) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorModel.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorModel.java deleted file mode 100644 index 9010ba9ca..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorModel.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.simibubi.create.content.contraptions.components.actors; - -import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; -import com.jozufozu.flywheel.backend.instancing.InstancedModel; -import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer; - -import net.minecraft.client.renderer.BufferBuilder; - -public class ActorModel extends InstancedModel { - public static VertexFormat FORMAT = VertexFormat.builder() - .addAttributes(ActorVertexAttributes.class) - .build(); - - public ActorModel(InstancedTileRenderer renderer, BufferBuilder buf) { - super(renderer, buf); - } - - @Override - protected VertexFormat getInstanceFormat() { - return FORMAT; - } - - @Override - protected ActorData newInstance() { - return new ActorData(this); - } -} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillActorInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillActorInstance.java index 517e4fcdb..e0dd37923 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillActorInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillActorInstance.java @@ -1,6 +1,5 @@ package com.simibubi.create.content.contraptions.components.actors; -import com.jozufozu.flywheel.backend.instancing.InstancedModel; import com.jozufozu.flywheel.backend.instancing.RenderMaterial; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; @@ -21,7 +20,7 @@ public class DrillActorInstance extends ActorInstance { public DrillActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) { super(modelManager, context); - RenderMaterial> renderMaterial = modelManager.getActorMaterial(); + RenderMaterial renderMaterial = modelManager.getActorMaterial(); BlockState state = context.state; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterActorInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterActorInstance.java index 60dfede9b..e04fa94a8 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterActorInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterActorInstance.java @@ -3,7 +3,6 @@ package com.simibubi.create.content.contraptions.components.actors; import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING; import com.jozufozu.flywheel.backend.core.materials.ModelData; -import com.jozufozu.flywheel.backend.instancing.InstancedModel; import com.jozufozu.flywheel.backend.instancing.RenderMaterial; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; @@ -36,7 +35,7 @@ public class HarvesterActorInstance extends ActorInstance { public HarvesterActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) { super(modelManager, context); - RenderMaterial> renderMaterial = modelManager.getTransformMaterial(); + RenderMaterial renderMaterial = modelManager.getTransformMaterial(); BlockState state = context.state; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerActorInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerActorInstance.java index 544fbf41f..94b874fca 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerActorInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerActorInstance.java @@ -5,7 +5,6 @@ import static com.simibubi.create.content.contraptions.base.DirectionalKineticBl import com.jozufozu.flywheel.backend.core.PartialModel; import com.jozufozu.flywheel.backend.core.materials.ModelData; -import com.jozufozu.flywheel.backend.instancing.InstancedModel; import com.jozufozu.flywheel.backend.instancing.RenderMaterial; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; @@ -45,7 +44,7 @@ public class DeployerActorInstance extends ActorInstance { public DeployerActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) { super(modelManager, context); - RenderMaterial> mat = modelManager.getTransformMaterial(); + RenderMaterial mat = modelManager.getTransformMaterial(); BlockState state = context.state; DeployerTileEntity.Mode mode = NBTHelper.readEnum(context.tileData, "Mode", DeployerTileEntity.Mode.class); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java index 96627328b..ef6f69d5b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java @@ -63,15 +63,15 @@ public class FlyWheelInstance extends KineticTileInstance im connectorAngleMult = flipAngle ? -1 : 1; - RenderMaterial> mat = getTransformMaterial(); + RenderMaterial mat = getTransformMaterial(); - upperRotating = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_ROTATING, blockState).createInstance(); - lowerRotating = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_ROTATING, blockState).createInstance(); - upperSliding = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_SLIDING, blockState).createInstance(); - lowerSliding = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_SLIDING, blockState).createInstance(); + upperRotating = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_ROTATING, blockState).createInstance(); + lowerRotating = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_ROTATING, blockState).createInstance(); + upperSliding = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_SLIDING, blockState).createInstance(); + lowerSliding = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_SLIDING, blockState).createInstance(); - connectors = Lists.newArrayList(upperRotating, lowerRotating, upperSliding, lowerSliding); - } else { + connectors = Lists.newArrayList(upperRotating, lowerRotating, upperSliding, lowerSliding); + } else { connectors = Collections.emptyList(); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java index 821cce83e..a65f178fa 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java @@ -7,7 +7,6 @@ import javax.annotation.Nullable; import org.apache.commons.lang3.tuple.Pair; -import com.jozufozu.flywheel.backend.instancing.InstancedModel; import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer; import com.jozufozu.flywheel.backend.instancing.RenderMaterial; import com.simibubi.create.AllMovementBehaviours; @@ -65,9 +64,9 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer> getActorMaterial() { + public RenderMaterial getActorMaterial() { return getMaterial(AllMaterialSpecs.ACTORS); - } + } public RenderedContraption getContraption() { return contraption.get(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionModel.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionModel.java index 6c4d90485..acdca2f9f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionModel.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionModel.java @@ -21,7 +21,7 @@ public class ContraptionModel extends BufferedModel { protected GlBuffer ebo; public ContraptionModel(BufferBuilder buf) { - super(buf); + super(FORMAT, buf); } @Override @@ -93,11 +93,6 @@ public class ContraptionModel extends BufferedModel { to.put(sky); } - @Override - protected VertexFormat getModelFormat() { - return FORMAT; - } - @Override protected void deleteInternal() { super.deleteInternal(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltData.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltData.java index 1d4025831..29264554a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltData.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltData.java @@ -21,9 +21,9 @@ public class BeltData extends KineticData { private float maxV; private byte scrollMult; - protected BeltData(InstancedModel owner) { - super(owner); - } + public BeltData(InstancedModel owner) { + super(owner); + } public BeltData setRotation(Quaternion q) { this.qX = q.getX(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstancedModel.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstancedModel.java deleted file mode 100644 index 58dc8e651..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstancedModel.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.simibubi.create.content.contraptions.relays.belt; - -import com.jozufozu.flywheel.backend.core.materials.BasicAttributes; -import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; -import com.jozufozu.flywheel.backend.instancing.InstancedModel; -import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer; -import com.simibubi.create.content.contraptions.base.KineticAttributes; - -import net.minecraft.client.renderer.BufferBuilder; - -public class BeltInstancedModel extends InstancedModel { - public static VertexFormat FORMAT = VertexFormat.builder() - .addAttributes(BasicAttributes.class) - .addAttributes(KineticAttributes.class) - .addAttributes(BeltAttributes.class) - .build(); - - public BeltInstancedModel(InstancedTileRenderer renderer, BufferBuilder buf) { - super(renderer, buf); - } - - @Override - protected BeltData newInstance() { - return new BeltData(this); - } - - @Override - protected VertexFormat getInstanceFormat() { - return FORMAT; - } - -} diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java index a2847452d..39596f241 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java @@ -26,7 +26,7 @@ public class SplitShaftInstance extends KineticTileInstance> rotatingMaterial = getRotatingMaterial(); + RenderMaterial rotatingMaterial = getRotatingMaterial(); for (Direction dir : Iterate.directionsInAxis(getRotationAxis())) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java index 747c6a9ec..cf85386ac 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java @@ -33,7 +33,7 @@ public class GearboxInstance extends KineticTileInstance { int skyLight = world.getLightLevel(LightType.SKY, pos); updateSourceFacing(); - RenderMaterial> rotatingMaterial = getRotatingMaterial(); + RenderMaterial rotatingMaterial = getRotatingMaterial(); for (Direction direction : Iterate.directions) { final Direction.Axis axis = direction.getAxis(); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/FlapModel.java b/src/main/java/com/simibubi/create/content/logistics/block/FlapModel.java deleted file mode 100644 index 42aeb46f5..000000000 --- a/src/main/java/com/simibubi/create/content/logistics/block/FlapModel.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.simibubi.create.content.logistics.block; - -import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; -import com.jozufozu.flywheel.backend.instancing.InstancedModel; -import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer; - -import net.minecraft.client.renderer.BufferBuilder; - -public class FlapModel extends InstancedModel { - public static VertexFormat FORMAT = VertexFormat.builder() - .addAttributes(FlapAttributes.class) - .build(); - - public FlapModel(InstancedTileRenderer renderer, BufferBuilder buf) { - super(renderer, buf); - } - - @Override - protected FlapData newInstance() { - return new FlapData(this); - } - - @Override - protected VertexFormat getInstanceFormat() { - return FORMAT; - } -} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java index 455659db6..42912a6a2 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java @@ -47,7 +47,7 @@ public class ArmInstance extends SingleRotatingInstance implements IDynamicInsta public ArmInstance(InstancedTileRenderer modelManager, ArmTileEntity tile) { super(modelManager, tile); - RenderMaterial> mat = getTransformMaterial(); + RenderMaterial mat = getTransformMaterial(); base = mat.getModel(AllBlockPartials.ARM_BASE, blockState).createInstance(); lowerBody = mat.getModel(AllBlockPartials.ARM_LOWER_BODY, blockState).createInstance(); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java index 995952c78..705fde20f 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java @@ -2,7 +2,6 @@ package com.simibubi.create.content.logistics.block.redstone; import com.jozufozu.flywheel.backend.core.materials.ModelData; import com.jozufozu.flywheel.backend.instancing.IDynamicInstance; -import com.jozufozu.flywheel.backend.instancing.InstancedModel; import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer; import com.jozufozu.flywheel.backend.instancing.RenderMaterial; import com.jozufozu.flywheel.backend.instancing.TileEntityInstance; @@ -27,7 +26,7 @@ public class AnalogLeverInstance extends TileEntityInstance modelManager, AnalogLeverTileEntity tile) { super(modelManager, tile); - RenderMaterial> mat = getTransformMaterial(); + RenderMaterial mat = getTransformMaterial(); handle = mat.getModel(AllBlockPartials.ANALOG_LEVER_HANDLE, blockState).createInstance(); indicator = mat.getModel(AllBlockPartials.ANALOG_LEVER_INDICATOR, blockState).createInstance(); diff --git a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonInstance.java b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonInstance.java index 0a011f316..9568583db 100644 --- a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonInstance.java +++ b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonInstance.java @@ -2,7 +2,6 @@ package com.simibubi.create.content.schematics.block; import com.jozufozu.flywheel.backend.core.materials.ModelData; import com.jozufozu.flywheel.backend.instancing.IDynamicInstance; -import com.jozufozu.flywheel.backend.instancing.InstancedModel; import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer; import com.jozufozu.flywheel.backend.instancing.RenderMaterial; import com.jozufozu.flywheel.backend.instancing.TileEntityInstance; @@ -21,7 +20,7 @@ public class SchematicannonInstance extends TileEntityInstance modelManager, SchematicannonTileEntity tile) { super(modelManager, tile); - RenderMaterial> mat = getTransformMaterial(); + RenderMaterial mat = getTransformMaterial(); connector = mat.getModel(AllBlockPartials.SCHEMATICANNON_CONNECTOR, blockState).createInstance(); pipe = mat.getModel(AllBlockPartials.SCHEMATICANNON_PIPE, blockState).createInstance(); diff --git a/src/main/java/com/simibubi/create/foundation/render/AllInstanceFormats.java b/src/main/java/com/simibubi/create/foundation/render/AllInstanceFormats.java new file mode 100644 index 000000000..70c2bf3e6 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/AllInstanceFormats.java @@ -0,0 +1,39 @@ +package com.simibubi.create.foundation.render; + +import com.jozufozu.flywheel.backend.core.materials.BasicAttributes; +import com.jozufozu.flywheel.backend.core.materials.OrientedAttributes; +import com.jozufozu.flywheel.backend.core.materials.TransformAttributes; +import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; +import com.simibubi.create.content.contraptions.base.KineticAttributes; +import com.simibubi.create.content.contraptions.base.RotatingAttributes; +import com.simibubi.create.content.contraptions.components.actors.ActorVertexAttributes; +import com.simibubi.create.content.contraptions.relays.belt.BeltAttributes; +import com.simibubi.create.content.logistics.block.FlapAttributes; + +public class AllInstanceFormats { + + public static final VertexFormat MODEL = VertexFormat.builder() + .addAttributes(BasicAttributes.class) + .addAttributes(TransformAttributes.class) + .build(); + public static final VertexFormat ORIENTED = VertexFormat.builder() + .addAttributes(BasicAttributes.class) + .addAttributes(OrientedAttributes.class) + .build(); + public static VertexFormat ROTATING = VertexFormat.builder() + .addAttributes(BasicAttributes.class) + .addAttributes(KineticAttributes.class) + .addAttributes(RotatingAttributes.class) + .build(); + public static VertexFormat ACTOR = VertexFormat.builder() + .addAttributes(ActorVertexAttributes.class) + .build(); + public static VertexFormat BELT = VertexFormat.builder() + .addAttributes(BasicAttributes.class) + .addAttributes(KineticAttributes.class) + .addAttributes(BeltAttributes.class) + .build(); + public static VertexFormat FLAP = VertexFormat.builder() + .addAttributes(FlapAttributes.class) + .build(); +} diff --git a/src/main/java/com/simibubi/create/foundation/render/AllMaterialSpecs.java b/src/main/java/com/simibubi/create/foundation/render/AllMaterialSpecs.java index 662fb707b..a26402155 100644 --- a/src/main/java/com/simibubi/create/foundation/render/AllMaterialSpecs.java +++ b/src/main/java/com/simibubi/create/foundation/render/AllMaterialSpecs.java @@ -4,19 +4,12 @@ import static com.jozufozu.flywheel.backend.Backend.register; import com.jozufozu.flywheel.backend.core.materials.ModelData; import com.jozufozu.flywheel.backend.core.materials.OrientedData; -import com.jozufozu.flywheel.backend.core.materials.OrientedModel; -import com.jozufozu.flywheel.backend.core.materials.TransformedModel; -import com.jozufozu.flywheel.backend.instancing.InstancedModel; import com.jozufozu.flywheel.backend.instancing.MaterialSpec; import com.simibubi.create.Create; import com.simibubi.create.content.contraptions.base.RotatingData; -import com.simibubi.create.content.contraptions.base.RotatingModel; import com.simibubi.create.content.contraptions.components.actors.ActorData; -import com.simibubi.create.content.contraptions.components.actors.ActorModel; import com.simibubi.create.content.contraptions.relays.belt.BeltData; -import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel; import com.simibubi.create.content.logistics.block.FlapData; -import com.simibubi.create.content.logistics.block.FlapModel; import net.minecraft.util.ResourceLocation; @@ -25,14 +18,13 @@ public class AllMaterialSpecs { // noop, make sure the static field are loaded. } + public static final MaterialSpec TRANSFORMED = register(new MaterialSpec<>(Locations.MODEL, AllProgramSpecs.MODEL, AllInstanceFormats.MODEL, ModelData::new)); + public static final MaterialSpec ORIENTED = register(new MaterialSpec<>(Locations.ORIENTED, AllProgramSpecs.ORIENTED, AllInstanceFormats.ORIENTED, OrientedData::new)); - public static final MaterialSpec> TRANSFORMED = register(new MaterialSpec<>(Locations.MODEL, AllProgramSpecs.MODEL, TransformedModel::new)); - public static final MaterialSpec> ORIENTED = register(new MaterialSpec<>(Locations.ORIENTED, AllProgramSpecs.ORIENTED, OrientedModel::new)); - - public static final MaterialSpec> ROTATING = register(new MaterialSpec<>(Locations.ROTATING, AllProgramSpecs.ROTATING, RotatingModel::new)); - public static final MaterialSpec> BELTS = register(new MaterialSpec<>(Locations.BELTS, AllProgramSpecs.BELT, BeltInstancedModel::new)); - public static final MaterialSpec> ACTORS = register(new MaterialSpec<>(Locations.ACTORS, AllProgramSpecs.ACTOR, ActorModel::new)); - public static final MaterialSpec> FLAPS = register(new MaterialSpec<>(Locations.FLAPS, AllProgramSpecs.FLAPS, FlapModel::new)); + public static final MaterialSpec ROTATING = register(new MaterialSpec<>(Locations.ROTATING, AllProgramSpecs.ROTATING, AllInstanceFormats.ROTATING, RotatingData::new)); + public static final MaterialSpec BELTS = register(new MaterialSpec<>(Locations.BELTS, AllProgramSpecs.BELT, AllInstanceFormats.BELT, BeltData::new)); + public static final MaterialSpec ACTORS = register(new MaterialSpec<>(Locations.ACTORS, AllProgramSpecs.ACTOR, AllInstanceFormats.ACTOR, ActorData::new)); + public static final MaterialSpec FLAPS = register(new MaterialSpec<>(Locations.FLAPS, AllProgramSpecs.FLAPS, AllInstanceFormats.FLAP, FlapData::new)); public static class Locations { public static final ResourceLocation MODEL = new ResourceLocation("create", "model"); diff --git a/src/main/java/com/simibubi/create/foundation/render/effects/EffectsHandler.java b/src/main/java/com/simibubi/create/foundation/render/effects/EffectsHandler.java index a2ce90c60..eae45b987 100644 --- a/src/main/java/com/simibubi/create/foundation/render/effects/EffectsHandler.java +++ b/src/main/java/com/simibubi/create/foundation/render/effects/EffectsHandler.java @@ -13,7 +13,6 @@ import com.jozufozu.flywheel.backend.gl.GlPrimitiveType; import com.jozufozu.flywheel.backend.gl.GlVertexArray; import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; -import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.util.RenderUtil; import com.simibubi.create.foundation.render.AllProgramSpecs; import com.simibubi.create.foundation.utility.AnimationTickHolder; @@ -67,9 +66,9 @@ public class EffectsHandler { private static final int bufferSize = vertices.length * 4; private final Framebuffer framebuffer; - private final GlVertexArray vao = new GlVertexArray(); + private final GlVertexArray vao; - private final GlBuffer vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER); + private final GlBuffer vbo; private final ArrayList spheres; @@ -79,12 +78,14 @@ public class EffectsHandler { Framebuffer render = Minecraft.getInstance().getFramebuffer(); framebuffer = new Framebuffer(render.framebufferWidth, render.framebufferHeight, false, Minecraft.IS_RUNNING_ON_MAC); + vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER); vbo.bind(); vbo.alloc(bufferSize); - MappedBuffer buffer = vbo.getBuffer(0, bufferSize); - buffer.putFloatArray(vertices); - buffer.flush(); + vbo.getBuffer(0, bufferSize) + .putFloatArray(vertices) + .flush(); + vao = new GlVertexArray(); vao.bind(); GL20.glEnableVertexAttribArray(0); diff --git a/src/main/java/com/simibubi/create/foundation/render/effects/SphereFilterProgram.java b/src/main/java/com/simibubi/create/foundation/render/effects/SphereFilterProgram.java index c04c61c36..a431579b2 100644 --- a/src/main/java/com/simibubi/create/foundation/render/effects/SphereFilterProgram.java +++ b/src/main/java/com/simibubi/create/foundation/render/effects/SphereFilterProgram.java @@ -81,8 +81,8 @@ public class SphereFilterProgram extends GlProgram { public void uploadFilters(ArrayList filters) { effectsUBO.bind(GlBufferType.ARRAY_BUFFER); - MappedBuffer buffer = effectsUBO.getBuffer(0, BUFFER_SIZE); - buffer.putInt(filters.size()) + MappedBuffer buffer = effectsUBO.getBuffer(0, BUFFER_SIZE) + .putInt(filters.size()) .position(16); filters.forEach(it -> it.write(buffer)); From 6227e81066630f77c4699bc0d691b57dce4e0600 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Sun, 16 May 2021 15:39:52 -0700 Subject: [PATCH 3/3] TemplateBuffer is no more - Instead, BufferBuilderReader can decode parts of a BufferBuilder. - BufferedModel and its subclasses are now created directly with a ByteBuffer. - ContraptionModel renamed to IndexedModel. - InstancedModel and IndexedModel both now take model formats as arguments. - All of this allows for better abstraction, composition, and control of models rendered with Flywheel. --- .../backend/{ => core}/BufferedModel.java | 33 ++--- .../flywheel/backend/core/IndexedModel.java | 69 ++++++++++ .../flywheel/backend/gl/buffer/GlBuffer.java | 2 +- .../backend/gl/buffer/MappedBuffer.java | 6 + .../backend/instancing/InstancedModel.java | 25 +--- .../backend/instancing/RenderMaterial.java | 31 ++++- .../flywheel/util/BufferBuilderReader.java | 106 +++++++++++++++ .../render/ContraptionModel.java | 101 --------------- .../render/RenderedContraption.java | 121 +++++++++++++----- .../foundation/render/SuperByteBuffer.java | 57 ++++----- .../foundation/render/TemplateBuffer.java | 101 --------------- 11 files changed, 340 insertions(+), 312 deletions(-) rename src/main/java/com/jozufozu/flywheel/backend/{ => core}/BufferedModel.java (69%) create mode 100644 src/main/java/com/jozufozu/flywheel/backend/core/IndexedModel.java create mode 100644 src/main/java/com/jozufozu/flywheel/util/BufferBuilderReader.java delete mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionModel.java delete mode 100644 src/main/java/com/simibubi/create/foundation/render/TemplateBuffer.java diff --git a/src/main/java/com/jozufozu/flywheel/backend/BufferedModel.java b/src/main/java/com/jozufozu/flywheel/backend/core/BufferedModel.java similarity index 69% rename from src/main/java/com/jozufozu/flywheel/backend/BufferedModel.java rename to src/main/java/com/jozufozu/flywheel/backend/core/BufferedModel.java index 934ba2722..28825202c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/BufferedModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/core/BufferedModel.java @@ -1,33 +1,35 @@ -package com.jozufozu.flywheel.backend; +package com.jozufozu.flywheel.backend.core; + +import java.nio.ByteBuffer; -import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL20; +import com.jozufozu.flywheel.backend.RenderWork; import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; 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.simibubi.create.foundation.render.TemplateBuffer; -import net.minecraft.client.renderer.BufferBuilder; - -public abstract class BufferedModel extends TemplateBuffer { +public abstract class BufferedModel { + protected final ByteBuffer data; protected final VertexFormat modelFormat; + protected final int vertexCount; protected GlBuffer modelVBO; private boolean initialized; // lazy init private boolean removed; - protected BufferedModel(VertexFormat modelFormat, BufferBuilder buf) { - super(buf); + protected BufferedModel(VertexFormat modelFormat, ByteBuffer data, int vertices) { + this.data = data; this.modelFormat = modelFormat; + this.vertexCount = vertices; } /** * Renders this model, checking first if there is anything to render. */ public final void render() { - if (vertexCount == 0 || removed) return; + if (vertexCount <= 0 || removed) return; if (!initialized) { // Lazily acquire resources in order to get around initialization order, as #getTotalShaderAttributeCount @@ -60,22 +62,15 @@ public abstract class BufferedModel extends TemplateBuffer { } protected void initModel() { - int stride = modelFormat.getStride(); - int invariantSize = vertexCount * stride; - // allocate the buffer on the gpu - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, invariantSize, GL15.GL_STATIC_DRAW); + modelVBO.alloc(data.capacity()); // mirror it in system memory so we can write to it - MappedBuffer buffer = modelVBO.getBuffer(0, invariantSize); - for (int i = 0; i < vertexCount; i++) { - copyVertex(buffer, i); - } + MappedBuffer buffer = modelVBO.getBuffer(0, data.capacity()); + buffer.put(data); buffer.flush(); } - protected abstract void copyVertex(MappedBuffer to, int index); - protected int getTotalShaderAttributeCount() { return modelFormat.getShaderAttributeCount(); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/IndexedModel.java b/src/main/java/com/jozufozu/flywheel/backend/core/IndexedModel.java new file mode 100644 index 000000000..1372a13ca --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/core/IndexedModel.java @@ -0,0 +1,69 @@ +package com.jozufozu.flywheel.backend.core; + +import java.nio.ByteBuffer; + +import org.lwjgl.opengl.GL20; + +import com.jozufozu.flywheel.backend.gl.GlPrimitiveType; +import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; +import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; +import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; + +public class IndexedModel extends BufferedModel { + + protected GlPrimitiveType eboIndexType; + protected GlBuffer ebo; + + public IndexedModel(VertexFormat modelFormat, ByteBuffer buf, int vertices) { + super(modelFormat, buf, vertices); + } + + @Override + protected void init() { + super.init(); + + createEBO(); + } + + @Override + protected void doRender() { + modelVBO.bind(); + ebo.bind(); + + setupAttributes(); + GL20.glDrawElements(GL20.GL_QUADS, vertexCount, eboIndexType.getGlConstant(), 0); + + int numAttributes = getTotalShaderAttributeCount(); + for (int i = 0; i <= numAttributes; i++) { + GL20.glDisableVertexAttribArray(i); + } + + ebo.unbind(); + modelVBO.unbind(); + } + + protected final void createEBO() { + ebo = new GlBuffer(GlBufferType.ELEMENT_ARRAY_BUFFER); + eboIndexType = GlPrimitiveType.UINT; // TODO: choose this based on the number of vertices + + int indicesSize = vertexCount * eboIndexType.getSize(); + + ebo.bind(); + + ebo.alloc(indicesSize); + MappedBuffer indices = ebo.getBuffer(0, indicesSize); + for (int i = 0; i < vertexCount; i++) { + indices.putInt(i); + } + indices.flush(); + + ebo.unbind(); + } + + @Override + protected void deleteInternal() { + super.deleteInternal(); + ebo.delete(); + } +} 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 c3c2da51a..4430fa76d 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 @@ -48,7 +48,7 @@ public class GlBuffer extends GlObject { } public MappedBuffer getBuffer(int offset, int length) { - if (Backend.compat.mapBufferRange == MapBufferRange.UNSUPPORTED) { + if (Backend.compat.mapBufferRange != MapBufferRange.UNSUPPORTED) { return new MappedBufferRange(this, offset, length, GL30.GL_MAP_WRITE_BIT); } else { MappedFullBuffer fullBuffer = new MappedFullBuffer(this, MappedBufferUsage.WRITE_ONLY); diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java index 16de2eb1e..f8ee93fdc 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java @@ -80,6 +80,12 @@ public abstract class MappedBuffer implements AutoCloseable { return this; } + public MappedBuffer put(ByteBuffer b) { + checkAndMap(); + internal.put(b); + return this; + } + public MappedBuffer putVec4(float x, float y, float z, float w) { checkAndMap(); internal.putFloat(x); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedModel.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedModel.java index 9409e4edf..a70108cbe 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedModel.java @@ -1,24 +1,21 @@ package com.jozufozu.flywheel.backend.instancing; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.BitSet; import org.lwjgl.opengl.GL11; import com.jozufozu.flywheel.backend.Backend; -import com.jozufozu.flywheel.backend.BufferedModel; -import com.jozufozu.flywheel.backend.core.materials.ModelAttributes; +import com.jozufozu.flywheel.backend.core.BufferedModel; import com.jozufozu.flywheel.backend.gl.GlVertexArray; import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; 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 net.minecraft.client.renderer.BufferBuilder; - public class InstancedModel extends BufferedModel { - public static final VertexFormat FORMAT = VertexFormat.builder().addAttributes(ModelAttributes.class).build(); public final InstancedTileRenderer renderer; @@ -34,8 +31,8 @@ public class InstancedModel extends BufferedModel { boolean anyToRemove; boolean anyToUpdate; - public InstancedModel(InstancedTileRenderer renderer, VertexFormat instanceFormat, InstanceFactory factory, BufferBuilder buf) { - super(FORMAT, buf); + public InstancedModel(VertexFormat modelFormat, ByteBuffer buf, int vertices, InstancedTileRenderer renderer, VertexFormat instanceFormat, InstanceFactory factory) { + super(modelFormat, buf, vertices); this.factory = factory; this.instanceFormat = instanceFormat; this.renderer = renderer; @@ -225,20 +222,6 @@ public class InstancedModel extends BufferedModel { } - @Override - protected void copyVertex(MappedBuffer constant, int i) { - constant.putFloat(getX(template, i)); - constant.putFloat(getY(template, i)); - constant.putFloat(getZ(template, i)); - - constant.put(getNX(template, i)); - constant.put(getNY(template, i)); - constant.put(getNZ(template, i)); - - constant.putFloat(getU(template, i)); - constant.putFloat(getV(template, i)); - } - protected int getTotalShaderAttributeCount() { return instanceFormat.getShaderAttributeCount() + super.getTotalShaderAttributeCount(); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/RenderMaterial.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/RenderMaterial.java index 7ce543169..19f0c8fcb 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/RenderMaterial.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/RenderMaterial.java @@ -1,5 +1,7 @@ package com.jozufozu.flywheel.backend.instancing; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.util.Arrays; import java.util.concurrent.ExecutionException; import java.util.function.Consumer; @@ -12,7 +14,10 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.jozufozu.flywheel.backend.core.BasicProgram; import com.jozufozu.flywheel.backend.core.PartialModel; +import com.jozufozu.flywheel.backend.core.materials.ModelAttributes; +import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; import com.jozufozu.flywheel.backend.gl.shader.ShaderCallback; +import com.jozufozu.flywheel.util.BufferBuilderReader; import com.jozufozu.flywheel.util.RenderUtil; import com.jozufozu.flywheel.util.VirtualEmptyModelData; import com.mojang.blaze3d.matrix.MatrixStack; @@ -31,6 +36,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Matrix4f; public class RenderMaterial

{ + public static final VertexFormat MODEL_FORMAT = VertexFormat.builder().addAttributes(ModelAttributes.class).build(); protected final InstancedTileRenderer

renderer; protected final Cache> models; @@ -113,9 +119,30 @@ public class RenderMaterial

{ } private InstancedModel buildModel(IBakedModel model, BlockState referenceState, MatrixStack ms) { - BufferBuilder builder = getBufferBuilder(model, referenceState, ms); + BufferBuilderReader reader = new BufferBuilderReader(getBufferBuilder(model, referenceState, ms)); - return new InstancedModel<>(renderer, spec.getInstanceFormat(), spec.getInstanceFactory(), builder); + VertexFormat format = MODEL_FORMAT; + int vertexCount = reader.getVertexCount(); + + ByteBuffer to = ByteBuffer.allocate(vertexCount * format.getStride()); + to.order(ByteOrder.nativeOrder()); + + for (int i = 0; i < vertexCount; i++) { + to.putFloat(reader.getX(i)); + to.putFloat(reader.getY(i)); + to.putFloat(reader.getZ(i)); + + to.put(reader.getNX(i)); + to.put(reader.getNY(i)); + to.put(reader.getNZ(i)); + + to.putFloat(reader.getU(i)); + to.putFloat(reader.getV(i)); + } + + to.rewind(); + + return new InstancedModel<>(format, to, vertexCount, renderer, spec.getInstanceFormat(), spec.getInstanceFactory()); } private static final Direction[] dirs; diff --git a/src/main/java/com/jozufozu/flywheel/util/BufferBuilderReader.java b/src/main/java/com/jozufozu/flywheel/util/BufferBuilderReader.java new file mode 100644 index 000000000..15a6e1390 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/util/BufferBuilderReader.java @@ -0,0 +1,106 @@ +package com.jozufozu.flywheel.util; + +import java.nio.ByteBuffer; + +import com.mojang.datafixers.util.Pair; + +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.vertex.VertexFormat; + +public class BufferBuilderReader { + + private final ByteBuffer buffer; + private final int vertexCount; + private final int formatSize; + private final int size; + + public BufferBuilderReader(BufferBuilder builder) { + VertexFormat vertexFormat = builder.getVertexFormat(); + Pair data = builder.popData(); + buffer = data.getSecond(); + + formatSize = vertexFormat.getSize(); + + vertexCount = data.getFirst() + .getCount(); + + size = vertexCount * formatSize; + + // TODO: adjust the getters based on the input format +// ImmutableList elements = vertexFormat.getElements(); +// for (int i = 0, size = elements.size(); i < size; i++) { +// VertexFormatElement element = elements.get(i); +// int offset = vertexFormat.getOffset(i); +// +// element.getUsage() +// } + } + + public boolean isEmpty() { + return vertexCount == 0; + } + + public int vertIdx(int vertexIndex) { + return vertexIndex * formatSize; + } + + public float getX(int index) { + return buffer.getFloat(vertIdx(index)); + } + + public float getY(int index) { + return buffer.getFloat(vertIdx(index) + 4); + } + + public float getZ(int index) { + return buffer.getFloat(vertIdx(index) + 8); + } + + public byte getR(int index) { + return buffer.get(vertIdx(index) + 12); + } + + public byte getG(int index) { + return buffer.get(vertIdx(index) + 13); + } + + public byte getB(int index) { + return buffer.get(vertIdx(index) + 14); + } + + public byte getA(int index) { + return buffer.get(vertIdx(index) + 15); + } + + public float getU(int index) { + return buffer.getFloat(vertIdx(index) + 16); + } + + public float getV(int index) { + return buffer.getFloat(vertIdx(index) + 20); + } + + public int getLight(int index) { + return buffer.getInt(vertIdx(index) + 24); + } + + public byte getNX(int index) { + return buffer.get(vertIdx(index) + 28); + } + + public byte getNY(int index) { + return buffer.get(vertIdx(index) + 29); + } + + public byte getNZ(int index) { + return buffer.get(vertIdx(index) + 30); + } + + public int getVertexCount() { + return vertexCount; + } + + public int getSize() { + return size; + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionModel.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionModel.java deleted file mode 100644 index acdca2f9f..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionModel.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.simibubi.create.content.contraptions.components.structureMovement.render; - -import org.lwjgl.opengl.GL20; - -import com.jozufozu.flywheel.backend.BufferedModel; -import com.jozufozu.flywheel.backend.gl.GlPrimitiveType; -import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; -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 net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.LightTexture; - -public class ContraptionModel extends BufferedModel { - public static final VertexFormat FORMAT = VertexFormat.builder() - .addAttributes(ContraptionAttributes.class) - .build(); - - protected GlPrimitiveType eboIndexType; - protected GlBuffer ebo; - - public ContraptionModel(BufferBuilder buf) { - super(FORMAT, buf); - } - - @Override - protected void init() { - super.init(); - - createEBO(); - } - - @Override - protected void doRender() { - modelVBO.bind(); - ebo.bind(); - - setupAttributes(); - GL20.glDrawElements(GL20.GL_QUADS, vertexCount, eboIndexType.getGlConstant(), 0); - - int numAttributes = getTotalShaderAttributeCount(); - for (int i = 0; i <= numAttributes; i++) { - GL20.glDisableVertexAttribArray(i); - } - - ebo.unbind(); - modelVBO.unbind(); - } - - protected final void createEBO() { - ebo = new GlBuffer(GlBufferType.ELEMENT_ARRAY_BUFFER); - eboIndexType = GlPrimitiveType.UINT; // TODO: choose this based on the number of vertices - - int indicesSize = vertexCount * eboIndexType.getSize(); - - ebo.bind(); - - ebo.alloc(indicesSize); - MappedBuffer indices = ebo.getBuffer(0, indicesSize); - for (int i = 0; i < vertexCount; i++) { - indices.putInt(i); - } - indices.flush(); - - ebo.unbind(); - } - - @Override - protected void copyVertex(MappedBuffer to, int vertex) { - to.putFloat(getX(template, vertex)); - to.putFloat(getY(template, vertex)); - to.putFloat(getZ(template, vertex)); - - to.put(getNX(template, vertex)); - to.put(getNY(template, vertex)); - to.put(getNZ(template, vertex)); - - to.putFloat(getU(template, vertex)); - to.putFloat(getV(template, vertex)); - - to.put(getR(template, vertex)); - to.put(getG(template, vertex)); - to.put(getB(template, vertex)); - to.put(getA(template, vertex)); - - int light = getLight(template, vertex); - - byte block = (byte) (LightTexture.getBlockLightCoordinates(light) << 4); - byte sky = (byte) (LightTexture.getSkyLightCoordinates(light) << 4); - - to.put(block); - to.put(sky); - } - - @Override - protected void deleteInternal() { - super.deleteInternal(); - ebo.delete(); - } -} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java index d847b9cd8..079ae0524 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java @@ -1,16 +1,23 @@ package com.simibubi.create.content.contraptions.components.structureMovement.render; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; +import javax.annotation.Nullable; + import org.lwjgl.opengl.GL11; import com.jozufozu.flywheel.backend.Backend; +import com.jozufozu.flywheel.backend.core.IndexedModel; +import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; import com.jozufozu.flywheel.backend.instancing.IInstanceRendered; import com.jozufozu.flywheel.backend.light.GridAlignedBB; +import com.jozufozu.flywheel.util.BufferBuilderReader; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; @@ -25,6 +32,7 @@ import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.BlockModelRenderer; import net.minecraft.client.renderer.BlockModelShapes; import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderTypeLookup; import net.minecraft.client.renderer.texture.OverlayTexture; @@ -40,17 +48,21 @@ import net.minecraftforge.client.ForgeHooksClient; import net.minecraftforge.client.model.data.EmptyModelData; public class RenderedContraption { - private static final BlockModelRenderer MODEL_RENDERER = new BlockModelRenderer(Minecraft.getInstance().getBlockColors()); - private static final BlockModelShapes BLOCK_MODELS = Minecraft.getInstance().getModelManager().getBlockModelShapes(); + public static final VertexFormat FORMAT = VertexFormat.builder() + .addAttributes(ContraptionAttributes.class) + .build(); - public Contraption contraption; - private final ContraptionLighter lighter; - public final ContraptionKineticRenderer kinetics; - public final PlacementSimulationWorld renderWorld; + private static final BlockModelRenderer MODEL_RENDERER = new BlockModelRenderer(Minecraft.getInstance().getBlockColors()); + private static final BlockModelShapes BLOCK_MODELS = Minecraft.getInstance().getModelManager().getBlockModelShapes(); - private final Map renderLayers = new HashMap<>(); + public Contraption contraption; + private final ContraptionLighter lighter; + public final ContraptionKineticRenderer kinetics; + public final PlacementSimulationWorld renderWorld; - private Matrix4f model; + private final Map renderLayers = new HashMap<>(); + + private Matrix4f model; private AxisAlignedBB lightBox; public RenderedContraption(World world, Contraption contraption) { @@ -79,7 +91,7 @@ public class RenderedContraption { } public void doRenderLayer(RenderType layer, ContraptionProgram shader) { - ContraptionModel structure = renderLayers.get(layer); + IndexedModel structure = renderLayers.get(layer); if (structure != null) { setup(shader); structure.render(); @@ -120,9 +132,9 @@ public class RenderedContraption { } void invalidate() { - for (ContraptionModel buffer : renderLayers.values()) { - buffer.delete(); - } + for (IndexedModel buffer : renderLayers.values()) { + buffer.delete(); + } renderLayers.clear(); lighter.lightVolume.delete(); @@ -131,17 +143,18 @@ public class RenderedContraption { } private void buildLayers() { - for (ContraptionModel buffer : renderLayers.values()) { - buffer.delete(); - } + for (IndexedModel buffer : renderLayers.values()) { + buffer.delete(); + } renderLayers.clear(); List blockLayers = RenderType.getBlockLayers(); for (RenderType layer : blockLayers) { - renderLayers.put(layer, buildStructureModel(renderWorld, contraption, layer)); - } + IndexedModel layerModel = buildStructureModel(renderWorld, contraption, layer); + if (layerModel != null) renderLayers.put(layer, layerModel); + } } private void buildInstancedTiles() { @@ -153,29 +166,67 @@ public class RenderedContraption { BlockPos pos = te.getPos(); te.setLocation(renderWorld, pos); kinetics.add(te); - te.setLocation(world, pos); - } - } - } - } + te.setLocation(world, pos); + } + } + } + } - private void buildActors() { - contraption.getActors().forEach(kinetics::createActor); - } + private void buildActors() { + contraption.getActors().forEach(kinetics::createActor); + } - private static ContraptionModel buildStructureModel(PlacementSimulationWorld renderWorld, Contraption c, RenderType layer) { - BufferBuilder builder = buildStructure(renderWorld, c, layer); - return new ContraptionModel(builder); - } + @Nullable + private static IndexedModel buildStructureModel(PlacementSimulationWorld renderWorld, Contraption c, RenderType layer) { + BufferBuilderReader reader = new BufferBuilderReader(buildStructure(renderWorld, c, layer)); - private static PlacementSimulationWorld setupRenderWorld(World world, Contraption c) { - PlacementSimulationWorld renderWorld = new PlacementSimulationWorld(world); + int vertexCount = reader.getVertexCount(); + if (vertexCount == 0) return null; - renderWorld.setTileEntities(c.presentTileEntities.values()); + VertexFormat format = FORMAT; - for (Template.BlockInfo info : c.getBlocks() - .values()) - // Skip individual lighting updates to prevent lag with large contraptions + ByteBuffer to = ByteBuffer.allocate(format.getStride() * vertexCount); + to.order(ByteOrder.nativeOrder()); + + for (int i = 0; i < vertexCount; i++) { + to.putFloat(reader.getX(i)); + to.putFloat(reader.getY(i)); + to.putFloat(reader.getZ(i)); + + to.put(reader.getNX(i)); + to.put(reader.getNY(i)); + to.put(reader.getNZ(i)); + + to.putFloat(reader.getU(i)); + to.putFloat(reader.getV(i)); + + to.put(reader.getR(i)); + to.put(reader.getG(i)); + to.put(reader.getB(i)); + to.put(reader.getA(i)); + + int light = reader.getLight(i); + + byte block = (byte) (LightTexture.getBlockLightCoordinates(light) << 4); + byte sky = (byte) (LightTexture.getSkyLightCoordinates(light) << 4); + + to.put(block); + to.put(sky); + } + + to.rewind(); + + return new IndexedModel(format, to, vertexCount); + } + + private static PlacementSimulationWorld setupRenderWorld(World world, Contraption c) { + PlacementSimulationWorld renderWorld = new PlacementSimulationWorld(world); + + renderWorld.setTileEntities(c.presentTileEntities.values()); + + for (Template.BlockInfo info : c.getBlocks() + .values()) + // Skip individual lighting updates to prevent lag with large contraptions renderWorld.setBlockState(info.pos, info.state, 128); renderWorld.updateLightSources(); diff --git a/src/main/java/com/simibubi/create/foundation/render/SuperByteBuffer.java b/src/main/java/com/simibubi/create/foundation/render/SuperByteBuffer.java index f3ff7ef80..94fbde2ab 100644 --- a/src/main/java/com/simibubi/create/foundation/render/SuperByteBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/render/SuperByteBuffer.java @@ -1,8 +1,6 @@ package com.simibubi.create.foundation.render; -import java.nio.Buffer; -import java.nio.ByteBuffer; - +import com.jozufozu.flywheel.util.BufferBuilderReader; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.vertex.IVertexBuilder; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher; @@ -26,12 +24,9 @@ import net.minecraft.world.LightType; import net.minecraft.world.World; import net.minecraftforge.client.model.pipeline.LightUtil; -public class SuperByteBuffer extends TemplateBuffer { - - public interface IVertexLighter { - public int getPackedLight(float x, float y, float z); - } +public class SuperByteBuffer { + private final BufferBuilderReader template; // Vertex Position private MatrixStack transforms; @@ -49,7 +44,7 @@ public class SuperByteBuffer extends TemplateBuffer { private int r, g, b, a; public SuperByteBuffer(BufferBuilder buf) { - super(buf); + template = new BufferBuilderReader(buf); transforms = new MatrixStack(); } @@ -70,22 +65,20 @@ public class SuperByteBuffer extends TemplateBuffer { Vector4f lightPos = new Vector4f(); public void renderInto(MatrixStack input, IVertexBuilder builder) { - ByteBuffer buffer = template; - if (((Buffer) buffer).limit() == 0) + if (isEmpty()) return; - ((Buffer) buffer).rewind(); Matrix3f normalMat = transforms.peek() - .getNormal() - .copy(); + .getNormal() + .copy(); // normalMat.multiply(transforms.peek().getNormal()); Matrix4f modelMat = input.peek() - .getModel() - .copy(); + .getModel() + .copy(); Matrix4f localTransforms = transforms.peek() - .getModel(); + .getModel(); modelMat.multiply(localTransforms); if (shouldLight && lightTransform != null) { @@ -94,18 +87,18 @@ public class SuperByteBuffer extends TemplateBuffer { } float f = .5f; - int vertexCount = vertexCount(buffer); + int vertexCount = template.getVertexCount(); for (int i = 0; i < vertexCount; i++) { - float x = getX(buffer, i); - float y = getY(buffer, i); - float z = getZ(buffer, i); - byte r = getR(buffer, i); - byte g = getG(buffer, i); - byte b = getB(buffer, i); - byte a = getA(buffer, i); - float normalX = getNX(buffer, i) / 127f; - float normalY = getNY(buffer, i) / 127f; - float normalZ = getNZ(buffer, i) / 127f; + float x = template.getX(i); + float y = template.getY(i); + float z = template.getZ(i); + byte r = template.getR(i); + byte g = template.getG(i); + byte b = template.getB(i); + byte a = template.getA(i); + float normalX = template.getNX(i) / 127f; + float normalY = template.getNY(i) / 127f; + float normalZ = template.getNZ(i) / 127f; float staticDiffuse = LightUtil.diffuseLight(normalX, normalY, normalZ); normal.set(normalX, normalY, normalZ); @@ -134,8 +127,8 @@ public class SuperByteBuffer extends TemplateBuffer { builder.color(colorR, colorG, colorB, a); } - float u = getU(buffer, i); - float v = getV(buffer, i); + float u = template.getU(i); + float v = template.getV(i); if (spriteShiftFunc != null) { spriteShiftFunc.shift(builder, u, v); @@ -156,7 +149,7 @@ public class SuperByteBuffer extends TemplateBuffer { } builder.light(light); } else - builder.light(getLight(buffer, i)); + builder.light(template.getLight(i)); builder.normal(nx, ny, nz) .endVertex(); @@ -297,7 +290,7 @@ public class SuperByteBuffer extends TemplateBuffer { } public boolean isEmpty() { - return ((Buffer) template).limit() == 0; + return template.isEmpty(); } @FunctionalInterface diff --git a/src/main/java/com/simibubi/create/foundation/render/TemplateBuffer.java b/src/main/java/com/simibubi/create/foundation/render/TemplateBuffer.java deleted file mode 100644 index 5f3eef7b5..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/TemplateBuffer.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.simibubi.create.foundation.render; - -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import com.mojang.datafixers.util.Pair; - -import net.minecraft.client.renderer.BufferBuilder; - -public class TemplateBuffer { - protected ByteBuffer template; - protected int formatSize; - protected int vertexCount; - - public TemplateBuffer() { - - } - - public TemplateBuffer(BufferBuilder buf) { - Pair state = buf.popData(); - ByteBuffer rendered = state.getSecond(); - rendered.order(ByteOrder.nativeOrder()); // Vanilla bug, endianness does not carry over into sliced buffers - - formatSize = buf.getVertexFormat() - .getSize(); - vertexCount = state.getFirst() - .getCount(); - int size = vertexCount * formatSize; - - template = ByteBuffer.allocate(size); - template.order(rendered.order()); - ((Buffer) template).limit(((Buffer) rendered).limit()); - template.put(rendered); - ((Buffer) template).rewind(); - } - - public boolean isEmpty() { - return ((Buffer) template).limit() == 0; - } - - protected int vertexCount(ByteBuffer buffer) { - return ((Buffer) buffer).limit() / formatSize; - } - - protected int getBufferPosition(int vertexIndex) { - return vertexIndex * formatSize; - } - - protected float getX(ByteBuffer buffer, int index) { - return buffer.getFloat(getBufferPosition(index)); - } - - protected float getY(ByteBuffer buffer, int index) { - return buffer.getFloat(getBufferPosition(index) + 4); - } - - protected float getZ(ByteBuffer buffer, int index) { - return buffer.getFloat(getBufferPosition(index) + 8); - } - - protected byte getR(ByteBuffer buffer, int index) { - return buffer.get(getBufferPosition(index) + 12); - } - - protected byte getG(ByteBuffer buffer, int index) { - return buffer.get(getBufferPosition(index) + 13); - } - - protected byte getB(ByteBuffer buffer, int index) { - return buffer.get(getBufferPosition(index) + 14); - } - - protected byte getA(ByteBuffer buffer, int index) { - return buffer.get(getBufferPosition(index) + 15); - } - - protected float getU(ByteBuffer buffer, int index) { - return buffer.getFloat(getBufferPosition(index) + 16); - } - - protected float getV(ByteBuffer buffer, int index) { - return buffer.getFloat(getBufferPosition(index) + 20); - } - - protected int getLight(ByteBuffer buffer, int index) { - return buffer.getInt(getBufferPosition(index) + 24); - } - - protected byte getNX(ByteBuffer buffer, int index) { - return buffer.get(getBufferPosition(index) + 28); - } - - protected byte getNY(ByteBuffer buffer, int index) { - return buffer.get(getBufferPosition(index) + 29); - } - - protected byte getNZ(ByteBuffer buffer, int index) { - return buffer.get(getBufferPosition(index) + 30); - } -}