Anonymous avatar Anonymous committed faa8ea1

added ShaderBox2, a GL20 port of ShaderBox

Comments (0)

Files changed (1)

src/main/java/tutorials/wiki/ShaderBox2.java

+package tutorials.wiki;
+
+import org.lwjgl.BufferUtils;
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.opengl.Display;
+import org.lwjgl.opengl.DisplayMode;
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.util.glu.GLU;
+
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.opengl.GL20.*;
+
+/**
+ * A minor evolution of ShaderBox to use standard OpenGL 2.0 instead of extensions.  The vertex
+ * color is different in order to differentiate it and the Box class had to be renamed, otherwise
+ * little is changed from the original -- no matter how much I'd like to clean it up.
+ */
+public class ShaderBox2 {
+
+    Square square;
+
+    private boolean done = false;
+
+    public ShaderBox2() {
+        init();
+
+        while (!done) {
+            if ((Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) || Display.isCloseRequested())
+                done = true;
+            render();
+            Display.update();
+        }
+
+        Display.destroy();
+    }
+
+    private void render() {
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+        glLoadIdentity();
+        square.draw();
+    }
+
+    private void init() {
+        int w = 1024;
+        int h = 768;
+
+        try {
+            Display.setDisplayMode(new DisplayMode(w, h));
+            Display.setVSyncEnabled(true);
+            Display.setTitle("Shader Setup");
+            Display.create();
+        } catch (Exception e) {
+            System.out.println("Error setting up display");
+            System.exit(0);
+        }
+
+        GL11.glViewport(0, 0, w, h);
+        GL11.glMatrixMode(GL11.GL_PROJECTION);
+        glLoadIdentity();
+        GLU.gluPerspective(45.0f, ((float) w / (float) h), 0.1f, 100.0f);
+        GL11.glMatrixMode(GL11.GL_MODELVIEW);
+        glLoadIdentity();
+        GL11.glShadeModel(GL11.GL_SMOOTH);
+        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+        GL11.glClearDepth(1.0f);
+        GL11.glEnable(GL11.GL_DEPTH_TEST);
+        GL11.glDepthFunc(GL11.GL_LEQUAL);
+        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
+
+        square = new Square();
+    }
+
+    public static void main(String[] args) {
+        new ShaderBox2();
+    }
+}
+
+
+/**
+ * The vertex and fragment shaders are setup when the square object is constructed. They are applied
+ * to the GL state prior to the square being drawn, and released from that state after drawing.
+ *
+ * @author Stephen Jones
+ */
+class Square {
+
+    /*
+    * if the shaders are setup ok we can use shaders, otherwise we just
+    * use default settings
+    */
+    private boolean useShader = true;
+
+    public static final String VERTEX_SHADER = "" +
+            "varying vec4 vertColor;\n" +
+            "void main(){\n" +
+            "    gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;\n" +
+            "    vertColor = vec4(0.9, 0.8, 0.1, 1.0);\n" +
+            "}";
+
+    public static final String FRAGMENT_SHADER = "" +
+            "varying vec4 vertColor;\n" +
+            "void main(){\n" +
+            "    gl_FragColor = vertColor;\n" +
+            "}";
+
+
+    /*
+    * 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
+    */
+    private int shader = 0;
+    private int vertShader = 0;
+    private int fragShader = 0;
+
+    public Square() {
+
+        /*
+        * create the shader program. If OK, create vertex
+        * and fragment shaders
+        */
+        shader = glCreateProgram();
+
+        if (shader != 0) {
+            vertShader = createVertShader(VERTEX_SHADER);
+            fragShader = createFragShader(FRAGMENT_SHADER);
+        } else useShader = false;
+
+        /*
+        * 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
+        */
+        if (vertShader != 0 && fragShader != 0) {
+            glAttachShader(shader, vertShader);
+            glAttachShader(shader, fragShader);
+            glLinkProgram(shader);
+            glValidateProgram(shader);
+            useShader = printLogInfo(shader);
+        } else useShader = false;
+    }
+
+    /*
+    * If the shader was setup succesfully, we use the shader. Otherwise
+    * we run normal drawing code.
+    */
+    public void draw() {
+        if (useShader) {
+            glUseProgram(shader);
+        }
+        glLoadIdentity();
+        GL11.glTranslatef(0.0f, 0.0f, -10.0f);
+        GL11.glColor3f(1.0f, 1.0f, 1.0f);//white
+
+        GL11.glBegin(GL11.GL_QUADS);
+        GL11.glVertex3f(-1.0f, 1.0f, 0.0f);
+        GL11.glVertex3f(1.0f, 1.0f, 0.0f);
+        GL11.glVertex3f(1.0f, -1.0f, 0.0f);
+        GL11.glVertex3f(-1.0f, -1.0f, 0.0f);
+        GL11.glEnd();
+
+        //release the shader
+        glUseProgram(0);
+
+    }
+
+    /*
+    * With the exception of syntax, setting up vertex and fragment shaders
+    * is the same.
+    * @param the name and path to the vertex shader
+    */
+    private int createVertShader(String source) {
+        //vertShader will be non zero if succefully created
+
+        vertShader = glCreateShader(GL_VERTEX_SHADER);
+        //if created, convert the vertex shader code to a String
+        if (vertShader == 0) {
+            return 0;
+        }
+        /*
+        * associate the vertex code String with the created vertex shader
+        * and compile
+        */
+        glShaderSource(vertShader, source);
+        glCompileShader(vertShader);
+        //if there was a problem compiling, reset vertShader to zero
+        if (!printLogInfo(vertShader)) {
+            vertShader = 0;
+        }
+        //if zero we won't be using the shader
+        return vertShader;
+    }
+
+    //same as per the vertex shader except for method syntax
+    private int createFragShader(String source) {
+
+        fragShader = glCreateShader(GL_FRAGMENT_SHADER);
+        if (fragShader == 0) {
+            return 0;
+        }
+        String fragCode = "";
+        String line;
+        glShaderSource(fragShader, source);
+        glCompileShader(fragShader);
+        if (!printLogInfo(fragShader)) {
+            fragShader = 0;
+        }
+
+        return fragShader;
+    }
+
+    private static boolean printLogInfo(int obj) {
+        IntBuffer iVal = BufferUtils.createIntBuffer(1);
+        glGetProgram(obj, GL_INFO_LOG_LENGTH, iVal);
+
+        int length = iVal.get();
+        if (length > 1) {
+            // We have some info we need to output.
+            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.out.println("Info log:\n" + out);
+        } else return true;
+        return false;
+    }
+
+}
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.