Anonymous avatar Anonymous committed d25c403

Converted HelloShader to use new ShaderProgram class

Comments (0)

Files changed (2)

src/main/java/sandbox/misc/HelloShader.java

 import org.lwjgl.util.vector.Vector3f;
 import org.lwjgl.util.vector.Vector4f;
 import sandbox.common.BaseApp;
+import sandbox.util.ShaderProgram;
 import sandbox.util.VBO;
 
 import java.nio.ByteBuffer;
 public class HelloShader extends BaseApp {
     VBO vbo = new VBO();
 
-    // starts off gold
+    // starts off gold  
     public static final String VERTEX_SHADER = "" +
             "varying vec4 vertColor;\n" +
             "void main(){\n" +
             "}";
 
 
-    private int shader = 0;
+    private ShaderProgram shader;
     private int vertShader = 0;
     private int fragShader = 0;
 
         );
 
         vbo.compile();
-        shader = glCreateProgram();
-
-        buildVertexShader(VERTEX_SHADER);
-        buildFragmentShader(FRAGMENT_SHADER);
-
-        glAttachShader(shader, vertShader);
-        glAttachShader(shader, fragShader);
-
-        glLinkProgram(shader);
-        checkLink(shader);
-        glValidateProgram(shader);
-        checkValidate(shader);
+        shader = new ShaderProgram();
+        shader.addVertexShader(VERTEX_SHADER);
+        shader.addFragmentShader(FRAGMENT_SHADER);
+        shader.link();
+        shader.validate();
     }
 
     @Override
     protected void render() {
-        glUseProgram(shader);
+        shader.use();
         glPushMatrix();
         glTranslatef(0, 0, -200);
         glClear(GL_COLOR_BUFFER_BIT);
         glDisableClientState(GL_NORMAL_ARRAY);
         glDisableClientState(GL_COLOR_ARRAY);
         glPopMatrix();
-        glUseProgram(0);
+        shader.stopUsing();
     }
 
     private void buildVertexShader(String source) {

src/main/java/sandbox/util/ShaderProgram.java

+package sandbox.util;
+
+import org.lwjgl.BufferUtils;
+import org.lwjgl.opengl.GL30;
+import org.lwjgl.opengl.GL31;
+import org.lwjgl.opengl.GL32;
+import sun.plugin.dom.exception.InvalidStateException;
+
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.lwjgl.opengl.GL11.GL_TRUE;
+import static org.lwjgl.opengl.GL20.*;
+import static org.lwjgl.opengl.GL32.GL_GEOMETRY_SHADER;
+
+/** A thin front end for shader functionality. */
+public class ShaderProgram {
+
+    private List<Integer> shaders = new ArrayList<Integer>();
+    private int programId;
+
+    public ShaderProgram() {
+        programId = glCreateProgram();
+        if (programId == 0)
+            throw new InvalidStateException("Cannot create shader program");
+    }
+
+    public int addVertexShader(String source) {
+        return addShader(GL_VERTEX_SHADER, source);
+    }
+
+    public int addFragmentShader(String source) {
+        return addShader(GL_FRAGMENT_SHADER, source);
+    }
+
+    public int addGeometryShader(String source) {
+        return addShader(GL_GEOMETRY_SHADER, source);
+    }
+
+    private int addShader(int type, String source) {
+        int shader = buildShader(glCreateShader(type), source);
+        if (shader == 0) return shader;
+        shaders.add(shader);
+        glAttachShader(programId, shader);
+        return shader;
+    }
+
+    public void link() {
+        glLinkProgram(programId);
+        checkLink(programId);
+    }
+
+    public void validate() {
+        glValidateProgram(programId);
+        checkValidate(programId);
+    }
+
+    public void use() {
+        glUseProgram(programId);
+    }
+
+    // Silly, but it bookends use() nicely
+    public void stopUsing() {
+        glUseProgram(0);
+    }
+
+    private int buildShader(int shader, String source) {
+        glShaderSource(shader, source);
+        glCompileShader(shader);
+        if (checkCompile(shader)) {
+            return shader;
+        } else {
+            glDeleteShader(shader);
+            return 0;
+        }
+    }
+
+    private static boolean checkCompile(int obj) {
+        if (glGetShader(obj, GL_COMPILE_STATUS) == GL_TRUE)
+            return true;
+
+        // Error compiling -- print the log to stderr
+        IntBuffer iVal = BufferUtils.createIntBuffer(1);
+        glGetShader(obj, GL_INFO_LOG_LENGTH, iVal);
+        int length = iVal.get();
+        if (length > 1) {
+            // 1 is for the null byte
+            ByteBuffer infoLog = BufferUtils.createByteBuffer(length);
+            iVal.flip();
+            glGetShaderInfoLog(obj, iVal, infoLog);
+            byte[] infoBytes = new byte[length];
+            infoLog.get(infoBytes);
+            String out = new String(infoBytes);
+            System.err.println(out);
+        }
+        return false;
+    }
+
+    private static boolean checkLink(int obj) {
+        return checkProgram(obj, GL_LINK_STATUS);
+    }
+
+    private static boolean checkValidate(int obj) {
+        return checkProgram(obj, GL_VALIDATE_STATUS);
+    }
+
+    // a copy and paste job from checkCompile
+    private static boolean checkProgram(int obj, int status) {
+        if (glGetProgram(obj, status) == GL_TRUE)
+            return true;
+
+        // Error compiling -- print the log to stderr
+        IntBuffer iVal = BufferUtils.createIntBuffer(1);
+        glGetShader(obj, GL_INFO_LOG_LENGTH, iVal);
+        int length = iVal.get();
+        if (length > 1) {
+            // 1 is for the null byte
+            ByteBuffer infoLog = BufferUtils.createByteBuffer(length);
+            iVal.flip();
+            glGetProgramInfoLog(obj, iVal, infoLog);
+            byte[] infoBytes = new byte[length];
+            infoLog.get(infoBytes);
+            String out = new String(infoBytes);
+            System.err.println(out);
+        }
+        return false;
+
+    }
+
+    public List<Integer> getShaders() {
+        return shaders;
+    }
+
+    public int getProgramId() {
+        return programId;
+    }
+
+}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.