package com.thecherno.ld29.graphics; import static org.lwjgl.opengl.GL11.GL_FALSE; import static org.lwjgl.opengl.GL20.*; import com.thecherno.ld29.util.FileUtils; public class Shader { private int shader; private String vertexPath, fragmentPath; public static Shader TILE, FORETILE, WATER, LIGHT, FONT, MOB; public Shader(String vertPath, String fragPath) { this.vertexPath = vertPath; this.fragmentPath = fragPath; String vertexSource = FileUtils.loadAsString(vertPath); String fragSource = FileUtils.loadAsString(fragPath); System.out.println("Loading shader: " + vertPath + ", " + fragPath); shader = create(vertexSource, fragSource); } public static void loadAll() { TILE = new Shader("shaders/tile.vert", "shaders/tile.frag"); FORETILE = new Shader("shaders/tile.vert", "shaders/foretile.frag"); WATER = new Shader("shaders/tile.vert", "shaders/water.frag"); LIGHT = new Shader("shaders/light.vert", "shaders/light.frag"); FONT = new Shader("shaders/font.vert", "shaders/font.frag"); MOB = new Shader("shaders/tile.vert", "shaders/mob.frag"); } public static int create(String vertexSource, String fragSource) { int program = glCreateProgram(); int vertID = glCreateShader(GL_VERTEX_SHADER); int fragID = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(vertID, vertexSource); glShaderSource(fragID, fragSource); glCompileShader(vertID); if (glGetShaderi(vertID, GL_COMPILE_STATUS) == GL_FALSE) { System.err.println("Failed to compile vertex shader!"); System.err.print(glGetShaderInfoLog(vertID, 2048)); return -1; } glCompileShader(fragID); if (glGetShaderi(fragID, GL_COMPILE_STATUS) == GL_FALSE) { System.err.println("Failed to compile fragment shader!"); System.err.print(glGetShaderInfoLog(fragID, 2048)); return -1; } glAttachShader(program, vertID); glAttachShader(program, fragID); glLinkProgram(program); glValidateProgram(program); return program; } public void recompile() { String vertexSource = FileUtils.loadAsString(vertexPath); String fragSource = FileUtils.loadAsString(fragmentPath); int shader = create(vertexSource, fragSource); if (shader == -1) return; this.shader = shader; } public void bind() { glUseProgram(shader); } public void release() { glUseProgram(0); } public int getID() { return shader; } public String toString() { return "Shader ID: " + getID() + "; " + vertexPath + ", " + fragmentPath; } public int getUniform(String name) { return glGetUniformLocation(shader, name); } public void setUniform1f(String name, float value) { bind(); glUniform1f(getUniform(name), value); release(); } public void setUniform2f(String name, float x, float y) { bind(); glUniform2f(getUniform(name), x, y); release(); } public void setUniform3f(String name, float x, float y, float z) { bind(); glUniform3f(getUniform(name), x, y, z); release(); } public void setUniformf(int location, float value) { glUniform1f(location, value); } public boolean equals(Object object) { if (!(object instanceof Shader)) return false; Shader shader = (Shader) object; return vertexPath.equals(shader.vertexPath) && fragmentPath.equals(shader.fragmentPath); } }