Jogamp
Adapt to JOGL commit 38f6915fedb765313c1f4646acf9e13dfbccef36 (FBObject)
[jogl-demos.git] / src / demos / es2 / RawGL2ES2demo.java
1 /**
2  * Copyright 2012-2013 JogAmp Community. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are
5  * permitted provided that the following conditions are met:
6  *
7  *    1. Redistributions of source code must retain the above copyright notice, this list of
8  *       conditions and the following disclaimer.
9  *
10  *    2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *       of conditions and the following disclaimer in the documentation and/or other materials
12  *       provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  * The views and conclusions contained in the software and documentation are those of the
25  * authors and should not be interpreted as representing official policies, either expressed
26  * or implied, of JogAmp Community.
27  */
28
29 package demos.es2;
30
31 import javax.media.opengl.GL;
32 import javax.media.opengl.GL2ES2;
33 import javax.media.opengl.GLAutoDrawable;
34 import javax.media.opengl.GLEventListener;
35 import javax.media.opengl.GLProfile;
36 import javax.media.opengl.GLCapabilities;
37 import com.jogamp.newt.opengl.GLWindow;
38
39 import com.jogamp.opengl.util.*;
40 import com.jogamp.common.nio.Buffers;
41
42 import java.nio.FloatBuffer;
43
44 /**
45  * <pre>
46  *   __ __|_  ___________________________________________________________________________  ___|__ __
47  *  //    /\                                           _                                  /\    \\
48  * //____/  \__     __ _____ _____ _____ _____ _____  | |     __ _____ _____ __        __/  \____\\
49  *  \    \  / /  __|  |     |   __|  _  |     |  _  | | |  __|  |     |   __|  |      /\ \  /    /
50  *   \____\/_/  |  |  |  |  |  |  |     | | | |   __| | | |  |  |  |  |  |  |  |__   "  \_\/____/
51  *  /\    \     |_____|_____|_____|__|__|_|_|_|__|    | | |_____|_____|_____|_____|  _  /    /\
52  * /  \____\                       http://jogamp.org  |_|                              /____/  \
53  * \  /   "' _________________________________________________________________________ `"   \  /
54  *  \/____.                                                                             .____\/
55  * </pre>
56  *
57  * <p>
58  * JOGL2 OpenGL ES 2 demo to expose and learn what the RAW OpenGL ES 2 API looks like.
59  *
60  * Compile, run and enjoy:
61    wget http://jogamp.org/deployment/jogamp-current/archive/jogamp-all-platforms.7z
62    7z x jogamp-all-platforms.7z
63    cd jogamp-all-platforms
64    mkdir -p demos/es2
65    cd demos/es2
66    wget https://raw.github.com/xranby/jogl-demos/master/src/demos/es2/RawGL2ES2demo.java
67    cd ../..
68    javac -cp jar/jogl-all.jar:jar/gluegen-rt.jar demos/es2/RawGL2ES2demo.java
69    java -cp jar/jogl-all.jar:jar/gluegen-rt.jar:. demos.es2.RawGL2ES2demo
70  * </p>
71  *
72  *
73  * @author Xerxes RĂ„nby (xranby)
74  */
75
76 public class RawGL2ES2demo implements GLEventListener{
77
78 /* Introducing the OpenGL ES 2 Vertex shader
79  *
80  * The main loop inside the vertex shader gets executed
81  * one time for each vertex.
82  *
83  *      vertex -> *       uniform data -> mat4 projection = ( 1, 0, 0, 0,
84  *      (0,1,0)  / \                                          0, 1, 0, 0,
85  *              / . \  <- origo (0,0,0)                       0, 0, 1, 0,
86  *             /     \                                        0, 0,-1, 1 );
87  *  vertex -> *-------* <- vertex
88  *  (-1,-1,0)             (1,-1,0) <- attribute data can be used
89  *                        (0, 0,1)    for color, position, normals etc.
90  *
91  * The vertex shader recive input data in form of
92  * "uniform" data that are common to all vertex
93  * and
94  * "attribute" data that are individual to each vertex.
95  * One vertex can have several "attribute" data sources enabled.
96  *
97  * The vertex shader produce output used by the fragment shader.
98  * gl_Position are expected to get set to the final vertex position.
99  * You can also send additional user defined
100  * "varying" data to the fragment shader.
101  *
102  * Model Translate, Scale and Rotate are done here by matrix-multiplying a
103  * projection matrix against each vertex position.
104  *
105  * The whole vertex shader program are a String containing GLSL ES language
106  * http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf
107  * sent to the GPU driver for compilation.
108  */
109 private String vertexShaderString =
110 // For GLSL 1 and 1.1 code i highly recomend to not include a
111 // GLSL ES language #version line, GLSL ES section 3.4
112 // Many GPU drivers refuse to compile the shader if #version is different from
113 // the drivers internal GLSL version.
114 //
115 // This demo use GLSL version 1.1 (the implicit version)
116
117 "#if __VERSION__ >= 130\n" + // GLSL 130+ uses in and out
118 "  #define attribute in\n" + // instead of attribute and varying
119 "  #define varying out\n" +  // used by OpenGL 3 core and later.
120 "#endif\n" +
121
122 "#ifdef GL_ES \n" +
123 "precision mediump float; \n" + // Precision Qualifiers
124 "precision mediump int; \n" +   // GLSL ES section 4.5.2
125 "#endif \n" +
126
127 "uniform mat4    uniform_Projection; \n" + // Incomming data used by
128 "attribute vec4  attribute_Position; \n" + // the vertex shader
129 "attribute vec4  attribute_Color; \n" +    // uniform and attributes
130
131 "varying vec4    varying_Color; \n" + // Outgoing varying data
132                                       // sent to the fragment shader
133 "void main(void) \n" +
134 "{ \n" +
135 "  varying_Color = attribute_Color; \n" +
136 "  gl_Position = uniform_Projection * attribute_Position; \n" +
137 "} ";
138
139 /* Introducing the OpenGL ES 2 Fragment shader
140  *
141  * The main loop of the fragment shader gets executed for each visible
142  * pixel fragment on the render buffer.
143  *
144  *       vertex-> *
145  *      (0,1,-1) /f\
146  *              /ffF\ <- This fragment F gl_FragCoord get interpolated
147  *             /fffff\                   to (0.25,0.25,-1) based on the
148  *   vertex-> *fffffff* <-vertex         three vertex gl_Position.
149  *  (-1,-1,-1)           (1,-1,-1)
150  *
151  *
152  * All incomming "varying" and gl_FragCoord data to the fragment shader
153  * gets interpolated based on the vertex positions.
154  *
155  * The fragment shader produce and store the final color data output into
156  * gl_FragColor.
157  *
158  * Is up to you to set the final colors and calculate lightning here based on
159  * supplied position, color and normal data.
160  *
161  * The whole fragment shader program are a String containing GLSL ES language
162  * http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf
163  * sent to the GPU driver for compilation.
164  */
165 private String fragmentShaderString =
166 "#if __VERSION__ >= 130\n" +
167 "  #define varying in\n" +
168 "  out vec4 mgl_FragColor;\n" +
169 "  #define texture2D texture\n" +
170 "  #define gl_FragColor mgl_FragColor\n" +
171 "#endif\n" +
172
173 "#ifdef GL_ES \n" +
174 "precision mediump float; \n" +
175 "precision mediump int; \n" +
176 "#endif \n" +
177
178 "varying   vec4    varying_Color; \n" + //incomming varying data to the
179                                         //frament shader
180                                         //sent from the vertex shader
181 "void main (void) \n" +
182 "{ \n" +
183 "  gl_FragColor = varying_Color; \n" +
184 "} ";
185
186 /* Introducing projection matrix helper functions
187  *
188  * OpenGL ES 2 vertex projection transformations gets applied inside the
189  * vertex shader, all you have to do are to calculate and supply a projection matrix.
190  *
191  * Its recomended to use the com/jogamp/opengl/util/PMVMatrix.java
192  * import com.jogamp.opengl.util.PMVMatrix;
193  * To simplify all your projection model view matrix creation needs.
194  *
195  * These helpers here are based on PMVMatrix code and common linear
196  * algebra for matrix multiplication, translate and rotations.
197  */
198     private void glMultMatrixf(FloatBuffer a, FloatBuffer b, FloatBuffer d) {
199         final int aP = a.position();
200         final int bP = b.position();
201         final int dP = d.position();
202         for (int i = 0; i < 4; i++) {
203             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);
204             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) );
205             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) );
206             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) );
207             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) );
208         }
209     }
210
211     private float[] multiply(float[] a,float[] b){
212         float[] tmp = new float[16];
213         glMultMatrixf(FloatBuffer.wrap(a),FloatBuffer.wrap(b),FloatBuffer.wrap(tmp));
214         return tmp;
215     }
216
217     private float[] translate(float[] m,float x,float y,float z){
218         float[] t = { 1.0f, 0.0f, 0.0f, 0.0f,
219                       0.0f, 1.0f, 0.0f, 0.0f,
220                       0.0f, 0.0f, 1.0f, 0.0f,
221                       x, y, z, 1.0f };
222         return multiply(m, t);
223     }
224
225     private float[] rotate(float[] m,float a,float x,float y,float z){
226         float s, c;
227         s = (float)Math.sin(Math.toRadians(a));
228         c = (float)Math.cos(Math.toRadians(a));
229         float[] r = {
230             x * x * (1.0f - c) + c,     y * x * (1.0f - c) + z * s, x * z * (1.0f - c) - y * s, 0.0f,
231             x * y * (1.0f - c) - z * s, y * y * (1.0f - c) + c,     y * z * (1.0f - c) + x * s, 0.0f,
232             x * z * (1.0f - c) + y * s, y * z * (1.0f - c) - x * s, z * z * (1.0f - c) + c,     0.0f,
233             0.0f, 0.0f, 0.0f, 1.0f };
234             return multiply(m, r);
235         }
236
237 /* Introducing the GL2ES2 demo
238  *
239  * How to render a triangle using ~500 lines of code using the RAW
240  * OpenGL ES 2 API.
241  * The Programmable pipeline in OpenGL ES 2 are both fast and flexible
242  * yet it do take some extra lines of code to setup.
243  *
244  */
245     private double t0 = System.currentTimeMillis();
246     private double theta;
247     private double s;
248
249     private static int width=1920;
250     private static int height=1080;
251
252     private int shaderProgram;
253     private int vertShader;
254     private int fragShader;
255     private int ModelViewProjectionMatrix_location;
256
257     static final int COLOR_IDX = 0;
258     static final int VERTICES_IDX = 1;
259     int[] vboHandles;
260
261     public static void main(String[] s){
262
263         /* This demo are based on the GL2ES2 GLProfile that uses common hardware acceleration
264          * functionality of desktop OpenGL 3, 2 and mobile OpenGL ES 2 devices.
265          * JogAmp JOGL will probe all the installed libGL.so, libEGL.so and libGLESv2.so librarys on
266          * the system to find which one provide hardware acceleration for your GPU device.
267          * Its common to find more than one version of these librarys installed on a system.
268          * For example on a ARM Linux system JOGL may find
269          * Hardware accelerated Nvidia tegra GPU drivers in: /usr/lib/nvidia-tegra/libEGL.so
270          * Software rendered Mesa Gallium driver in: /usr/lib/arm-linux-gnueabi/mesa-egl/libEGL.so.1
271          * Software rendered Mesa X11 in: /usr/lib/arm-linux-gnueabi/mesa/libGL.so
272          * Good news!: JOGL does all this probing for you all you have to do are to ask for
273          * the GLProfile you want to use.
274          */
275
276         GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2ES2));
277         // We may at this point tweak the caps and request a translucent drawable
278         caps.setBackgroundOpaque(false);
279         GLWindow glWindow = GLWindow.create(caps);
280
281         /* You may combine the NEWT GLWindow inside existing Swing and AWT
282          * applications by encapsulating the glWindow inside a
283          * com.jogamp.newt.awt.NewtCanvasAWT canvas.
284          *
285          *  NewtCanvasAWT newtCanvas = new NewtCanvasAWT(glWindow);
286          *  JFrame frame = new JFrame("RAW GL2ES2 Demo inside a JFrame!");
287          *  frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
288          *  frame.setSize(width,height);
289          *  frame.add(newtCanvas);
290          *  // add some swing code if you like.
291          *  // javax.swing.JButton b = new javax.swing.JButton();
292          *  // b.setText("Hi");
293          *  // frame.add(b);
294          *  frame.setVisible(true);
295          */
296
297         // In this demo we prefer to setup and view the GLWindow directly
298         // this allows the demo to run on -Djava.awt.headless=true systems
299         glWindow.setTitle("Raw GL2ES2 Demo");
300         glWindow.setSize(width,height);
301         glWindow.setUndecorated(false);
302         glWindow.setPointerVisible(true);
303         glWindow.setVisible(true);
304
305         // Finally we connect the GLEventListener application code to the NEWT GLWindow.
306         // GLWindow will call the GLEventListener init, reshape, display and dispose
307         // functions when needed.
308         glWindow.addGLEventListener(new RawGL2ES2demo() /* GLEventListener */);
309         Animator animator = new Animator();
310         animator.add(glWindow);
311         animator.start();
312     }
313
314     public void init(GLAutoDrawable drawable) {
315         GL2ES2 gl = drawable.getGL().getGL2ES2();
316
317         System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
318         System.err.println("INIT GL IS: " + gl.getClass().getName());
319         System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
320         System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
321         System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
322
323         /* The initialization below will use the OpenGL ES 2 API directly
324          * to setup the two shader programs that will be run on the GPU.
325          *
326          * Its recommended to use the jogamp/opengl/util/glsl/ classes
327          * import com.jogamp.opengl.util.glsl.ShaderCode;
328          * import com.jogamp.opengl.util.glsl.ShaderProgram;
329          * import com.jogamp.opengl.util.glsl.ShaderState;
330          * to simplify shader customization, compile and loading.
331          *
332          * You may also want to look at the JOGL RedSquareES2 demo
333          * http://jogamp.org/git/?p=jogl.git;a=blob;f=src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java;hb=HEAD#l78
334          * to see how the shader customization, compile and loading is done
335          * using the recommended JogAmp GLSL utility classes.
336          */
337
338         // Make the shader strings compatible with OpenGL 3 core if needed
339         // GL2ES2 also includes the intersection of GL3 core
340         // The default implicit GLSL version 1.1 is now depricated in GL3 core
341         // GLSL 1.3 is the minimum version that now has to be explicitly set.
342         // This allows the shaders to compile using the latest
343         // desktop OpenGL 3 and 4 drivers.
344         if(gl.isGL3core()){
345             System.out.println("GL3 core detected: explicit add #version 130 to shaders");
346             vertexShaderString = "#version 130\n"+vertexShaderString;
347             fragmentShaderString = "#version 130\n"+fragmentShaderString;
348         }
349
350         // Create GPU shader handles
351         // OpenGL ES retuns a index id to be stored for future reference.
352         vertShader = gl.glCreateShader(GL2ES2.GL_VERTEX_SHADER);
353         fragShader = gl.glCreateShader(GL2ES2.GL_FRAGMENT_SHADER);
354
355         //Compile the vertexShader String into a program.
356         String[] vlines = new String[] { vertexShaderString };
357         int[] vlengths = new int[] { vlines[0].length() };
358         gl.glShaderSource(vertShader, vlines.length, vlines, vlengths, 0);
359         gl.glCompileShader(vertShader);
360
361         //Check compile status.
362         int[] compiled = new int[1];
363         gl.glGetShaderiv(vertShader, GL2ES2.GL_COMPILE_STATUS, compiled,0);
364         if(compiled[0]!=0){System.out.println("Horray! vertex shader compiled");}
365         else {
366             int[] logLength = new int[1];
367             gl.glGetShaderiv(vertShader, GL2ES2.GL_INFO_LOG_LENGTH, logLength, 0);
368
369             byte[] log = new byte[logLength[0]];
370             gl.glGetShaderInfoLog(vertShader, logLength[0], (int[])null, 0, log, 0);
371
372             System.err.println("Error compiling the vertex shader: " + new String(log));
373             System.exit(1);
374         }
375
376         //Compile the fragmentShader String into a program.
377         String[] flines = new String[] { fragmentShaderString };
378         int[] flengths = new int[] { flines[0].length() };
379         gl.glShaderSource(fragShader, flines.length, flines, flengths, 0);
380         gl.glCompileShader(fragShader);
381
382         //Check compile status.
383         gl.glGetShaderiv(fragShader, GL2ES2.GL_COMPILE_STATUS, compiled,0);
384         if(compiled[0]!=0){System.out.println("Horray! fragment shader compiled");}
385         else {
386             int[] logLength = new int[1];
387             gl.glGetShaderiv(fragShader, GL2ES2.GL_INFO_LOG_LENGTH, logLength, 0);
388
389             byte[] log = new byte[logLength[0]];
390             gl.glGetShaderInfoLog(fragShader, logLength[0], (int[])null, 0, log, 0);
391
392             System.err.println("Error compiling the fragment shader: " + new String(log));
393             System.exit(1);
394         }
395
396         //Each shaderProgram must have
397         //one vertex shader and one fragment shader.
398         shaderProgram = gl.glCreateProgram();
399         gl.glAttachShader(shaderProgram, vertShader);
400         gl.glAttachShader(shaderProgram, fragShader);
401
402         //Associate attribute ids with the attribute names inside
403         //the vertex shader.
404         gl.glBindAttribLocation(shaderProgram, 0, "attribute_Position");
405         gl.glBindAttribLocation(shaderProgram, 1, "attribute_Color");
406
407         gl.glLinkProgram(shaderProgram);
408
409         //Get a id number to the uniform_Projection matrix
410         //so that we can update it.
411         ModelViewProjectionMatrix_location = gl.glGetUniformLocation(shaderProgram, "uniform_Projection");
412
413         /* GL2ES2 also includes the intersection of GL3 core
414          * GL3 core and later mandates that a "Vector Buffer Object" must
415          * be created and bound before calls such as gl.glDrawArrays is used.
416          * The VBO lines in this demo makes the code forward compatible with
417          * OpenGL 3 and ES 3 core and later where a default
418          * vector buffer object is deprecated.
419          *
420          * Generate two VBO pointers / handles
421          * VBO is data buffers stored inside the graphics card memory.
422          */
423         vboHandles = new int[2];
424         gl.glGenBuffers(2, vboHandles, 0);
425     }
426
427     public void reshape(GLAutoDrawable drawable, int x, int y, int z, int h) {
428         System.out.println("Window resized to width=" + z + " height=" + h);
429         width = z;
430         height = h;
431
432         // Get gl
433         GL2ES2 gl = drawable.getGL().getGL2ES2();
434
435         // Optional: Set viewport
436         // Render to a square at the center of the window.
437         gl.glViewport((width-height)/2,0,height,height);
438     }
439
440     public void display(GLAutoDrawable drawable) {
441         // Update variables used in animation
442         double t1 = System.currentTimeMillis();
443         theta += (t1-t0)*0.005f;
444         t0 = t1;
445         s = Math.sin(theta);
446
447         // Get gl
448         GL2ES2 gl = drawable.getGL().getGL2ES2();
449
450         // Clear screen
451         gl.glClearColor(1, 0, 1, 0.5f);  // Purple
452         gl.glClear(GL2ES2.GL_STENCIL_BUFFER_BIT |
453                    GL2ES2.GL_COLOR_BUFFER_BIT   |
454                    GL2ES2.GL_DEPTH_BUFFER_BIT   );
455
456         // Use the shaderProgram that got linked during the init part.
457         gl.glUseProgram(shaderProgram);
458
459         /* Change a projection matrix
460          * The matrix multiplications and OpenGL ES2 code below
461          * basically match this OpenGL ES1 code.
462          * note that the model_view_projection matrix gets sent to the vertexShader.
463          *
464          * gl.glLoadIdentity();
465          * gl.glTranslatef(0.0f,0.0f,-0.1f);
466          * gl.glRotatef((float)30f*(float)s,1.0f,0.0f,1.0f);
467          *
468          */
469
470         float[] model_view_projection;
471         float[] identity_matrix = {
472             1.0f, 0.0f, 0.0f, 0.0f,
473             0.0f, 1.0f, 0.0f, 0.0f,
474             0.0f, 0.0f, 1.0f, 0.0f,
475             0.0f, 0.0f, 0.0f, 1.0f,
476         };
477         model_view_projection =  translate(identity_matrix,0.0f,0.0f, -0.1f);
478         model_view_projection =  rotate(model_view_projection,30f*(float)s,1.0f,0.0f,1.0f);
479
480         // Send the final projection matrix to the vertex shader by
481         // using the uniform location id obtained during the init part.
482         gl.glUniformMatrix4fv(ModelViewProjectionMatrix_location, 1, false, model_view_projection, 0);
483
484         /*
485          *  Render a triangle:
486          *  The OpenGL ES2 code below basically match this OpenGL code.
487          *
488          *    gl.glBegin(GL_TRIANGLES);                      // Drawing Using Triangles
489          *    gl.glVertex3f( 0.0f, 1.0f, 0.0f);              // Top
490          *    gl.glVertex3f(-1.0f,-1.0f, 0.0f);              // Bottom Left
491          *    gl.glVertex3f( 1.0f,-1.0f, 0.0f);              // Bottom Right
492          *    gl.glEnd();                            // Finished Drawing The Triangle
493          */
494
495         float[] vertices = {  0.0f,  1.0f, 0.0f, //Top
496                              -1.0f, -1.0f, 0.0f, //Bottom Left
497                               1.0f, -1.0f, 0.0f  //Bottom Right
498                                               };
499
500
501         // Observe that the vertex data passed to glVertexAttribPointer must stay valid
502         // through the OpenGL rendering lifecycle.
503         // Therefore it is mandatory to allocate a NIO Direct buffer that stays pinned in memory
504         // and thus can not get moved by the java garbage collector.
505         // Also we need to keep a reference to the NIO Direct buffer around up untill
506         // we call glDisableVertexAttribArray first then will it be safe to garbage collect the memory.
507         // I will here use the com.jogamp.common.nio.Buffers to quicly wrap the array in a Direct NIO buffer.
508         FloatBuffer fbVertices = Buffers.newDirectFloatBuffer(vertices);
509
510         // Select the VBO, GPU memory data, to use for vertices
511         gl.glBindBuffer(GL2ES2.GL_ARRAY_BUFFER, vboHandles[VERTICES_IDX]);
512
513         // transfer data to VBO, this perform the copy of data from CPU -> GPU memory
514         int numBytes = vertices.length * 4;
515         gl.glBufferData(GL.GL_ARRAY_BUFFER, numBytes, fbVertices, GL.GL_STATIC_DRAW);
516         fbVertices = null; // It is OK to release CPU vertices memory after transfer to GPU
517
518         // Associate Vertex attribute 0 with the last bound VBO
519         gl.glVertexAttribPointer(0 /* the vertex attribute */, 3,
520                                  GL2ES2.GL_FLOAT, false /* normalized? */, 0 /* stride */,
521                                  0 /* The bound VBO data offset */);
522
523         // VBO
524         // gl.glBindBuffer(GL2ES2.GL_ARRAY_BUFFER, 0); // You can unbind the VBO after it have been associated using glVertexAttribPointer
525
526         gl.glEnableVertexAttribArray(0);
527
528
529
530         float[] colors = {    1.0f, 0.0f, 0.0f, 1.0f, //Top color (red)
531                               0.0f, 0.0f, 0.0f, 1.0f, //Bottom Left color (black)
532                               1.0f, 1.0f, 0.0f, 0.9f  //Bottom Right color (yellow) with 10% transparence
533                                                    };
534
535         FloatBuffer fbColors = Buffers.newDirectFloatBuffer(colors);
536
537         // Select the VBO, GPU memory data, to use for colors
538         gl.glBindBuffer(GL2ES2.GL_ARRAY_BUFFER, vboHandles[COLOR_IDX]);
539
540         numBytes = colors.length * 4;
541         gl.glBufferData(GL.GL_ARRAY_BUFFER, numBytes, fbColors, GL.GL_STATIC_DRAW);
542         fbColors = null; // It is OK to release CPU color memory after transfer to GPU
543
544         // Associate Vertex attribute 1 with the last bound VBO
545         gl.glVertexAttribPointer(1 /* the vertex attribute */, 4 /* four possitions used for each vertex */,
546                                  GL2ES2.GL_FLOAT, false /* normalized? */, 0 /* stride */,
547                                  0 /* The bound VBO data offset */);
548
549         gl.glEnableVertexAttribArray(1);
550
551         gl.glDrawArrays(GL2ES2.GL_TRIANGLES, 0, 3); //Draw the vertices as triangle
552
553         gl.glDisableVertexAttribArray(0); // Allow release of vertex position memory
554         gl.glDisableVertexAttribArray(1); // Allow release of vertex color memory
555     }
556
557     public void dispose(GLAutoDrawable drawable){
558         System.out.println("cleanup, remember to release shaders");
559         GL2ES2 gl = drawable.getGL().getGL2ES2();
560         gl.glUseProgram(0);
561         gl.glDeleteBuffers(2, vboHandles, 0); // Release VBO, color and vertices, buffer GPU memory.
562         vboHandles = null;
563         gl.glDetachShader(shaderProgram, vertShader);
564         gl.glDeleteShader(vertShader);
565         gl.glDetachShader(shaderProgram, fragShader);
566         gl.glDeleteShader(fragShader);
567         gl.glDeleteProgram(shaderProgram);
568         System.exit(0);
569     }
570 }
http://JogAmp.org git info: FAQ, tutorial and man pages.