mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-29 08:26:37 +01:00
Errors and pools
- GlException and error checking WIP - Put all models within a material in a ModelPool - Instancers directly accept IModels - ModelPools are very WIP
This commit is contained in:
parent
f4f6087e08
commit
2137f9e46d
20 changed files with 513 additions and 69 deletions
|
@ -1,6 +1,8 @@
|
||||||
package com.jozufozu.flywheel.backend.gl.attrib;
|
package com.jozufozu.flywheel.backend.gl.attrib;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL20;
|
import org.lwjgl.opengl.GL20;
|
||||||
|
import org.lwjgl.opengl.GL44;
|
||||||
|
import org.lwjgl.opengl.GL46;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.GlNumericType;
|
import com.jozufozu.flywheel.backend.gl.GlNumericType;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package com.jozufozu.flywheel.backend.gl.buffer;
|
package com.jozufozu.flywheel.backend.gl.buffer;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.error.GlError;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.error.GlException;
|
||||||
|
import com.jozufozu.flywheel.util.StringUtil;
|
||||||
|
|
||||||
public class MappedBufferRange extends MappedBuffer {
|
public class MappedBufferRange extends MappedBuffer {
|
||||||
|
|
||||||
|
@ -27,6 +30,12 @@ public class MappedBufferRange extends MappedBuffer {
|
||||||
protected void checkAndMap() {
|
protected void checkAndMap() {
|
||||||
if (!mapped) {
|
if (!mapped) {
|
||||||
setInternal(Backend.getInstance().compat.mapBufferRange.mapBuffer(owner.type, offset, length, access));
|
setInternal(Backend.getInstance().compat.mapBufferRange.mapBuffer(owner.type, offset, length, access));
|
||||||
|
|
||||||
|
GlError error = GlError.poll();
|
||||||
|
|
||||||
|
if (error != null) {
|
||||||
|
throw new GlException(error, StringUtil.args("mapBufferRange", owner.type, offset, length, access));
|
||||||
|
}
|
||||||
mapped = true;
|
mapped = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,10 @@ package com.jozufozu.flywheel.backend.gl.buffer;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL15;
|
import org.lwjgl.opengl.GL15;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.gl.error.GlError;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.error.GlException;
|
||||||
|
import com.jozufozu.flywheel.util.StringUtil;
|
||||||
|
|
||||||
public class MappedFullBuffer extends MappedBuffer {
|
public class MappedFullBuffer extends MappedBuffer {
|
||||||
|
|
||||||
MappedBufferUsage usage;
|
MappedBufferUsage usage;
|
||||||
|
@ -15,6 +19,13 @@ public class MappedFullBuffer extends MappedBuffer {
|
||||||
protected void checkAndMap() {
|
protected void checkAndMap() {
|
||||||
if (!mapped) {
|
if (!mapped) {
|
||||||
setInternal(GL15.glMapBuffer(owner.type.glEnum, usage.glEnum));
|
setInternal(GL15.glMapBuffer(owner.type.glEnum, usage.glEnum));
|
||||||
|
|
||||||
|
GlError error = GlError.poll();
|
||||||
|
|
||||||
|
if (error != null) {
|
||||||
|
throw new GlException(error, StringUtil.args("mapBuffer", owner.type, usage));
|
||||||
|
}
|
||||||
|
|
||||||
mapped = true;
|
mapped = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,9 @@ import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlFence;
|
import com.jozufozu.flywheel.backend.gl.GlFence;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.error.GlError;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.error.GlException;
|
||||||
|
import com.jozufozu.flywheel.util.StringUtil;
|
||||||
|
|
||||||
|
|
||||||
public class PersistentGlBuffer extends GlBuffer {
|
public class PersistentGlBuffer extends GlBuffer {
|
||||||
|
@ -35,11 +38,19 @@ public class PersistentGlBuffer extends GlBuffer {
|
||||||
if (buffer != null) {
|
if (buffer != null) {
|
||||||
deleteInternal(handle());
|
deleteInternal(handle());
|
||||||
_create();
|
_create();
|
||||||
|
|
||||||
|
bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
fence.clear();
|
fence.clear();
|
||||||
|
|
||||||
Backend.getInstance().compat.bufferStorage.bufferStorage(type.glEnum, size, flags);
|
Backend.getInstance().compat.bufferStorage.bufferStorage(type, size, flags);
|
||||||
|
|
||||||
|
GlError error = GlError.poll();
|
||||||
|
|
||||||
|
if (error != null) {
|
||||||
|
throw new GlException(error, StringUtil.args("bufferStorage", type, size, flags));
|
||||||
|
}
|
||||||
|
|
||||||
buffer = new PersistentMappedBuffer(this);
|
buffer = new PersistentMappedBuffer(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,25 +2,42 @@ package com.jozufozu.flywheel.backend.gl.buffer;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL15;
|
|
||||||
import org.lwjgl.opengl.GL44;
|
|
||||||
import org.lwjgl.opengl.GL46;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.error.GlError;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.error.GlException;
|
||||||
|
import com.jozufozu.flywheel.util.StringUtil;
|
||||||
|
|
||||||
public class PersistentMappedBuffer extends MappedBuffer {
|
public class PersistentMappedBuffer extends MappedBuffer {
|
||||||
|
|
||||||
|
private final long offset;
|
||||||
|
private final long length;
|
||||||
PersistentGlBuffer owner;
|
PersistentGlBuffer owner;
|
||||||
|
|
||||||
public PersistentMappedBuffer(PersistentGlBuffer buffer) {
|
public PersistentMappedBuffer(PersistentGlBuffer buffer) {
|
||||||
super(buffer);
|
super(buffer);
|
||||||
owner = buffer;
|
owner = buffer;
|
||||||
|
offset = 0;
|
||||||
|
length = owner.size;
|
||||||
|
|
||||||
ByteBuffer byteBuffer = Backend.getInstance().compat.mapBufferRange.mapBuffer(owner.type, 0, owner.size, owner.flags);
|
ByteBuffer byteBuffer = Backend.getInstance().compat.mapBufferRange.mapBuffer(owner.type, offset, length, owner.flags);
|
||||||
|
|
||||||
|
GlError error = GlError.poll();
|
||||||
|
|
||||||
|
if (error != null) {
|
||||||
|
throw new GlException(error, StringUtil.args("mapBuffer", owner.type, offset, length, owner.flags));
|
||||||
|
}
|
||||||
|
|
||||||
setInternal(byteBuffer);
|
setInternal(byteBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.jozufozu.flywheel.backend.gl.error;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL20;
|
||||||
|
import org.lwjgl.opengl.GL30;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
|
||||||
|
public enum GlError {
|
||||||
|
INVALID_ENUM(GL20.GL_INVALID_ENUM),
|
||||||
|
INVALID_VALUE(GL20.GL_INVALID_VALUE),
|
||||||
|
INVALID_OPERATION(GL20.GL_INVALID_OPERATION),
|
||||||
|
INVALID_FRAMEBUFFER_OPERATION(GL30.GL_INVALID_FRAMEBUFFER_OPERATION),
|
||||||
|
OUT_OF_MEMORY(GL20.GL_OUT_OF_MEMORY),
|
||||||
|
STACK_UNDERFLOW(GL20.GL_STACK_UNDERFLOW),
|
||||||
|
STACK_OVERFLOW(GL20.GL_STACK_OVERFLOW),
|
||||||
|
;
|
||||||
|
|
||||||
|
private static final Int2ObjectMap<GlError> errorLookup = new Int2ObjectArrayMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
errorLookup.defaultReturnValue(null);
|
||||||
|
for (GlError value : values()) {
|
||||||
|
errorLookup.put(value.glEnum, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final int glEnum;
|
||||||
|
|
||||||
|
GlError(int glEnum) {
|
||||||
|
this.glEnum = glEnum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static GlError poll() {
|
||||||
|
return errorLookup.get(GL20.glGetError());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.jozufozu.flywheel.backend.gl.error;
|
||||||
|
|
||||||
|
public class GlException extends RuntimeException {
|
||||||
|
|
||||||
|
final GlError errorCode;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String s = getClass().getName();
|
||||||
|
String message = getLocalizedMessage();
|
||||||
|
String withCode = s + ": " + errorCode;
|
||||||
|
return (message != null) ? (withCode + ": " + message) : withCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlException(GlError errorCode) {
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlException(GlError errorCode, String message) {
|
||||||
|
super(message);
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlException(GlError errorCode, String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlException(GlError errorCode, Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlException(GlError errorCode, String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||||
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,8 @@ import org.lwjgl.opengl.ARBBufferStorage;
|
||||||
import org.lwjgl.opengl.GL44;
|
import org.lwjgl.opengl.GL44;
|
||||||
import org.lwjgl.opengl.GLCapabilities;
|
import org.lwjgl.opengl.GLCapabilities;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||||
|
|
||||||
public enum BufferStorage implements GlVersioned {
|
public enum BufferStorage implements GlVersioned {
|
||||||
|
|
||||||
GL44CORE {
|
GL44CORE {
|
||||||
|
@ -13,8 +15,8 @@ public enum BufferStorage implements GlVersioned {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bufferStorage(int target, long size, int flags) {
|
public void bufferStorage(GlBufferType target, long size, int flags) {
|
||||||
GL44.glBufferStorage(target, size, flags);
|
GL44.glBufferStorage(target.glEnum, size, flags);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ARB {
|
ARB {
|
||||||
|
@ -24,8 +26,8 @@ public enum BufferStorage implements GlVersioned {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bufferStorage(int target, long size, int flags) {
|
public void bufferStorage(GlBufferType target, long size, int flags) {
|
||||||
ARBBufferStorage.glBufferStorage(target, size, flags);
|
ARBBufferStorage.glBufferStorage(target.glEnum, size, flags);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
UNSUPPORTED {
|
UNSUPPORTED {
|
||||||
|
@ -35,10 +37,10 @@ public enum BufferStorage implements GlVersioned {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bufferStorage(int target, long size, int flags) {
|
public void bufferStorage(GlBufferType target, long size, int flags) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public abstract void bufferStorage(int target, long size, int flags);
|
public abstract void bufferStorage(GlBufferType target, long size, int flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.lwjgl.system.MemoryUtil;
|
||||||
import com.jozufozu.flywheel.backend.gl.versioned.framebuffer.Blit;
|
import com.jozufozu.flywheel.backend.gl.versioned.framebuffer.Blit;
|
||||||
import com.jozufozu.flywheel.backend.gl.versioned.framebuffer.Framebuffer;
|
import com.jozufozu.flywheel.backend.gl.versioned.framebuffer.Framebuffer;
|
||||||
import com.jozufozu.flywheel.backend.gl.versioned.instancing.DrawInstanced;
|
import com.jozufozu.flywheel.backend.gl.versioned.instancing.DrawInstanced;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.versioned.instancing.BaseVertex;
|
||||||
import com.jozufozu.flywheel.backend.gl.versioned.instancing.InstancedArrays;
|
import com.jozufozu.flywheel.backend.gl.versioned.instancing.InstancedArrays;
|
||||||
import com.jozufozu.flywheel.backend.gl.versioned.instancing.VertexArrayObject;
|
import com.jozufozu.flywheel.backend.gl.versioned.instancing.VertexArrayObject;
|
||||||
|
|
||||||
|
@ -32,6 +33,7 @@ public class GlCompat {
|
||||||
public final BufferStorage bufferStorage;
|
public final BufferStorage bufferStorage;
|
||||||
|
|
||||||
public final RGPixelFormat pixelFormat;
|
public final RGPixelFormat pixelFormat;
|
||||||
|
public final BaseVertex baseVertex;
|
||||||
|
|
||||||
public GlCompat(GLCapabilities caps) {
|
public GlCompat(GLCapabilities caps) {
|
||||||
mapBufferRange = getLatest(MapBufferRange.class, caps);
|
mapBufferRange = getLatest(MapBufferRange.class, caps);
|
||||||
|
@ -39,6 +41,7 @@ public class GlCompat {
|
||||||
vao = getLatest(VertexArrayObject.class, caps);
|
vao = getLatest(VertexArrayObject.class, caps);
|
||||||
instancedArrays = getLatest(InstancedArrays.class, caps);
|
instancedArrays = getLatest(InstancedArrays.class, caps);
|
||||||
drawInstanced = getLatest(DrawInstanced.class, caps);
|
drawInstanced = getLatest(DrawInstanced.class, caps);
|
||||||
|
baseVertex = getLatest(BaseVertex.class, caps);
|
||||||
blit = getLatest(Blit.class, caps);
|
blit = getLatest(Blit.class, caps);
|
||||||
fbo = getLatest(Framebuffer.class, caps);
|
fbo = getLatest(Framebuffer.class, caps);
|
||||||
bufferStorage = getLatest(BufferStorage.class, caps);
|
bufferStorage = getLatest(BufferStorage.class, caps);
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.jozufozu.flywheel.backend.gl.versioned.instancing;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.ARBDrawElementsBaseVertex;
|
||||||
|
import org.lwjgl.opengl.ARBDrawInstanced;
|
||||||
|
import org.lwjgl.opengl.EXTDrawInstanced;
|
||||||
|
import org.lwjgl.opengl.GL32;
|
||||||
|
import org.lwjgl.opengl.GLCapabilities;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.gl.GlNumericType;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.GlPrimitive;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.versioned.GlVersioned;
|
||||||
|
|
||||||
|
public enum BaseVertex implements GlVersioned {
|
||||||
|
GL31_CORE {
|
||||||
|
@Override
|
||||||
|
public boolean supported(GLCapabilities caps) {
|
||||||
|
return caps.OpenGL31;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawElementsInstancedBaseVertex(GlPrimitive mode, int elementCount, GlNumericType type, long indices, int instanceCount, int baseVertex) {
|
||||||
|
GL32.glDrawElementsInstancedBaseVertex(mode.glEnum, elementCount, type.getGlEnum(), indices, instanceCount, baseVertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawElementsBaseVertex(GlPrimitive mode, int elementCount, GlNumericType type, long indices, int baseVertex) {
|
||||||
|
GL32.glDrawElementsBaseVertex(mode.glEnum, elementCount, type.getGlEnum(), indices, baseVertex);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ARB {
|
||||||
|
@Override
|
||||||
|
public boolean supported(GLCapabilities caps) {
|
||||||
|
return caps.GL_ARB_draw_elements_base_vertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawElementsInstancedBaseVertex(GlPrimitive mode, int elementCount, GlNumericType type, long indices, int instanceCount, int baseVertex) {
|
||||||
|
ARBDrawElementsBaseVertex.glDrawElementsInstancedBaseVertex(mode.glEnum, elementCount, type.getGlEnum(), indices, instanceCount, baseVertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawElementsBaseVertex(GlPrimitive mode, int elementCount, GlNumericType type, long indices, int baseVertex) {
|
||||||
|
ARBDrawElementsBaseVertex.glDrawElementsBaseVertex(mode.glEnum, elementCount, type.getGlEnum(), indices, baseVertex);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
UNSUPPORTED {
|
||||||
|
@Override
|
||||||
|
public boolean supported(GLCapabilities caps) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public void drawElementsInstancedBaseVertex(GlPrimitive mode, int elementCount, GlNumericType type, long indices, int instanceCount, int baseVertex) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void drawElementsBaseVertex(GlPrimitive mode, int elementCount, GlNumericType type, long indices, int baseVertex) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package com.jozufozu.flywheel.backend.gl.versioned.instancing;
|
||||||
import org.lwjgl.opengl.ARBDrawInstanced;
|
import org.lwjgl.opengl.ARBDrawInstanced;
|
||||||
import org.lwjgl.opengl.EXTDrawInstanced;
|
import org.lwjgl.opengl.EXTDrawInstanced;
|
||||||
import org.lwjgl.opengl.GL31;
|
import org.lwjgl.opengl.GL31;
|
||||||
|
import org.lwjgl.opengl.GL46;
|
||||||
import org.lwjgl.opengl.GLCapabilities;
|
import org.lwjgl.opengl.GLCapabilities;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.GlNumericType;
|
import com.jozufozu.flywheel.backend.gl.GlNumericType;
|
||||||
|
@ -10,7 +11,7 @@ import com.jozufozu.flywheel.backend.gl.GlPrimitive;
|
||||||
import com.jozufozu.flywheel.backend.gl.versioned.GlVersioned;
|
import com.jozufozu.flywheel.backend.gl.versioned.GlVersioned;
|
||||||
|
|
||||||
public enum DrawInstanced implements GlVersioned {
|
public enum DrawInstanced implements GlVersioned {
|
||||||
GL31_DRAW_INSTANCED {
|
GL31_CORE {
|
||||||
@Override
|
@Override
|
||||||
public boolean supported(GLCapabilities caps) {
|
public boolean supported(GLCapabilities caps) {
|
||||||
return caps.OpenGL31;
|
return caps.OpenGL31;
|
||||||
|
@ -26,7 +27,7 @@ public enum DrawInstanced implements GlVersioned {
|
||||||
GL31.glDrawElementsInstanced(mode.glEnum, elementCount, type.getGlEnum(), indices, primcount);
|
GL31.glDrawElementsInstanced(mode.glEnum, elementCount, type.getGlEnum(), indices, primcount);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ARB_DRAW_INSTANCED {
|
ARB {
|
||||||
@Override
|
@Override
|
||||||
public boolean supported(GLCapabilities caps) {
|
public boolean supported(GLCapabilities caps) {
|
||||||
return caps.GL_ARB_draw_instanced;
|
return caps.GL_ARB_draw_instanced;
|
||||||
|
@ -42,7 +43,7 @@ public enum DrawInstanced implements GlVersioned {
|
||||||
ARBDrawInstanced.glDrawElementsInstancedARB(mode.glEnum, elementCount, type.getGlEnum(), indices, primcount);
|
ARBDrawInstanced.glDrawElementsInstancedARB(mode.glEnum, elementCount, type.getGlEnum(), indices, primcount);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
EXT_DRAW_INSTANCED {
|
EXT {
|
||||||
@Override
|
@Override
|
||||||
public boolean supported(GLCapabilities caps) {
|
public boolean supported(GLCapabilities caps) {
|
||||||
return caps.GL_EXT_draw_instanced;
|
return caps.GL_EXT_draw_instanced;
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.jozufozu.flywheel.backend.instancing;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
|
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
|
||||||
|
@ -11,8 +10,8 @@ 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.backend.material.MaterialSpec;
|
import com.jozufozu.flywheel.backend.material.MaterialSpec;
|
||||||
|
import com.jozufozu.flywheel.backend.model.ModelPool;
|
||||||
import com.jozufozu.flywheel.backend.model.IBufferedModel;
|
import com.jozufozu.flywheel.backend.model.IBufferedModel;
|
||||||
import com.jozufozu.flywheel.backend.model.IndexedModel;
|
|
||||||
import com.jozufozu.flywheel.core.model.IModel;
|
import com.jozufozu.flywheel.core.model.IModel;
|
||||||
import com.jozufozu.flywheel.util.AttribUtil;
|
import com.jozufozu.flywheel.util.AttribUtil;
|
||||||
|
|
||||||
|
@ -36,25 +35,27 @@ import com.jozufozu.flywheel.util.AttribUtil;
|
||||||
*/
|
*/
|
||||||
public class Instancer<D extends InstanceData> {
|
public class Instancer<D extends InstanceData> {
|
||||||
|
|
||||||
protected final Supplier<IModel> gen;
|
private final ModelPool modelAllocator;
|
||||||
protected final VertexFormat instanceFormat;
|
private final IModel modelData;
|
||||||
protected final IInstanceFactory<D> factory;
|
private final VertexFormat instanceFormat;
|
||||||
|
private final IInstanceFactory<D> factory;
|
||||||
|
|
||||||
protected IBufferedModel model;
|
private IBufferedModel model;
|
||||||
protected GlVertexArray vao;
|
private GlVertexArray vao;
|
||||||
protected GlBuffer instanceVBO;
|
private GlBuffer instanceVBO;
|
||||||
protected int glBufferSize = -1;
|
private int glBufferSize = -1;
|
||||||
protected int glInstanceCount = 0;
|
private int glInstanceCount = 0;
|
||||||
private boolean deleted;
|
private boolean deleted;
|
||||||
private boolean initialized;
|
private boolean initialized;
|
||||||
|
|
||||||
protected final ArrayList<D> data = new ArrayList<>();
|
private final ArrayList<D> data = new ArrayList<>();
|
||||||
|
|
||||||
boolean anyToRemove;
|
boolean anyToRemove;
|
||||||
boolean anyToUpdate;
|
boolean anyToUpdate;
|
||||||
|
|
||||||
public Instancer(Supplier<IModel> model, MaterialSpec<D> spec) {
|
public Instancer(ModelPool modelAllocator, IModel model, MaterialSpec<D> spec) {
|
||||||
this.gen = model;
|
this.modelAllocator = modelAllocator;
|
||||||
|
this.modelData = model;
|
||||||
this.factory = spec.getInstanceFactory();
|
this.factory = spec.getInstanceFactory();
|
||||||
this.instanceFormat = spec.getInstanceFormat();
|
this.instanceFormat = spec.getInstanceFormat();
|
||||||
}
|
}
|
||||||
|
@ -80,7 +81,6 @@ public class Instancer<D extends InstanceData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render() {
|
public void render() {
|
||||||
if (!isInitialized()) init();
|
|
||||||
if (invalid()) return;
|
if (invalid()) return;
|
||||||
|
|
||||||
vao.bind();
|
vao.bind();
|
||||||
|
@ -98,28 +98,28 @@ public class Instancer<D extends InstanceData> {
|
||||||
return deleted || model == null;
|
return deleted || model == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init() {
|
public void init() {
|
||||||
|
if (isInitialized()) return;
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
IModel iModel = gen.get();
|
|
||||||
|
|
||||||
if (iModel.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
model = new IndexedModel(iModel);
|
|
||||||
vao = new GlVertexArray();
|
vao = new GlVertexArray();
|
||||||
instanceVBO = GlBuffer.requestPersistent(GlBufferType.ARRAY_BUFFER);
|
|
||||||
|
model = modelAllocator.alloc(modelData)
|
||||||
|
.setReallocCallback(arenaModel -> {
|
||||||
|
vao.bind();
|
||||||
|
|
||||||
|
model.setupState();
|
||||||
|
|
||||||
|
vao.unbind();
|
||||||
|
});
|
||||||
|
|
||||||
vao.bind();
|
vao.bind();
|
||||||
|
|
||||||
// bind the model's vbo to our vao
|
instanceVBO = GlBuffer.requestPersistent(GlBufferType.ARRAY_BUFFER);
|
||||||
model.setupState();
|
|
||||||
|
|
||||||
AttribUtil.enableArrays(model.getAttributeCount() + instanceFormat.getAttributeCount());
|
AttribUtil.enableArrays(model.getAttributeCount() + instanceFormat.getAttributeCount());
|
||||||
|
|
||||||
vao.unbind();
|
vao.unbind();
|
||||||
|
|
||||||
model.clearState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInitialized() {
|
public boolean isInitialized() {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.jozufozu.flywheel.backend.material;
|
package com.jozufozu.flywheel.backend.material;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.google.common.cache.Cache;
|
import com.google.common.cache.Cache;
|
||||||
|
@ -9,6 +8,7 @@ import com.google.common.cache.CacheBuilder;
|
||||||
import com.jozufozu.flywheel.backend.RenderWork;
|
import com.jozufozu.flywheel.backend.RenderWork;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||||
import com.jozufozu.flywheel.backend.instancing.Instancer;
|
import com.jozufozu.flywheel.backend.instancing.Instancer;
|
||||||
|
import com.jozufozu.flywheel.backend.model.ModelPool;
|
||||||
import com.jozufozu.flywheel.core.PartialModel;
|
import com.jozufozu.flywheel.core.PartialModel;
|
||||||
import com.jozufozu.flywheel.core.model.BlockModel;
|
import com.jozufozu.flywheel.core.model.BlockModel;
|
||||||
import com.jozufozu.flywheel.core.model.IModel;
|
import com.jozufozu.flywheel.core.model.IModel;
|
||||||
|
@ -25,12 +25,14 @@ import net.minecraft.util.Direction;
|
||||||
*/
|
*/
|
||||||
public class InstanceMaterial<D extends InstanceData> {
|
public class InstanceMaterial<D extends InstanceData> {
|
||||||
|
|
||||||
|
final ModelPool modelPool;
|
||||||
protected final Cache<Object, Instancer<D>> models;
|
protected final Cache<Object, Instancer<D>> models;
|
||||||
protected final MaterialSpec<D> spec;
|
protected final MaterialSpec<D> spec;
|
||||||
|
|
||||||
public InstanceMaterial(MaterialSpec<D> spec) {
|
public InstanceMaterial(MaterialSpec<D> spec) {
|
||||||
this.spec = spec;
|
this.spec = spec;
|
||||||
|
|
||||||
|
modelPool = new ModelPool(spec.getModelFormat(), spec.getModelFormat().getStride() * 64);
|
||||||
this.models = CacheBuilder.newBuilder()
|
this.models = CacheBuilder.newBuilder()
|
||||||
.removalListener(notification -> {
|
.removalListener(notification -> {
|
||||||
Instancer<?> instancer = (Instancer<?>) notification.getValue();
|
Instancer<?> instancer = (Instancer<?>) notification.getValue();
|
||||||
|
@ -48,7 +50,7 @@ public class InstanceMaterial<D extends InstanceData> {
|
||||||
*/
|
*/
|
||||||
public Instancer<D> model(Object key, Supplier<IModel> modelSupplier) {
|
public Instancer<D> model(Object key, Supplier<IModel> modelSupplier) {
|
||||||
try {
|
try {
|
||||||
return models.get(key, () -> new Instancer<>(modelSupplier, spec));
|
return models.get(key, () -> new Instancer<>(modelPool, modelSupplier.get(), spec));
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
throw new RuntimeException("error creating instancer", e);
|
throw new RuntimeException("error creating instancer", e);
|
||||||
}
|
}
|
||||||
|
@ -79,6 +81,7 @@ public class InstanceMaterial<D extends InstanceData> {
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
models.invalidateAll();
|
models.invalidateAll();
|
||||||
|
modelPool.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,11 +93,4 @@ public class InstanceMaterial<D extends InstanceData> {
|
||||||
.forEach(Instancer::clear);
|
.forEach(Instancer::clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void forEachInstancer(Consumer<Instancer<D>> f) {
|
|
||||||
for (Instancer<D> model : models.asMap()
|
|
||||||
.values()) {
|
|
||||||
f.accept(model);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
import com.jozufozu.flywheel.util.WeakHashSet;
|
import com.jozufozu.flywheel.util.WeakHashSet;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.inventory.container.PlayerContainer;
|
import net.minecraft.inventory.container.PlayerContainer;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.jozufozu.flywheel.backend.material;
|
package com.jozufozu.flywheel.backend.material;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
@ -24,6 +25,14 @@ public class MaterialRenderer<P extends WorldProgram> {
|
||||||
public void render(Matrix4f viewProjection, double camX, double camY, double camZ) {
|
public void render(Matrix4f viewProjection, double camX, double camY, double camZ) {
|
||||||
if (material.nothingToRender()) return;
|
if (material.nothingToRender()) return;
|
||||||
|
|
||||||
|
Collection<? extends Instancer<?>> instancers = material.models.asMap()
|
||||||
|
.values();
|
||||||
|
|
||||||
|
// initialize all uninitialized instancers...
|
||||||
|
instancers.forEach(Instancer::init);
|
||||||
|
// ...and then flush the model arena in case anything was marked for upload
|
||||||
|
material.modelPool.flush();
|
||||||
|
|
||||||
P program = this.program.get();
|
P program = this.program.get();
|
||||||
|
|
||||||
program.bind();
|
program.bind();
|
||||||
|
@ -32,7 +41,7 @@ public class MaterialRenderer<P extends WorldProgram> {
|
||||||
|
|
||||||
setupFunc.accept(program);
|
setupFunc.accept(program);
|
||||||
|
|
||||||
material.forEachInstancer(Instancer::render);
|
instancers.forEach(Instancer::render);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ package com.jozufozu.flywheel.backend.model;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL20.glDrawArrays;
|
import static org.lwjgl.opengl.GL20.glDrawArrays;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL44;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
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;
|
||||||
|
@ -37,6 +39,10 @@ public class BufferedModel implements IBufferedModel {
|
||||||
vbo.unbind();
|
vbo.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDeleted() {
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
public VertexFormat getFormat() {
|
public VertexFormat getFormat() {
|
||||||
return model.format();
|
return model.format();
|
||||||
}
|
}
|
||||||
|
@ -45,10 +51,6 @@ public class BufferedModel implements IBufferedModel {
|
||||||
return model.vertexCount();
|
return model.vertexCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean valid() {
|
|
||||||
return getVertexCount() > 0 && !deleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The VBO/VAO should be bound externally.
|
* The VBO/VAO should be bound externally.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -8,8 +8,6 @@ public interface IBufferedModel {
|
||||||
|
|
||||||
int getVertexCount();
|
int getVertexCount();
|
||||||
|
|
||||||
boolean valid();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The VBO/VAO should be bound externally.
|
* The VBO/VAO should be bound externally.
|
||||||
*/
|
*/
|
||||||
|
@ -24,8 +22,14 @@ public interface IBufferedModel {
|
||||||
*/
|
*/
|
||||||
void drawInstances(int instanceCount);
|
void drawInstances(int instanceCount);
|
||||||
|
|
||||||
|
boolean isDeleted();
|
||||||
|
|
||||||
void delete();
|
void delete();
|
||||||
|
|
||||||
|
default boolean valid() {
|
||||||
|
return getVertexCount() > 0 && !isDeleted();
|
||||||
|
}
|
||||||
|
|
||||||
default int getAttributeCount() {
|
default int getAttributeCount() {
|
||||||
return getFormat().getAttributeCount();
|
return getFormat().getAttributeCount();
|
||||||
}
|
}
|
||||||
|
|
229
src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java
Normal file
229
src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
package com.jozufozu.flywheel.backend.model;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
|
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.backend.gl.buffer.MappedBuffer;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer;
|
||||||
|
import com.jozufozu.flywheel.core.model.IModel;
|
||||||
|
import com.jozufozu.flywheel.util.AttribUtil;
|
||||||
|
import com.jozufozu.flywheel.util.StringUtil;
|
||||||
|
|
||||||
|
public class ModelPool {
|
||||||
|
|
||||||
|
protected final VertexFormat format;
|
||||||
|
|
||||||
|
private final List<PooledModel> models = new ArrayList<>();
|
||||||
|
|
||||||
|
private final List<PooledModel> pendingUpload = new ArrayList<>();
|
||||||
|
|
||||||
|
private final GlBuffer vbo;
|
||||||
|
private int bufferSize;
|
||||||
|
|
||||||
|
private int vertices;
|
||||||
|
|
||||||
|
private boolean dirty;
|
||||||
|
private boolean anyToRemove;
|
||||||
|
|
||||||
|
public ModelPool(VertexFormat format, int initialSize) {
|
||||||
|
this.format = format;
|
||||||
|
bufferSize = initialSize;
|
||||||
|
|
||||||
|
vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER);
|
||||||
|
|
||||||
|
vbo.bind();
|
||||||
|
vbo.alloc(bufferSize);
|
||||||
|
vbo.unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate a model in the arena.
|
||||||
|
*
|
||||||
|
* @param model The model to allocate.
|
||||||
|
* @return A handle to the allocated model.
|
||||||
|
*/
|
||||||
|
public PooledModel alloc(IModel model) {
|
||||||
|
PooledModel bufferedModel = new PooledModel(model, vertices);
|
||||||
|
vertices += model.vertexCount();
|
||||||
|
models.add(bufferedModel);
|
||||||
|
pendingUpload.add(bufferedModel);
|
||||||
|
|
||||||
|
setDirty();
|
||||||
|
return bufferedModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush() {
|
||||||
|
if (dirty) {
|
||||||
|
if (anyToRemove) processDeletions();
|
||||||
|
|
||||||
|
vbo.bind();
|
||||||
|
if (realloc()) {
|
||||||
|
uploadAll();
|
||||||
|
} else {
|
||||||
|
uploadPending();
|
||||||
|
}
|
||||||
|
vbo.unbind();
|
||||||
|
|
||||||
|
dirty = false;
|
||||||
|
pendingUpload.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processDeletions() {
|
||||||
|
|
||||||
|
// remove deleted models
|
||||||
|
models.removeIf(PooledModel::isDeleted);
|
||||||
|
|
||||||
|
// re-evaluate first vertex for each model
|
||||||
|
int vertices = 0;
|
||||||
|
for (PooledModel model : models) {
|
||||||
|
if (model.first != vertices)
|
||||||
|
pendingUpload.add(model);
|
||||||
|
|
||||||
|
model.first = vertices;
|
||||||
|
|
||||||
|
vertices += model.getVertexCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.vertices = vertices;
|
||||||
|
this.anyToRemove = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assumes vbo is bound.
|
||||||
|
*
|
||||||
|
* @return true if the buffer was reallocated
|
||||||
|
*/
|
||||||
|
private boolean realloc() {
|
||||||
|
int neededSize = vertices * format.getStride();
|
||||||
|
if (neededSize > bufferSize) {
|
||||||
|
bufferSize = neededSize + 128;
|
||||||
|
vbo.alloc(bufferSize);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void uploadAll() {
|
||||||
|
MappedBuffer buffer = vbo.getBuffer(0, bufferSize);
|
||||||
|
|
||||||
|
for (PooledModel model : models) {
|
||||||
|
model.model.buffer(buffer);
|
||||||
|
if (model.callback != null)
|
||||||
|
model.callback.invoke(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void uploadPending() {
|
||||||
|
MappedBuffer buffer = vbo.getBuffer(0, bufferSize);
|
||||||
|
|
||||||
|
int stride = format.getStride();
|
||||||
|
for (PooledModel model : pendingUpload) {
|
||||||
|
int pos = model.first * stride;
|
||||||
|
buffer.position(pos);
|
||||||
|
model.model.buffer(buffer);
|
||||||
|
if (model.callback != null)
|
||||||
|
model.callback.invoke(model);
|
||||||
|
}
|
||||||
|
pendingUpload.clear();
|
||||||
|
|
||||||
|
buffer.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDirty() {
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
vbo.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PooledModel implements IBufferedModel {
|
||||||
|
|
||||||
|
private final ElementBuffer ebo;
|
||||||
|
private Callback callback;
|
||||||
|
|
||||||
|
private final IModel model;
|
||||||
|
private int first;
|
||||||
|
|
||||||
|
private boolean remove;
|
||||||
|
|
||||||
|
public PooledModel(IModel model, int first) {
|
||||||
|
this.model = model;
|
||||||
|
this.first = first;
|
||||||
|
ebo = model.createEBO();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VertexFormat getFormat() {
|
||||||
|
return model.format();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getVertexCount() {
|
||||||
|
return model.vertexCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setupState() {
|
||||||
|
vbo.bind();
|
||||||
|
ebo.bind();
|
||||||
|
AttribUtil.enableArrays(getAttributeCount());
|
||||||
|
getFormat().vertexAttribPointers(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearState() {
|
||||||
|
AttribUtil.disableArrays(getAttributeCount());
|
||||||
|
ebo.unbind();
|
||||||
|
vbo.unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawCall() {
|
||||||
|
Backend.getInstance().compat.baseVertex.drawElementsBaseVertex(GlPrimitive.TRIANGLES, ebo.elementCount, ebo.eboIndexType, 0, first);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawInstances(int instanceCount) {
|
||||||
|
if (!valid()) return;
|
||||||
|
|
||||||
|
ebo.bind();
|
||||||
|
|
||||||
|
Backend.log.info(StringUtil.args("drawElementsInstancedBaseVertex", GlPrimitive.TRIANGLES, ebo.elementCount, ebo.eboIndexType, 0, instanceCount, first));
|
||||||
|
|
||||||
|
Backend.getInstance().compat.baseVertex.drawElementsInstancedBaseVertex(GlPrimitive.TRIANGLES, ebo.elementCount, ebo.eboIndexType, 0, instanceCount, first);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDeleted() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete() {
|
||||||
|
setDirty();
|
||||||
|
anyToRemove = true;
|
||||||
|
remove = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PooledModel setReallocCallback(Callback callback) {
|
||||||
|
this.callback = callback;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Callback {
|
||||||
|
void invoke(PooledModel arenaModel);
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,14 +30,14 @@ import net.minecraftforge.fml.common.Mod;
|
||||||
@Mod.EventBusSubscriber(Dist.CLIENT)
|
@Mod.EventBusSubscriber(Dist.CLIENT)
|
||||||
public class QuadConverter {
|
public class QuadConverter {
|
||||||
|
|
||||||
public static final int STARTING_CAPACITY = 42;
|
public static final int STARTING_CAPACITY = 42; // 255 / 6 = 42
|
||||||
|
|
||||||
private static QuadConverter INSTANCE;
|
private static QuadConverter INSTANCE;
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static QuadConverter getInstance() {
|
public static QuadConverter getInstance() {
|
||||||
if (INSTANCE == null) {
|
if (INSTANCE == null) {
|
||||||
INSTANCE = new QuadConverter(STARTING_CAPACITY); // 255 / 6 = 42
|
INSTANCE = new QuadConverter(STARTING_CAPACITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
|
@ -157,14 +157,14 @@ public class QuadConverter {
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
private static GlNumericType getSmallestIndexType(int indexCount) {
|
private static GlNumericType getSmallestIndexType(int indexCount) {
|
||||||
indexCount = indexCount >>> 8;
|
// indexCount = indexCount >>> 8;
|
||||||
if (indexCount == 0) {
|
// if (indexCount == 0) {
|
||||||
return GlNumericType.UBYTE;
|
// return GlNumericType.UBYTE;
|
||||||
}
|
// }
|
||||||
indexCount = indexCount >>> 8;
|
// indexCount = indexCount >>> 8;
|
||||||
if (indexCount == 0) {
|
// if (indexCount == 0) {
|
||||||
return GlNumericType.USHORT;
|
// return GlNumericType.USHORT;
|
||||||
}
|
// }
|
||||||
|
|
||||||
return GlNumericType.UINT;
|
return GlNumericType.UINT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,17 @@
|
||||||
package com.jozufozu.flywheel.util;
|
package com.jozufozu.flywheel.util;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class StringUtil {
|
public class StringUtil {
|
||||||
|
|
||||||
|
public static String args(String functionName, Object... args) {
|
||||||
|
|
||||||
|
return functionName + '(' + Arrays.stream(args)
|
||||||
|
.map(Object::toString)
|
||||||
|
.collect(Collectors.joining(", ")) + ')';
|
||||||
|
}
|
||||||
|
|
||||||
public static String trimEnd(String value) {
|
public static String trimEnd(String value) {
|
||||||
int len = value.length();
|
int len = value.length();
|
||||||
int st = 0;
|
int st = 0;
|
||||||
|
|
Loading…
Reference in a new issue