Refactor VertexAttribute Pre/Post GL43

This commit is contained in:
James Seibel
2023-10-16 07:19:39 -05:00
parent c40067359f
commit 35d2d638d4
8 changed files with 179 additions and 94 deletions
@@ -20,13 +20,11 @@
package com.seibel.distanthorizons.core.config.gui;
import com.seibel.distanthorizons.api.enums.config.EGpuUploadMethod;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
import com.seibel.distanthorizons.core.render.glObject.GLState;
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttribute;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import org.lwjgl.opengl.GL32;
import java.nio.ByteBuffer;
@@ -109,12 +107,12 @@ public class OpenGLConfigScreen extends AbstractScreen
if (System.currentTimeMillis() % 2000 < 1000)
{
sameContextBuffer.bind();
va.bindBufferToAllBindingPoint(sameContextBuffer.getId());
va.bindBufferToAllBindingPoints(sameContextBuffer.getId());
}
else
{
sameContextBuffer.bind();
va.bindBufferToAllBindingPoint(sharedContextBuffer.getId());
va.bindBufferToAllBindingPoints(sharedContextBuffer.getId());
}
// Render the square
GL32.glDrawArrays(GL32.GL_TRIANGLE_FAN, 0, 4);
@@ -143,7 +143,7 @@ public abstract class VertexAttribute
}
// Requires VertexAttribute binded, VertexBuffer binded
public abstract void bindBufferToAllBindingPoint(int buffer);
public abstract void bindBufferToAllBindingPoints(int buffer);
// Requires VertexAttribute binded, VertexBuffer binded
public abstract void bindBufferToBindingPoint(int buffer, int bindingPoint);
// Requires VertexAttribute binded
@@ -22,87 +22,126 @@ package com.seibel.distanthorizons.core.render.glObject.vertexAttribute;
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
import org.lwjgl.opengl.GL43;
// In OpenGL 4.3 and later, Vertex Attribute got a make-over.
// Now it provides support for buffer binding points natively.
// This means that setting up the VAO just use ONE native call when
// binding to a buffer.
//
// Since I no longer needs to implement binding points, I also no
// longer needs to keep track of Pointers.
/**
* In OpenGL 4.3 and later, Vertex Attribute got a make-over.
* Now it provides support for buffer binding points natively.
* This means that setting up the VAO just use ONE native call when
* binding to a buffer. <br><br>
*
* Since I no longer needs to implement binding points, I also no
* longer needs to keep track of Pointers.
*/
public final class VertexAttributePostGL43 extends VertexAttribute
{
int numberOfBindingPoints = 0;
int strideSize = 0;
// This will bind VertexAttribute
//=============//
// constructor //
//=============//
/** This will bind the {@link VertexAttribute} */
public VertexAttributePostGL43()
{
super(); // also bind VertexAttribute
}
//=========//
// binding //
//=========//
/** Requires both VertexAttribute and VertexBuffer to be bound */
@Override
// Requires VertexAttribute binded, VertexBuffer binded
public void bindBufferToAllBindingPoint(int buffer)
public void bindBufferToAllBindingPoints(int buffer)
{
for (int i = 0; i < numberOfBindingPoints; i++)
for (int i = 0; i < this.numberOfBindingPoints; i++)
{
GL43.glBindVertexBuffer(i, buffer, 0, strideSize);
GL43.glBindVertexBuffer(i, buffer, 0, this.strideSize);
}
}
/** Requires both VertexAttribute and VertexBuffer to be bound */
@Override
// Requires VertexAttribute binded, VertexBuffer binded
public void bindBufferToBindingPoint(int buffer, int bindingPoint)
{
GL43.glBindVertexBuffer(bindingPoint, buffer, 0, strideSize);
GL43.glBindVertexBuffer(bindingPoint, buffer, 0, this.strideSize);
}
//===========//
// unbinding //
//===========//
/** Requires VertexAttribute to be bound */
@Override
// Requires VertexAttribute binded
public void unbindBuffersFromAllBindingPoint()
{
for (int i = 0; i < numberOfBindingPoints; i++)
for (int i = 0; i < this.numberOfBindingPoints; i++)
{
GL43.glBindVertexBuffer(i, 0, 0, 0);
}
}
/** Requires VertexAttribute to be bound */
@Override
// Requires VertexAttribute binded
public void unbindBuffersFromBindingPoint(int bindingPoint)
{
GL43.glBindVertexBuffer(bindingPoint, 0, 0, 0);
}
//==========================//
// manual attribute setting //
//==========================//
/** Requires VertexAttribute to be bound */
@Override
// Requires VertexAttribute binded
public void setVertexAttribute(int bindingPoint, int attributeIndex, VertexPointer attribute)
{
if (attribute.useInteger)
GL43.glVertexAttribIFormat(attributeIndex, attribute.elementCount, attribute.glType, strideSize);
{
GL43.glVertexAttribIFormat(attributeIndex, attribute.elementCount, attribute.glType, this.strideSize);
}
else
{
GL43.glVertexAttribFormat(attributeIndex, attribute.elementCount, attribute.glType,
attribute.normalized, strideSize); // Here strideSize is new attrib offset
strideSize += attribute.byteSize;
if (numberOfBindingPoints <= bindingPoint) numberOfBindingPoints = bindingPoint + 1;
attribute.normalized, this.strideSize); // Here strideSize is new attrib offset
}
this.strideSize += attribute.byteSize;
if (this.numberOfBindingPoints <= bindingPoint)
{
this.numberOfBindingPoints = bindingPoint + 1;
}
GL43.glVertexAttribBinding(attributeIndex, bindingPoint);
GL43.glEnableVertexAttribArray(attributeIndex);
}
//============//
// validation //
//============//
/** Requires VertexAttribute to be bound */
@Override
// Requires VertexAttribute binded
public void completeAndCheck(int expectedStrideSize)
{
if (strideSize != expectedStrideSize)
if (this.strideSize != expectedStrideSize)
{
GLProxy.GL_LOGGER.error("Vertex Attribute calculated stride size " + strideSize +
GLProxy.GL_LOGGER.error("Vertex Attribute calculated stride size " + this.strideSize +
" does not match the provided expected stride size " + expectedStrideSize + "!");
throw new IllegalArgumentException("Vertex Attribute Incorrect Format");
}
GLProxy.GL_LOGGER.info("Vertex Attribute (GL43+) completed. It contains " + numberOfBindingPoints
+ " binding points and a stride size of " + strideSize);
GLProxy.GL_LOGGER.info("Vertex Attribute (GL43+) completed. It contains " + this.numberOfBindingPoints
+ " binding points and a stride size of " + this.strideSize);
}
}
@@ -30,9 +30,8 @@ import org.lwjgl.opengl.GL32;
public final class VertexAttributePreGL43 extends VertexAttribute
{
// I tried to use as much raw arrays as possible as those lookups
// happens every frame, and the speed directly effects fps
// I tried to use raw arrays as much as possible since those lookups
// happens every frame, and the speed directly affects fps
int strideSize = 0;
int[][] bindingPointsToIndex;
VertexPointer[] pointers;
@@ -41,153 +40,202 @@ public final class VertexAttributePreGL43 extends VertexAttribute
TreeMap<Integer, TreeSet<Integer>> bindingPointsToIndexBuilder;
ArrayList<VertexPointer> pointersBuilder;
// This will bind VertexAttribute
//=============//
// constructor //
//=============//
/** This will bind the {@link VertexAttribute} */
public VertexAttributePreGL43()
{
super(); // also bind VertexAttribute
bindingPointsToIndexBuilder = new TreeMap<Integer, TreeSet<Integer>>();
pointersBuilder = new ArrayList<VertexPointer>();
this.bindingPointsToIndexBuilder = new TreeMap<>();
this.pointersBuilder = new ArrayList<>();
}
//=========//
// binding //
//=========//
/** Requires both VertexAttribute and VertexBuffer to be bound */
@Override
// Requires VertexAttribute binded, VertexBuffer binded
public void bindBufferToAllBindingPoint(int buffer)
public void bindBufferToAllBindingPoints(int buffer)
{
for (int i = 0; i < pointers.length; i++)
for (int i = 0; i < this.pointers.length; i++)
{
GL32.glEnableVertexAttribArray(i);
}
for (int i = 0; i < pointers.length; i++)
for (int i = 0; i < this.pointers.length; i++)
{
VertexPointer pointer = pointers[i];
if (pointer == null) continue;
VertexPointer pointer = this.pointers[i];
if (pointer == null)
{
continue;
}
if (pointer.useInteger)
{
GL32.glVertexAttribIPointer(i, pointer.elementCount, pointer.glType,
strideSize, pointersOffset[i]);
else GL32.glVertexAttribPointer(i, pointer.elementCount, pointer.glType,
pointer.normalized, strideSize, pointersOffset[i]);
this.strideSize, this.pointersOffset[i]);
}
else
{
GL32.glVertexAttribPointer(i, pointer.elementCount, pointer.glType,
pointer.normalized, this.strideSize, this.pointersOffset[i]);
}
}
}
/** Requires both VertexAttribute and VertexBuffer to be bound */
@Override
// Requires VertexAttribute binded, VertexBuffer binded
public void bindBufferToBindingPoint(int buffer, int bindingPoint)
{
int[] toBind = bindingPointsToIndex[bindingPoint];
int[] bindingPointIndexes = this.bindingPointsToIndex[bindingPoint];
for (int k : toBind)
for (int bindingPointIndex : bindingPointIndexes)
{
GL32.glEnableVertexAttribArray(k);
GL32.glEnableVertexAttribArray(bindingPointIndex);
}
for (int j : toBind)
for (int bindingPointIndex : bindingPointIndexes)
{
VertexPointer pointer = pointers[j];
VertexPointer pointer = this.pointers[bindingPointIndex];
if (pointer == null)
{
continue;
}
if (pointer.useInteger)
GL32.glVertexAttribIPointer(j, pointer.elementCount, pointer.glType,
strideSize, pointersOffset[j]);
else GL32.glVertexAttribPointer(j, pointer.elementCount, pointer.glType,
pointer.normalized, strideSize, pointersOffset[j]);
{
GL32.glVertexAttribIPointer(bindingPointIndex, pointer.elementCount, pointer.glType,
this.strideSize, this.pointersOffset[bindingPointIndex]);
}
else
{
GL32.glVertexAttribPointer(bindingPointIndex, pointer.elementCount, pointer.glType,
pointer.normalized, this.strideSize, this.pointersOffset[bindingPointIndex]);
}
}
}
//===========//
// unbinding //
//===========//
/** Requires VertexAttribute to be bound */
@Override
// Requires VertexAttribute binded
public void unbindBuffersFromAllBindingPoint()
{
for (int i = 0; i < pointers.length; i++)
for (int i = 0; i < this.pointers.length; i++)
{
GL32.glDisableVertexAttribArray(i);
}
}
/** Requires VertexAttribute to be bound */
@Override
// Requires VertexAttribute binded
public void unbindBuffersFromBindingPoint(int bindingPoint)
{
int[] toBind = bindingPointsToIndex[bindingPoint];
for (int j : toBind)
int[] bindingPointIndexes = this.bindingPointsToIndex[bindingPoint];
for (int bindingPointIndex : bindingPointIndexes)
{
GL32.glDisableVertexAttribArray(j);
GL32.glDisableVertexAttribArray(bindingPointIndex);
}
}
//==========================//
// manual attribute setting //
//==========================//
/** Requires VertexAttribute to be bound */
@Override
// Requires VertexAttribute binded
public void setVertexAttribute(int bindingPoint, int attributeIndex, VertexPointer attribute)
{
TreeSet<Integer> intArray = bindingPointsToIndexBuilder.computeIfAbsent(bindingPoint, k -> new TreeSet<Integer>());
TreeSet<Integer> intArray = this.bindingPointsToIndexBuilder.computeIfAbsent(bindingPoint, k -> new TreeSet<>());
intArray.add(attributeIndex);
while (pointersBuilder.size() <= attributeIndex)
while (this.pointersBuilder.size() <= attributeIndex)
{
// This is dumb, but ArrayList doesn't have a resize, And this code
// should only be ran when it's building the Vertex Attribute anyways.
pointersBuilder.add(null);
// should only be run when it's building the Vertex Attribute anyway.
this.pointersBuilder.add(null);
}
pointersBuilder.set(attributeIndex, attribute);
this.pointersBuilder.set(attributeIndex, attribute);
}
//============//
// validation //
//============//
/** Requires VertexAttribute to be bound */
@Override
// Requires VertexAttribute binded
public void completeAndCheck(int expectedStrideSize)
{
int maxBindPointNumber = bindingPointsToIndexBuilder.lastKey();
bindingPointsToIndex = new int[maxBindPointNumber + 1][];
int maxBindPointNumber = this.bindingPointsToIndexBuilder.lastKey();
this.bindingPointsToIndex = new int[maxBindPointNumber + 1][];
bindingPointsToIndexBuilder.forEach((Integer i, TreeSet<Integer> set) -> {
bindingPointsToIndex[i] = new int[set.size()];
this.bindingPointsToIndexBuilder.forEach((Integer i, TreeSet<Integer> set) ->
{
this.bindingPointsToIndex[i] = new int[set.size()];
Iterator<Integer> iter = set.iterator();
for (int j = 0; j < set.size(); j++)
{
bindingPointsToIndex[i][j] = iter.next();
this.bindingPointsToIndex[i][j] = iter.next();
}
});
pointers = pointersBuilder.toArray(new VertexPointer[pointersBuilder.size()]);
pointersOffset = new int[pointers.length];
pointersBuilder = null; // Release the builder
bindingPointsToIndexBuilder = null; // Release the builder
this.pointers = this.pointersBuilder.toArray(new VertexPointer[this.pointersBuilder.size()]);
this.pointersOffset = new int[this.pointers.length];
this.pointersBuilder = null; // Release the builder
this.bindingPointsToIndexBuilder = null; // Release the builder
// Check if all pointers are valid
int currentOffset = 0;
for (int i = 0; i < pointers.length; i++)
for (int i = 0; i < this.pointers.length; i++)
{
VertexPointer pointer = pointers[i];
VertexPointer pointer = this.pointers[i];
if (pointer == null)
{
GLProxy.GL_LOGGER.warn("Vertex Attribute index " + i + " is not set! No index should be skipped normally!");
continue;
}
pointersOffset[i] = currentOffset;
this.pointersOffset[i] = currentOffset;
currentOffset += pointer.byteSize;
}
if (currentOffset != expectedStrideSize)
{
GLProxy.GL_LOGGER.error("Vertex Attribute calculated stride size " + currentOffset +
" does not match the provided expected stride size " + expectedStrideSize + "!");
throw new IllegalArgumentException("Vertex Attribute Incorrect Format");
}
strideSize = currentOffset;
this.strideSize = currentOffset;
GLProxy.GL_LOGGER.info("Vertex Attribute (pre GL43) completed.");
// Debug logging
GLProxy.GL_LOGGER.debug("AttributeIndex: ElementCount, glType, normalized, strideSize, offset");
for (int i = 0; i < pointers.length; i++)
for (int i = 0; i < this.pointers.length; i++)
{
VertexPointer pointer = pointers[i];
VertexPointer pointer = this.pointers[i];
if (pointer == null)
{
GLProxy.GL_LOGGER.debug(i + ": Null!!!!");
continue;
}
GLProxy.GL_LOGGER.debug(i + ": " + pointer.elementCount + ", " +
pointer.glType + ", " + pointer.normalized + ", " + strideSize + ", " + pointersOffset[i]);
pointer.glType + ", " + pointer.normalized + ", " + this.strideSize + ", " + this.pointersOffset[i]);
}
}
@@ -206,7 +206,7 @@ public class DebugRenderer
this.basicShader.bind();
this.va.bind();
this.va.bindBufferToAllBindingPoint(this.boxBuffer.getId());
this.va.bindBufferToAllBindingPoints(this.boxBuffer.getId());
this.boxOutlineBuffer.bind();
@@ -159,7 +159,7 @@ public class LodRenderProgram extends ShaderProgram
public void bindVertexBuffer(int vbo)
{
vao.bindBufferToAllBindingPoint(vbo);
vao.bindBufferToAllBindingPoints(vbo);
}
public void unbindVertexBuffer()
@@ -72,7 +72,7 @@ public class ScreenQuad
this.init();
this.va.bind();
this.va.bindBufferToAllBindingPoint(this.boxBuffer.getId());
this.va.bindBufferToAllBindingPoints(this.boxBuffer.getId());
GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 6);
}
@@ -123,13 +123,13 @@ public class TestRenderer
if (System.currentTimeMillis() % 2000 < 1000)
{
sameContextBuffer.bind();
va.bindBufferToAllBindingPoint(sameContextBuffer.getId());
va.bindBufferToAllBindingPoints(sameContextBuffer.getId());
spamLogger.debug("same context buffer");
}
else
{
sameContextBuffer.bind();
va.bindBufferToAllBindingPoint(sharedContextBuffer.getId());
va.bindBufferToAllBindingPoints(sharedContextBuffer.getId());
spamLogger.debug("shared context buffer");
}
// Render the square