package electrosphere.renderer; import electrosphere.main.Main; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import org.lwjgl.opengl.GL20; import static org.lwjgl.opengl.GL20.*; /** * * @author amaterasu */ public class ShaderProgram { // //Program stuff // int vertexShader; int fragmentShader; int shaderProgram; // //Uniform locations // public int shaderVertexModelLoc; public int shaderVertexViewLoc; public int shaderVertexProjectionLoc; public int shaderVertexViewPosLoc; public int shaderVertexBonesLoc; public int shaderVertexHasBonesLoc; public int shaderVertexNumBonesLoc; //Uniforms //list of names of all uniforms in the shader public ArrayList uniformList; //map //string -> tuple //tuple: a string describing the type of the data,the current value,location //ie arrayVec3,[<1,0,0>,<2,0,0>],colors // Mat4,[Matrix4f],modelMatrix public HashMap uniformMap; public static ShaderProgram smart_assemble_shader(boolean ContainsBones, boolean apply_lighting){ String vertex_shader_path = ""; if(ContainsBones){ vertex_shader_path = "/Shaders/VertexShader.vs"; } else { vertex_shader_path = "/Shaders/VertexShaderNoBones.vs"; } String fragment_shader_path = "/Shaders/FragmentShader.fs"; // //Create ShaderProgram object // ShaderProgram rVal = new ShaderProgram(); // //Read in shader programs // String tempForReadingShaders = ""; try { BufferedReader br = new BufferedReader(new FileReader(Main.class.getResource(vertex_shader_path).getFile())); try { StringBuilder sb = new StringBuilder(); String line = br.readLine(); while (line != null) { sb.append(line); sb.append(System.lineSeparator()); line = br.readLine(); } tempForReadingShaders = sb.toString(); } finally { br.close(); } } catch (IOException e) { } String vertexShaderSource = tempForReadingShaders; //This try-catch block reads the FragmentShader source into memory try { BufferedReader br = new BufferedReader(new FileReader(Main.class.getResource(fragment_shader_path).getFile())); try { StringBuilder sb = new StringBuilder(); String line = br.readLine(); while (line != null) { sb.append(line); sb.append(System.lineSeparator()); line = br.readLine(); } tempForReadingShaders = sb.toString(); } finally { br.close(); } } catch (IOException e) { } String fragmentShaderSource = tempForReadingShaders; //Creates a new shader object and assigns its 'pointer' to the integer "vertexShader" rVal.vertexShader = glCreateShader(GL20.GL_VERTEX_SHADER); //This alerts openGL to the presence of a vertex shader and points the shader at its source glShaderSource(rVal.vertexShader, vertexShaderSource); //Compiles the source for the vertex shader object glCompileShader(rVal.vertexShader); //The following tests if the vertex shader compiles successfully int success; success = glGetShaderi(rVal.vertexShader, GL_COMPILE_STATUS); if (success != GL_TRUE) { System.out.println("Vertex Shader failed to compile!"); System.out.println("Source is: "); System.out.println(GL20.glGetShaderSource(rVal.vertexShader)); throw new RuntimeException(GL20.glGetShaderInfoLog(rVal.vertexShader)); } //Creates and opengl object for a fragment shader and assigns its 'pointer' to the integer fragmentShader rVal.fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); //This points the opengl shadder object to its proper source glShaderSource(rVal.fragmentShader, fragmentShaderSource); //This compiles the shader object glCompileShader(rVal.fragmentShader); //This tests for the success of the compile attempt success = glGetShaderi(rVal.fragmentShader, GL_COMPILE_STATUS); if (success != GL_TRUE) { System.out.println("Fragment Shader failed to compile!"); System.out.println("Source is: "); System.out.println(GL20.glGetShaderSource(rVal.fragmentShader)); throw new RuntimeException(GL20.glGetShaderInfoLog(rVal.fragmentShader)); } //This creates a shader program opengl object and assigns its 'pointer' to the integer shaderProgram rVal.shaderProgram = glCreateProgram(); //This attaches the vertex and fragment shaders to the program glAttachShader(rVal.shaderProgram, rVal.vertexShader); glAttachShader(rVal.shaderProgram, rVal.fragmentShader); //This links the program to the GPU (I think its to the GPU anyway) glLinkProgram(rVal.shaderProgram); //Tests for the success of the shader program creation success = glGetProgrami(rVal.shaderProgram, GL_LINK_STATUS); if (success != GL_TRUE) { throw new RuntimeException(glGetProgramInfoLog(rVal.shaderProgram)); } //Deletes the individual shader objects to free up memory glDeleteShader(rVal.vertexShader); glDeleteShader(rVal.fragmentShader); // //Set locations // rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderProgram, "model"); rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderProgram, "view"); rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderProgram, "projection"); rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderProgram, "viewPos"); if(ContainsBones){ rVal.shaderVertexBonesLoc = glGetUniformLocation(rVal.shaderProgram, "bones"); rVal.shaderVertexNumBonesLoc = glGetUniformLocation(rVal.shaderProgram, "numBones"); } rVal.shaderVertexHasBonesLoc = glGetUniformLocation(rVal.shaderProgram, "hasBones"); return rVal; } public static ShaderProgram load_default_shader_program(){ // //Create ShaderProgram object // ShaderProgram rVal = new ShaderProgram(); // //Read in shader programs // String tempForReadingShaders = ""; try { BufferedReader br = new BufferedReader(new FileReader(Main.class.getResource("/Shaders/VertexShader.vs").getFile())); try { StringBuilder sb = new StringBuilder(); String line = br.readLine(); while (line != null) { sb.append(line); sb.append(System.lineSeparator()); line = br.readLine(); } tempForReadingShaders = sb.toString(); } finally { br.close(); } } catch (IOException e) { } String vertexShaderSource = tempForReadingShaders; //This try-catch block reads the FragmentShader source into memory try { BufferedReader br = new BufferedReader(new FileReader(Main.class.getResource("/Shaders/FragmentShader.fs").getFile())); try { StringBuilder sb = new StringBuilder(); String line = br.readLine(); while (line != null) { sb.append(line); sb.append(System.lineSeparator()); line = br.readLine(); } tempForReadingShaders = sb.toString(); } finally { br.close(); } } catch (IOException e) { } String fragmentShaderSource = tempForReadingShaders; //Creates a new shader object and assigns its 'pointer' to the integer "vertexShader" rVal.vertexShader = glCreateShader(GL_VERTEX_SHADER); //This alerts openGL to the presence of a vertex shader and points the shader at its source glShaderSource(rVal.vertexShader, vertexShaderSource); //Compiles the source for the vertex shader object glCompileShader(rVal.vertexShader); //The following tests if the vertex shader compiles successfully int success; success = glGetShaderi(rVal.vertexShader, GL_COMPILE_STATUS); if (success != GL_TRUE) { System.out.println("Vertex Shader failed to compile!"); throw new RuntimeException(GL20.glGetShaderInfoLog(rVal.vertexShader)); } //Creates and opengl object for a fragment shader and assigns its 'pointer' to the integer fragmentShader rVal.fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); //This points the opengl shadder object to its proper source glShaderSource(rVal.fragmentShader, fragmentShaderSource); //This compiles the shader object glCompileShader(rVal.fragmentShader); //This tests for the success of the compile attempt success = glGetShaderi(rVal.fragmentShader, GL_COMPILE_STATUS); if (success != GL_TRUE) { System.out.println("Fragment Shader failed to compile!"); throw new RuntimeException(GL20.glGetShaderInfoLog(rVal.fragmentShader)); } //This creates a shader program opengl object and assigns its 'pointer' to the integer shaderProgram rVal.shaderProgram = glCreateProgram(); //This attaches the vertex and fragment shaders to the program glAttachShader(rVal.shaderProgram, rVal.vertexShader); glAttachShader(rVal.shaderProgram, rVal.fragmentShader); //This links the program to the GPU (I think its to the GPU anyway) glLinkProgram(rVal.shaderProgram); //Tests for the success of the shader program creation success = glGetProgrami(rVal.shaderProgram, GL_LINK_STATUS); if (success != GL_TRUE) { throw new RuntimeException(glGetProgramInfoLog(rVal.shaderProgram)); } //Deletes the individual shader objects to free up memory glDeleteShader(rVal.vertexShader); glDeleteShader(rVal.fragmentShader); // //Set locations // rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderProgram, "model"); rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderProgram, "view"); rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderProgram, "projection"); rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderProgram, "viewPos"); rVal.shaderVertexBonesLoc = glGetUniformLocation(rVal.shaderProgram, "bones"); rVal.shaderVertexNumBonesLoc = glGetUniformLocation(rVal.shaderProgram, "numBones"); rVal.shaderVertexHasBonesLoc = glGetUniformLocation(rVal.shaderProgram, "hasBones"); return rVal; } public static ShaderProgram loadSpecificShader(String vertexPath, String fragmentPath){ ShaderProgram rVal = new ShaderProgram(); String vertex_shader_path = vertexPath; String fragment_shader_path = fragmentPath; // //Read in shader programs // String tempForReadingShaders = ""; try { BufferedReader br = new BufferedReader(new FileReader(Main.class.getResource(vertex_shader_path).getFile())); try { StringBuilder sb = new StringBuilder(); String line = br.readLine(); while (line != null) { sb.append(line); sb.append(System.lineSeparator()); line = br.readLine(); } tempForReadingShaders = sb.toString(); } finally { br.close(); } } catch (IOException e) { } String vertexShaderSource = tempForReadingShaders; //This try-catch block reads the FragmentShader source into memory try { BufferedReader br = new BufferedReader(new FileReader(Main.class.getResource(fragment_shader_path).getFile())); try { StringBuilder sb = new StringBuilder(); String line = br.readLine(); while (line != null) { sb.append(line); sb.append(System.lineSeparator()); line = br.readLine(); } tempForReadingShaders = sb.toString(); } finally { br.close(); } } catch (IOException e) { } String fragmentShaderSource = tempForReadingShaders; //Creates a new shader object and assigns its 'pointer' to the integer "vertexShader" rVal.vertexShader = glCreateShader(GL_VERTEX_SHADER); //This alerts openGL to the presence of a vertex shader and points the shader at its source glShaderSource(rVal.vertexShader, vertexShaderSource); //Compiles the source for the vertex shader object glCompileShader(rVal.vertexShader); //The following tests if the vertex shader compiles successfully int success; success = glGetShaderi(rVal.vertexShader, GL_COMPILE_STATUS); if (success != GL_TRUE) { System.out.println("Vertex Shader failed to compile!"); throw new RuntimeException(GL20.glGetShaderInfoLog(rVal.vertexShader)); } //Creates and opengl object for a fragment shader and assigns its 'pointer' to the integer fragmentShader rVal.fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); //This points the opengl shadder object to its proper source glShaderSource(rVal.fragmentShader, fragmentShaderSource); //This compiles the shader object glCompileShader(rVal.fragmentShader); //This tests for the success of the compile attempt success = glGetShaderi(rVal.fragmentShader, GL_COMPILE_STATUS); if (success != GL_TRUE) { System.out.println("Fragment Shader failed to compile!"); throw new RuntimeException(GL20.glGetShaderInfoLog(rVal.fragmentShader)); } //This creates a shader program opengl object and assigns its 'pointer' to the integer shaderProgram rVal.shaderProgram = glCreateProgram(); //This attaches the vertex and fragment shaders to the program glAttachShader(rVal.shaderProgram, rVal.vertexShader); glAttachShader(rVal.shaderProgram, rVal.fragmentShader); //This links the program to the GPU (I think its to the GPU anyway) glLinkProgram(rVal.shaderProgram); //Tests for the success of the shader program creation success = glGetProgrami(rVal.shaderProgram, GL_LINK_STATUS); if (success != GL_TRUE) { throw new RuntimeException(glGetProgramInfoLog(rVal.shaderProgram)); } //Deletes the individual shader objects to free up memory glDeleteShader(rVal.vertexShader); glDeleteShader(rVal.fragmentShader); // //Set locations // rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderProgram, "model"); rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderProgram, "view"); rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderProgram, "projection"); rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderProgram, "viewPos"); return rVal; } }