171 lines
7.9 KiB
Java
171 lines
7.9 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*
|
|
* Could not load the following classes:
|
|
* org.jspecify.annotations.Nullable
|
|
* org.lwjgl.opengl.ARBVertexAttribBinding
|
|
* org.lwjgl.opengl.GLCapabilities
|
|
*/
|
|
package com.mojang.blaze3d.opengl;
|
|
|
|
import com.mojang.blaze3d.opengl.GlBuffer;
|
|
import com.mojang.blaze3d.opengl.GlConst;
|
|
import com.mojang.blaze3d.opengl.GlDebugLabel;
|
|
import com.mojang.blaze3d.opengl.GlDevice;
|
|
import com.mojang.blaze3d.opengl.GlStateManager;
|
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
|
import com.mojang.blaze3d.vertex.VertexFormatElement;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import org.jspecify.annotations.Nullable;
|
|
import org.lwjgl.opengl.ARBVertexAttribBinding;
|
|
import org.lwjgl.opengl.GLCapabilities;
|
|
|
|
public abstract class VertexArrayCache {
|
|
public static VertexArrayCache create(GLCapabilities capabilities, GlDebugLabel debugLabels, Set<String> enabledExtensions) {
|
|
if (capabilities.GL_ARB_vertex_attrib_binding && GlDevice.USE_GL_ARB_vertex_attrib_binding) {
|
|
enabledExtensions.add("GL_ARB_vertex_attrib_binding");
|
|
return new Separate(debugLabels);
|
|
}
|
|
return new Emulated(debugLabels);
|
|
}
|
|
|
|
public abstract void bindVertexArray(VertexFormat var1, @Nullable GlBuffer var2);
|
|
|
|
private static class Separate
|
|
extends VertexArrayCache {
|
|
private final Map<VertexFormat, VertexArray> cache = new HashMap<VertexFormat, VertexArray>();
|
|
private final GlDebugLabel debugLabels;
|
|
private final boolean needsMesaWorkaround;
|
|
|
|
public Separate(GlDebugLabel debugLabels) {
|
|
String version;
|
|
this.debugLabels = debugLabels;
|
|
this.needsMesaWorkaround = "Mesa".equals(GlStateManager._getString(7936)) ? (version = GlStateManager._getString(7938)).contains("25.0.0") || version.contains("25.0.1") || version.contains("25.0.2") : false;
|
|
}
|
|
|
|
@Override
|
|
public void bindVertexArray(VertexFormat format, @Nullable GlBuffer vertexBuffer) {
|
|
VertexArray vertexArray = this.cache.get(format);
|
|
if (vertexArray == null) {
|
|
int id = GlStateManager._glGenVertexArrays();
|
|
GlStateManager._glBindVertexArray(id);
|
|
if (vertexBuffer != null) {
|
|
List<VertexFormatElement> elements = format.getElements();
|
|
for (int i = 0; i < elements.size(); ++i) {
|
|
VertexFormatElement element = elements.get(i);
|
|
GlStateManager._enableVertexAttribArray(i);
|
|
switch (element.usage()) {
|
|
case POSITION:
|
|
case GENERIC:
|
|
case UV: {
|
|
if (element.type() == VertexFormatElement.Type.FLOAT) {
|
|
ARBVertexAttribBinding.glVertexAttribFormat((int)i, (int)element.count(), (int)GlConst.toGl(element.type()), (boolean)false, (int)format.getOffset(element));
|
|
break;
|
|
}
|
|
ARBVertexAttribBinding.glVertexAttribIFormat((int)i, (int)element.count(), (int)GlConst.toGl(element.type()), (int)format.getOffset(element));
|
|
break;
|
|
}
|
|
case NORMAL:
|
|
case COLOR: {
|
|
ARBVertexAttribBinding.glVertexAttribFormat((int)i, (int)element.count(), (int)GlConst.toGl(element.type()), (boolean)true, (int)format.getOffset(element));
|
|
}
|
|
}
|
|
ARBVertexAttribBinding.glVertexAttribBinding((int)i, (int)0);
|
|
}
|
|
}
|
|
if (vertexBuffer != null) {
|
|
ARBVertexAttribBinding.glBindVertexBuffer((int)0, (int)vertexBuffer.handle, (long)0L, (int)format.getVertexSize());
|
|
}
|
|
VertexArray vao = new VertexArray(id, format, vertexBuffer);
|
|
this.debugLabels.applyLabel(vao);
|
|
this.cache.put(format, vao);
|
|
return;
|
|
}
|
|
GlStateManager._glBindVertexArray(vertexArray.id);
|
|
if (vertexBuffer != null && vertexArray.lastVertexBuffer != vertexBuffer) {
|
|
if (this.needsMesaWorkaround && vertexArray.lastVertexBuffer != null && vertexArray.lastVertexBuffer.handle == vertexBuffer.handle) {
|
|
ARBVertexAttribBinding.glBindVertexBuffer((int)0, (int)0, (long)0L, (int)0);
|
|
}
|
|
ARBVertexAttribBinding.glBindVertexBuffer((int)0, (int)vertexBuffer.handle, (long)0L, (int)format.getVertexSize());
|
|
vertexArray.lastVertexBuffer = vertexBuffer;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static class Emulated
|
|
extends VertexArrayCache {
|
|
private final Map<VertexFormat, VertexArray> cache = new HashMap<VertexFormat, VertexArray>();
|
|
private final GlDebugLabel debugLabels;
|
|
|
|
public Emulated(GlDebugLabel debugLabels) {
|
|
this.debugLabels = debugLabels;
|
|
}
|
|
|
|
@Override
|
|
public void bindVertexArray(VertexFormat format, @Nullable GlBuffer vertexBuffer) {
|
|
VertexArray vertexArray = this.cache.get(format);
|
|
if (vertexArray == null) {
|
|
int id = GlStateManager._glGenVertexArrays();
|
|
GlStateManager._glBindVertexArray(id);
|
|
if (vertexBuffer != null) {
|
|
GlStateManager._glBindBuffer(34962, vertexBuffer.handle);
|
|
Emulated.setupCombinedAttributes(format, true);
|
|
}
|
|
VertexArray vao = new VertexArray(id, format, vertexBuffer);
|
|
this.debugLabels.applyLabel(vao);
|
|
this.cache.put(format, vao);
|
|
return;
|
|
}
|
|
GlStateManager._glBindVertexArray(vertexArray.id);
|
|
if (vertexBuffer != null && vertexArray.lastVertexBuffer != vertexBuffer) {
|
|
GlStateManager._glBindBuffer(34962, vertexBuffer.handle);
|
|
vertexArray.lastVertexBuffer = vertexBuffer;
|
|
Emulated.setupCombinedAttributes(format, false);
|
|
}
|
|
}
|
|
|
|
private static void setupCombinedAttributes(VertexFormat format, boolean enable) {
|
|
int vertexSize = format.getVertexSize();
|
|
List<VertexFormatElement> elements = format.getElements();
|
|
block4: for (int i = 0; i < elements.size(); ++i) {
|
|
VertexFormatElement element = elements.get(i);
|
|
if (enable) {
|
|
GlStateManager._enableVertexAttribArray(i);
|
|
}
|
|
switch (element.usage()) {
|
|
case POSITION:
|
|
case GENERIC:
|
|
case UV: {
|
|
if (element.type() == VertexFormatElement.Type.FLOAT) {
|
|
GlStateManager._vertexAttribPointer(i, element.count(), GlConst.toGl(element.type()), false, vertexSize, format.getOffset(element));
|
|
continue block4;
|
|
}
|
|
GlStateManager._vertexAttribIPointer(i, element.count(), GlConst.toGl(element.type()), vertexSize, format.getOffset(element));
|
|
continue block4;
|
|
}
|
|
case NORMAL:
|
|
case COLOR: {
|
|
GlStateManager._vertexAttribPointer(i, element.count(), GlConst.toGl(element.type()), true, vertexSize, format.getOffset(element));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static class VertexArray {
|
|
final int id;
|
|
final VertexFormat format;
|
|
@Nullable GlBuffer lastVertexBuffer;
|
|
|
|
private VertexArray(int id, VertexFormat format, @Nullable GlBuffer lastVertexBuffer) {
|
|
this.id = id;
|
|
this.format = format;
|
|
this.lastVertexBuffer = lastVertexBuffer;
|
|
}
|
|
}
|
|
}
|
|
|