package dwarf; import static dwarf.Util.readFileAsString; import static org.lwjgl.opengl.GL11.GL_FALSE; import static org.lwjgl.opengl.GL20.GL_COMPILE_STATUS; import static org.lwjgl.opengl.GL20.GL_FRAGMENT_SHADER; import static org.lwjgl.opengl.GL20.GL_VERTEX_SHADER; import static org.lwjgl.opengl.GL20.glAttachShader; import static org.lwjgl.opengl.GL20.glCompileShader; import static org.lwjgl.opengl.GL20.glCreateProgram; import static org.lwjgl.opengl.GL20.glCreateShader; import static org.lwjgl.opengl.GL20.glDeleteShader; import static org.lwjgl.opengl.GL20.glDetachShader; import static org.lwjgl.opengl.GL20.glGetShaderi; import static org.lwjgl.opengl.GL20.glGetUniformLocation; import static org.lwjgl.opengl.GL20.glLinkProgram; import static org.lwjgl.opengl.GL20.glShaderSource; import static org.lwjgl.opengl.GL20.glUniform1f; import static org.lwjgl.opengl.GL20.glUniform1i; import static org.lwjgl.opengl.GL20.glUniform2f; import static org.lwjgl.opengl.GL20.glUniform2i; import static org.lwjgl.opengl.GL20.glUniform3f; import static org.lwjgl.opengl.GL20.glUniform3i; import static org.lwjgl.opengl.GL20.glUniform4f; import static org.lwjgl.opengl.GL20.glUniform4i; import static org.lwjgl.opengl.GL20.glUseProgram; /** * Provides a interface that offers GLSL (shader) support to the user. * * <p> * OpenGL Shading Language (abbreviated: GLSL or GLslang), is a high-level * shading language based on the syntax of the C programming language. It was * created by the OpenGL ARB (OpenGL Architecture Review Board) to give * developers more direct control of the graphics pipeline without having to use * ARB assembly language or hardware-specific languages.</p> * * @author Matthew 'siD' Van der Bijl * * @see * <a href='http://en.wikipedia.org/wiki/OpenGL_Shading_Language'>wikipedia</a> * @see dwarf.Shader */ public final class GLSL { /** * you can not instantiate this class. */ public GLSL() throws UnsupportedOperationException { // Prevents instantiation of this class. throw new UnsupportedOperationException( "you can not instantiate this class."); } /** * A Vertex Shader is the programmable Shader stage in the rendering * pipeline that handles the processing of individual vertices. */ public final static int VERTEX_SHADER = GL_VERTEX_SHADER; /** * A Fragment Shader is a user-supplied program that, when executed, will * process a Fragment from the rasterization process into a set of colours * and a single depth value. */ public final static int FRAGMENT_SHADER = GL_FRAGMENT_SHADER; /** * Send floats to the shader. */ public static void sendFloats(String name, int program, float... values) { int location = glGetUniformLocation(program, name); switch (values.length) { case 1: glUniform1f(location, values[0]); break; case 2: glUniform2f(location, values[0], values[1]); break; case 3: glUniform3f(location, values[0], values[1], values[2]); break; case 4: glUniform4f(location, values[0], values[1], values[2], values[3]); break; default: break; } } /** * Send integers to the shader. */ public static void sendIntegers(String name, int program, int... values) { int location = glGetUniformLocation(program, name); switch (values.length) { case 1: glUniform1i(location, values[0]); break; case 2: glUniform2i(location, values[0], values[1]); break; case 3: glUniform3i(location, values[0], values[1], values[2]); break; case 4: glUniform4i(location, values[0], values[1], values[2], values[3]); break; default: break; } } /** * Run a given shader program. * * @param program to shader program to be run */ public static void useProgram(int program) { glUseProgram(program); } /** * Reset the shader program being used. */ public static void resetShaders() { glUseProgram(0); } /** * Create a shader program. */ public static int createShaderProgram(int... shaders) { int program = glCreateProgram(); for (int shader : shaders) { glAttachShader(program, shader); } glLinkProgram(program); for (int shader : shaders) { glDetachShader(program, shader); glDeleteShader(shader); } return program; } /** * Create a shader * * @see dwarf.GLSL#VERTEX_SHADER * @see dwarf.GLSL#FRAGMENT_SHADER * * @param type the type of shader to be created * @param path the path to the shader file * * @throws DwarfException the shader wasn't able to be compiled correctly * * @return the shader */ public static int createShader(String path, int type) throws DwarfException { int shader = -1; shader = glCreateShader(type); try { glShaderSource(shader, readFileAsString(path)); } catch (Exception ex) { glDeleteShader(shader); throw new DwarfException(ex); } finally { glCompileShader(shader); if (glGetShaderi(shader, GL_COMPILE_STATUS) == GL_FALSE) { throw new DwarfException("the shader wasn't able to be compiled correctly."); } } return shader; } }