Fix GL state corruption for mods not using MC's GlStateManager

This specifically fixes a bug with Iris where `GL46C.glDisable(GL46C.GL_CULL_FACE);` is called (instead of `GlStateManager._disableCull()`) during the transparent rendering pass, causing vanilla MC water chunks to have their normals inverted.
This commit is contained in:
James Seibel
2025-01-11 08:24:28 -06:00
parent 46cafb4cbe
commit 2b38dc2575
2 changed files with 95 additions and 31 deletions
@@ -29,13 +29,23 @@ import org.lwjgl.opengl.GL32;
/**
* A singleton that contains everything
* related to rendering in Minecraft.
*
* @author James Seibel
* @version 12-12-2021
* <b>Why does DH often call GL methods twice? </b><br>
* Once using the base {@link GL32} function and a second time using
* Minecraft's {@link GlStateManager}?<br><br>
*
* <b>Answer: </b><br>
* Compatibility and robustness<br>
* In general all MC rendering should go through MC's {@link GlStateManager},
* however that isn't always the case.
* So, to prevent issues if a mod (or MC itself) calls a direct GL function
* instead of the {@link GlStateManager} wrapper, we need to be sure about what the actual
* set value is (whether setting or getting) and that MC knows what DH has done.
* This way whether a mod (or MC) is using the {@link GlStateManager} or direct GL calls,
* they should always have the correct value for anything DH has modified.
* <br><br>
* This may slow down some low end GPUs that are driver limited,
* however James would rather have slow correct rendering vs fast broken rendering.
*/
//@Environment(EnvType.CLIENT)
public class MinecraftGLWrapper implements IMinecraftGLWrapper
{
public static final MinecraftGLWrapper INSTANCE = new MinecraftGLWrapper();
@@ -53,10 +63,18 @@ public class MinecraftGLWrapper implements IMinecraftGLWrapper
/** @see GL32#GL_SCISSOR_TEST */
@Override
public void enableScissorTest() { GlStateManager._enableScissorTest(); }
public void enableScissorTest()
{
GL32.glEnable(GL32.GL_SCISSOR_TEST);
GlStateManager._enableScissorTest();
}
/** @see GL32#GL_SCISSOR_TEST */
@Override
public void disableScissorTest() { GlStateManager._disableScissorTest(); }
public void disableScissorTest()
{
GL32.glDisable(GL32.GL_SCISSOR_TEST);
GlStateManager._disableScissorTest();
}
// stencil //
@@ -71,39 +89,74 @@ public class MinecraftGLWrapper implements IMinecraftGLWrapper
/** @see GL32#GL_DEPTH_TEST */
@Override
public void enableDepthTest() { GlStateManager._enableDepthTest(); }
public void enableDepthTest()
{
GL32.glEnable(GL32.GL_DEPTH_TEST);
GlStateManager._enableDepthTest();
}
/** @see GL32#GL_DEPTH_TEST */
@Override
public void disableDepthTest() { GlStateManager._disableDepthTest(); }
public void disableDepthTest()
{
GL32.glDisable(GL32.GL_DEPTH_TEST);
GlStateManager._disableDepthTest();
}
/** @see GL32#glDepthFunc(int) */
@Override
public void glDepthFunc(int func) { GlStateManager._depthFunc(func); }
public void glDepthFunc(int func)
{
GL32.glDepthFunc(func);
GlStateManager._depthFunc(func);
}
/** @see GL32#glDepthMask(boolean) */
@Override
public void enableDepthMask() { GlStateManager._depthMask(true); }
public void enableDepthMask()
{
GL32.glDepthMask(true);
GlStateManager._depthMask(true);
}
/** @see GL32#glDepthMask(boolean) */
@Override
public void disableDepthMask() { GlStateManager._depthMask(false); }
public void disableDepthMask()
{
GL32.glDepthMask(false);
GlStateManager._depthMask(false);
}
// blending //
/** @see GL32#GL_BLEND */
@Override
public void enableBlend() { GlStateManager._enableBlend(); }
public void enableBlend()
{
GL32.glEnable(GL32.GL_BLEND);
GlStateManager._enableBlend();
}
/** @see GL32#GL_BLEND */
@Override
public void disableBlend() { GlStateManager._disableBlend(); }
public void disableBlend()
{
GL32.glDisable(GL32.GL_BLEND);
GlStateManager._disableBlend();
}
/** @see GL32#glBlendFunc */
@Override
public void glBlendFunc(int sfactor, int dfactor) { GlStateManager._blendFunc(sfactor, dfactor); }
public void glBlendFunc(int sfactor, int dfactor)
{
GL32.glBlendFunc(sfactor, dfactor);
GlStateManager._blendFunc(sfactor, dfactor);
}
/** @see GL32#glBlendFuncSeparate */
@Override
public void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dfactorAlpha)
{ GlStateManager._blendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); }
{
GL32.glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
GlStateManager._blendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
}
// frame buffers //
@@ -111,7 +164,10 @@ public class MinecraftGLWrapper implements IMinecraftGLWrapper
/** @see GL32#glBindFramebuffer */
@Override
public void glBindFramebuffer(int target, int framebuffer)
{ GlStateManager._glBindFramebuffer(target, framebuffer); }
{
GL32.glBindFramebuffer(target, framebuffer);
GlStateManager._glBindFramebuffer(target, framebuffer);
}
// buffers //
@@ -131,10 +187,18 @@ public class MinecraftGLWrapper implements IMinecraftGLWrapper
/** @see GL32#GL_CULL_FACE */
@Override
public void enableFaceCulling() { GlStateManager._enableCull(); }
public void enableFaceCulling()
{
GL32.glEnable(GL32.GL_CULL_FACE);
GlStateManager._enableCull();
}
/** @see GL32#GL_CULL_FACE */
@Override
public void disableFaceCulling() { GlStateManager._disableCull(); }
public void disableFaceCulling()
{
GL32.glDisable(GL32.GL_CULL_FACE);
GlStateManager._disableCull();
}
// textures //
@@ -148,24 +212,24 @@ public class MinecraftGLWrapper implements IMinecraftGLWrapper
/** @see GL32#glActiveTexture(int) */
@Override
public void glActiveTexture(int textureId) { GlStateManager._activeTexture(textureId); }
/** only works for textures bound via this system or MC's {@link GlStateManager} */
@Override
public int getActiveTexture()
public void glActiveTexture(int textureId)
{
#if MC_VER <= MC_1_16_5
return GL32.glGetInteger(GL32.GL_ACTIVE_TEXTURE);
#else
return GlStateManager._getActiveTexture();
#endif
GL32.glActiveTexture(textureId);
GlStateManager._activeTexture(textureId);
}
@Override
public int getActiveTexture() { return GL32.glGetInteger(GL32.GL_ACTIVE_TEXTURE); }
/**
* Always binds to {@link GL32#GL_TEXTURE_2D}
* @see GL32#glBindTexture(int, int)
*/
@Override
public void glBindTexture(int texture) { GlStateManager._bindTexture(texture); }
public void glBindTexture(int texture)
{
GL32.glBindTexture(GL32.GL_TEXTURE_2D, texture);
GlStateManager._bindTexture(texture);
}