package tk.captainsplexx.Shader; import java.io.BufferedReader; import java.io.FileReader; import java.nio.FloatBuffer; import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL20; import org.lwjgl.util.vector.Matrix4f; import org.lwjgl.util.vector.Vector3f; public abstract class ShaderProgram { private int programID; private int vertexShaderID; private int fragmentShaderID; public static FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16); //4x4 public ShaderProgram(String vertexFile, String fragmentFile){ vertexShaderID = loadShader(vertexFile, GL20.GL_VERTEX_SHADER); fragmentShaderID = loadShader(fragmentFile, GL20.GL_FRAGMENT_SHADER); programID = GL20.glCreateProgram(); GL20.glAttachShader(programID, vertexShaderID); GL20.glAttachShader(programID, fragmentShaderID); bindAttributes(); GL20.glLinkProgram(programID); GL20.glValidateProgram(programID); getAllUniformLocations(); } public void start(){ GL20.glUseProgram(programID); } public void stop(){ GL20.glUseProgram(0); } public void cleanUp(){ stop(); GL20.glDetachShader(programID, vertexShaderID); GL20.glDetachShader(programID, fragmentShaderID); GL20.glDeleteShader(vertexShaderID); GL20.glDeleteShader(fragmentShaderID); GL20.glDeleteProgram(programID); } protected abstract void getAllUniformLocations(); protected int getUniformLocation(String name){ return GL20.glGetUniformLocation(programID, name); } public void loadFloat(int location, float value){ GL20.glUniform1f(location, value); } public void loadVector(int location, Vector3f vector){ GL20.glUniform3f(location, vector.x, vector.y, vector.z); } public void loadBoolean(int location, boolean value){ float toLoad = 0; if (value){ toLoad = 1; } GL20.glUniform1f(location, toLoad); } public void loadMatrix(int location, Matrix4f matrix){ matrix.store(matrixBuffer); matrixBuffer.flip(); GL20.glUniformMatrix4(location, false, matrixBuffer); } protected abstract void bindAttributes(); protected void bindAttribute(int attribute, String variableName){ GL20.glBindAttribLocation(programID, attribute, variableName); } public static int loadShader(String file, int type){ StringBuilder shaderSource = new StringBuilder(); try { BufferedReader reader = new BufferedReader(new FileReader(file)); String line; while ((line = reader.readLine()) != null){ shaderSource.append(line).append("\n");{ } } reader.close(); } catch (Exception e) { System.err.println("Could not read file! - "+file); e.printStackTrace(); } int shaderID = GL20.glCreateShader(type); GL20.glShaderSource(shaderID, shaderSource); GL20.glCompileShader(shaderID); if (GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS)==GL11.GL_FALSE){ System.out.println(GL20.glGetShaderInfoLog(shaderID, 5000)); System.err.println("Could not compile shader with id: "+shaderID); } return shaderID; } }