mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-13 15:56:07 +01:00
InDSAanced vertex arrays
- Make GlCompat static - Expand InstancedArrays compat to encompass all vertex array ops - GlVertexArray calls into VertexArray compat layer - VertexAttributes still use 2 separate interface methods
This commit is contained in:
parent
128a77275a
commit
684d9c7913
13 changed files with 221 additions and 188 deletions
|
@ -32,8 +32,7 @@ public class Backends {
|
||||||
.engineMessage(new TextComponent("Using Instancing Engine").withStyle(ChatFormatting.GREEN))
|
.engineMessage(new TextComponent("Using Instancing Engine").withStyle(ChatFormatting.GREEN))
|
||||||
.engineFactory(level -> new InstancingEngine(256, Contexts.WORLD))
|
.engineFactory(level -> new InstancingEngine(256, Contexts.WORLD))
|
||||||
.fallback(() -> Backends.BATCHING)
|
.fallback(() -> Backends.BATCHING)
|
||||||
.supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.getInstance()
|
.supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.supportsInstancing() && InstancingPrograms.allLoaded())
|
||||||
.instancedArraysSupported() && InstancingPrograms.allLoaded())
|
|
||||||
.register(Flywheel.rl("instancing"));
|
.register(Flywheel.rl("instancing"));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,8 +42,7 @@ public class Backends {
|
||||||
.engineMessage(new TextComponent("Using Indirect Engine").withStyle(ChatFormatting.GREEN))
|
.engineMessage(new TextComponent("Using Indirect Engine").withStyle(ChatFormatting.GREEN))
|
||||||
.engineFactory(level -> new IndirectEngine(256))
|
.engineFactory(level -> new IndirectEngine(256))
|
||||||
.fallback(() -> Backends.INSTANCING)
|
.fallback(() -> Backends.INSTANCING)
|
||||||
.supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.getInstance()
|
.supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.supportsIndirect() && IndirectPrograms.allLoaded())
|
||||||
.supportsIndirect() && IndirectPrograms.allLoaded())
|
|
||||||
.register(Flywheel.rl("indirect"));
|
.register(Flywheel.rl("indirect"));
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
package com.jozufozu.flywheel.backend.engine.indirect;
|
package com.jozufozu.flywheel.backend.engine.indirect;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL30.glBindVertexArray;
|
import static org.lwjgl.opengl.GL30.glBindVertexArray;
|
||||||
import static org.lwjgl.opengl.GL30.glDeleteVertexArrays;
|
|
||||||
import static org.lwjgl.opengl.GL42.GL_COMMAND_BARRIER_BIT;
|
import static org.lwjgl.opengl.GL42.GL_COMMAND_BARRIER_BIT;
|
||||||
import static org.lwjgl.opengl.GL42.glMemoryBarrier;
|
import static org.lwjgl.opengl.GL42.glMemoryBarrier;
|
||||||
import static org.lwjgl.opengl.GL43.GL_SHADER_STORAGE_BARRIER_BIT;
|
import static org.lwjgl.opengl.GL43.GL_SHADER_STORAGE_BARRIER_BIT;
|
||||||
import static org.lwjgl.opengl.GL43.glDispatchCompute;
|
import static org.lwjgl.opengl.GL43.glDispatchCompute;
|
||||||
import static org.lwjgl.opengl.GL45.glCreateVertexArrays;
|
|
||||||
import static org.lwjgl.opengl.GL45.glEnableVertexArrayAttrib;
|
|
||||||
import static org.lwjgl.opengl.GL45.glVertexArrayElementBuffer;
|
|
||||||
import static org.lwjgl.opengl.GL45.glVertexArrayVertexBuffer;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instance.Instance;
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
|
@ -17,6 +12,7 @@ import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.backend.compile.IndirectPrograms;
|
import com.jozufozu.flywheel.backend.compile.IndirectPrograms;
|
||||||
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
|
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
|
||||||
|
import com.jozufozu.flywheel.gl.array.GlVertexArray;
|
||||||
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
||||||
import com.jozufozu.flywheel.lib.context.Contexts;
|
import com.jozufozu.flywheel.lib.context.Contexts;
|
||||||
import com.jozufozu.flywheel.lib.util.QuadConverter;
|
import com.jozufozu.flywheel.lib.util.QuadConverter;
|
||||||
|
@ -35,7 +31,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
final IndirectMeshPool meshPool;
|
final IndirectMeshPool meshPool;
|
||||||
private final int elementBuffer;
|
private final int elementBuffer;
|
||||||
|
|
||||||
int vertexArray;
|
GlVertexArray vertexArray;
|
||||||
|
|
||||||
final IndirectDrawSet<I> drawSet = new IndirectDrawSet<>();
|
final IndirectDrawSet<I> drawSet = new IndirectDrawSet<>();
|
||||||
|
|
||||||
|
@ -55,7 +51,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
|
|
||||||
meshPool = new IndirectMeshPool(vertexType, 1024);
|
meshPool = new IndirectMeshPool(vertexType, 1024);
|
||||||
|
|
||||||
vertexArray = glCreateVertexArrays();
|
vertexArray = new GlVertexArray();
|
||||||
|
|
||||||
elementBuffer = QuadConverter.getInstance()
|
elementBuffer = QuadConverter.getInstance()
|
||||||
.quads2Tris(2048).glBuffer;
|
.quads2Tris(2048).glBuffer;
|
||||||
|
@ -67,21 +63,8 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupVertexArray() {
|
private void setupVertexArray() {
|
||||||
glVertexArrayElementBuffer(vertexArray, elementBuffer);
|
vertexArray.setElementBuffer(elementBuffer);
|
||||||
|
vertexArray.bindAttributes(vertexType.getLayout(), meshPool.vbo, 0, 0);
|
||||||
var meshLayout = vertexType.getLayout();
|
|
||||||
var meshAttribs = meshLayout.getAttributeCount();
|
|
||||||
|
|
||||||
var attributes = meshLayout.attributes();
|
|
||||||
|
|
||||||
long offset = 0;
|
|
||||||
for (int i = 0; i < meshAttribs; i++) {
|
|
||||||
var attribute = attributes.get(i);
|
|
||||||
glEnableVertexArrayAttrib(vertexArray, i);
|
|
||||||
glVertexArrayVertexBuffer(vertexArray, i, meshPool.vbo, offset, meshLayout.getStride());
|
|
||||||
attribute.format(vertexArray, i);
|
|
||||||
offset += attribute.getByteWidth();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void beginFrame() {
|
void beginFrame() {
|
||||||
|
@ -127,7 +110,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
}
|
}
|
||||||
|
|
||||||
UniformBuffer.syncAndBind(draw);
|
UniformBuffer.syncAndBind(draw);
|
||||||
glBindVertexArray(vertexArray);
|
vertexArray.bindForDraw();
|
||||||
buffers.bindForDraw();
|
buffers.bindForDraw();
|
||||||
|
|
||||||
memoryBarrier();
|
memoryBarrier();
|
||||||
|
@ -180,7 +163,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
glDeleteVertexArrays(vertexArray);
|
vertexArray.delete();
|
||||||
buffers.delete();
|
buffers.delete();
|
||||||
meshPool.delete();
|
meshPool.delete();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ public class DrawCall {
|
||||||
|
|
||||||
meshAttributes = this.mesh.getAttributeCount();
|
meshAttributes = this.mesh.getAttributeCount();
|
||||||
vao = new GlVertexArray();
|
vao = new GlVertexArray();
|
||||||
vao.enableArrays(meshAttributes + this.instancer.getAttributeCount());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInvalid() {
|
public boolean isInvalid() {
|
||||||
|
|
|
@ -90,7 +90,7 @@ public class GPUInstancer<I extends Instance> extends AbstractInstancer<I> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vao.bindAttributes(vbo, attributeOffset, instanceFormat, 0L);
|
vao.bindAttributes(instanceFormat, vbo.handle(), attributeOffset, 0L);
|
||||||
|
|
||||||
for (int i = 0; i < instanceFormat.getAttributeCount(); i++) {
|
for (int i = 0; i < instanceFormat.getAttributeCount(); i++) {
|
||||||
vao.setAttributeDivisor(attributeOffset + i, 1);
|
vao.setAttributeDivisor(attributeOffset + i, 1);
|
||||||
|
|
|
@ -221,11 +221,10 @@ public class InstancedMeshPool {
|
||||||
|
|
||||||
private void setup(GlVertexArray vao) {
|
private void setup(GlVertexArray vao) {
|
||||||
if (boundTo.add(vao)) {
|
if (boundTo.add(vao)) {
|
||||||
vao.enableArrays(getAttributeCount());
|
vao.bindAttributes(vertexType.getLayout(), InstancedMeshPool.this.vbo.handle(), 0, byteIndex);
|
||||||
vao.bindAttributes(InstancedMeshPool.this.vbo, 0, vertexType.getLayout(), byteIndex);
|
vao.setElementBuffer(ebo.glBuffer);
|
||||||
}
|
}
|
||||||
vao.bindElementArray(ebo.glBuffer);
|
vao.bindForDraw();
|
||||||
vao.bind();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void draw(int instanceCount) {
|
private void draw(int instanceCount) {
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
package com.jozufozu.flywheel.gl.array;
|
package com.jozufozu.flywheel.gl.array;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL20;
|
import java.util.List;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL32;
|
import org.lwjgl.opengl.GL32;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.layout.BufferLayout;
|
import com.jozufozu.flywheel.api.layout.BufferLayout;
|
||||||
import com.jozufozu.flywheel.gl.GlObject;
|
import com.jozufozu.flywheel.gl.GlObject;
|
||||||
import com.jozufozu.flywheel.gl.GlStateTracker;
|
import com.jozufozu.flywheel.gl.GlStateTracker;
|
||||||
import com.jozufozu.flywheel.gl.buffer.GlBuffer;
|
|
||||||
import com.jozufozu.flywheel.gl.buffer.GlBufferType;
|
|
||||||
import com.jozufozu.flywheel.gl.versioned.GlCompat;
|
import com.jozufozu.flywheel.gl.versioned.GlCompat;
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
|
||||||
|
@ -24,22 +23,18 @@ public class GlVertexArray extends GlObject {
|
||||||
* Each attribute's divisor.
|
* Each attribute's divisor.
|
||||||
*/
|
*/
|
||||||
private final int[] divisors = new int[MAX_ATTRIBS];
|
private final int[] divisors = new int[MAX_ATTRIBS];
|
||||||
|
|
||||||
/**
|
|
||||||
* The VBO to which each attribute is bound.
|
|
||||||
*/
|
|
||||||
private final int[] targets = new int[MAX_ATTRIBS];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Each attribute's data type.
|
* Each attribute's data type.
|
||||||
*/
|
*/
|
||||||
private final VertexAttribute[] attributes = new VertexAttribute[MAX_ATTRIBS];
|
private final VertexAttribute[] attributes = new VertexAttribute[MAX_ATTRIBS];
|
||||||
|
/**
|
||||||
|
* The VBO to which each attribute is bound.
|
||||||
|
*/
|
||||||
|
private final int[] targets = new int[MAX_ATTRIBS];
|
||||||
/**
|
/**
|
||||||
* Each attribute's offset.
|
* Each attribute's offset.
|
||||||
*/
|
*/
|
||||||
private final long[] offsets = new long[MAX_ATTRIBS];
|
private final long[] offsets = new long[MAX_ATTRIBS];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Each attribute's stride.
|
* Each attribute's stride.
|
||||||
*/
|
*/
|
||||||
|
@ -49,16 +44,16 @@ public class GlVertexArray extends GlObject {
|
||||||
|
|
||||||
|
|
||||||
public GlVertexArray() {
|
public GlVertexArray() {
|
||||||
setHandle(GlStateManager._glGenVertexArrays());
|
setHandle(GlCompat.vertexArray.create());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind() {
|
public void bindForDraw() {
|
||||||
if (!isBound()) {
|
if (!isBound()) {
|
||||||
GlStateManager._glBindVertexArray(handle());
|
GlStateManager._glBindVertexArray(handle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBound() {
|
private boolean isBound() {
|
||||||
return handle() == GlStateTracker.getVertexArray();
|
return handle() == GlStateTracker.getVertexArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,62 +61,21 @@ public class GlVertexArray extends GlObject {
|
||||||
GlStateManager._glBindVertexArray(0);
|
GlStateManager._glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void bindAttributes(BufferLayout type, int vbo, int startAttrib, long startOffset) {
|
||||||
* @param buffer The buffer where the data is stored.
|
|
||||||
* @param startAttrib The first attribute to be used by the data.
|
|
||||||
* @param type The format of the attributes.
|
|
||||||
* @param offset The offset in bytes to the start of the data.
|
|
||||||
*/
|
|
||||||
public void bindAttributes(GlBuffer buffer, int startAttrib, BufferLayout type, long offset) {
|
|
||||||
bind();
|
|
||||||
|
|
||||||
int targetBuffer = buffer.handle();
|
|
||||||
|
|
||||||
GlBufferType.ARRAY_BUFFER.bind(targetBuffer);
|
|
||||||
|
|
||||||
int i = startAttrib;
|
|
||||||
final int stride = type.getStride();
|
final int stride = type.getStride();
|
||||||
|
|
||||||
for (var attribute : type.attributes()) {
|
List<VertexAttribute> vertexAttributes = type.attributes();
|
||||||
targets[i] = targetBuffer;
|
for (int i = 0; i < vertexAttributes.size(); i++) {
|
||||||
attributes[i] = attribute;
|
var attribute = vertexAttributes.get(i);
|
||||||
offsets[i] = offset;
|
int index = i + startAttrib;
|
||||||
strides[i] = stride;
|
targets[index] = vbo;
|
||||||
|
attributes[index] = attribute;
|
||||||
|
offsets[index] = startOffset;
|
||||||
|
strides[index] = stride;
|
||||||
|
|
||||||
attribute.pointer(offset, i, stride);
|
GlCompat.vertexArray.setupAttrib(handle(), stride, vbo, startOffset, attribute, index);
|
||||||
|
|
||||||
i++;
|
startOffset += attribute.getByteWidth();
|
||||||
offset += attribute.getByteWidth();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableArrays(int count) {
|
|
||||||
bind();
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
enable(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void disableArrays(int count) {
|
|
||||||
bind();
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
disable(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void enable(int i) {
|
|
||||||
if (!enabled[i]) {
|
|
||||||
GL20.glEnableVertexAttribArray(i);
|
|
||||||
enabled[i] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void disable(int i) {
|
|
||||||
if (enabled[i]) {
|
|
||||||
GL20.glDisableVertexAttribArray(i);
|
|
||||||
enabled[i] = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,16 +85,14 @@ public class GlVertexArray extends GlObject {
|
||||||
|
|
||||||
public void setAttributeDivisor(int index, int divisor) {
|
public void setAttributeDivisor(int index, int divisor) {
|
||||||
if (divisors[index] != divisor) {
|
if (divisors[index] != divisor) {
|
||||||
bind();
|
GlCompat.vertexArray.setAttribDivisor(handle(), index, divisor);
|
||||||
GlCompat.getInstance().instancedArrays.vertexAttribDivisor(index, divisor);
|
|
||||||
divisors[index] = divisor;
|
divisors[index] = divisor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bindElementArray(int ebo) {
|
public void setElementBuffer(int ebo) {
|
||||||
if (elementBufferBinding != ebo) {
|
if (elementBufferBinding != ebo) {
|
||||||
bind();
|
GlCompat.vertexArray.setElementBuffer(handle(), ebo);
|
||||||
GlBufferType.ELEMENT_ARRAY_BUFFER.bind(ebo);
|
|
||||||
elementBufferBinding = ebo;
|
elementBufferBinding = ebo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,16 +5,18 @@ public interface VertexAttribute {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply this vertex attribute to the bound vertex array.
|
* Apply this vertex attribute to the bound vertex array.
|
||||||
|
*
|
||||||
* @param offset The byte offset to the first element of the attribute.
|
* @param offset The byte offset to the first element of the attribute.
|
||||||
* @param i The attribute index.
|
* @param i The attribute index.
|
||||||
* @param stride The byte stride between consecutive elements of the attribute.
|
* @param stride The byte stride between consecutive elements of the attribute.
|
||||||
*/
|
*/
|
||||||
void pointer(long offset, int i, int stride);
|
void setup(long offset, int i, int stride);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use DSA to apply this vertex attribute to the given vertex array.
|
* Use DSA to apply this vertex attribute to the given vertex array.
|
||||||
|
*
|
||||||
* @param vaobj The vertex array object to modify.
|
* @param vaobj The vertex array object to modify.
|
||||||
* @param i The attribute index.
|
* @param i The attribute index.
|
||||||
*/
|
*/
|
||||||
void format(int vaobj, int i);
|
void setupDSA(int vaobj, int i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,12 @@ public record VertexAttributeF(GlNumericType type, int size, boolean normalized)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pointer(long offset, int i, int stride) {
|
public void setup(long offset, int i, int stride) {
|
||||||
GL32.glVertexAttribPointer(i, size(), type().getGlEnum(), normalized(), stride, offset);
|
GL32.glVertexAttribPointer(i, size(), type().getGlEnum(), normalized(), stride, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void format(int vaobj, int i) {
|
public void setupDSA(int vaobj, int i) {
|
||||||
GL45.glVertexArrayAttribFormat(vaobj, i, size(), type().getGlEnum(), normalized(), 0);
|
GL45.glVertexArrayAttribFormat(vaobj, i, size(), type().getGlEnum(), normalized(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,12 +19,12 @@ public record VertexAttributeI(GlNumericType type, int size) implements VertexAt
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pointer(long offset, int i, int stride) {
|
public void setup(long offset, int i, int stride) {
|
||||||
GL32.glVertexAttribIPointer(i, size(), type().getGlEnum(), stride, offset);
|
GL32.glVertexAttribIPointer(i, size(), type().getGlEnum(), stride, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void format(int vaobj, int i) {
|
public void setupDSA(int vaobj, int i) {
|
||||||
GL45.glVertexArrayAttribIFormat(vaobj, i, size(), type().getGlEnum(), 0);
|
GL45.glVertexArrayAttribIFormat(vaobj, i, size(), type().getGlEnum(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,40 +18,35 @@ import net.minecraft.Util;
|
||||||
* system.
|
* system.
|
||||||
*/
|
*/
|
||||||
public class GlCompat {
|
public class GlCompat {
|
||||||
|
public static final VertexArray vertexArray;
|
||||||
|
public static final BufferStorage bufferStorage;
|
||||||
|
public static final boolean amd;
|
||||||
|
public static final boolean supportsIndirect;
|
||||||
|
|
||||||
private static GlCompat instance;
|
static {
|
||||||
|
|
||||||
public static GlCompat getInstance() {
|
|
||||||
if (instance == null) {
|
|
||||||
instance = new GlCompat();
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final InstancedArrays instancedArrays;
|
|
||||||
public final BufferStorage bufferStorage;
|
|
||||||
public final boolean amd;
|
|
||||||
public final boolean supportsIndirect;
|
|
||||||
|
|
||||||
private GlCompat() {
|
|
||||||
GLCapabilities caps = GL.createCapabilities();
|
GLCapabilities caps = GL.createCapabilities();
|
||||||
instancedArrays = getLatest(InstancedArrays.class, caps);
|
|
||||||
bufferStorage = getLatest(BufferStorage.class, caps);
|
bufferStorage = getLatest(BufferStorage.class, caps);
|
||||||
|
vertexArray = getLatest(VertexArray.class, caps);
|
||||||
supportsIndirect = true;
|
supportsIndirect = caps.OpenGL46;
|
||||||
|
|
||||||
amd = _isAmdWindows();
|
amd = _isAmdWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onAMDWindows() {
|
private GlCompat() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean onAMDWindows() {
|
||||||
return amd;
|
return amd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean instancedArraysSupported() {
|
public static boolean supportsInstancing() {
|
||||||
return instancedArrays != InstancedArrays.UNSUPPORTED;
|
return vertexArray != VertexArray.UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean bufferStorageSupported() {
|
public static boolean supportsIndirect() {
|
||||||
|
return supportsIndirect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean bufferStorageSupported() {
|
||||||
return bufferStorage != BufferStorage.UNSUPPORTED;
|
return bufferStorage != BufferStorage.UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +58,7 @@ public class GlCompat {
|
||||||
* @param <V> The type of the versioning enum.
|
* @param <V> The type of the versioning enum.
|
||||||
* @return The first defined enum variant to return true.
|
* @return The first defined enum variant to return true.
|
||||||
*/
|
*/
|
||||||
public static <V extends Enum<V> & GlVersioned> V getLatest(Class<V> clazz, GLCapabilities caps) {
|
private static <V extends Enum<V> & GlVersioned> V getLatest(Class<V> clazz, GLCapabilities caps) {
|
||||||
V[] constants = clazz.getEnumConstants();
|
V[] constants = clazz.getEnumConstants();
|
||||||
V last = constants[constants.length - 1];
|
V last = constants[constants.length - 1];
|
||||||
if (!last.supported(caps)) {
|
if (!last.supported(caps)) {
|
||||||
|
@ -111,9 +106,5 @@ public class GlCompat {
|
||||||
// vendor string I got was "ATI Technologies Inc."
|
// vendor string I got was "ATI Technologies Inc."
|
||||||
return vendor.contains("ATI") || vendor.contains("AMD");
|
return vendor.contains("ATI") || vendor.contains("AMD");
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean supportsIndirect() {
|
|
||||||
return supportsIndirect;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
package com.jozufozu.flywheel.gl.versioned;
|
|
||||||
|
|
||||||
import org.lwjgl.opengl.ARBInstancedArrays;
|
|
||||||
import org.lwjgl.opengl.GL33;
|
|
||||||
import org.lwjgl.opengl.GLCapabilities;
|
|
||||||
|
|
||||||
public enum InstancedArrays implements GlVersioned {
|
|
||||||
GL33_INSTANCED_ARRAYS {
|
|
||||||
@Override
|
|
||||||
public boolean supported(GLCapabilities caps) {
|
|
||||||
return caps.OpenGL33;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void vertexAttribDivisor(int index, int divisor) {
|
|
||||||
GL33.glVertexAttribDivisor(index, divisor);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ARB_INSTANCED_ARRAYS {
|
|
||||||
@Override
|
|
||||||
public boolean supported(GLCapabilities caps) {
|
|
||||||
return caps.GL_ARB_instanced_arrays;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void vertexAttribDivisor(int index, int divisor) {
|
|
||||||
ARBInstancedArrays.glVertexAttribDivisorARB(index, divisor);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
UNSUPPORTED {
|
|
||||||
@Override
|
|
||||||
public boolean supported(GLCapabilities caps) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void vertexAttribDivisor(int index, int divisor) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public abstract void vertexAttribDivisor(int index, int divisor);
|
|
||||||
}
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
package com.jozufozu.flywheel.gl.versioned;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.ARBInstancedArrays;
|
||||||
|
import org.lwjgl.opengl.GL30;
|
||||||
|
import org.lwjgl.opengl.GL33;
|
||||||
|
import org.lwjgl.opengl.GL45C;
|
||||||
|
import org.lwjgl.opengl.GLCapabilities;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.gl.GlStateTracker;
|
||||||
|
import com.jozufozu.flywheel.gl.array.VertexAttribute;
|
||||||
|
import com.jozufozu.flywheel.gl.buffer.GlBufferType;
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
|
||||||
|
public enum VertexArray implements GlVersioned {
|
||||||
|
DSA {
|
||||||
|
@Override
|
||||||
|
public boolean supported(GLCapabilities caps) {
|
||||||
|
// The static methods from GL45 and ARBDirectStateAccess all point to GL45C.
|
||||||
|
return caps.OpenGL45 || caps.GL_ARB_direct_state_access;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int create() {
|
||||||
|
return GL45C.glCreateVertexArrays();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setElementBuffer(int vao, int elementBuffer) {
|
||||||
|
GL45C.glVertexArrayElementBuffer(vao, elementBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setupAttrib(int vao, int stride, int vbo, long offset, VertexAttribute attribute, int index) {
|
||||||
|
GL45C.glEnableVertexArrayAttrib(vao, index);
|
||||||
|
GL45C.glVertexArrayVertexBuffer(vao, index, vbo, offset, stride);
|
||||||
|
attribute.setupDSA(vao, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAttribDivisor(int vao, int attrib, int divisor) {
|
||||||
|
GL45C.glVertexArrayBindingDivisor(vao, attrib, divisor);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
GL_33 {
|
||||||
|
@Override
|
||||||
|
public boolean supported(GLCapabilities caps) {
|
||||||
|
return caps.OpenGL33;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int create() {
|
||||||
|
return GL33.glGenVertexArrays();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setElementBuffer(int vao, int elementBuffer) {
|
||||||
|
if (vao != GlStateTracker.getVertexArray()) {
|
||||||
|
GlStateManager._glBindVertexArray(vao);
|
||||||
|
}
|
||||||
|
GlBufferType.ELEMENT_ARRAY_BUFFER.bind(elementBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setupAttrib(int vao, int stride, int vbo, long offset, VertexAttribute attribute, int index) {
|
||||||
|
if (vao != GlStateTracker.getVertexArray()) {
|
||||||
|
GlStateManager._glBindVertexArray(vao);
|
||||||
|
}
|
||||||
|
GlBufferType.ARRAY_BUFFER.bind(vbo);
|
||||||
|
|
||||||
|
GL33.glEnableVertexAttribArray(index);
|
||||||
|
attribute.setup(offset, index, stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAttribDivisor(int vao, int attrib, int divisor) {
|
||||||
|
if (vao != GlStateTracker.getVertexArray()) {
|
||||||
|
GlStateManager._glBindVertexArray(vao);
|
||||||
|
}
|
||||||
|
GL33.glVertexAttribDivisor(attrib, divisor);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ARB_INSTANCED_ARRAYS {
|
||||||
|
@Override
|
||||||
|
public boolean supported(GLCapabilities caps) {
|
||||||
|
return caps.GL_ARB_instanced_arrays;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int create() {
|
||||||
|
return GL30.glGenVertexArrays();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setElementBuffer(int vao, int elementBuffer) {
|
||||||
|
if (vao != GlStateTracker.getVertexArray()) {
|
||||||
|
GlStateManager._glBindVertexArray(vao);
|
||||||
|
}
|
||||||
|
GlBufferType.ELEMENT_ARRAY_BUFFER.bind(elementBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setupAttrib(int vao, int stride, int vbo, long offset, VertexAttribute attribute, int index) {
|
||||||
|
if (vao != GlStateTracker.getVertexArray()) {
|
||||||
|
GlStateManager._glBindVertexArray(vao);
|
||||||
|
}
|
||||||
|
GlBufferType.ARRAY_BUFFER.bind(vbo);
|
||||||
|
|
||||||
|
GL30.glEnableVertexAttribArray(index);
|
||||||
|
attribute.setup(offset, index, stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAttribDivisor(int vao, int attrib, int divisor) {
|
||||||
|
if (vao != GlStateTracker.getVertexArray()) {
|
||||||
|
GlStateManager._glBindVertexArray(vao);
|
||||||
|
}
|
||||||
|
ARBInstancedArrays.glVertexAttribDivisorARB(attrib, divisor);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
UNSUPPORTED {
|
||||||
|
@Override
|
||||||
|
public boolean supported(GLCapabilities caps) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int create() {
|
||||||
|
throw new UnsupportedOperationException("Cannot use vertex arrays");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setElementBuffer(int vao, int elementBuffer) {
|
||||||
|
throw new UnsupportedOperationException("Cannot use vertex arrays");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setupAttrib(int vao, int stride, int vbo, long offset, VertexAttribute attribute, int index) {
|
||||||
|
throw new UnsupportedOperationException("Cannot use vertex arrays");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAttribDivisor(int vao, int attrib, int divisor) {
|
||||||
|
throw new UnsupportedOperationException("Cannot use vertex arrays");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public abstract int create();
|
||||||
|
|
||||||
|
public abstract void setElementBuffer(int vao, int elementBuffer);
|
||||||
|
|
||||||
|
public abstract void setupAttrib(int vao, int stride, int vbo, long offset, VertexAttribute attribute, int index);
|
||||||
|
|
||||||
|
public abstract void setAttribDivisor(int vao, int attrib, int divisor);
|
||||||
|
}
|
|
@ -50,14 +50,12 @@ public class FullscreenQuad {
|
||||||
|
|
||||||
vao = new GlVertexArray();
|
vao = new GlVertexArray();
|
||||||
|
|
||||||
vao.enableArrays(1);
|
vao.bindAttributes(LAYOUT, vbo.handle(), 0, 0L);
|
||||||
|
|
||||||
vao.bindAttributes(vbo, 0, LAYOUT, 0L);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw() {
|
public void draw() {
|
||||||
vao.bind();
|
vao.bindForDraw();
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
GlVertexArray.unbind();
|
GlVertexArray.unbind();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue