From 20c3caaed4962b2537c9d09070a20f2a1e2293f1 Mon Sep 17 00:00:00 2001 From: Jason Mitchell Date: Sat, 13 Jun 2026 16:50:44 -0700 Subject: [PATCH] A few redirects for calls that DH was using that we weren't redirecting (#1859) --- .../angelica/glsm/GLStateManager.java | 52 +++++++++++++++++-- .../glsm/backend/Lwjgl2GLRenderBackend.java | 5 ++ .../angelica/glsm/backend/RenderBackend.java | 1 + .../glsm/redirect/GLSMRedirector.java | 27 +++++----- .../lwjgl3/Lwjgl3GLRenderBackend.java | 13 ++++- 5 files changed, 80 insertions(+), 18 deletions(-) diff --git a/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/GLStateManager.java b/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/GLStateManager.java index 080e64814..d437d0fb3 100644 --- a/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/GLStateManager.java +++ b/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/GLStateManager.java @@ -1,6 +1,7 @@ package com.gtnewhorizons.angelica.glsm; import com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities; +import com.gtnewhorizon.gtnhlib.bytebuf.Pointer; import com.gtnewhorizon.gtnhlib.client.renderer.DirectTessellator; import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack; import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFlags; @@ -628,12 +629,16 @@ public class GLStateManager { LOGGER.info("GLStateManager cache bypassed"); } if (initConfig != null && initConfig.isLwjglDebug()) { - LOGGER.info("Enabling additional LWJGL debug output"); + if (RENDER_BACKEND.supportsDebugOutput()) { + LOGGER.info("Enabling additional LWJGL debug output"); - GLDebug.setupDebugMessageCallback(); - GLDebug.initDebugState(); + GLDebug.setupDebugMessageCallback(); + GLDebug.initDebugState(); - GLDebug.debugMessage("Angelica Debug Annotator Initialized"); + GLDebug.debugMessage("Angelica Debug Annotator Initialized"); + } else { + LOGGER.info("LWJGL debug output requested but unavailable in this GL context (requires GL 4.3 or GL_KHR_debug); skipping"); + } } defaultVAO = RENDER_BACKEND.genVertexArrays(); @@ -1194,6 +1199,22 @@ public class GLStateManager { }; } + private static final FloatBuffer glGetFloatScratch = BufferUtils.createFloatBuffer(16); + + public static void glGetFloat(int pname, float[] params) { + final FloatBuffer buf; + if (params.length <= glGetFloatScratch.capacity()) { + buf = glGetFloatScratch; + buf.clear(); + buf.limit(params.length); + } else { + buf = BufferUtils.createFloatBuffer(params.length); + } + glGetFloat(pname, buf); + buf.position(0); + buf.get(params); + } + // GLStateManager Functions public static void glBlendColor(float red, float green, float blue, float alpha) { @@ -4550,6 +4571,25 @@ public class GLStateManager { glShaderSource(shader, sb.toString()); } + public static void nglShaderSource(int shader, int count, long strings, long lengths) { + if (count <= 0) return; + final CharSequence source; + if (count == 1) { + source = decodeShaderSourceString(strings, lengths, 0); + } else { + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < count; i++) sb.append(decodeShaderSourceString(strings, lengths, i)); + source = sb.toString(); + } + glShaderSource(shader, source); + } + + private static String decodeShaderSourceString(long strings, long lengths, int i) { + final long strAddr = MemoryUtilities.memGetAddress(strings + (long) i * Pointer.POINTER_SIZE); + final int len = lengths == MemoryUtilities.NULL ? -1 : MemoryUtilities.memGetInt(lengths + (long) i * 4); + return len < 0 ? MemoryUtilities.memUTF8(strAddr) : MemoryUtilities.memUTF8(strAddr, len); + } + /** Check shader type to determine if fragment output transformation is needed. */ private static boolean isFragmentShader(int shader) { return RENDER_BACKEND.getShaderi(shader, GL20.GL_SHADER_TYPE) == GL20.GL_FRAGMENT_SHADER; @@ -5193,6 +5233,10 @@ public class GLStateManager { return RENDER_BACKEND.genVertexArrays(); } + public static boolean glIsVertexArray(int array) { + return RENDER_BACKEND.isVertexArray(array); + } + public static void glBindVertexArrayAPPLE(int array) { glBindVertexArray(array); } diff --git a/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/backend/Lwjgl2GLRenderBackend.java b/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/backend/Lwjgl2GLRenderBackend.java index 3e0a66898..2a2f9e02f 100644 --- a/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/backend/Lwjgl2GLRenderBackend.java +++ b/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/backend/Lwjgl2GLRenderBackend.java @@ -1038,6 +1038,11 @@ public final class Lwjgl2GLRenderBackend extends RenderBackend { GL30.glBindVertexArray(array); } + @Override + public boolean isVertexArray(int array) { + return GL30.glIsVertexArray(array); + } + @Override public void vertexAttribPointer(int index, int size, int type, boolean normalized, int stride, long pointer) { GL20.glVertexAttribPointer(index, size, type, normalized, stride, pointer); diff --git a/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/backend/RenderBackend.java b/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/backend/RenderBackend.java index c8bb6048f..25a9f4039 100644 --- a/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/backend/RenderBackend.java +++ b/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/backend/RenderBackend.java @@ -246,6 +246,7 @@ public abstract class RenderBackend { public abstract int genVertexArrays(); public abstract void deleteVertexArrays(int array); public abstract void bindVertexArray(int array); + public abstract boolean isVertexArray(int array); public abstract void vertexAttribPointer(int index, int size, int type, boolean normalized, int stride, long pointer); public void vertexAttribPointer(int index, int size, int type, boolean normalized, int stride, ByteBuffer pointer) { vertexAttribPointer(index, size, type, normalized, stride, MemoryUtilities.memAddress0(pointer)); diff --git a/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/redirect/GLSMRedirector.java b/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/redirect/GLSMRedirector.java index e11e8fdd2..143760fdf 100644 --- a/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/redirect/GLSMRedirector.java +++ b/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/redirect/GLSMRedirector.java @@ -126,6 +126,7 @@ public class GLSMRedirector { .add("glFrustum") .add("glGetBoolean") .add("glGetFloat") + .add("glGetFloatv", "glGetFloat") .add("glGetInteger") .add("glGetLight") .add("glGetMaterial") @@ -296,6 +297,7 @@ public class GLSMRedirector { .add("glStencilOpSeparate") .add("glUseProgram") .add("glShaderSource") + .add("nglShaderSource") .add("glLinkProgram") .add("glDeleteProgram") .add("glCreateShader") @@ -321,6 +323,7 @@ public class GLSMRedirector { .add("glUniformMatrix2") .add("glUniformMatrix3") .add("glUniformMatrix4") + .add("glUniformMatrix4fv", "glUniformMatrix4") .add("glDeleteShader") .add("glGetShaderi") .add("glGetShaderInfoLog") @@ -342,6 +345,7 @@ public class GLSMRedirector { .add("glGenVertexArrays") .add("glBindVertexArray") .add("glDeleteVertexArrays") + .add("glIsVertexArray") .add("glBindFramebuffer") .add("glDeleteFramebuffers") .add("glGenFramebuffers") @@ -587,18 +591,16 @@ public class GLSMRedirector { } } else { final Map redirects = mNode.owner.startsWith(GL_PREFIX) ? glMethodRedirects : methodRedirects.get(mNode.owner); - if (redirects != null) { - final String glsmName = redirects.get(mNode.name); - if (glsmName != null) { - if (LOG_SPAM) { - final String shortOwner = mNode.owner.substring(mNode.owner.lastIndexOf("/") + 1); - LOGGER.info("Redirecting call in {} from {}.{}{} to GLStateManager.{}{}", transformedName, shortOwner, mNode.name, mNode.desc, glsmName, mNode.desc); - } - mNode.owner = GLStateManager; - mNode.name = glsmName; - changed = true; - redirectInMethod = true; + final String glsmName = redirects != null ? redirects.get(mNode.name) : null; + if (glsmName != null) { + if (LOG_SPAM) { + final String shortOwner = mNode.owner.substring(mNode.owner.lastIndexOf("/") + 1); + LOGGER.info("Redirecting call in {} from {}.{}{} to GLStateManager.{}{}", transformedName, shortOwner, mNode.name, mNode.desc, glsmName, mNode.desc); } + mNode.owner = GLStateManager; + mNode.name = glsmName; + changed = true; + redirectInMethod = true; } } // Redirect calls for quadric classes @@ -617,8 +619,7 @@ public class GLSMRedirector { for (int i = 0; i < dynNode.bsmArgs.length; i++) { if (!(dynNode.bsmArgs[i] instanceof Handle handle)) continue; final Map redirects = handle.getOwner().startsWith(GL_PREFIX) ? glMethodRedirects : methodRedirects.get(handle.getOwner()); - if (redirects == null) continue; - final String glsmName = redirects.get(handle.getName()); + final String glsmName = redirects != null ? redirects.get(handle.getName()) : null; if (glsmName == null) continue; if (LOG_SPAM) { final String shortOwner = handle.getOwner().substring(handle.getOwner().lastIndexOf("/") + 1); diff --git a/lwjgl3-backend/src/main/java/com/gtnewhorizons/angelica/lwjgl3/Lwjgl3GLRenderBackend.java b/lwjgl3-backend/src/main/java/com/gtnewhorizons/angelica/lwjgl3/Lwjgl3GLRenderBackend.java index 44d27a8b0..f9c514892 100644 --- a/lwjgl3-backend/src/main/java/com/gtnewhorizons/angelica/lwjgl3/Lwjgl3GLRenderBackend.java +++ b/lwjgl3-backend/src/main/java/com/gtnewhorizons/angelica/lwjgl3/Lwjgl3GLRenderBackend.java @@ -1076,6 +1076,11 @@ public final class Lwjgl3GLRenderBackend extends RenderBackend { GL30C.glBindVertexArray(array); } + @Override + public boolean isVertexArray(int array) { + return GL30C.glIsVertexArray(array); + } + @Override public void vertexAttribPointer(int index, int size, int type, boolean normalized, int stride, long pointer) { GL20C.glVertexAttribPointer(index, size, type, normalized, stride, pointer); @@ -1366,11 +1371,14 @@ public final class Lwjgl3GLRenderBackend extends RenderBackend { @Override public boolean supportsDebugOutput() { - return caps != null && caps.OpenGL43; + return caps != null && (caps.OpenGL43 || caps.GL_KHR_debug); } @Override public int setupDebugOutput(DebugMessageHandler handler) { + if (caps == null || !(caps.OpenGL43 || caps.GL_KHR_debug)) { + return 0; + } debugCallback = GLDebugMessageCallback.create( (source, type, id, severity, length, message, userParam) -> { final String msg = GLDebugMessageCallback.getMessage(length, message); @@ -1398,6 +1406,9 @@ public final class Lwjgl3GLRenderBackend extends RenderBackend { @Override public int disableDebugOutput() { + if (caps == null || !(caps.OpenGL43 || caps.GL_KHR_debug)) { + return 0; + } GL43C.glDebugMessageCallback(null, 0L); if (debugCallback != null) { debugCallback.free();