diff --git a/src/main/java/shit/zen/render/StencilHelper.java b/src/main/java/shit/zen/render/StencilHelper.java index 98fd001..2fea263 100644 --- a/src/main/java/shit/zen/render/StencilHelper.java +++ b/src/main/java/shit/zen/render/StencilHelper.java @@ -29,6 +29,12 @@ public class StencilHelper { private static final RenderTarget mainRenderTarget = ClientBase.mc.getMainRenderTarget(); public static void applyStencil(PoseStack poseStack, Runnable drawMask, Runnable drawContent, float opacity) { + if (!stencilShader.isValid()) { + // Stencil shader unavailable on this driver — skip the rounded composite and + // just draw the content directly so the panel still shows (without rounding). + drawContent.run(); + return; + } Matrix4f pose = poseStack.last().pose(); RenderTarget mask = maskTarget.get(); if (mask.width != StencilHelper.mainRenderTarget.width || mask.height != StencilHelper.mainRenderTarget.height) { diff --git a/src/main/java/shit/zen/render/shader/ShaderProgram.java b/src/main/java/shit/zen/render/shader/ShaderProgram.java index 65a74c2..d31b7a3 100644 --- a/src/main/java/shit/zen/render/shader/ShaderProgram.java +++ b/src/main/java/shit/zen/render/shader/ShaderProgram.java @@ -19,6 +19,8 @@ public class ShaderProgram { @Getter private final int programId; @Getter + private final boolean valid; + @Getter private final Map uniformCache = new HashMap<>(); @Getter private final Matrix4Uniform modelViewUniform; @@ -50,6 +52,18 @@ public class ShaderProgram { this.programId = GL20.glCreateProgram(); int fragmentShader = ShaderProgram.compileShader(ShaderSource.getByFileName(fragmentName + ".fsh").getSource(), 35632); int vertexShader = ShaderProgram.compileShader(ShaderSource.getByFileName(vertexName + ".vsh").getSource(), 35633); + // Shader compilation can fail on some drivers (notably Intel forward-compatible + // GL contexts, which reject legacy GLSL such as texture2D). Degrade gracefully — + // disable this program so callers skip the effect — instead of crashing the game. + if (fragmentShader == 0 || vertexShader == 0) { + if (fragmentShader != 0) GL20.glDeleteShader(fragmentShader); + if (vertexShader != 0) GL20.glDeleteShader(vertexShader); + LOGGER.error("Shader '{}' disabled: compilation failed; the effect will be skipped.", fragmentName); + this.modelViewUniform = null; + this.projectionUniform = null; + this.valid = false; + return; + } GL20.glAttachShader(this.programId, fragmentShader); GL20.glAttachShader(this.programId, vertexShader); for (Map.Entry entry : attributesSupplier.get().entrySet()) { @@ -59,15 +73,25 @@ public class ShaderProgram { GL20.glLinkProgram(this.programId); if (GL20.glGetProgrami(this.programId, 35714) == 0) { LOGGER.error(GL20.glGetProgramInfoLog(this.programId, Short.MAX_VALUE)); - throw new IllegalStateException("Failed to link shader program!"); + LOGGER.error("Shader '{}' disabled: program link failed; the effect will be skipped.", fragmentName); + GL20.glDeleteShader(fragmentShader); + GL20.glDeleteShader(vertexShader); + this.modelViewUniform = null; + this.projectionUniform = null; + this.valid = false; + return; } GL20.glDeleteShader(fragmentShader); GL20.glDeleteShader(vertexShader); this.modelViewUniform = new Matrix4Uniform(modelViewName).bindToProgram(this.programId); this.projectionUniform = new Matrix4Uniform(projName).bindToProgram(this.programId); + this.valid = true; } public void use() { + if (!this.valid) { + return; + } prevProgram = GL20.glGetInteger(35725); GL20.glUseProgram(this.programId); this.setModelView(RenderSystem.getModelViewMatrix()); @@ -112,8 +136,9 @@ public class ShaderProgram { GL20.glShaderSource(shader, source); GL20.glCompileShader(shader); if (GL20.glGetShaderi(shader, 35713) == 0) { - LOGGER.error(GL20.glGetShaderInfoLog(shader, Short.MAX_VALUE)); - throw new IllegalStateException(String.format("Failed to compile shader! (Type: %s)", new Object[]{type})); + LOGGER.error("Failed to compile shader (type {}):\n{}", type, GL20.glGetShaderInfoLog(shader, Short.MAX_VALUE)); + GL20.glDeleteShader(shader); + return 0; } return shader; } diff --git a/src/main/java/shit/zen/utils/render/RenderUtil.java b/src/main/java/shit/zen/utils/render/RenderUtil.java index 51df1e1..f374c44 100644 --- a/src/main/java/shit/zen/utils/render/RenderUtil.java +++ b/src/main/java/shit/zen/utils/render/RenderUtil.java @@ -141,6 +141,11 @@ extends ClientBase { if (roundedRectShader == null) { roundedRectShader = new ShaderProgram("rounded_rect", "vertex_color", ShaderFormats.POSITION_UV_COLOR); } + if (!roundedRectShader.isValid()) { + // Rounded-rect shader unavailable on this driver — draw a plain rect instead of crashing. + RenderUtil.drawFilledRect(poseStack, x, y, width, height, color); + return; + } Matrix4f matrix4f = poseStack.last().pose(); roundedRectShader.use(); GL20.glUniform2f(roundedRectShader.getUniformLocation("Size"), width, height); @@ -222,6 +227,11 @@ extends ClientBase { if (blurShader == null) { blurShader = new ShaderProgram("blur", ShaderFormats.POSITION_UV_COLOR); } + if (!blurShader.isValid()) { + // Blur shader unavailable on this driver — disable blur for the rest of the session. + blurFailed = true; + return; + } if (mainRenderTarget == null) { mainRenderTarget = mc.getMainRenderTarget(); }