diff --git a/.editorconfig b/.editorconfig
index 1eeca6433..f1abc2e0c 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -13,6 +13,17 @@ insert_final_newline = true
[*.json]
indent_style = space
indent_size = 2
+max_line_length = 500
+ij_json_keep_blank_lines_in_code = 0
+ij_json_keep_indents_on_empty_lines = false
+ij_json_keep_line_breaks = true
+ij_json_space_after_colon = true
+ij_json_space_after_comma = true
+ij_json_space_before_colon = true
+ij_json_space_before_comma = false
+ij_json_spaces_within_braces = true
+ij_json_spaces_within_brackets = false
+ij_json_wrap_long_lines = false
[*.java]
indent_style = tab
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 25155a1d0..c95a398cb 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
@@ -39,7 +39,7 @@ public class MappedBuffer extends VecBuffer implements AutoCloseable {
}
@Override
- public void close() throws Exception {
+ public void close() {
flush();
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java
index 1f8310d1e..7743fb0b8 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java
@@ -1,6 +1,7 @@
package com.jozufozu.flywheel.backend.instancing;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -359,4 +360,14 @@ public abstract class InstanceManager implements InstancingEngine.OriginShift
LightUpdater.get(value.world).removeListener(value);
}
}
+
+ public void queueAddAll(Collection extends T> objects) {
+ if (!Backend.isOn() || objects.isEmpty()) {
+ return;
+ }
+
+ synchronized (queuedAdditions) {
+ queuedAdditions.addAll(objects);
+ }
+ }
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/ElementBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/model/ElementBuffer.java
index 8227ad019..aba15457b 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/model/ElementBuffer.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/model/ElementBuffer.java
@@ -2,14 +2,16 @@ package com.jozufozu.flywheel.backend.model;
import com.jozufozu.flywheel.backend.gl.GlNumericType;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
+import com.mojang.blaze3d.vertex.VertexBuffer;
+import com.mojang.blaze3d.vertex.VertexFormat;
public class ElementBuffer {
private final GlBuffer buffer;
public final int elementCount;
- public final GlNumericType eboIndexType;
+ public final VertexFormat.IndexType eboIndexType;
- public ElementBuffer(GlBuffer backing, int elementCount, GlNumericType indexType) {
+ public ElementBuffer(GlBuffer backing, int elementCount, VertexFormat.IndexType indexType) {
this.buffer = backing;
this.eboIndexType = indexType;
this.elementCount = elementCount;
diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java b/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java
index 7a372b0c8..4052e569e 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java
@@ -60,7 +60,7 @@ public class IndexedModel implements BufferedModel {
@Override
public void drawCall() {
ebo.bind();
- GL20.glDrawElements(primitiveMode.glEnum, ebo.elementCount, ebo.eboIndexType.getGlEnum(), 0);
+ GL20.glDrawElements(primitiveMode.glEnum, ebo.elementCount, ebo.eboIndexType.asGLType, 0);
}
/**
@@ -72,7 +72,7 @@ public class IndexedModel implements BufferedModel {
ebo.bind();
- GL31.glDrawElementsInstanced(primitiveMode.glEnum, ebo.elementCount, ebo.eboIndexType.getGlEnum(), 0, instanceCount);
+ GL31.glDrawElementsInstanced(primitiveMode.glEnum, ebo.elementCount, ebo.eboIndexType.asGLType, 0, instanceCount);
}
public boolean isDeleted() {
diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java b/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java
index 5c1d426c7..d9ce70838 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java
@@ -189,7 +189,7 @@ public class ModelPool implements ModelAllocator {
@Override
public void drawCall() {
- GL32.glDrawElementsBaseVertex(GlPrimitive.TRIANGLES.glEnum, ebo.elementCount, ebo.eboIndexType.getGlEnum(), 0, first);
+ GL32.glDrawElementsBaseVertex(GlPrimitive.TRIANGLES.glEnum, ebo.elementCount, ebo.eboIndexType.asGLType, 0, first);
}
@Override
@@ -200,7 +200,7 @@ public class ModelPool implements ModelAllocator {
//Backend.log.info(StringUtil.args("drawElementsInstancedBaseVertex", GlPrimitive.TRIANGLES, ebo.elementCount, ebo.eboIndexType, 0, instanceCount, first));
- GL32.glDrawElementsInstancedBaseVertex(GlPrimitive.TRIANGLES.glEnum, ebo.elementCount, ebo.eboIndexType.getGlEnum(), 0, instanceCount, first);
+ GL32.glDrawElementsInstancedBaseVertex(GlPrimitive.TRIANGLES.glEnum, ebo.elementCount, ebo.eboIndexType.asGLType, 0, instanceCount, first);
}
@Override
diff --git a/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java b/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java
index d1871224b..6e461b019 100644
--- a/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java
+++ b/src/main/java/com/jozufozu/flywheel/core/QuadConverter.java
@@ -3,41 +3,30 @@ package com.jozufozu.flywheel.core;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.util.EnumMap;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.lwjgl.system.MemoryStack;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.backend.gl.GlNumericType;
-import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
+import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer;
import com.jozufozu.flywheel.backend.model.ElementBuffer;
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
-
-import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.eventbus.api.EventPriority;
-import net.minecraftforge.eventbus.api.SubscribeEvent;
-import net.minecraftforge.fml.common.Mod;
+import com.mojang.blaze3d.vertex.VertexFormat;
/**
* A class to manage EBOs that index quads as triangles.
*/
-@Mod.EventBusSubscriber(Dist.CLIENT)
public class QuadConverter {
- public static final int STARTING_CAPACITY = 42; // 255 / 6 = 42
-
private static QuadConverter INSTANCE;
- @Nonnull
+ @NotNull
public static QuadConverter getInstance() {
if (INSTANCE == null) {
- INSTANCE = new QuadConverter(STARTING_CAPACITY);
+ INSTANCE = new QuadConverter();
}
return INSTANCE;
@@ -48,130 +37,80 @@ public class QuadConverter {
return INSTANCE;
}
- Map ebos;
- int[] capacities;
+ private final MappedGlBuffer ebo;
+ private int quadCapacity;
- public QuadConverter(int initialCapacity) {
- this.ebos = new EnumMap<>(GlNumericType.class);
- initCapacities();
-
- fillBuffer(initialCapacity);
+ public QuadConverter() {
+ this.ebo = new MappedGlBuffer(GlBufferType.ELEMENT_ARRAY_BUFFER);
+ this.quadCapacity = 0;
}
public ElementBuffer quads2Tris(int quads) {
int indexCount = quads * 6;
- GlNumericType type = getSmallestIndexType(indexCount);
- if (quads > getCapacity(type)) {
- fillBuffer(quads, indexCount, type);
+ if (quads > quadCapacity) {
+ ebo.bind();
+ ebo.ensureCapacity((long) indexCount * GlNumericType.UINT.getByteWidth());
+
+ try (MappedBuffer map = ebo.getBuffer()) {
+ ByteBuffer indices = map.unwrap();
+
+ fillBuffer(indices, quads);
+ }
+ ebo.unbind();
+
+ this.quadCapacity = quads;
}
- return new ElementBuffer(getBuffer(type), indexCount, type);
- }
-
- private void initCapacities() {
- this.capacities = new int[GlNumericType.values().length];
- }
-
- private int getCapacity(GlNumericType type) {
- return capacities[type.ordinal()];
- }
-
- private void updateCapacity(GlNumericType type, int capacity) {
- if (getCapacity(type) < capacity) {
- capacities[type.ordinal()] = capacity;
- }
+ return new ElementBuffer(ebo, indexCount, VertexFormat.IndexType.INT);
}
public void delete() {
- ebos.values()
- .forEach(GlBuffer::delete);
- ebos.clear();
- initCapacities();
+ ebo.delete();
+ this.quadCapacity = 0;
}
- private void fillBuffer(int quads) {
- int indexCount = quads * 6;
+ private void fillBuffer(ByteBuffer indices, int quads) {
+ long addr = MemoryUtil.memAddress(indices);
+ int numVertices = 4 * quads;
+ int baseVertex = 0;
+ while (baseVertex < numVertices) {
+ // writeQuadIndices(indices, baseVertex);
+ writeQuadIndicesUnsafe(addr, baseVertex);
- fillBuffer(quads, indexCount, getSmallestIndexType(indexCount));
- }
-
- private void fillBuffer(int quads, int indexCount, GlNumericType type) {
- MemoryStack stack = MemoryStack.stackPush();
- int bytes = indexCount * type.getByteWidth();
-
- ByteBuffer indices;
- if (bytes > stack.getSize()) {
- indices = MemoryUtil.memAlloc(bytes); // not enough space on the preallocated stack
- } else {
- stack.push();
- indices = stack.malloc(bytes);
+ baseVertex += 4;
+ addr += 6 * 4;
}
-
- indices.order(ByteOrder.nativeOrder());
-
- fillBuffer(indices, type, quads);
-
- GlBuffer buffer = getBuffer(type);
-
- buffer.bind();
- buffer.upload(indices);
- buffer.unbind();
-
- if (bytes > stack.getSize()) {
- MemoryUtil.memFree(indices);
- } else {
- stack.pop();
- }
-
- updateCapacity(type, quads);
+ // ((Buffer) indices).flip();
}
- private void fillBuffer(ByteBuffer indices, GlNumericType type, int quads) {
- for (int i = 0, max = 4 * quads; i < max; i += 4) {
- // triangle a
- type.castAndBuffer(indices, i);
- type.castAndBuffer(indices, i + 1);
- type.castAndBuffer(indices, i + 2);
- // triangle b
- type.castAndBuffer(indices, i);
- type.castAndBuffer(indices, i + 2);
- type.castAndBuffer(indices, i + 3);
- }
- ((Buffer) indices).flip();
+ private void writeQuadIndices(ByteBuffer indices, int baseVertex) {
+ // triangle a
+ indices.putInt(baseVertex);
+ indices.putInt(baseVertex + 1);
+ indices.putInt(baseVertex + 2);
+ // triangle b
+ indices.putInt(baseVertex);
+ indices.putInt(baseVertex + 2);
+ indices.putInt(baseVertex + 3);
}
- private GlBuffer getBuffer(GlNumericType type) {
- return ebos.computeIfAbsent(type, $ -> new MappedGlBuffer(GlBufferType.ELEMENT_ARRAY_BUFFER));
- }
-
- /**
- * Given the needed number of indices, what is the smallest bit width type that can index everything?
- *
- *
- * | indexCount | type |
- * |--------------|-------|
- * | [0, 255) | byte |
- * | [256, 65536) | short |
- * | [65537, ) | int |
- *
- */
- private static GlNumericType getSmallestIndexType(int indexCount) {
-// indexCount = indexCount >>> 8;
-// if (indexCount == 0) {
-// return GlNumericType.UBYTE;
-// }
-// indexCount = indexCount >>> 8;
-// if (indexCount == 0) {
-// return GlNumericType.USHORT;
-// }
-
- return GlNumericType.UINT;
+ private void writeQuadIndicesUnsafe(long addr, int baseVertex) {
+ // triangle a
+ MemoryUtil.memPutInt(addr, baseVertex);
+ MemoryUtil.memPutInt(addr + 4, baseVertex + 1);
+ MemoryUtil.memPutInt(addr + 8, baseVertex + 2);
+ // triangle b
+ MemoryUtil.memPutInt(addr + 12, baseVertex);
+ MemoryUtil.memPutInt(addr + 16, baseVertex + 2);
+ MemoryUtil.memPutInt(addr + 20, baseVertex + 3);
}
// make sure this gets reset first so it has a chance to repopulate
- @SubscribeEvent(priority = EventPriority.HIGHEST)
public static void onRendererReload(ReloadRenderersEvent event) {
- if (INSTANCE != null) INSTANCE.delete();
+ if (INSTANCE != null) {
+ INSTANCE.delete();
+ INSTANCE = null;
+ }
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java b/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java
index 67bdeb798..d67ca22d3 100644
--- a/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java
+++ b/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java
@@ -3,7 +3,9 @@ package com.jozufozu.flywheel.core.hardcoded;
import java.util.List;
import com.jozufozu.flywheel.api.vertex.VertexList;
+import com.jozufozu.flywheel.backend.model.ElementBuffer;
import com.jozufozu.flywheel.core.Formats;
+import com.jozufozu.flywheel.core.QuadConverter;
import com.jozufozu.flywheel.core.model.Model;
import com.jozufozu.flywheel.core.vertex.PosTexNormalWriterUnsafe;
import com.mojang.blaze3d.platform.MemoryTracker;
@@ -51,4 +53,10 @@ public class ModelPart implements Model {
public VertexList getReader() {
return reader;
}
+
+ @Override
+ public ElementBuffer createEBO() {
+ return QuadConverter.getInstance()
+ .quads2Tris(vertices / 4);
+ }
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java b/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java
index 8c527bea6..45b2e6f1a 100644
--- a/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java
+++ b/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java
@@ -1,8 +1,25 @@
package com.jozufozu.flywheel.core.model;
+import java.lang.management.MemoryUsage;
+import java.nio.ByteBuffer;
+import java.util.function.Supplier;
+
+import org.lwjgl.system.MemoryUtil;
+
import com.jozufozu.flywheel.api.vertex.VertexList;
+import com.jozufozu.flywheel.api.vertex.VertexType;
+import com.jozufozu.flywheel.backend.gl.GlNumericType;
+import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
+import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
+import com.jozufozu.flywheel.backend.gl.buffer.GlBufferUsage;
+import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer;
+import com.jozufozu.flywheel.backend.model.ElementBuffer;
import com.jozufozu.flywheel.core.Formats;
+import com.jozufozu.flywheel.core.QuadConverter;
+import com.mojang.blaze3d.platform.MemoryTracker;
+import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.blaze3d.vertex.VertexBuffer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.model.BakedModel;
@@ -12,12 +29,12 @@ import net.minecraft.world.level.block.state.BlockState;
* A model of a single block.
*/
public class BlockModel implements Model {
- private static final PoseStack IDENTITY = new PoseStack();
-
private final VertexList reader;
private final String name;
+ private final Supplier eboSupplier;
+
public BlockModel(BlockState state) {
this(Minecraft.getInstance()
.getBlockRenderer()
@@ -25,12 +42,49 @@ public class BlockModel implements Model {
}
public BlockModel(BakedModel model, BlockState referenceState) {
- this(model, referenceState, IDENTITY);
+ this(new BakedModelBuilder(model).withReferenceState(referenceState), referenceState.toString());
}
public BlockModel(BakedModel model, BlockState referenceState, PoseStack ms) {
- reader = Formats.BLOCK.createReader(ModelUtil.getBufferBuilder(model, referenceState, ms));
- name = referenceState.toString();
+ this(new BakedModelBuilder(model).withReferenceState(referenceState)
+ .withPoseStack(ms), referenceState.toString());
+ }
+
+ public BlockModel(Bufferable bufferable, String name) {
+ this(bufferable.build(), name);
+ }
+
+ public BlockModel(ShadeSeparatedBufferBuilder buffer, String name) {
+ this.name = name;
+
+ BufferBuilder.RenderedBuffer renderedBuffer = buffer.endOrDiscardIfEmpty();
+
+ if (renderedBuffer == null) {
+ reader = null;
+ eboSupplier = () -> null;
+ return;
+ }
+
+ BufferBuilder.DrawState drawState = renderedBuffer.drawState();
+
+ reader = Formats.BLOCK.createReader(renderedBuffer, buffer.getUnshadedStartVertex());
+
+ if (drawState.sequentialIndex()) {
+ ByteBuffer src = renderedBuffer.indexBuffer();
+ ByteBuffer indexBuffer = MemoryTracker.create(src.capacity());
+ MemoryUtil.memCopy(src, indexBuffer);
+ eboSupplier = () -> {
+
+ MappedGlBuffer vbo = new MappedGlBuffer(GlBufferType.ELEMENT_ARRAY_BUFFER, GlBufferUsage.STATIC_DRAW);
+
+ vbo.upload(indexBuffer);
+
+ return new ElementBuffer(vbo, drawState.indexCount(), drawState.indexType());
+ };
+ } else {
+ eboSupplier = () -> QuadConverter.getInstance()
+ .quads2Tris(vertexCount() / 4);
+ }
}
@Override
@@ -47,4 +101,14 @@ public class BlockModel implements Model {
public VertexList getReader() {
return reader;
}
+
+ @Override
+ public ElementBuffer createEBO() {
+ return eboSupplier.get();
+ }
+
+ @Override
+ public VertexType getType() {
+ return Formats.BLOCK;
+ }
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/model/Model.java b/src/main/java/com/jozufozu/flywheel/core/model/Model.java
index eacfd3394..c93e1df84 100644
--- a/src/main/java/com/jozufozu/flywheel/core/model/Model.java
+++ b/src/main/java/com/jozufozu/flywheel/core/model/Model.java
@@ -56,10 +56,7 @@ public interface Model {
*
* @return an element buffer object indexing this model's vertices.
*/
- default ElementBuffer createEBO() {
- return QuadConverter.getInstance()
- .quads2Tris(vertexCount() / 4);
- }
+ ElementBuffer createEBO();
/**
* The size in bytes that this model's data takes up.
diff --git a/src/main/java/com/jozufozu/flywheel/core/model/ShadeSeparatedBufferBuilder.java b/src/main/java/com/jozufozu/flywheel/core/model/ShadeSeparatedBufferBuilder.java
index 38043702b..71a05d70f 100644
--- a/src/main/java/com/jozufozu/flywheel/core/model/ShadeSeparatedBufferBuilder.java
+++ b/src/main/java/com/jozufozu/flywheel/core/model/ShadeSeparatedBufferBuilder.java
@@ -14,9 +14,16 @@ public class ShadeSeparatedBufferBuilder extends BufferBuilder {
}
public void appendUnshadedVertices(BufferBuilder unshadedBuilder) {
- Pair data = unshadedBuilder.popNextBuffer();
+ RenderedBuffer renderedBuffer = unshadedBuilder.endOrDiscardIfEmpty();
+
+ if (renderedBuffer == null) {
+ return;
+ }
+
+ // FIXME: Unshaded indices
+ ByteBuffer buffer = renderedBuffer.vertexBuffer();
unshadedStartVertex = ((BufferBuilderExtension) this).flywheel$getVertices();
- ((BufferBuilderExtension) this).flywheel$appendBufferUnsafe(data.getSecond());
+ ((BufferBuilderExtension) this).flywheel$appendBufferUnsafe(buffer);
}
public int getUnshadedStartVertex() {
diff --git a/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java b/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java
deleted file mode 100644
index c144f43c6..000000000
--- a/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.jozufozu.flywheel.core.model;
-
-import com.jozufozu.flywheel.api.vertex.VertexList;
-import com.jozufozu.flywheel.api.vertex.VertexType;
-import com.jozufozu.flywheel.core.Formats;
-import com.mojang.blaze3d.vertex.BufferBuilder;
-
-public class WorldModel implements Model {
-
- private final VertexList reader;
- private final String name;
-
- public WorldModel(BufferBuilder bufferBuilder, String name) {
- this.reader = Formats.BLOCK.createReader(bufferBuilder);
- this.name = name;
- }
-
- @Override
- public String name() {
- return name;
- }
-
- @Override
- public VertexType getType() {
- return Formats.BLOCK;
- }
-
- @Override
- public int vertexCount() {
- return reader.getVertexCount();
- }
-
- @Override
- public VertexList getReader() {
- return reader;
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java b/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java
index 03a145dfd..614bb0e9d 100644
--- a/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java
+++ b/src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java
@@ -77,7 +77,7 @@ public final class WorldModelBuilder implements Bufferable {
return this;
}
- public WorldModel intoMesh(String name) {
- return new WorldModel(ModelUtil.getBufferBuilder(this), name);
+ public BlockModel intoMesh(String name) {
+ return new BlockModel(this, name);
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java b/src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java
index a68e0c943..24ec1eeab 100644
--- a/src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java
+++ b/src/main/java/com/jozufozu/flywheel/core/vertex/AbstractVertexList.java
@@ -22,15 +22,6 @@ public abstract class AbstractVertexList implements VertexList, AutoCloseable {
init(copyFrom);
}
- public AbstractVertexList(BufferBuilder builder) {
- var pair = builder.popNextBuffer();
- ByteBuffer copyFrom = pair.getSecond();
- this.contents = MemoryTracker.create(copyFrom.capacity());
- this.vertexCount = pair.getFirst().vertexCount();
- this.base = MemoryUtil.memAddress(this.contents);
- init(copyFrom);
- }
-
private void init(ByteBuffer copyFrom) {
this.contents.order(copyFrom.order());
this.contents.put(copyFrom);
diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java
index d74dde894..1ac22ae94 100644
--- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java
+++ b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java
@@ -62,19 +62,20 @@ Vertex FLWCreateVertex() {
return new BlockVertexListUnsafe.Shaded(buffer, vertexCount, unshadedStartVertex);
}
- public VertexList createReader(BufferBuilder bufferBuilder) {
+ public VertexList createReader(BufferBuilder.RenderedBuffer renderedBuffer, int unshadedStartVertex) {
+
// TODO: try to avoid virtual model rendering
- Pair pair = bufferBuilder.popNextBuffer();
- BufferBuilder.DrawState drawState = pair.getFirst();
+ BufferBuilder.DrawState drawState = renderedBuffer.drawState();
if (drawState.format() != DefaultVertexFormat.BLOCK) {
throw new RuntimeException("Cannot use BufferBuilder with " + drawState.format());
}
+ ByteBuffer vertexBuffer = renderedBuffer.vertexBuffer();
- if (bufferBuilder instanceof ShadeSeparatedBufferBuilder separated) {
- return createReader(pair.getSecond(), drawState.vertexCount(), separated.getUnshadedStartVertex());
+ if (unshadedStartVertex > 0) {
+ return createReader(vertexBuffer, drawState.vertexCount(), unshadedStartVertex);
} else {
- return createReader(pair.getSecond(), drawState.vertexCount());
+ return createReader(vertexBuffer, drawState.vertexCount());
}
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java
index f84385f78..654f94865 100644
--- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java
+++ b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java
@@ -1,5 +1,7 @@
package com.jozufozu.flywheel.core.vertex;
+import java.nio.ByteBuffer;
+
import com.jozufozu.flywheel.api.vertex.ShadedVertexList;
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder;
import com.jozufozu.flywheel.util.RenderMath;
@@ -9,10 +11,9 @@ public class BlockVertexList extends AbstractVertexList {
private final int stride;
- public BlockVertexList(BufferBuilder builder) {
- super(builder);
- this.stride = builder.getVertexFormat()
- .getVertexSize();
+ public BlockVertexList(ByteBuffer copyFrom, int vertexCount, int stride) {
+ super(copyFrom, vertexCount);
+ this.stride = stride;
}
@Override
@@ -93,9 +94,9 @@ public class BlockVertexList extends AbstractVertexList {
private final int unshadedStartVertex;
- public Shaded(ShadeSeparatedBufferBuilder builder) {
- super(builder);
- unshadedStartVertex = builder.getUnshadedStartVertex();
+ public Shaded(ByteBuffer copyFrom, int vertexCount, int stride, int unshadedStartVertex) {
+ super(copyFrom, vertexCount, stride);
+ this.unshadedStartVertex = unshadedStartVertex;
}
@Override
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/BufferUploaderMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/BufferUploaderMixin.java
index 7cd63581c..92058feb9 100644
--- a/src/main/java/com/jozufozu/flywheel/mixin/BufferUploaderMixin.java
+++ b/src/main/java/com/jozufozu/flywheel/mixin/BufferUploaderMixin.java
@@ -10,6 +10,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
import com.mojang.blaze3d.vertex.BufferUploader;
+import com.mojang.blaze3d.vertex.VertexBuffer;
import com.mojang.blaze3d.vertex.VertexFormat;
@Mixin(BufferUploader.class)
@@ -17,13 +18,13 @@ public class BufferUploaderMixin {
@Shadow
@Nullable
- private static VertexFormat lastFormat;
+ private static VertexBuffer lastImmediateBuffer;
@Inject(method = "reset", at = @At("HEAD"))
private static void stopBufferUploaderFromClearingBufferStateIfNothingIsBound(CallbackInfo ci) {
// Trust our tracker over BufferUploader's.
if (GlStateTracker.getVertexArray() == 0) {
- lastFormat = null;
+ lastImmediateBuffer = null;
}
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/ChunkRebuildHooksMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/ChunkRebuildHooksMixin.java
deleted file mode 100644
index a4accbe24..000000000
--- a/src/main/java/com/jozufozu/flywheel/mixin/ChunkRebuildHooksMixin.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.jozufozu.flywheel.mixin;
-
-import java.util.Set;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-import com.jozufozu.flywheel.backend.Backend;
-import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
-import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
-
-import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher;
-import net.minecraft.world.level.block.entity.BlockEntity;
-import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.api.distmarker.OnlyIn;
-
-@OnlyIn(Dist.CLIENT)
-@Mixin(targets = "net.minecraft.client.renderer.chunk.ChunkRenderDispatcher$RenderChunk$RebuildTask")
-public class ChunkRebuildHooksMixin {
-
- @Inject(method = "handleBlockEntity", at = @At("HEAD"), cancellable = true)
- private void addAndFilterBEs(ChunkRenderDispatcher.CompiledChunk compiledChunk, Set set, E be, CallbackInfo ci) {
- if (Backend.canUseInstancing(be.getLevel())) {
- if (InstancedRenderRegistry.canInstance(be.getType()))
- InstancedRenderDispatcher.getBlockEntities(be.getLevel()).queueAdd(be);
-
- if (InstancedRenderRegistry.shouldSkipRender(be))
- ci.cancel();
- }
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java
new file mode 100644
index 000000000..599c7fc9a
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java
@@ -0,0 +1,82 @@
+package com.jozufozu.flywheel.mixin.instancemanage;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Unique;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.Redirect;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import com.jozufozu.flywheel.backend.Backend;
+import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
+import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
+import com.jozufozu.flywheel.util.RenderChunkExtension;
+
+import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher;
+import net.minecraft.client.renderer.chunk.RenderChunkRegion;
+import net.minecraft.world.level.ChunkPos;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+
+@OnlyIn(Dist.CLIENT)
+@Mixin(targets = "net.minecraft.client.renderer.chunk.ChunkRenderDispatcher$RenderChunk$RebuildTask")
+public abstract class ChunkRebuildHooksMixin {
+ @Unique
+ private Level flywheel$level;
+
+ @Inject(method = "(Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$RenderChunk;Lnet/minecraft/world/level/ChunkPos;DLnet/minecraft/client/renderer/chunk/RenderChunkRegion;Z)V", at = @At("RETURN"))
+ private void setLevel(ChunkRenderDispatcher.RenderChunk this$1, ChunkPos pos, double p_194427_, RenderChunkRegion region, boolean p_194429_, CallbackInfo ci) {
+ flywheel$level = ((RenderChunkExtension) this$1).flywheel$getLevel();
+ }
+
+ @Redirect(method = "doTask", at = @At(value = "INVOKE", target = "Ljava/util/List;addAll(Ljava/util/Collection;)Z"))
+ private boolean addAndFilterBEs(List self, Collection extends E> es) {
+ if (!Backend.canUseInstancing(flywheel$level)) {
+ return self.addAll(es);
+ }
+
+ boolean added = false;
+ var instanced = new ArrayList();
+ for (E be : es) {
+ if (InstancedRenderRegistry.canInstance(be.getType())) {
+ instanced.add(be);
+ }
+
+ if (!InstancedRenderRegistry.shouldSkipRender(be)) {
+ self.add(be);
+ added = true;
+ }
+ }
+ InstancedRenderDispatcher.getBlockEntities(flywheel$level).queueAddAll(instanced);
+ return added;
+ }
+
+ @Redirect(method = "doTask", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$RenderChunk;updateGlobalBlockEntities(Ljava/util/Collection;)V"))
+ private void addAndFilterBEs(ChunkRenderDispatcher.RenderChunk self, Collection bes) {
+ if (!Backend.canUseInstancing(flywheel$level)) {
+ ((RenderChunkAccessor) self).flywheel$updateGlobalBlockEntities(bes);
+ return;
+ }
+
+ var global = new ArrayList();
+ var instanced = new ArrayList();
+ for (BlockEntity be : bes) {
+ if (InstancedRenderRegistry.canInstance(be.getType())) {
+ instanced.add(be);
+ }
+
+ if (!InstancedRenderRegistry.shouldSkipRender(be)) {
+ global.add(be);
+ }
+ }
+
+ InstancedRenderDispatcher.getBlockEntities(flywheel$level).queueAddAll(instanced);
+ ((RenderChunkAccessor) self).flywheel$updateGlobalBlockEntities(global);
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRenderDispatcherAccessor.java b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRenderDispatcherAccessor.java
new file mode 100644
index 000000000..7e8e0de6d
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRenderDispatcherAccessor.java
@@ -0,0 +1,14 @@
+package com.jozufozu.flywheel.mixin.instancemanage;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import net.minecraft.client.multiplayer.ClientLevel;
+import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher;
+
+@Mixin(ChunkRenderDispatcher.class)
+public interface ChunkRenderDispatcherAccessor {
+
+ @Accessor
+ ClientLevel getLevel();
+}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/InstanceAddMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceAddMixin.java
similarity index 95%
rename from src/main/java/com/jozufozu/flywheel/mixin/InstanceAddMixin.java
rename to src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceAddMixin.java
index b28fbfa84..7568c28e9 100644
--- a/src/main/java/com/jozufozu/flywheel/mixin/InstanceAddMixin.java
+++ b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceAddMixin.java
@@ -1,4 +1,4 @@
-package com.jozufozu.flywheel.mixin;
+package com.jozufozu.flywheel.mixin.instancemanage;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/InstanceRemoveMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceRemoveMixin.java
similarity index 96%
rename from src/main/java/com/jozufozu/flywheel/mixin/InstanceRemoveMixin.java
rename to src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceRemoveMixin.java
index 0ee0fd088..1d115cfda 100644
--- a/src/main/java/com/jozufozu/flywheel/mixin/InstanceRemoveMixin.java
+++ b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceRemoveMixin.java
@@ -1,4 +1,4 @@
-package com.jozufozu.flywheel.mixin;
+package com.jozufozu.flywheel.mixin.instancemanage;
import javax.annotation.Nullable;
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/RenderChunkAccessor.java b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/RenderChunkAccessor.java
new file mode 100644
index 000000000..9bd5a2d3a
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/RenderChunkAccessor.java
@@ -0,0 +1,19 @@
+package com.jozufozu.flywheel.mixin.instancemanage;
+
+import java.util.Collection;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Invoker;
+
+import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher;
+import net.minecraft.world.level.block.entity.BlockEntity;
+
+/**
+ * For use in {@link ChunkRebuildHooksMixin#addAndFilterBEs(ChunkRenderDispatcher.RenderChunk, Collection)}
+ */
+@Mixin(ChunkRenderDispatcher.RenderChunk.class)
+public interface RenderChunkAccessor {
+
+ @Invoker("updateGlobalBlockEntities")
+ void flywheel$updateGlobalBlockEntities(Collection blockEntities);
+}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/RenderChunkMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/RenderChunkMixin.java
new file mode 100644
index 000000000..987d7e8e7
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/RenderChunkMixin.java
@@ -0,0 +1,21 @@
+package com.jozufozu.flywheel.mixin.instancemanage;
+
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+
+import net.minecraft.client.multiplayer.ClientLevel;
+import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher;
+
+@Mixin(ChunkRenderDispatcher.RenderChunk.class)
+public class RenderChunkMixin implements com.jozufozu.flywheel.util.RenderChunkExtension {
+
+ @Shadow
+ @Final
+ private ChunkRenderDispatcher this$0;
+
+ @Override
+ public ClientLevel flywheel$getLevel() {
+ return ((ChunkRenderDispatcherAccessor) this$0).getLevel();
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/util/RenderChunkExtension.java b/src/main/java/com/jozufozu/flywheel/util/RenderChunkExtension.java
new file mode 100644
index 000000000..acaa7faff
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/util/RenderChunkExtension.java
@@ -0,0 +1,7 @@
+package com.jozufozu.flywheel.util;
+
+import net.minecraft.client.multiplayer.ClientLevel;
+
+public interface RenderChunkExtension {
+ ClientLevel flywheel$getLevel();
+}
diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml
index 2f6649f40..4c6b69b3c 100644
--- a/src/main/resources/META-INF/mods.toml
+++ b/src/main/resources/META-INF/mods.toml
@@ -17,13 +17,13 @@ A modern engine for modded minecraft.'''
[[dependencies.flywheel]]
modId = "forge"
mandatory = true
-versionRange = "[40.0.0,)"
+versionRange = "[41.0.0,)"
ordering = "NONE"
side = "CLIENT"
[[dependencies.flywheel]]
modId = "minecraft"
mandatory = true
-versionRange = "[1.18.2,1.19)"
+versionRange = "[1.19,1.20)"
ordering = "NONE"
side = "CLIENT"
diff --git a/src/main/resources/flywheel.mixins.json b/src/main/resources/flywheel.mixins.json
index cccc7ef58..284039b65 100644
--- a/src/main/resources/flywheel.mixins.json
+++ b/src/main/resources/flywheel.mixins.json
@@ -10,17 +10,20 @@
"BufferBuilderMixin",
"BufferUploaderMixin",
"CameraMixin",
+ "instancemanage.ChunkRebuildHooksMixin",
+ "instancemanage.ChunkRenderDispatcherAccessor",
"ClientLevelMixin",
- "ChunkRebuildHooksMixin",
"EntityTypeMixin",
"FixFabulousDepthMixin",
"FrustumMixin",
"GlStateManagerMixin",
- "InstanceAddMixin",
- "InstanceRemoveMixin",
+ "instancemanage.InstanceAddMixin",
+ "instancemanage.InstanceRemoveMixin",
"LevelRendererAccessor",
"LevelRendererMixin",
"PausedPartialTickAccessor",
+ "instancemanage.RenderChunkAccessor",
+ "instancemanage.RenderChunkMixin",
"RenderTexturesMixin",
"RenderTypeMixin",
"atlas.AtlasDataMixin",