From 7f02346217306f2c77601b19d8fe28cfadd30ccb Mon Sep 17 00:00:00 2001
From: Xerxes Rånby <xerxes@zafena.se>
Date: Fri, 23 Mar 2012 02:51:43 +0100
Subject: JOGL2 OpenGL ES 2 demo to expose and learn what the RAW OpenGL ES 2
 API looks like.

---
 src/demos/es2/RawGL2ES2demo.java | 426 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 426 insertions(+)
 create mode 100644 src/demos/es2/RawGL2ES2demo.java

(limited to 'src/demos/es2/RawGL2ES2demo.java')

diff --git a/src/demos/es2/RawGL2ES2demo.java b/src/demos/es2/RawGL2ES2demo.java
new file mode 100644
index 0000000..c76b43a
--- /dev/null
+++ b/src/demos/es2/RawGL2ES2demo.java
@@ -0,0 +1,426 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright notice, this list of
+ *       conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright notice, this list
+ *       of conditions and the following disclaimer in the documentation and/or other materials
+ *       provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLContext;
+import com.jogamp.newt.opengl.GLWindow;
+
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderState;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.*;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.Buffer;
+
+import javax.swing.JFrame;
+import javax.media.opengl.*;
+import javax.media.opengl.awt.GLCanvas;
+
+/**
+ * <pre>
+ *   __ __|_  ___________________________________________________________________________  ___|__ __
+ *  //    /\                                           _                                  /\    \\
+ * //____/  \__     __ _____ _____ _____ _____ _____  | |     __ _____ _____ __        __/  \____\\
+ *  \    \  / /  __|  |     |   __|  _  |     |  _  | | |  __|  |     |   __|  |      /\ \  /    /
+ *   \____\/_/  |  |  |  |  |  |  |     | | | |   __| | | |  |  |  |  |  |  |  |__   "  \_\/____/
+ *  /\    \     |_____|_____|_____|__|__|_|_|_|__|    | | |_____|_____|_____|_____|  _  /    /\
+ * /  \____\                       http://jogamp.org  |_|                              /____/  \
+ * \  /   "' _________________________________________________________________________ `"   \  /
+ *  \/____.                                                                             .____\/
+ * </pre>
+ *
+ * <p>
+ * JOGL2 OpenGL ES 2 demo to expose and learn what the RAW OpenGL ES 2 API looks like.
+ *
+ * Compile, run and enjoy:
+ * javac -cp jar/jogl.all.jar:jar/gluegen-rt.jar RawGL2ES2demo.java
+ * java -cp jar/jogl.all.jar:jar/gluegen-rt.jar:. RawGL2ES2demo
+ * </p>
+ *
+ *
+ * @author Xerxes Rånby (xranby)
+ */
+
+public class RawGL2ES2demo implements GLEventListener{
+
+/* Introducing the OpenGL ES 2 Vertex shader
+ *
+ * The main loop inside the vertex shader gets executed
+ * one time for each vertice.
+ *
+ *      vertex -> *       uniform data -> mat4 projection = ( 1, 0, 0, 0,
+ *      (0,1,0)  / \                                          0, 1, 0, 0,
+ *              / . \  <- origo (0,0,0)                       0, 0, 1, 0,
+ *             /     \                                        0, 0,-1, 1 );
+ *  vertex -> *-------* <- vertex
+ *  (-1,-1,0)             (1,-1,0) <- attribute data can be used
+ *                        (0, 0,1)    for color, position, normals etc.
+ *
+ * The vertex shader recive input data in form of
+ * "uniform" data that are common to all vertex
+ * and
+ * "attribute" data that are individual to each vertex.
+ * One vertex can have several "attribute" data sources enabled.
+ *
+ * The vertex shader produce output used by the fragment shader.
+ * gl_Position are expected to get set to the final vertex position.
+ * You can also send additional user defined
+ * "varying" data to the fragment shader.
+ *
+ * Model Translate, Scale and Rotate are done here by matrix-multiplying a
+ * projection matrix against each vertex position.
+ *
+ * The whole vertex shader program are a String containing GLSL ES language
+ * http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf
+ * sent to the GPU driver for compilation.
+ */
+static final String vertexShader =
+"#version 100 \n" + // GLSL ES language version, GLSL ES section 3.4
+                    // many GPU drivers require it.
+"precision mediump float; \n" + // Precision Qualifiers
+"precision mediump int; \n" +   // GLSL ES section 4.5.2
+
+"uniform mat4    uniform_Projection; \n" + // Incomming data used by
+"attribute vec4  attribute_Position; \n" + // the vertex shader
+"attribute vec4  attribute_Color; \n" +    // uniform and attributes
+
+"varying vec4    varying_Color; \n" + // Outgoing varying data
+                                      // sent to the fragment shader
+"void main(void) \n" +
+"{ \n" +
+"  varying_Color = attribute_Color; \n" +
+"  gl_Position = uniform_Projection * attribute_Position; \n" +
+"} ";
+
+/* Introducing the OpenGL ES 2 Fragment shader
+ *
+ * The main loop of the fragment shader gets executed for each visible
+ * pixel fragment on the render buffer.
+ *
+ *       vertex-> *
+ *      (0,1,-1) /f\
+ *              /ffF\ <- This fragment F gl_FragCoord get interpolated
+ *             /fffff\                   to (0.25,0.25,-1) based on the
+ *   vertex-> *fffffff* <-vertex         three vertex gl_Position.
+ *  (-1,-1,-1)           (1,-1,-1)
+ *
+ *
+ * All incomming "varying" and gl_FragCoord data to the fragment shader
+ * gets interpolated based on the vertex positions.
+ *
+ * The fragment shader produce and store the final color data output into
+ * gl_FragColor.
+ *
+ * Is up to you to set the final colors and calculate lightning here based on
+ * supplied position, color and normal data.
+ *
+ * The whole fragment shader program are a String containing GLSL ES language
+ * http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf
+ * sent to the GPU driver for compilation.
+ */
+static final String fragmentShader =
+"#version 100 \n" +
+"precision mediump float; \n" +
+"precision mediump int; \n" +
+
+"varying   vec4    varying_Color; \n" + //incomming varying data to the
+                                        //frament shader
+                                        //sent from the vertex shader
+"void main (void)\n" +
+"{ \n" +
+"  gl_FragColor = varying_Color; \n" +
+"} ";
+
+/* Introducing projection matrix helper functions
+ *
+ * OpenGL ES 2 vertex projection transformations gets applied inside the
+ * vertex shader, all you have to calculate and supply a projection matrix.
+ *
+ * Its recomended to use the com/jogamp/opengl/util/PMVMatrix.java
+ * import com.jogamp.opengl.util.PMVMatrix;
+ * To simplify all your projection model view matrix creation needs.
+ *
+ * These helpers here are based on PMVMatrix code and common linear
+ * algebra for matrix multiplication, translate and rotations.
+ */
+    private void glMultMatrixf(final FloatBuffer a, final FloatBuffer b, FloatBuffer d) {
+        final int aP = a.position();
+        final int bP = b.position();
+        final int dP = d.position();
+        for (int i = 0; i < 4; i++) {
+            final float ai0=a.get(aP+i+0*4),  ai1=a.get(aP+i+1*4),  ai2=a.get(aP+i+2*4),  ai3=a.get(aP+i+3*4);
+            d.put(dP+i+0*4 , ai0 * b.get(bP+0+0*4) + ai1 * b.get(bP+1+0*4) + ai2 * b.get(bP+2+0*4) + ai3 * b.get(bP+3+0*4) );
+            d.put(dP+i+1*4 , ai0 * b.get(bP+0+1*4) + ai1 * b.get(bP+1+1*4) + ai2 * b.get(bP+2+1*4) + ai3 * b.get(bP+3+1*4) );
+            d.put(dP+i+2*4 , ai0 * b.get(bP+0+2*4) + ai1 * b.get(bP+1+2*4) + ai2 * b.get(bP+2+2*4) + ai3 * b.get(bP+3+2*4) );
+            d.put(dP+i+3*4 , ai0 * b.get(bP+0+3*4) + ai1 * b.get(bP+1+3*4) + ai2 * b.get(bP+2+3*4) + ai3 * b.get(bP+3+3*4) );
+        }
+    }
+
+    private float[] multiply(float[] a,float[] b){
+        float tmp[] = new float[16];
+        glMultMatrixf(FloatBuffer.wrap(a),FloatBuffer.wrap(b),FloatBuffer.wrap(tmp));
+        return tmp;
+    }
+
+    private float[] translate(float[] m,float x,float y,float z){
+        float t[] = { 1.0f, 0.0f, 0.0f, 0.0f,
+                      0.0f, 1.0f, 0.0f, 0.0f,
+                      0.0f, 0.0f, 1.0f, 0.0f,
+                      x, y, z, 1.0f };
+        return multiply(m, t);
+    }
+
+    private float[] rotate(float[] m,float a,float x,float y,float z){
+        float s, c;
+        s = (float)Math.sin(Math.toRadians(a));
+        c = (float)Math.cos(Math.toRadians(a));
+        float r[] = {
+            x * x * (1.0f - c) + c,     y * x * (1.0f - c) + z * s, x * z * (1.0f - c) - y * s, 0.0f,
+            x * y * (1.0f - c) - z * s, y * y * (1.0f - c) + c,     y * z * (1.0f - c) + x * s, 0.0f,
+            x * z * (1.0f - c) + y * s, y * z * (1.0f - c) - x * s, z * z * (1.0f - c) + c,     0.0f,
+            0.0f, 0.0f, 0.0f, 1.0f };
+            return multiply(m, r);
+        }
+
+    private void printMatrix(float[] m){
+        System.out.println(m[0]+" "+m[1]+" "+m[2]+" "+m[3]+"\n"+
+                           m[4]+" "+m[5]+" "+m[6]+" "+m[7]+"\n"+
+                           m[8]+" "+m[9]+" "+m[10]+" "+m[11]+"\n"+
+                           m[12]+" "+m[13]+" "+m[14]+" "+m[15]+"\n");
+    }
+
+/* Introducing the GL2ES demo
+ *
+ * How to render a triangle using 424 lines of code using the RAW
+ * OpenGL ES 2 API.
+ * The Programmable pipeline in OpenGL ES 2 are both fast and flexible
+ * yet it do take some extra lines of code to setup.
+ *
+ */
+    private double theta=0;
+    private double s=0;
+    private double c=0;
+
+    private int shaderProgram;
+    private int vertShader;
+    private int fragShader;
+    private int ModelViewProjectionMatrix_location;
+
+    public static void main(String[] s){
+        GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2ES2));
+        GLWindow canvas = GLWindow.create(caps);
+
+        NewtCanvasAWT newtCanvas = new NewtCanvasAWT(canvas);
+        JFrame frame = new JFrame("RAW GL2ES Demo");
+        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+        frame.setSize(300,300);
+        frame.add(newtCanvas);
+        //add some swing code if you like.
+        /* javax.swing.JButton b = new javax.swing.JButton();
+        b.setText("Hi");
+        frame.add(b); */
+        frame.setVisible(true);
+
+        canvas.addGLEventListener(new RawGL2ES2demo());
+        FPSAnimator animator = new FPSAnimator(canvas,60);
+        animator.add(canvas);
+        animator.start();
+    }
+
+    public void init(GLAutoDrawable drawable) {
+        GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+        System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
+        System.err.println("INIT GL IS: " + gl.getClass().getName());
+        System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
+        System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
+        System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+
+        //Create shaders
+        //OpenGL ES retuns a index id to be stored for future reference.
+        vertShader = gl.glCreateShader(GL2ES2.GL_VERTEX_SHADER);
+        fragShader = gl.glCreateShader(GL2ES2.GL_FRAGMENT_SHADER);
+
+        //Compile the vertexShader String into a program.
+        String[] vlines = new String[] { vertexShader };
+        int[] vlengths = new int[] { vlines[0].length() };
+        gl.glShaderSource(vertShader, vlines.length, vlines, vlengths, 0);
+        gl.glCompileShader(vertShader);
+
+        //Check compile status.
+        int[] compiled = new int[1];
+        gl.glGetShaderiv(vertShader, GL2ES2.GL_COMPILE_STATUS, compiled,0);
+        if(compiled[0]!=0){System.out.println("Horray! vertexShader compiled");}
+        else {
+            int[] logLength = new int[1];
+            gl.glGetShaderiv(vertShader, GL2ES2.GL_INFO_LOG_LENGTH, logLength, 0);
+
+            byte[] log = new byte[logLength[0]];
+            gl.glGetShaderInfoLog(vertShader, logLength[0], (int[])null, 0, log, 0);
+
+            System.err.println("Error compiling the shader: " + new String(log));
+        }
+
+        //Compile the fragmentShader String into a program.
+        String[] flines = new String[] { fragmentShader };
+        int[] flengths = new int[] { flines[0].length() };
+        gl.glShaderSource(fragShader, flines.length, flines, flengths, 0);
+        gl.glCompileShader(fragShader);
+
+        //Check compile status.
+        gl.glGetShaderiv(fragShader, GL2ES2.GL_COMPILE_STATUS, compiled,0);
+        if(compiled[0]!=0){System.out.println("Horray! fragmentShader compiled");}
+        else {
+            int[] logLength = new int[1];
+            gl.glGetShaderiv(fragShader, GL2ES2.GL_INFO_LOG_LENGTH, logLength, 0);
+
+            byte[] log = new byte[logLength[0]];
+            gl.glGetShaderInfoLog(fragShader, logLength[0], (int[])null, 0, log, 0);
+
+            System.err.println("Error compiling the shader: " + new String(log));
+        }
+
+        //Each shaderProgram must have
+        //one vertex shader and one fragment shader.
+        shaderProgram = gl.glCreateProgram();
+        gl.glAttachShader(shaderProgram, vertShader);
+        gl.glAttachShader(shaderProgram, fragShader);
+
+        //Associate attribute ids with the attribute names inside
+        //the vertex shader.
+        gl.glBindAttribLocation(shaderProgram, 0, "attribute_Position");
+        gl.glBindAttribLocation(shaderProgram, 1, "attribute_Color");
+
+        gl.glLinkProgram(shaderProgram);
+
+        //Get a id number to the uniform_Projection matrix
+        //so that we can update it.
+        ModelViewProjectionMatrix_location = gl.glGetUniformLocation(shaderProgram, "uniform_Projection");
+    }
+
+    public void reshape(GLAutoDrawable drawable, int x, int y, int z, int h) {
+    }
+
+    public void display(GLAutoDrawable drawable) {
+        // Update variables used in animation
+        theta += 0.08;
+        s = Math.sin(theta);
+        c = Math.cos(theta);
+
+        // Get gl
+        GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+        // Set viewport
+        //gl.glViewport(0,0,300,300);
+
+        // Clear screen
+        gl.glClearColor(1, 0, 1, 1);  //Purple
+        gl.glClear(GL2ES2.GL_COLOR_BUFFER_BIT | GL2ES2.GL_DEPTH_BUFFER_BIT);
+
+        // Use the shaderProgram that got linked during the init part.
+        gl.glUseProgram(shaderProgram);
+
+        /* Change a projection matrix
+         * The matrix multiplications and OpenGL ES2 code below
+         * basically match this OpenGL ES1 code.
+         * note that the model_view_projection matrix gets sent to the vertexShader.
+         *
+         * gl.glLoadIdentity();
+         * gl.glTranslatef(0.0f,0.0f,-0.1f);
+         * gl.glRotatef((float)30f*(float)s,1.0f,0.0f,1.0f);
+         *
+         */
+
+        float model_view_projection[];
+        float identity_matrix[] = {
+            1.0f, 0.0f, 0.0f, 0.0f,
+            0.0f, 1.0f, 0.0f, 0.0f,
+            0.0f, 0.0f, 1.0f, 0.0f,
+            0.0f, 0.0f, 0.0f, 1.0f,
+        };
+        model_view_projection =  translate(identity_matrix,0.0f,0.0f, -0.1f);
+        model_view_projection =  rotate(model_view_projection,(float)30f*(float)s,1.0f,0.0f,1.0f);
+
+        // Send the final projection matrix to the vertex shader by
+        // using the uniform location id obtained during the init part.
+        gl.glUniformMatrix4fv(ModelViewProjectionMatrix_location, 1, false, model_view_projection, 0);
+
+        /*
+         *  Render a triangle:
+         *  The OpenGL ES2 code below basically match this OpenGL code.
+         *
+         *    gl.glBegin(GL_TRIANGLES);                      // Drawing Using Triangles
+         *    gl.glVertex3f( 0.0f, 1.0f, 0.0f);              // Top
+         *    gl.glVertex3f(-1.0f,-1.0f, 0.0f);              // Bottom Left
+         *    gl.glVertex3f( 1.0f,-1.0f, 0.0f);              // Bottom Right
+         *    gl.glEnd();                            // Finished Drawing The Triangle
+         */
+
+        float vertices[] = {  0.0f,  1.0f, 0.0f, //Top
+                             -1.0f, -1.0f, 0.0f, //Bottom Left
+                              1.0f, -1.0f, 0.0f  //Bottom Right
+                                              };
+
+        gl.glVertexAttribPointer(0, 3, GL2ES2.GL_FLOAT, false, 0, FloatBuffer.wrap(vertices));
+        gl.glEnableVertexAttribArray(0);
+
+        float colors[] = {    1.0f, 0.0f, 0.0f, //Top color (red)
+                              0.0f, 0.0f, 0.0f, //Bottom Left color (black)
+                              1.0f, 1.0f, 0.0f  //Bottom Right color (yellow)
+                                             };
+                                             
+        gl.glVertexAttribPointer(1, 3, GL2ES2.GL_FLOAT, false, 0, FloatBuffer.wrap(colors));
+        gl.glEnableVertexAttribArray(1);
+
+        gl.glDrawArrays(GL2ES2.GL_TRIANGLES, 0, 3); //Draw the vertices as triangle
+        
+        gl.glDisableVertexAttribArray(0); // Allow release of vertex position memory
+		gl.glDisableVertexAttribArray(1); // Allow release of vertex color memory		
+    }
+
+    public void dispose(GLAutoDrawable drawable){
+        System.out.println("cleanup, remember to release shaders");
+        GL2ES2 gl = drawable.getGL().getGL2ES2();
+        gl.glUseProgram(0);
+        gl.glDetachShader(shaderProgram, vertShader);
+        gl.glDeleteShader(vertShader);
+        gl.glDetachShader(shaderProgram, fragShader);
+        gl.glDeleteShader(fragShader);
+        gl.glDeleteProgram(shaderProgram);
+    }
+}
-- 
cgit v1.2.3