package com.javamarcher.shader; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import org.lwjgl.opengl.GL20; public class ShaderCreator { private static final String INCLUDE_KEYWORD = "#include"; private final int vertexShaderId; private final int fragmentShaderId; private int programId = 0; public ShaderCreator(String vertexFileName, String fragmentFileName) { vertexShaderId = loadShader(vertexFileName, GL20.GL_VERTEX_SHADER); fragmentShaderId = loadShader(fragmentFileName, GL20.GL_FRAGMENT_SHADER); } /** * Binds the shader ids to a shader program * and returns the program id. */ public int createShader() { programId = GL20.glCreateProgram(); GL20.glAttachShader(programId, vertexShaderId); GL20.glAttachShader(programId, fragmentShaderId); return programId; } public void cleanup() { GL20.glUseProgram(0); GL20.glDetachShader(getProgramId(), vertexShaderId); GL20.glDetachShader(getProgramId(), fragmentShaderId); GL20.glDeleteShader(vertexShaderId); GL20.glDeleteShader(fragmentShaderId); GL20.glDeleteProgram(getProgramId()); } /** * Loads the shader based on the given path and returns the shader id. */ private int loadShader(String filename, int type) { final StringBuilder shaderSource = new StringBuilder(); int shaderId = 0; try { final BufferedReader reader = new BufferedReader(new FileReader(filename)); String sourceLine; while((sourceLine = reader.readLine()) != null) { // Only append if no include pragma was found if(!parseIncludePragma(shaderSource, sourceLine)) { shaderSource.append(sourceLine).append("\n"); } } reader.close(); } catch (IOException e) { e.printStackTrace(); System.exit(-1); } shaderId = GL20.glCreateShader(type); GL20.glShaderSource(shaderId, shaderSource); GL20.glCompileShader(shaderId); if(GL20.glGetShaderi(shaderId, GL20.GL_COMPILE_STATUS) == 0) { System.err.println("Shader compilation failed!"); System.err.println(GL20.glGetShaderInfoLog(shaderId)); System.exit(1); } return shaderId; } private boolean parseIncludePragma(StringBuilder shaderSource, String currentLine) throws IOException { if(currentLine.startsWith(INCLUDE_KEYWORD)) { final String includeFilename = currentLine.substring(currentLine.indexOf("[") + 1, currentLine.indexOf("]")); final BufferedReader reader = new BufferedReader(new FileReader(includeFilename)); String line; while((line = reader.readLine()) != null) { shaderSource.append(line).append("\n"); } reader.close(); return true; } return false; } public int getVertexShaderId() { return vertexShaderId; } public int getFragmentShaderId() { return fragmentShaderId; } public int getProgramId() { return programId; } }