Java tutorial
package utils; import org.lwjgl.opengl.ARBFragmentShader; import org.lwjgl.opengl.ARBShaderObjects; import org.lwjgl.opengl.ARBVertexShader; import org.lwjgl.opengl.GL11; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; /** * Created by user on 11/24/2014. */ public class ShaderHelper { //http://wiki.lwjgl.org/index.php?title=GLSL_Shaders_with_LWJGL /* * if the shaders are setup ok we can use shaders, otherwise we just * use default settings */ public static boolean useShader = false; /* * program shader, to which is attached a vertex and fragment shaders. * They are set to 0 as a check because GL will assign unique int * values to each */ public static int program = 0; static public void setupShaders(String vertShaderName, String fragShaderName) { int vertShader = 0, fragShader = 0; try { vertShader = createShader("shaders/" + vertShaderName, ARBVertexShader.GL_VERTEX_SHADER_ARB); fragShader = createShader("shaders/" + fragShaderName, ARBFragmentShader.GL_FRAGMENT_SHADER_ARB); } catch (Exception exc) { exc.printStackTrace(); return; } finally { if (vertShader == 0 || fragShader == 0) return; } program = ARBShaderObjects.glCreateProgramObjectARB(); if (program == 0) return; /* * if the vertex and fragment shaders setup sucessfully, * attach them to the shader program, link the sahder program * (into the GL context I suppose), and validate */ ARBShaderObjects.glAttachObjectARB(program, vertShader); ARBShaderObjects.glAttachObjectARB(program, fragShader); ARBShaderObjects.glLinkProgramARB(program); if (ARBShaderObjects.glGetObjectParameteriARB(program, ARBShaderObjects.GL_OBJECT_LINK_STATUS_ARB) == GL11.GL_FALSE) { System.err.println(getLogInfo(program)); return; } ARBShaderObjects.glValidateProgramARB(program); if (ARBShaderObjects.glGetObjectParameteriARB(program, ARBShaderObjects.GL_OBJECT_VALIDATE_STATUS_ARB) == GL11.GL_FALSE) { System.err.println(getLogInfo(program)); return; } useShader = true; } /* With the exception of syntax, setting up vertex and fragment shaders * is the same. * @param the name and path to the vertex shader */ static private int createShader(String filename, int shaderType) throws Exception { int shader = 0; try { shader = ARBShaderObjects.glCreateShaderObjectARB(shaderType); if (shader == 0) return 0; ARBShaderObjects.glShaderSourceARB(shader, readFileAsString(filename)); ARBShaderObjects.glCompileShaderARB(shader); if (ARBShaderObjects.glGetObjectParameteriARB(shader, ARBShaderObjects.GL_OBJECT_COMPILE_STATUS_ARB) == GL11.GL_FALSE) throw new RuntimeException("Error creating shader: " + getLogInfo(shader)); return shader; } catch (Exception exc) { ARBShaderObjects.glDeleteObjectARB(shader); throw exc; } } private static String getLogInfo(int obj) { return ARBShaderObjects.glGetInfoLogARB(obj, ARBShaderObjects.glGetObjectParameteriARB(obj, ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB)); } static private String readFileAsString(String filename) throws Exception { StringBuilder source = new StringBuilder(); FileInputStream in = new FileInputStream(filename); Exception exception = null; BufferedReader reader; try { reader = new BufferedReader(new InputStreamReader(in, "UTF-8")); Exception innerExc = null; try { String line; while ((line = reader.readLine()) != null) source.append(line).append('\n'); } catch (Exception exc) { exception = exc; } finally { try { reader.close(); } catch (Exception exc) { if (innerExc == null) innerExc = exc; else exc.printStackTrace(); } } if (innerExc != null) throw innerExc; } catch (Exception exc) { exception = exc; } finally { try { in.close(); } catch (Exception exc) { if (exception == null) exception = exc; else exc.printStackTrace(); } if (exception != null) throw exception; } return source.toString(); } } /* //http://stackoverflow.com/questions/15777757/drawing-normals-in-lwjgl-messes-with-lighting //Feel free to use this for whatever you want, no licenses applied or anything. //p1, p2, p3 - Vertices of triangle public Vector3f getNormal(Vector3f p1, Vector3f p2, Vector3f p3) { //Create normal vector we are going to output. Vector3f output = new Vector3f(); //Calculate vectors used for creating normal (these are the edges of the triangle). Vector3f calU = new Vector3f(p2.x-p1.x, p2.y-p1.y, p2.z-p1.z); Vector3f calV = new Vector3f(p3.x-p1.x, p3.y-p1.y, p3.z-p1.z); //The output vector is equal to the cross products of the two edges of the triangle output.x = calU.y*calV.z - calU.z*calV.y; output.y = calU.z*calV.x - calU.x*calV.z; output.z = calU.x*calV.y - calU.y*calV.x; //Return the resulting vector. return output.normalise(); } */