From b7869646ae203cb129cb6e626643ce3f31080907 Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Tue, 20 Feb 2024 17:57:18 +0100 Subject: Added shader reload capabilities for chroma resource packs. #958 --- .../at/hannibal2/skyhanni/utils/shader/Shader.kt | 95 +++++++++++++++------- 1 file changed, 64 insertions(+), 31 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt b/src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt index 6a95655ca..f846c3d4d 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt @@ -2,11 +2,14 @@ package at.hannibal2.skyhanni.utils.shader import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.LorenzUtils -import java.util.function.Supplier +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.OpenGlHelper +import net.minecraft.client.resources.IReloadableResourceManager import net.minecraft.client.shader.ShaderLinkHelper import org.apache.commons.lang3.StringUtils import org.lwjgl.opengl.GL11 import org.lwjgl.opengl.OpenGLException +import java.util.function.Supplier /** * Superclass for shader objects to compile and attach vertex and fragment shaders to the shader program @@ -15,44 +18,74 @@ import org.lwjgl.opengl.OpenGLException * * Credit: [Shader.java](https://github.com/BiscuitDevelopment/SkyblockAddons/blob/main/src/main/java/codes/biscuit/skyblockaddons/shader/Shader.java) */ -abstract class Shader(vertex: String, fragment: String) { +abstract class Shader(val vertex: String, val fragment: String) { + + var shaderProgram: Int = -1 + private var vertexShaderID: Int = -1 + private var fragmentShaderID: Int = -1 - var shaderProgram: Int = ShaderLinkHelper.getStaticShaderLinkHelper().createProgram() private val uniforms: MutableList> = mutableListOf() var created = false init { - run { - val vertexShaderID = ShaderManager.loadShader(ShaderType.VERTEX, vertex).also { if (it == -1) return@run } - ShaderManager.attachShader(shaderProgram, vertexShaderID) - - val fragmentShaderID = ShaderManager.loadShader(ShaderType.FRAGMENT, fragment).also { if (it == -1) return@run } - ShaderManager.attachShader(shaderProgram, fragmentShaderID) - - ShaderHelper.glLinkProgram(shaderProgram) - - if (ShaderHelper.glGetProgrami(shaderProgram, ShaderHelper.GL_LINK_STATUS) == GL11.GL_FALSE) { - val errorMessage = "Failed to link vertex shader $vertex and fragment shader $fragment. Features that " + - "utilise this shader will not work correctly, if at all." - val errorLog = StringUtils.trim(ShaderHelper.glGetShaderInfoLog(shaderProgram, 1024)) - - if (ShaderManager.inWorld()) { - ErrorManager.logErrorWithData( - OpenGLException("Shader linking error."), - errorMessage, - "Link Error:\n" to errorLog - ) - } else { - LorenzUtils.consoleLog("$errorMessage $errorLog") - } - - return@run - } + recompile() + (Minecraft.getMinecraft().resourceManager as IReloadableResourceManager).registerReloadListener { + recompile() + } + } - this.registerUniforms() - created = true + fun deleteOldShaders() { + if (vertexShaderID >= 0) { + OpenGlHelper.glDeleteShader(vertexShaderID) + vertexShaderID = -1 + } + if (fragmentShaderID >= 0) { + OpenGlHelper.glDeleteShader(fragmentShaderID) + fragmentShaderID = -1 } + if (shaderProgram >= 0) { + OpenGlHelper.glDeleteProgram(shaderProgram) + shaderProgram = -1 + } + uniforms.clear() + created = false + } + + fun recompile() { + deleteOldShaders() + shaderProgram = ShaderLinkHelper.getStaticShaderLinkHelper().createProgram() + if (shaderProgram < 0) return + + vertexShaderID = ShaderManager.loadShader(ShaderType.VERTEX, vertex) + if (vertexShaderID < 0) return + ShaderManager.attachShader(shaderProgram, vertexShaderID) + + fragmentShaderID = ShaderManager.loadShader(ShaderType.FRAGMENT, fragment) + if (fragmentShaderID < 0) return + ShaderManager.attachShader(shaderProgram, fragmentShaderID) + + ShaderHelper.glLinkProgram(shaderProgram) + + if (ShaderHelper.glGetProgrami(shaderProgram, ShaderHelper.GL_LINK_STATUS) == GL11.GL_FALSE) { + val errorMessage = "Failed to link vertex shader $vertex and fragment shader $fragment. Features that " + + "utilise this shader will not work correctly, if at all." + val errorLog = StringUtils.trim(ShaderHelper.glGetShaderInfoLog(shaderProgram, 1024)) + + if (ShaderManager.inWorld()) { + ErrorManager.logErrorWithData( + OpenGLException("Shader linking error."), + errorMessage, + "Link Error:\n" to errorLog + ) + } else { + LorenzUtils.consoleLog("$errorMessage $errorLog") + } + return + } + + this.registerUniforms() + created = true } abstract fun registerUniforms() -- cgit