diff options
Diffstat (limited to 'mod/src/main')
3 files changed, 249 insertions, 1 deletions
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/DungeonsGuide.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/DungeonsGuide.java index f583d143..c1f5e8c8 100755 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/DungeonsGuide.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/DungeonsGuide.java @@ -40,6 +40,7 @@ import kr.syeyoung.dungeonsguide.mod.guiv2.elements.richtext.fonts.DefaultFontRe import kr.syeyoung.dungeonsguide.mod.overlay.OverlayManager; import kr.syeyoung.dungeonsguide.mod.party.PartyManager; import kr.syeyoung.dungeonsguide.mod.resources.DGTexturePack; +import kr.syeyoung.dungeonsguide.mod.shader.ShaderManager; import kr.syeyoung.dungeonsguide.mod.stomp.StompManager; import kr.syeyoung.dungeonsguide.mod.utils.AhUtils; import kr.syeyoung.dungeonsguide.mod.utils.BlockCache; @@ -287,7 +288,6 @@ public class DungeonsGuide implements DGInterface { public void unload() { // have FUN! - for (Object registeredListener : registeredListeners) { MinecraftForge.EVENT_BUS.unregister(registeredListener); } @@ -391,6 +391,7 @@ public class DungeonsGuide implements DGInterface { } catch (Exception e) { e.printStackTrace(); } + ShaderManager.unload(); DiscordIntegrationManager.INSTANCE.cleanup(); @@ -407,6 +408,7 @@ public class DungeonsGuide implements DGInterface { public void onResourceReload(IResourceManager a) { GLCursors.setupCursors(); DefaultFontRenderer.DEFAULT_RENDERER.onResourceManagerReload(); + ShaderManager.onResourceReload(); } private boolean showedStartUpGuide; diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/shader/ShaderManager.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/shader/ShaderManager.java new file mode 100644 index 00000000..dbb3178c --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/shader/ShaderManager.java @@ -0,0 +1,120 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2023 cyoung06 (syeyoung) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.shader; + +import net.minecraft.client.Minecraft; +import net.minecraft.util.ResourceLocation; +import org.apache.commons.io.IOUtils; +import org.lwjgl.opengl.GL20; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class ShaderManager { + private static final Map<String, ShaderProgram> shaders = new HashMap<>(); + + public static void onResourceReload() { + for (ShaderProgram value : shaders.values()) { + value.close(); + } + Set<String> keySet = new HashSet<>(shaders.keySet()); + shaders.clear(); + for (String s : keySet) { + loadShader(s); + } + } + + public static void unload() { + for (ShaderProgram value : shaders.values()) { + value.close(); + } + } + + public static ShaderProgram getShader(String str) { + if (shaders.containsKey(str)) return shaders.get(str); + return loadShader(str); + } + + private static ShaderProgram loadShader(String name) { + int vertex = -1; + String sourceVert = getShaderSource(name+".vert"); + String sourceFrag = getShaderSource(name + ".frag"); + if (sourceVert == null && sourceFrag == null) { + shaders.put(name, null); // shortcut + return null; + } + if (sourceVert != null) { + vertex = GL20.glCreateShader(GL20.GL_VERTEX_SHADER); + GL20.glShaderSource(vertex, sourceVert); + GL20.glCompileShader(vertex); + + if (GL20.glGetShaderi(vertex, 35713) == 0) { + System.err.println(GL20.glGetShaderInfoLog(vertex, 100)); + } + } + + int fragment = -1; + if (sourceFrag != null) { + fragment = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER); + GL20.glShaderSource(fragment, sourceFrag); + GL20.glCompileShader(fragment); + + if (GL20.glGetShaderi(fragment, 35713) == 0) { + System.err.println(GL20.glGetShaderInfoLog(fragment, 100)); + } + } + + + int program = GL20.glCreateProgram(); + if (vertex != -1) GL20.glAttachShader(program, vertex); + if (fragment != -1) GL20.glAttachShader(program, fragment); + + GL20.glLinkProgram(program); + + if (vertex != -1) GL20.glDeleteShader(vertex); + if (fragment != -1) GL20.glDeleteShader(fragment); + + if (GL20.glGetProgrami(program, 35714) == 0) { + System.err.println(GL20.glGetProgramInfoLog(program, 100)); + } + GL20.glValidateProgram(program); + if (GL20.glGetProgrami(program, 35715) == 0) { + System.err.println(GL20.glGetProgramInfoLog(program, 100)); + } + ShaderProgram shaderProgram = new ShaderProgram(name, program); + shaders.put(name, shaderProgram); + return shaderProgram; + } + + private static String getShaderSource(String name) { + ResourceLocation location = new ResourceLocation( + "dungeonsguide:"+name + ); + try (InputStream is = Minecraft.getMinecraft().getResourceManager().getResource(location).getInputStream()) { + return IOUtils.toString(is); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/shader/ShaderProgram.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/shader/ShaderProgram.java new file mode 100644 index 00000000..95f8ee5d --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/shader/ShaderProgram.java @@ -0,0 +1,126 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2023 cyoung06 (syeyoung) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.shader; + +import lombok.AllArgsConstructor; +import org.lwjgl.opengl.GL20; +import org.lwjgl.util.vector.Matrix2f; + +import javax.vecmath.Matrix3f; +import javax.vecmath.Matrix4f; +import java.nio.FloatBuffer; + +@AllArgsConstructor +public class ShaderProgram { + private String shaderName; + private int shaderId; + + private void ensureInitialized() { + if (shaderId == -1) throw new IllegalStateException("ShaderProgram not initialized"); + } + + public void useShader() { + ensureInitialized(); + GL20.glUseProgram(shaderId); + } + + public int getUniformLocation(String name) { + ensureInitialized(); + return GL20.glGetUniformLocation(shaderId, name); + } + + public void uploadUniform(String name, int val) { + GL20.glUniform1i(getUniformLocation(name), val); + } + + public void uploadUniform(String name, int v1, int v2) { + GL20.glUniform2i(getUniformLocation(name), v1, v2); + } + + public void uploadUniform(String name, int v1, int v2, int v3) { + GL20.glUniform3i(getUniformLocation(name), v1, v2, v3); + } + + public void uploadUniform(String name, int v1, int v2, int v3, int v4) { + GL20.glUniform4i(getUniformLocation(name), v1, v2, v3, v4); + } + + public void uploadUniform(String name, float val) { + GL20.glUniform1f(getUniformLocation(name), val); + } + + public void uploadUniform(String name, float v1, float v2) { + GL20.glUniform2f(getUniformLocation(name), v1, v2); + } + + public void uploadUniform(String name, float v1, float v2, float v3) { + GL20.glUniform3f(getUniformLocation(name), v1, v2, v3); + } + + public void uploadUniform(String name, float v1, float v2, float v3, float v4) { + GL20.glUniform4f(getUniformLocation(name), v1, v2, v3, v4); + } + + public void uploadUniform(String name, Matrix2f matrix2f) { + FloatBuffer floatBuffer = FloatBuffer.allocate(4); + matrix2f.store(floatBuffer); + GL20.glUniformMatrix2(getUniformLocation(name), false, floatBuffer); + } + + public void uploadUniform(String name, Matrix3f matrix3f) { + FloatBuffer floatBuffer = FloatBuffer.allocate(9); + floatBuffer.put(matrix3f.m00); + floatBuffer.put(matrix3f.m01); + floatBuffer.put(matrix3f.m02); + floatBuffer.put(matrix3f.m10); + floatBuffer.put(matrix3f.m11); + floatBuffer.put(matrix3f.m12); + floatBuffer.put(matrix3f.m20); + floatBuffer.put(matrix3f.m21); + floatBuffer.put(matrix3f.m22); + GL20.glUniformMatrix3(getUniformLocation(name), false, floatBuffer); + } + + public void uploadUniform(String name, Matrix4f matrix4f) { + FloatBuffer floatBuffer = FloatBuffer.allocate(16); + floatBuffer.put(matrix4f.m00); + floatBuffer.put(matrix4f.m01); + floatBuffer.put(matrix4f.m02); + floatBuffer.put(matrix4f.m03); + floatBuffer.put(matrix4f.m10); + floatBuffer.put(matrix4f.m11); + floatBuffer.put(matrix4f.m12); + floatBuffer.put(matrix4f.m13); + floatBuffer.put(matrix4f.m20); + floatBuffer.put(matrix4f.m21); + floatBuffer.put(matrix4f.m22); + floatBuffer.put(matrix4f.m23); + floatBuffer.put(matrix4f.m30); + floatBuffer.put(matrix4f.m31); + floatBuffer.put(matrix4f.m32); + floatBuffer.put(matrix4f.m33); + GL20.glUniformMatrix4(getUniformLocation(name), false, floatBuffer); + } + + public void close() { + if (shaderId == -1) return; + GL20.glDeleteProgram(shaderId); + shaderId = -1; + } +} |