diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/GlNumericType.java b/src/main/java/com/jozufozu/flywheel/backend/gl/GlNumericType.java index 7a39b34b6..29baffd7f 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/GlNumericType.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/GlNumericType.java @@ -1,5 +1,6 @@ package com.jozufozu.flywheel.backend.gl; +import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Locale; import java.util.Map; @@ -27,18 +28,18 @@ public enum GlNumericType { private static final Map NAME_LOOKUP = Arrays.stream(VALUES) .collect(Collectors.toMap(GlNumericType::getDisplayName, type -> type)); - private final int size; + private final int byteWidth; private final String displayName; private final int glEnum; GlNumericType(int bytes, String name, int glEnum) { - this.size = bytes; + this.byteWidth = bytes; this.displayName = name; this.glEnum = glEnum; } - public int getSize() { - return this.size; + public int getByteWidth() { + return this.byteWidth; } public String getDisplayName() { @@ -49,6 +50,16 @@ public enum GlNumericType { return this.glEnum; } + public void castAndBuffer(ByteBuffer buf, int val) { + if (this == UBYTE || this == BYTE) { + buf.put((byte) val); + } else if (this == USHORT || this == SHORT) { + buf.putShort((short) val); + } else if (this == UINT || this == INT) { + buf.putInt(val); + } + } + @Nullable public static GlNumericType byName(String name) { return name == null ? null : NAME_LOOKUP.get(name.toLowerCase(Locale.ROOT)); diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/attrib/MatrixAttributes.java b/src/main/java/com/jozufozu/flywheel/backend/gl/attrib/MatrixAttributes.java index 49b6731fe..0a16dd11f 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/attrib/MatrixAttributes.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/attrib/MatrixAttributes.java @@ -20,14 +20,14 @@ public enum MatrixAttributes implements IAttribSpec { @Override public void vertexAttribPointer(int stride, int index, int pointer) { for (int i = 0; i < rows; i++) { - long attribPointer = pointer + (long) i * cols * GlNumericType.FLOAT.getSize(); + long attribPointer = pointer + (long) i * cols * GlNumericType.FLOAT.getByteWidth(); GL20.glVertexAttribPointer(index + i, cols, GlNumericType.FLOAT.getGlEnum(), false, stride, attribPointer); } } @Override public int getSize() { - return GlNumericType.FLOAT.getSize() * rows * cols; + return GlNumericType.FLOAT.getByteWidth() * rows * cols; } @Override diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/attrib/VertexAttribSpec.java b/src/main/java/com/jozufozu/flywheel/backend/gl/attrib/VertexAttribSpec.java index 663ad8342..373f4cfb6 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/attrib/VertexAttribSpec.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/attrib/VertexAttribSpec.java @@ -19,7 +19,7 @@ public class VertexAttribSpec implements IAttribSpec { public VertexAttribSpec(GlNumericType type, int count, boolean normalized) { this.type = type; this.count = count; - this.size = type.getSize() * count; + this.size = type.getByteWidth() * count; this.attributeCount = (this.size + 15) / 16; // ceiling division. GLSL vertex attributes can only be 16 bytes wide this.normalized = normalized; } diff --git a/src/main/java/com/jozufozu/flywheel/core/IndexedModel.java b/src/main/java/com/jozufozu/flywheel/core/IndexedModel.java index b909b4c30..ff7f08945 100644 --- a/src/main/java/com/jozufozu/flywheel/core/IndexedModel.java +++ b/src/main/java/com/jozufozu/flywheel/core/IndexedModel.java @@ -25,7 +25,7 @@ public class IndexedModel extends BufferedModel { this.eboIndexType = indexType; this.elementCount = elementCount; - int indicesSize = elementCount * indexType.getSize(); + int indicesSize = elementCount * indexType.getByteWidth(); ebo.bind(); @@ -38,13 +38,13 @@ public class IndexedModel extends BufferedModel { } public void draw() { - vbo.bind(); ebo.bind(); + vbo.bind(); AttribUtil.enableArrays(getAttributeCount()); format.vertexAttribPointers(0); - GL20.glDrawElements(primitiveMode.glEnum, vertexCount, eboIndexType.getGlEnum(), 0); + GL20.glDrawElements(primitiveMode.glEnum, elementCount, eboIndexType.getGlEnum(), 0); AttribUtil.disableArrays(getAttributeCount()); 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 5cf1f5953..572474654 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 @@ -10,12 +10,13 @@ import java.util.Map; import javax.annotation.Nullable; import com.jozufozu.flywheel.backend.Backend; +import com.jozufozu.flywheel.backend.gl.GlNumericType; import com.jozufozu.flywheel.backend.gl.GlPrimitive; import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes; import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; import com.jozufozu.flywheel.backend.instancing.IInstanceRendered; -import com.jozufozu.flywheel.core.BufferedArrayModel; import com.jozufozu.flywheel.core.BufferedModel; +import com.jozufozu.flywheel.core.IndexedModel; import com.jozufozu.flywheel.light.GridAlignedBB; import com.jozufozu.flywheel.util.BufferBuilderReader; import com.mojang.blaze3d.matrix.MatrixStack; @@ -163,40 +164,74 @@ public class RenderedContraption extends ContraptionWorldHolder { VertexFormat format = FORMAT; - ByteBuffer to = ByteBuffer.allocate(format.getStride() * vertexCount); - to.order(ByteOrder.nativeOrder()); + ByteBuffer vertices = ByteBuffer.allocate(format.getStride() * vertexCount); + vertices.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)); + vertices.putFloat(reader.getX(i)); + vertices.putFloat(reader.getY(i)); + vertices.putFloat(reader.getZ(i)); - to.put(reader.getNX(i)); - to.put(reader.getNY(i)); - to.put(reader.getNZ(i)); + vertices.put(reader.getNX(i)); + vertices.put(reader.getNY(i)); + vertices.put(reader.getNZ(i)); - to.putFloat(reader.getU(i)); - to.putFloat(reader.getV(i)); + vertices.putFloat(reader.getU(i)); + vertices.putFloat(reader.getV(i)); - to.put(reader.getR(i)); - to.put(reader.getG(i)); - to.put(reader.getB(i)); - to.put(reader.getA(i)); + vertices.put(reader.getR(i)); + vertices.put(reader.getG(i)); + vertices.put(reader.getB(i)); + vertices.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); + vertices.put(block); + vertices.put(sky); } - to.rewind(); + vertices.rewind(); - if (Backend.compat.vertexArrayObjectsSupported()) - return new BufferedArrayModel(GlPrimitive.QUADS, format, to, vertexCount); - else - return new BufferedModel(GlPrimitive.QUADS, format, to, vertexCount); +//// if (Backend.compat.vertexArrayObjectsSupported()) +//// return new BufferedArrayModel(GlPrimitive.QUADS, format, vertices, vertexCount); +//// else +// return new BufferedModel(GlPrimitive.QUADS, format, vertices, vertexCount); + + int quadCount = vertexCount / 4; + int triangleCount = vertexCount / 2; + int indexCount = triangleCount * 3; + + GlNumericType type; + + int bitWidth = MathHelper.log2(indexCount); + if (bitWidth <= 8) { + type = GlNumericType.UBYTE; + } else if (bitWidth <= 16) { + type = GlNumericType.USHORT; + } else { + type = GlNumericType.UINT; + } + + ByteBuffer indices = ByteBuffer.allocate(indexCount * type.getByteWidth()); + indices.order(ByteOrder.nativeOrder()); + + for (int i = 0; i < quadCount; i++) { + int qStart = 4 * i; + // triangle 1 + type.castAndBuffer(indices, qStart); + type.castAndBuffer(indices, qStart + 1); + type.castAndBuffer(indices, qStart + 2); + // triangle 2 + type.castAndBuffer(indices, qStart); + type.castAndBuffer(indices, qStart + 2); + type.castAndBuffer(indices, qStart + 3); + } + + indices.flip(); + + return new IndexedModel(GlPrimitive.TRIANGLES, format, vertices, vertexCount, indices, indexCount, type); } }