Renderer/src/main/java/electrosphere/renderer/ShaderProgram.java
2021-04-04 23:30:33 -04:00

379 lines
16 KiB
Java

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<String> 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<String,ArrayList> 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;
}
}