mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-08 13:26:39 +01:00
Separate separate attributes
- Add new GL43 vertex array impl - GlNumericType cleaning - Make GlBuffer growth more abstract - Organize VertexArrayGL3, track bound ebo
This commit is contained in:
parent
e2bcc5f325
commit
aa38ae4125
11 changed files with 175 additions and 95 deletions
|
@ -56,7 +56,7 @@ public class BufferLayout {
|
||||||
private static int calculateStride(List<VertexAttribute> layoutItems) {
|
private static int calculateStride(List<VertexAttribute> layoutItems) {
|
||||||
int stride = 0;
|
int stride = 0;
|
||||||
for (var spec : layoutItems) {
|
for (var spec : layoutItems) {
|
||||||
stride += spec.getByteWidth();
|
stride += spec.byteWidth();
|
||||||
}
|
}
|
||||||
return stride;
|
return stride;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class GPUInstancer<I extends Instance> extends AbstractInstancer<I> {
|
||||||
}
|
}
|
||||||
|
|
||||||
vbo = new GlBuffer(GlBufferUsage.DYNAMIC_DRAW);
|
vbo = new GlBuffer(GlBufferUsage.DYNAMIC_DRAW);
|
||||||
vbo.growthMargin(instanceStride * 16);
|
vbo.growthFunction(l -> Math.max(l + (long) instanceStride * 16, (long) (l * 1.6)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update() {
|
public void update() {
|
||||||
|
@ -70,7 +70,7 @@ public class GPUInstancer<I extends Instance> extends AbstractInstancer<I> {
|
||||||
|
|
||||||
int count = instances.size();
|
int count = instances.size();
|
||||||
for (int i = changed.nextSetBit(0); i >= 0 && i < count; i = changed.nextSetBit(i + 1)) {
|
for (int i = changed.nextSetBit(0); i >= 0 && i < count; i = changed.nextSetBit(i + 1)) {
|
||||||
writer.write(ptr + instanceStride * i, instances.get(i));
|
writer.write(ptr + (long) instanceStride * i, instances.get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
changed.clear();
|
changed.clear();
|
||||||
|
|
|
@ -40,7 +40,7 @@ public class InstancedMeshPool {
|
||||||
this.vertexType = vertexType;
|
this.vertexType = vertexType;
|
||||||
int stride = vertexType.getLayout().getStride();
|
int stride = vertexType.getLayout().getStride();
|
||||||
vbo = new GlBuffer();
|
vbo = new GlBuffer();
|
||||||
vbo.growthMargin(stride * 32);
|
vbo.growthFunction(l -> Math.max(l + stride * 32L, (long) (l * 1.6)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public VertexType getVertexType() {
|
public VertexType getVertexType() {
|
||||||
|
|
|
@ -1,12 +1,5 @@
|
||||||
package com.jozufozu.flywheel.gl;
|
package com.jozufozu.flywheel.gl;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
public enum GlNumericType {
|
public enum GlNumericType {
|
||||||
|
@ -20,13 +13,9 @@ public enum GlNumericType {
|
||||||
DOUBLE(8, "double", GL11.GL_DOUBLE),
|
DOUBLE(8, "double", GL11.GL_DOUBLE),
|
||||||
;
|
;
|
||||||
|
|
||||||
private static final GlNumericType[] VALUES = values();
|
public final int byteWidth;
|
||||||
private static final Map<String, GlNumericType> NAME_LOOKUP = Arrays.stream(VALUES)
|
public final String typeName;
|
||||||
.collect(Collectors.toMap(GlNumericType::getTypeName, type -> type));
|
public final int glEnum;
|
||||||
|
|
||||||
private final int byteWidth;
|
|
||||||
private final String typeName;
|
|
||||||
private final int glEnum;
|
|
||||||
|
|
||||||
GlNumericType(int bytes, String name, int glEnum) {
|
GlNumericType(int bytes, String name, int glEnum) {
|
||||||
this.byteWidth = bytes;
|
this.byteWidth = bytes;
|
||||||
|
@ -34,31 +23,16 @@ public enum GlNumericType {
|
||||||
this.glEnum = glEnum;
|
this.glEnum = glEnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteWidth() {
|
public int byteWidth() {
|
||||||
return this.byteWidth;
|
return byteWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTypeName() {
|
public String typeName() {
|
||||||
return this.typeName;
|
return typeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGlEnum() {
|
public int glEnum() {
|
||||||
return this.glEnum;
|
return 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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -15,6 +15,8 @@ public abstract class GlVertexArray extends GlObject {
|
||||||
public static GlVertexArray create() {
|
public static GlVertexArray create() {
|
||||||
if (GlVertexArrayDSA.SUPPORTED) {
|
if (GlVertexArrayDSA.SUPPORTED) {
|
||||||
return new GlVertexArrayDSA();
|
return new GlVertexArrayDSA();
|
||||||
|
} else if (GlVertexArraySeparateAttributes.SUPPORTED) {
|
||||||
|
return new GlVertexArraySeparateAttributes();
|
||||||
} else if (GlVertexArrayGL3.Core33.SUPPORTED) {
|
} else if (GlVertexArrayGL3.Core33.SUPPORTED) {
|
||||||
return new GlVertexArrayGL3.Core33();
|
return new GlVertexArrayGL3.Core33();
|
||||||
} else if (GlVertexArrayGL3.ARB.SUPPORTED) {
|
} else if (GlVertexArrayGL3.ARB.SUPPORTED) {
|
||||||
|
|
|
@ -57,11 +57,9 @@ public class GlVertexArrayDSA extends GlVertexArray {
|
||||||
|
|
||||||
if (!attribute.equals(attributes[attribIndex])) {
|
if (!attribute.equals(attributes[attribIndex])) {
|
||||||
if (attribute instanceof VertexAttribute.Float f) {
|
if (attribute instanceof VertexAttribute.Float f) {
|
||||||
GL45C.glVertexArrayAttribFormat(handle, attribIndex, f.size(), f.type()
|
GL45C.glVertexArrayAttribFormat(handle, attribIndex, f.size(), f.type().glEnum, f.normalized(), offset);
|
||||||
.getGlEnum(), f.normalized(), offset);
|
|
||||||
} else if (attribute instanceof VertexAttribute.Int vi) {
|
} else if (attribute instanceof VertexAttribute.Int vi) {
|
||||||
GL45C.glVertexArrayAttribIFormat(handle, attribIndex, vi.size(), vi.type()
|
GL45C.glVertexArrayAttribIFormat(handle, attribIndex, vi.size(), vi.type().glEnum, offset);
|
||||||
.getGlEnum(), offset);
|
|
||||||
}
|
}
|
||||||
attributes[attribIndex] = attribute;
|
attributes[attribIndex] = attribute;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +70,7 @@ public class GlVertexArrayDSA extends GlVertexArray {
|
||||||
}
|
}
|
||||||
|
|
||||||
attribIndex++;
|
attribIndex++;
|
||||||
offset += attribute.getByteWidth();
|
offset += attribute.byteWidth();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@ public abstract class GlVertexArrayGL3 extends GlVertexArray {
|
||||||
private final long[] bindingOffsets = new long[MAX_ATTRIB_BINDINGS];
|
private final long[] bindingOffsets = new long[MAX_ATTRIB_BINDINGS];
|
||||||
private final int[] bindingStrides = new int[MAX_ATTRIB_BINDINGS];
|
private final int[] bindingStrides = new int[MAX_ATTRIB_BINDINGS];
|
||||||
private final int[] bindingDivisors = new int[MAX_ATTRIB_BINDINGS];
|
private final int[] bindingDivisors = new int[MAX_ATTRIB_BINDINGS];
|
||||||
private int elementBufferBinding = 0;
|
private int requestedElementBuffer = 0;
|
||||||
|
private int boundElementBuffer = 0;
|
||||||
|
|
||||||
public GlVertexArrayGL3() {
|
public GlVertexArrayGL3() {
|
||||||
handle(GL30.glGenVertexArrays());
|
handle(GL30.glGenVertexArrays());
|
||||||
|
@ -33,42 +34,11 @@ public abstract class GlVertexArrayGL3 extends GlVertexArray {
|
||||||
public void bindForDraw() {
|
public void bindForDraw() {
|
||||||
super.bindForDraw();
|
super.bindForDraw();
|
||||||
|
|
||||||
for (int attribIndex = attributeDirty.nextSetBit(0); attribIndex < MAX_ATTRIB_BINDINGS && attribIndex >= 0; attribIndex = attributeDirty.nextSetBit(attribIndex + 1)) {
|
maybeUpdateAttributes();
|
||||||
|
|
||||||
int bindingIndex = attributeBindings[attribIndex];
|
maybeUpdateEBOBinding();
|
||||||
var attribute = attributes[attribIndex];
|
|
||||||
|
|
||||||
if (bindingIndex == -1 || attribute == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
GlBufferType.ARRAY_BUFFER.bind(bindingBuffers[bindingIndex]);
|
|
||||||
GL20C.glEnableVertexAttribArray(attribIndex);
|
|
||||||
|
|
||||||
long offset = bindingOffsets[bindingIndex] + attributeOffsets[attribIndex];
|
|
||||||
int stride = bindingStrides[bindingIndex];
|
|
||||||
|
|
||||||
if (attribute instanceof VertexAttribute.Float f) {
|
|
||||||
GL32.glVertexAttribPointer(attribIndex, f.size(), f.type()
|
|
||||||
.getGlEnum(), f.normalized(), stride, offset);
|
|
||||||
} else if (attribute instanceof VertexAttribute.Int vi) {
|
|
||||||
GL32.glVertexAttribIPointer(attribIndex, vi.size(), vi.type()
|
|
||||||
.getGlEnum(), stride, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
int divisor = bindingDivisors[bindingIndex];
|
|
||||||
if (divisor != 0) {
|
|
||||||
setDivisor(attribIndex, divisor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GlBufferType.ELEMENT_ARRAY_BUFFER.bind(elementBufferBinding);
|
|
||||||
|
|
||||||
attributeDirty.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void setDivisor(int attribIndex, int divisor);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bindVertexBuffer(int bindingIndex, int vbo, long offset, int stride) {
|
public void bindVertexBuffer(int bindingIndex, int vbo, long offset, int stride) {
|
||||||
if (bindingBuffers[bindingIndex] != vbo || bindingOffsets[bindingIndex] != offset || bindingStrides[bindingIndex] != stride) {
|
if (bindingBuffers[bindingIndex] != vbo || bindingOffsets[bindingIndex] != offset || bindingStrides[bindingIndex] != stride) {
|
||||||
|
@ -83,7 +53,6 @@ public abstract class GlVertexArrayGL3 extends GlVertexArray {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBindingDivisor(int bindingIndex, int divisor) {
|
public void setBindingDivisor(int bindingIndex, int divisor) {
|
||||||
if (bindingDivisors[bindingIndex] != divisor) {
|
if (bindingDivisors[bindingIndex] != divisor) {
|
||||||
|
@ -104,15 +73,59 @@ public abstract class GlVertexArrayGL3 extends GlVertexArray {
|
||||||
attributeDirty.set(attribIndex);
|
attributeDirty.set(attribIndex);
|
||||||
|
|
||||||
attribIndex++;
|
attribIndex++;
|
||||||
offset += attribute.getByteWidth();
|
offset += attribute.byteWidth();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setElementBuffer(int ebo) {
|
public void setElementBuffer(int ebo) {
|
||||||
elementBufferBinding = ebo;
|
requestedElementBuffer = ebo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void maybeUpdateEBOBinding() {
|
||||||
|
if (requestedElementBuffer != boundElementBuffer) {
|
||||||
|
GlBufferType.ELEMENT_ARRAY_BUFFER.bind(requestedElementBuffer);
|
||||||
|
boundElementBuffer = requestedElementBuffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void maybeUpdateAttributes() {
|
||||||
|
for (int attribIndex = attributeDirty.nextSetBit(0); attribIndex < MAX_ATTRIB_BINDINGS && attribIndex >= 0; attribIndex = attributeDirty.nextSetBit(attribIndex + 1)) {
|
||||||
|
updateAttribute(attribIndex);
|
||||||
|
}
|
||||||
|
attributeDirty.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateAttribute(int attribIndex) {
|
||||||
|
int bindingIndex = attributeBindings[attribIndex];
|
||||||
|
var attribute = attributes[attribIndex];
|
||||||
|
|
||||||
|
if (bindingIndex == -1 || attribute == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GlBufferType.ARRAY_BUFFER.bind(bindingBuffers[bindingIndex]);
|
||||||
|
GL20C.glEnableVertexAttribArray(attribIndex);
|
||||||
|
|
||||||
|
long offset = bindingOffsets[bindingIndex] + attributeOffsets[attribIndex];
|
||||||
|
int stride = bindingStrides[bindingIndex];
|
||||||
|
|
||||||
|
if (attribute instanceof VertexAttribute.Float f) {
|
||||||
|
GL32.glVertexAttribPointer(attribIndex, f.size(), f.type()
|
||||||
|
.glEnum(), f.normalized(), stride, offset);
|
||||||
|
} else if (attribute instanceof VertexAttribute.Int vi) {
|
||||||
|
GL32.glVertexAttribIPointer(attribIndex, vi.size(), vi.type()
|
||||||
|
.glEnum(), stride, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
int divisor = bindingDivisors[bindingIndex];
|
||||||
|
if (divisor != 0) {
|
||||||
|
setDivisor(attribIndex, divisor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void setDivisor(int attribIndex, int divisor);
|
||||||
|
|
||||||
public static class Core33 extends GlVertexArrayGL3 {
|
public static class Core33 extends GlVertexArrayGL3 {
|
||||||
public static final boolean SUPPORTED = isSupported();
|
public static final boolean SUPPORTED = isSupported();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
package com.jozufozu.flywheel.gl.array;
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL43C;
|
||||||
|
import org.lwjgl.system.Checks;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.gl.GlCompat;
|
||||||
|
import com.jozufozu.flywheel.gl.GlStateTracker;
|
||||||
|
import com.jozufozu.flywheel.gl.buffer.GlBufferType;
|
||||||
|
import com.jozufozu.flywheel.util.FlwUtil;
|
||||||
|
|
||||||
|
public class GlVertexArraySeparateAttributes extends GlVertexArray {
|
||||||
|
public static final boolean SUPPORTED = isSupported();
|
||||||
|
private final BitSet attributeEnabled = new BitSet(MAX_ATTRIBS);
|
||||||
|
private final VertexAttribute[] attributes = new VertexAttribute[MAX_ATTRIBS];
|
||||||
|
private final int[] attributeBindings = FlwUtil.initArray(MAX_ATTRIBS, -1);
|
||||||
|
private final int[] bindingBuffers = new int[MAX_ATTRIB_BINDINGS];
|
||||||
|
private final long[] bindingOffsets = new long[MAX_ATTRIB_BINDINGS];
|
||||||
|
private final int[] bindingStrides = new int[MAX_ATTRIB_BINDINGS];
|
||||||
|
private final int[] bindingDivisors = new int[MAX_ATTRIB_BINDINGS];
|
||||||
|
|
||||||
|
private int elementBufferBinding = 0;
|
||||||
|
|
||||||
|
public GlVertexArraySeparateAttributes() {
|
||||||
|
handle(GL43C.glGenVertexArrays());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bindVertexBuffer(final int bindingIndex, final int vbo, final long offset, final int stride) {
|
||||||
|
if (bindingBuffers[bindingIndex] != vbo || bindingOffsets[bindingIndex] != offset || bindingStrides[bindingIndex] != stride) {
|
||||||
|
GlStateTracker.bindVao(handle());
|
||||||
|
GL43C.glBindVertexBuffer(bindingIndex, vbo, offset, stride);
|
||||||
|
bindingBuffers[bindingIndex] = vbo;
|
||||||
|
bindingOffsets[bindingIndex] = offset;
|
||||||
|
bindingStrides[bindingIndex] = stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBindingDivisor(final int bindingIndex, final int divisor) {
|
||||||
|
if (bindingDivisors[bindingIndex] != divisor) {
|
||||||
|
GL43C.glVertexBindingDivisor(bindingIndex, divisor);
|
||||||
|
bindingDivisors[bindingIndex] = divisor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bindAttributes(final int bindingIndex, final int startAttribIndex, List<VertexAttribute> vertexAttributes) {
|
||||||
|
GlStateTracker.bindVao(handle());
|
||||||
|
int attribIndex = startAttribIndex;
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
for (var attribute : vertexAttributes) {
|
||||||
|
if (!attributeEnabled.get(attribIndex)) {
|
||||||
|
GL43C.glEnableVertexAttribArray(attribIndex);
|
||||||
|
attributeEnabled.set(attribIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!attribute.equals(attributes[attribIndex])) {
|
||||||
|
if (attribute instanceof VertexAttribute.Float f) {
|
||||||
|
GL43C.glVertexAttribFormat(attribIndex, f.size(), f.type().glEnum, f.normalized(), offset);
|
||||||
|
} else if (attribute instanceof VertexAttribute.Int vi) {
|
||||||
|
GL43C.glVertexAttribIFormat(attribIndex, vi.size(), vi.type().glEnum, offset);
|
||||||
|
}
|
||||||
|
attributes[attribIndex] = attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attributeBindings[attribIndex] != bindingIndex) {
|
||||||
|
GL43C.glVertexAttribBinding(attribIndex, bindingIndex);
|
||||||
|
attributeBindings[attribIndex] = bindingIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
attribIndex++;
|
||||||
|
offset += attribute.byteWidth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setElementBuffer(int ebo) {
|
||||||
|
if (elementBufferBinding != ebo) {
|
||||||
|
GlStateTracker.bindVao(handle());
|
||||||
|
GlBufferType.ELEMENT_ARRAY_BUFFER.bind(ebo);
|
||||||
|
elementBufferBinding = ebo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isSupported() {
|
||||||
|
var c = GlCompat.CAPABILITIES;
|
||||||
|
return GlCompat.ALLOW_DSA && Checks.checkFunctions(c.glBindVertexBuffer, c.glVertexBindingDivisor, c.glEnableVertexAttribArray, c.glVertexAttribFormat, c.glVertexAttribIFormat, c.glVertexAttribBinding);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ package com.jozufozu.flywheel.gl.array;
|
||||||
import com.jozufozu.flywheel.gl.GlNumericType;
|
import com.jozufozu.flywheel.gl.GlNumericType;
|
||||||
|
|
||||||
public sealed interface VertexAttribute {
|
public sealed interface VertexAttribute {
|
||||||
int getByteWidth();
|
int byteWidth();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A bindable attribute in a vertex array.
|
* A bindable attribute in a vertex array.
|
||||||
|
@ -14,8 +14,8 @@ public sealed interface VertexAttribute {
|
||||||
*/
|
*/
|
||||||
record Float(GlNumericType type, int size, boolean normalized) implements VertexAttribute {
|
record Float(GlNumericType type, int size, boolean normalized) implements VertexAttribute {
|
||||||
@Override
|
@Override
|
||||||
public int getByteWidth() {
|
public int byteWidth() {
|
||||||
return size * type.getByteWidth();
|
return size * type.byteWidth();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,8 +27,8 @@ public sealed interface VertexAttribute {
|
||||||
*/
|
*/
|
||||||
record Int(GlNumericType type, int size) implements VertexAttribute {
|
record Int(GlNumericType type, int size) implements VertexAttribute {
|
||||||
@Override
|
@Override
|
||||||
public int getByteWidth() {
|
public int byteWidth() {
|
||||||
return size * type.getByteWidth();
|
return size * type.byteWidth();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package com.jozufozu.flywheel.gl.buffer;
|
package com.jozufozu.flywheel.gl.buffer;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL15.glDeleteBuffers;
|
|
||||||
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.gl.GlObject;
|
import com.jozufozu.flywheel.gl.GlObject;
|
||||||
|
@ -9,6 +7,8 @@ import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker;
|
||||||
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.longs.LongUnaryOperator;
|
||||||
|
|
||||||
public class GlBuffer extends GlObject {
|
public class GlBuffer extends GlObject {
|
||||||
public static final Buffer IMPL = new Buffer.DSA().fallback();
|
public static final Buffer IMPL = new Buffer.DSA().fallback();
|
||||||
protected final GlBufferUsage usage;
|
protected final GlBufferUsage usage;
|
||||||
|
@ -17,9 +17,9 @@ public class GlBuffer extends GlObject {
|
||||||
*/
|
*/
|
||||||
protected long size;
|
protected long size;
|
||||||
/**
|
/**
|
||||||
* How much extra room to give the buffer when we reallocate.
|
* A mapping to adjust the size of the buffer when allocating.
|
||||||
*/
|
*/
|
||||||
protected int growthMargin;
|
protected LongUnaryOperator growthFunction = LongUnaryOperator.identity();
|
||||||
|
|
||||||
public GlBuffer() {
|
public GlBuffer() {
|
||||||
this(GlBufferUsage.STATIC_DRAW);
|
this(GlBufferUsage.STATIC_DRAW);
|
||||||
|
@ -70,7 +70,7 @@ public class GlBuffer extends GlObject {
|
||||||
int newHandle = IMPL.create();
|
int newHandle = IMPL.create();
|
||||||
IMPL.data(newHandle, size, MemoryUtil.NULL, usage.glEnum);
|
IMPL.data(newHandle, size, MemoryUtil.NULL, usage.glEnum);
|
||||||
IMPL.copyData(oldHandle, newHandle, 0, 0, oldSize);
|
IMPL.copyData(oldHandle, newHandle, 0, 0, oldSize);
|
||||||
glDeleteBuffers(oldHandle);
|
GlStateManager._glDeleteBuffers(oldHandle);
|
||||||
handle(newHandle);
|
handle(newHandle);
|
||||||
|
|
||||||
FlwMemoryTracker._allocGPUMemory(size);
|
FlwMemoryTracker._allocGPUMemory(size);
|
||||||
|
@ -80,7 +80,7 @@ public class GlBuffer extends GlObject {
|
||||||
* Increase the size of the buffer to at least the given capacity.
|
* Increase the size of the buffer to at least the given capacity.
|
||||||
*/
|
*/
|
||||||
private void increaseSize(long capacity) {
|
private void increaseSize(long capacity) {
|
||||||
size = capacity + growthMargin;
|
size = growthFunction.apply(capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void upload(MemoryBlock directBuffer) {
|
public void upload(MemoryBlock directBuffer) {
|
||||||
|
@ -94,8 +94,8 @@ public class GlBuffer extends GlObject {
|
||||||
return new MappedBuffer(handle(), size);
|
return new MappedBuffer(handle(), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void growthMargin(int growthMargin) {
|
public void growthFunction(LongUnaryOperator growthFunction) {
|
||||||
this.growthMargin = growthMargin;
|
this.growthFunction = growthFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long size() {
|
public long size() {
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class QuadConverter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void grow(int quads) {
|
private void grow(int quads) {
|
||||||
int byteSize = quads * 6 * GlNumericType.UINT.getByteWidth();
|
int byteSize = quads * 6 * GlNumericType.UINT.byteWidth();
|
||||||
final long ptr = MemoryUtil.nmemAlloc(byteSize);
|
final long ptr = MemoryUtil.nmemAlloc(byteSize);
|
||||||
|
|
||||||
fillBuffer(ptr, quads);
|
fillBuffer(ptr, quads);
|
||||||
|
|
Loading…
Reference in a new issue