Instance triangles
This commit is contained in:
parent
3500b4ec87
commit
8fab6c4643
12 changed files with 275 additions and 194 deletions
|
@ -30,7 +30,7 @@ public abstract class GlObject {
|
||||||
this.handle = INVALID_HANDLE;
|
this.handle = INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void delete() {
|
public void delete() {
|
||||||
if (!isHandleValid()) {
|
if (!isHandleValid()) {
|
||||||
throw new IllegalStateException("Handle already deleted.");
|
throw new IllegalStateException("Handle already deleted.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
|
||||||
import com.jozufozu.flywheel.core.BufferedModel;
|
import com.jozufozu.flywheel.core.model.BufferedModel;
|
||||||
import com.jozufozu.flywheel.util.AttribUtil;
|
import com.jozufozu.flywheel.util.AttribUtil;
|
||||||
|
|
||||||
public class Instancer<D extends InstanceData> {
|
public class Instancer<D extends InstanceData> {
|
||||||
|
@ -47,13 +47,13 @@ public class Instancer<D extends InstanceData> {
|
||||||
vao.bind();
|
vao.bind();
|
||||||
|
|
||||||
// bind the model's vbo to our vao
|
// bind the model's vbo to our vao
|
||||||
model.bindBuffer();
|
model.setupState();
|
||||||
model.getFormat().vertexAttribPointers(0);
|
|
||||||
model.unbindBuffer();
|
AttribUtil.enableArrays(model.getAttributeCount() + instanceFormat.getAttributeCount());
|
||||||
|
|
||||||
// enable all the attribute arrays in our vao. we only need to do this once
|
|
||||||
AttribUtil.enableArrays(model.getAttributeCount() + this.instanceFormat.getAttributeCount());
|
|
||||||
vao.unbind();
|
vao.unbind();
|
||||||
|
|
||||||
|
model.clearState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render() {
|
public void render() {
|
||||||
|
|
|
@ -15,11 +15,13 @@ import com.google.common.cache.CacheBuilder;
|
||||||
import com.jozufozu.flywheel.backend.RenderWork;
|
import com.jozufozu.flywheel.backend.RenderWork;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlPrimitive;
|
import com.jozufozu.flywheel.backend.gl.GlPrimitive;
|
||||||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||||
import com.jozufozu.flywheel.core.BufferedModel;
|
|
||||||
import com.jozufozu.flywheel.core.PartialModel;
|
import com.jozufozu.flywheel.core.PartialModel;
|
||||||
|
import com.jozufozu.flywheel.core.model.BufferedModel;
|
||||||
|
import com.jozufozu.flywheel.core.model.IndexedModel;
|
||||||
import com.jozufozu.flywheel.core.shader.IProgramCallback;
|
import com.jozufozu.flywheel.core.shader.IProgramCallback;
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
import com.jozufozu.flywheel.util.BufferBuilderReader;
|
import com.jozufozu.flywheel.util.BufferBuilderReader;
|
||||||
|
import com.jozufozu.flywheel.util.QuadConverter;
|
||||||
import com.jozufozu.flywheel.util.RenderUtil;
|
import com.jozufozu.flywheel.util.RenderUtil;
|
||||||
import com.jozufozu.flywheel.util.VirtualEmptyModelData;
|
import com.jozufozu.flywheel.util.VirtualEmptyModelData;
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
@ -128,25 +130,26 @@ public class RenderMaterial<P extends WorldProgram, D extends InstanceData> {
|
||||||
VertexFormat format = spec.getModelFormat();
|
VertexFormat format = spec.getModelFormat();
|
||||||
int vertexCount = reader.getVertexCount();
|
int vertexCount = reader.getVertexCount();
|
||||||
|
|
||||||
ByteBuffer to = ByteBuffer.allocate(vertexCount * format.getStride());
|
ByteBuffer vertices = ByteBuffer.allocate(vertexCount * format.getStride());
|
||||||
to.order(ByteOrder.nativeOrder());
|
vertices.order(ByteOrder.nativeOrder());
|
||||||
|
|
||||||
for (int i = 0; i < vertexCount; i++) {
|
for (int i = 0; i < vertexCount; i++) {
|
||||||
to.putFloat(reader.getX(i));
|
vertices.putFloat(reader.getX(i));
|
||||||
to.putFloat(reader.getY(i));
|
vertices.putFloat(reader.getY(i));
|
||||||
to.putFloat(reader.getZ(i));
|
vertices.putFloat(reader.getZ(i));
|
||||||
|
|
||||||
to.put(reader.getNX(i));
|
vertices.put(reader.getNX(i));
|
||||||
to.put(reader.getNY(i));
|
vertices.put(reader.getNY(i));
|
||||||
to.put(reader.getNZ(i));
|
vertices.put(reader.getNZ(i));
|
||||||
|
|
||||||
to.putFloat(reader.getU(i));
|
vertices.putFloat(reader.getU(i));
|
||||||
to.putFloat(reader.getV(i));
|
vertices.putFloat(reader.getV(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
to.rewind();
|
vertices.rewind();
|
||||||
|
|
||||||
BufferedModel bufferedModel = new BufferedModel(GlPrimitive.QUADS, format, to, vertexCount);
|
BufferedModel bufferedModel = new IndexedModel(GlPrimitive.TRIANGLES, format, vertices, vertexCount, QuadConverter.getInstance().getEboForNQuads(vertexCount / 4));
|
||||||
|
//BufferedModel bufferedModel = new BufferedModel(GlPrimitive.QUADS, format, vertices, vertexCount);
|
||||||
|
|
||||||
return new Instancer<>(bufferedModel, renderer, spec.getInstanceFormat(), spec.getInstanceFactory());
|
return new Instancer<>(bufferedModel, renderer, spec.getInstanceFormat(), spec.getInstanceFactory());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
package com.jozufozu.flywheel.core;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL11;
|
|
||||||
import org.lwjgl.opengl.GL20;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.GlPrimitive;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
|
||||||
import com.jozufozu.flywheel.util.AttribUtil;
|
|
||||||
|
|
||||||
public class BufferedArrayModel extends BufferedModel {
|
|
||||||
|
|
||||||
protected GlVertexArray vao;
|
|
||||||
|
|
||||||
public BufferedArrayModel(GlPrimitive primitiveMode, VertexFormat format, ByteBuffer data, int vertices) {
|
|
||||||
super(primitiveMode, format, data, vertices);
|
|
||||||
|
|
||||||
vao = new GlVertexArray();
|
|
||||||
|
|
||||||
vao.bind();
|
|
||||||
|
|
||||||
// bind the model's vbo to our vao
|
|
||||||
vbo.bind();
|
|
||||||
getFormat().vertexAttribPointers(0);
|
|
||||||
|
|
||||||
// enable all the attribute arrays in our vao. we only need to do this once
|
|
||||||
AttribUtil.enableArrays(getAttributeCount());
|
|
||||||
vbo.unbind();
|
|
||||||
vao.unbind();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw() {
|
|
||||||
if (vertexCount <= 0 || deleted) return;
|
|
||||||
|
|
||||||
vao.bind();
|
|
||||||
|
|
||||||
GL20.glDrawArrays(GL11.GL_QUADS, 0, vertexCount);
|
|
||||||
|
|
||||||
vao.unbind();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete() {
|
|
||||||
super.delete();
|
|
||||||
vao.delete();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
package com.jozufozu.flywheel.core;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL20;
|
|
||||||
|
|
||||||
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.VertexFormat;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
|
||||||
import com.jozufozu.flywheel.util.AttribUtil;
|
|
||||||
|
|
||||||
public class IndexedModel extends BufferedModel {
|
|
||||||
|
|
||||||
protected int elementCount;
|
|
||||||
protected GlNumericType eboIndexType;
|
|
||||||
protected GlBuffer ebo;
|
|
||||||
|
|
||||||
public IndexedModel(GlPrimitive primitiveMode, VertexFormat modelFormat, ByteBuffer buf, int vertices, ByteBuffer indices, int elementCount, GlNumericType indexType) {
|
|
||||||
super(primitiveMode, modelFormat, buf, vertices);
|
|
||||||
|
|
||||||
this.ebo = new GlBuffer(GlBufferType.ELEMENT_ARRAY_BUFFER);
|
|
||||||
this.eboIndexType = indexType;
|
|
||||||
this.elementCount = elementCount;
|
|
||||||
|
|
||||||
int indicesSize = elementCount * indexType.getByteWidth();
|
|
||||||
|
|
||||||
ebo.bind();
|
|
||||||
|
|
||||||
ebo.alloc(indicesSize);
|
|
||||||
ebo.getBuffer(0, indicesSize)
|
|
||||||
.put(indices)
|
|
||||||
.flush();
|
|
||||||
|
|
||||||
ebo.unbind();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw() {
|
|
||||||
ebo.bind();
|
|
||||||
vbo.bind();
|
|
||||||
|
|
||||||
AttribUtil.enableArrays(getAttributeCount());
|
|
||||||
format.vertexAttribPointers(0);
|
|
||||||
|
|
||||||
GL20.glDrawElements(primitiveMode.glEnum, elementCount, eboIndexType.getGlEnum(), 0);
|
|
||||||
|
|
||||||
AttribUtil.disableArrays(getAttributeCount());
|
|
||||||
|
|
||||||
ebo.unbind();
|
|
||||||
vbo.unbind();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drawInstances(int instanceCount) {
|
|
||||||
if (vertexCount <= 0 || deleted) return;
|
|
||||||
|
|
||||||
ebo.bind();
|
|
||||||
Backend.compat.drawInstanced.drawElementsInstanced(primitiveMode, 0, eboIndexType, 0, instanceCount);
|
|
||||||
ebo.unbind();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete() {
|
|
||||||
super.delete();
|
|
||||||
ebo.delete();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.jozufozu.flywheel.core.model;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
|
||||||
|
|
||||||
|
public class ArrayModelRenderer extends ModelRenderer {
|
||||||
|
|
||||||
|
protected GlVertexArray vao;
|
||||||
|
|
||||||
|
public ArrayModelRenderer(BufferedModel model) {
|
||||||
|
super(model);
|
||||||
|
vao = new GlVertexArray();
|
||||||
|
|
||||||
|
vao.bind();
|
||||||
|
model.setupState();
|
||||||
|
vao.unbind();
|
||||||
|
model.clearState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw() {
|
||||||
|
if (!model.valid()) return;
|
||||||
|
|
||||||
|
vao.bind();
|
||||||
|
|
||||||
|
model.drawCall();
|
||||||
|
|
||||||
|
vao.unbind();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.core;
|
package com.jozufozu.flywheel.core.model;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL20.glDrawArrays;
|
import static org.lwjgl.opengl.GL20.glDrawArrays;
|
||||||
|
|
||||||
|
@ -55,29 +55,33 @@ public class BufferedModel {
|
||||||
vbo.unbind();
|
vbo.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean valid() {
|
||||||
|
return vertexCount > 0 && !deleted;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders this model, checking first if there is anything to render.
|
* The VBO/VAO should be bound externally.
|
||||||
*/
|
*/
|
||||||
public void draw() {
|
public void setupState() {
|
||||||
if (vertexCount <= 0 || deleted) return;
|
|
||||||
|
|
||||||
vbo.bind();
|
vbo.bind();
|
||||||
|
|
||||||
AttribUtil.enableArrays(getAttributeCount());
|
AttribUtil.enableArrays(getAttributeCount());
|
||||||
format.vertexAttribPointers(0);
|
format.vertexAttribPointers(0);
|
||||||
|
}
|
||||||
|
|
||||||
glDrawArrays(primitiveMode.glEnum, 0, vertexCount);
|
public void clearState() {
|
||||||
|
|
||||||
AttribUtil.disableArrays(getAttributeCount());
|
AttribUtil.disableArrays(getAttributeCount());
|
||||||
|
|
||||||
vbo.unbind();
|
vbo.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void drawCall() {
|
||||||
|
glDrawArrays(primitiveMode.glEnum, 0, vertexCount);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws many instances of this model, assuming the appropriate state is already bound.
|
* Draws many instances of this model, assuming the appropriate state is already bound.
|
||||||
*/
|
*/
|
||||||
public void drawInstances(int instanceCount) {
|
public void drawInstances(int instanceCount) {
|
||||||
if (vertexCount <= 0 || deleted) return;
|
if (!valid()) return;
|
||||||
|
|
||||||
Backend.compat.drawInstanced.drawArraysInstanced(primitiveMode, 0, vertexCount, instanceCount);
|
Backend.compat.drawInstanced.drawArraysInstanced(primitiveMode, 0, vertexCount, instanceCount);
|
||||||
}
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.jozufozu.flywheel.core.model;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.gl.GlNumericType;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||||
|
|
||||||
|
public class ElementBuffer extends GlBuffer {
|
||||||
|
|
||||||
|
public final int elementCount;
|
||||||
|
public final GlNumericType eboIndexType;
|
||||||
|
|
||||||
|
public ElementBuffer(ByteBuffer indices, int elementCount, GlNumericType indexType) {
|
||||||
|
super(GlBufferType.ELEMENT_ARRAY_BUFFER);
|
||||||
|
this.eboIndexType = indexType;
|
||||||
|
this.elementCount = elementCount;
|
||||||
|
|
||||||
|
int indicesSize = elementCount * indexType.getByteWidth();
|
||||||
|
|
||||||
|
bind();
|
||||||
|
|
||||||
|
alloc(indicesSize);
|
||||||
|
getBuffer(0, indicesSize)
|
||||||
|
.put(indices)
|
||||||
|
.flush();
|
||||||
|
|
||||||
|
unbind();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.jozufozu.flywheel.core.model;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL20;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.GlPrimitive;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||||
|
|
||||||
|
public class IndexedModel extends BufferedModel {
|
||||||
|
|
||||||
|
protected ElementBuffer ebo;
|
||||||
|
|
||||||
|
public IndexedModel(GlPrimitive primitiveMode, VertexFormat modelFormat, ByteBuffer buf, int vertices, ElementBuffer ebo) {
|
||||||
|
super(primitiveMode, modelFormat, buf, vertices);
|
||||||
|
|
||||||
|
this.ebo = ebo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setupState() {
|
||||||
|
super.setupState();
|
||||||
|
ebo.bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearState() {
|
||||||
|
super.clearState();
|
||||||
|
ebo.unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawCall() {
|
||||||
|
GL20.glDrawElements(primitiveMode.glEnum, ebo.elementCount, ebo.eboIndexType.getGlEnum(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawInstances(int instanceCount) {
|
||||||
|
if (vertexCount <= 0 || deleted) return;
|
||||||
|
|
||||||
|
Backend.compat.drawInstanced.drawElementsInstanced(primitiveMode, ebo.elementCount, ebo.eboIndexType, 0, instanceCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete() {
|
||||||
|
super.delete();
|
||||||
|
ebo.delete();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.jozufozu.flywheel.core.model;
|
||||||
|
|
||||||
|
public class ModelRenderer {
|
||||||
|
|
||||||
|
protected BufferedModel model;
|
||||||
|
|
||||||
|
public ModelRenderer(BufferedModel model) {
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders this model, checking first if there is anything to render.
|
||||||
|
*/
|
||||||
|
public void draw() {
|
||||||
|
if (!model.valid()) return;
|
||||||
|
|
||||||
|
model.setupState();
|
||||||
|
model.drawCall();
|
||||||
|
model.clearState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
model.delete();
|
||||||
|
}
|
||||||
|
}
|
88
src/main/java/com/jozufozu/flywheel/util/QuadConverter.java
Normal file
88
src/main/java/com/jozufozu/flywheel/util/QuadConverter.java
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
package com.jozufozu.flywheel.util;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.gl.GlNumericType;
|
||||||
|
import com.jozufozu.flywheel.core.model.ElementBuffer;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
|
public class QuadConverter {
|
||||||
|
|
||||||
|
private static QuadConverter INSTANCE = new QuadConverter();
|
||||||
|
|
||||||
|
public static QuadConverter getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Int2ObjectMap<CachedEbo> quads2Tris;
|
||||||
|
|
||||||
|
public QuadConverter() {
|
||||||
|
quads2Tris = new Int2ObjectOpenHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ElementBuffer getEboForNQuads(int quads) {
|
||||||
|
quads2Tris.values().removeIf(CachedEbo::noReferences);
|
||||||
|
|
||||||
|
CachedEbo ebo = quads2Tris.computeIfAbsent(quads, quadCount -> {
|
||||||
|
int triangleCount = quadCount * 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 CachedEbo(indices, indexCount, type);
|
||||||
|
});
|
||||||
|
|
||||||
|
ebo.refCount++;
|
||||||
|
|
||||||
|
return ebo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CachedEbo extends ElementBuffer {
|
||||||
|
int refCount = 1;
|
||||||
|
|
||||||
|
public CachedEbo(ByteBuffer indices, int elementCount, GlNumericType indexType) {
|
||||||
|
super(indices, elementCount, indexType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete() {
|
||||||
|
refCount--;
|
||||||
|
|
||||||
|
if (refCount == 0)
|
||||||
|
super.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean noReferences() {
|
||||||
|
return refCount == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,15 +10,17 @@ import java.util.Map;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
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.GlPrimitive;
|
||||||
import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes;
|
import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes;
|
||||||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||||
import com.jozufozu.flywheel.backend.instancing.IInstanceRendered;
|
import com.jozufozu.flywheel.backend.instancing.IInstanceRendered;
|
||||||
import com.jozufozu.flywheel.core.BufferedModel;
|
import com.jozufozu.flywheel.core.model.ArrayModelRenderer;
|
||||||
import com.jozufozu.flywheel.core.IndexedModel;
|
import com.jozufozu.flywheel.core.model.BufferedModel;
|
||||||
|
import com.jozufozu.flywheel.core.model.IndexedModel;
|
||||||
|
import com.jozufozu.flywheel.core.model.ModelRenderer;
|
||||||
import com.jozufozu.flywheel.light.GridAlignedBB;
|
import com.jozufozu.flywheel.light.GridAlignedBB;
|
||||||
import com.jozufozu.flywheel.util.BufferBuilderReader;
|
import com.jozufozu.flywheel.util.BufferBuilderReader;
|
||||||
|
import com.jozufozu.flywheel.util.QuadConverter;
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||||
|
@ -48,7 +50,7 @@ public class RenderedContraption extends ContraptionWorldHolder {
|
||||||
private final ContraptionLighter<?> lighter;
|
private final ContraptionLighter<?> lighter;
|
||||||
public final ContraptionKineticRenderer kinetics;
|
public final ContraptionKineticRenderer kinetics;
|
||||||
|
|
||||||
private final Map<RenderType, BufferedModel> renderLayers = new HashMap<>();
|
private final Map<RenderType, ModelRenderer> renderLayers = new HashMap<>();
|
||||||
|
|
||||||
private Matrix4f model;
|
private Matrix4f model;
|
||||||
private AxisAlignedBB lightBox;
|
private AxisAlignedBB lightBox;
|
||||||
|
@ -70,7 +72,7 @@ public class RenderedContraption extends ContraptionWorldHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doRenderLayer(RenderType layer, ContraptionProgram shader) {
|
public void doRenderLayer(RenderType layer, ContraptionProgram shader) {
|
||||||
BufferedModel structure = renderLayers.get(layer);
|
ModelRenderer structure = renderLayers.get(layer);
|
||||||
if (structure != null) {
|
if (structure != null) {
|
||||||
setup(shader);
|
setup(shader);
|
||||||
structure.draw();
|
structure.draw();
|
||||||
|
@ -111,7 +113,7 @@ public class RenderedContraption extends ContraptionWorldHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
void invalidate() {
|
void invalidate() {
|
||||||
for (BufferedModel buffer : renderLayers.values()) {
|
for (ModelRenderer buffer : renderLayers.values()) {
|
||||||
buffer.delete();
|
buffer.delete();
|
||||||
}
|
}
|
||||||
renderLayers.clear();
|
renderLayers.clear();
|
||||||
|
@ -122,7 +124,7 @@ public class RenderedContraption extends ContraptionWorldHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildLayers() {
|
private void buildLayers() {
|
||||||
for (BufferedModel buffer : renderLayers.values()) {
|
for (ModelRenderer buffer : renderLayers.values()) {
|
||||||
buffer.delete();
|
buffer.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +134,13 @@ public class RenderedContraption extends ContraptionWorldHolder {
|
||||||
|
|
||||||
for (RenderType layer : blockLayers) {
|
for (RenderType layer : blockLayers) {
|
||||||
BufferedModel layerModel = buildStructureModel(renderWorld, contraption, layer);
|
BufferedModel layerModel = buildStructureModel(renderWorld, contraption, layer);
|
||||||
if (layerModel != null) renderLayers.put(layer, layerModel);
|
|
||||||
|
if (layerModel != null) {
|
||||||
|
if (Backend.compat.vertexArrayObjectsSupported())
|
||||||
|
renderLayers.put(layer, new ArrayModelRenderer(layerModel));
|
||||||
|
else
|
||||||
|
renderLayers.put(layer, new ModelRenderer(layerModel));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,43 +203,6 @@ public class RenderedContraption extends ContraptionWorldHolder {
|
||||||
|
|
||||||
vertices.rewind();
|
vertices.rewind();
|
||||||
|
|
||||||
//// if (Backend.compat.vertexArrayObjectsSupported())
|
return new IndexedModel(GlPrimitive.TRIANGLES, format, vertices, vertexCount, QuadConverter.getInstance().getEboForNQuads(vertexCount / 4));
|
||||||
//// 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue