|
|
|
@@ -0,0 +1,570 @@
|
|
|
|
|
/**
|
|
|
|
|
* Copyright 2012-2013 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.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package demos.es2;
|
|
|
|
|
|
|
|
|
|
import com.jogamp.opengl.GL;
|
|
|
|
|
import com.jogamp.opengl.GL2ES2;
|
|
|
|
|
import com.jogamp.opengl.GLAutoDrawable;
|
|
|
|
|
import com.jogamp.opengl.GLEventListener;
|
|
|
|
|
import com.jogamp.opengl.GLProfile;
|
|
|
|
|
import com.jogamp.opengl.GLCapabilities;
|
|
|
|
|
import com.jogamp.newt.opengl.GLWindow;
|
|
|
|
|
|
|
|
|
|
import com.jogamp.opengl.util.*;
|
|
|
|
|
import com.jogamp.common.nio.Buffers;
|
|
|
|
|
|
|
|
|
|
import java.nio.FloatBuffer;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <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:
|
|
|
|
|
wget http://jogamp.org/deployment/jogamp-current/archive/jogamp-all-platforms.7z
|
|
|
|
|
7z x jogamp-all-platforms.7z
|
|
|
|
|
cd jogamp-all-platforms
|
|
|
|
|
mkdir -p demos/es2
|
|
|
|
|
cd demos/es2
|
|
|
|
|
wget https://raw.github.com/xranby/jogl-demos/master/src/demos/es2/RawGL2ES2demo.java
|
|
|
|
|
cd ../..
|
|
|
|
|
javac -cp jar/jogl-all.jar:jar/gluegen-rt.jar demos/es2/RawGL2ES2demo.java
|
|
|
|
|
java -cp jar/jogl-all.jar:jar/gluegen-rt.jar:. demos.es2.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 vertex.
|
|
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
|
|
|
|
private String vertexShaderString =
|
|
|
|
|
// For GLSL 1 and 1.1 code i highly recomend to not include a
|
|
|
|
|
// GLSL ES language #version line, GLSL ES section 3.4
|
|
|
|
|
// Many GPU drivers refuse to compile the shader if #version is different from
|
|
|
|
|
// the drivers internal GLSL version.
|
|
|
|
|
//
|
|
|
|
|
// This demo use GLSL version 1.1 (the implicit version)
|
|
|
|
|
|
|
|
|
|
"#if __VERSION__ >= 130\n" + // GLSL 130+ uses in and out
|
|
|
|
|
" #define attribute in\n" + // instead of attribute and varying
|
|
|
|
|
" #define varying out\n" + // used by OpenGL 3 core and later.
|
|
|
|
|
"#endif\n" +
|
|
|
|
|
|
|
|
|
|
"#ifdef GL_ES \n" +
|
|
|
|
|
"precision mediump float; \n" + // Precision Qualifiers
|
|
|
|
|
"precision mediump int; \n" + // GLSL ES section 4.5.2
|
|
|
|
|
"#endif \n" +
|
|
|
|
|
|
|
|
|
|
"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.
|
|
|
|
|
*/
|
|
|
|
|
private String fragmentShaderString =
|
|
|
|
|
"#if __VERSION__ >= 130\n" +
|
|
|
|
|
" #define varying in\n" +
|
|
|
|
|
" out vec4 mgl_FragColor;\n" +
|
|
|
|
|
" #define texture2D texture\n" +
|
|
|
|
|
" #define gl_FragColor mgl_FragColor\n" +
|
|
|
|
|
"#endif\n" +
|
|
|
|
|
|
|
|
|
|
"#ifdef GL_ES \n" +
|
|
|
|
|
"precision mediump float; \n" +
|
|
|
|
|
"precision mediump int; \n" +
|
|
|
|
|
"#endif \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 do are 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(FloatBuffer a, 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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Introducing the GL2ES2 demo
|
|
|
|
|
*
|
|
|
|
|
* How to render a triangle using ~500 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 t0 = System.currentTimeMillis();
|
|
|
|
|
private double theta;
|
|
|
|
|
private double s;
|
|
|
|
|
|
|
|
|
|
private static int width=1920;
|
|
|
|
|
private static int height=1080;
|
|
|
|
|
|
|
|
|
|
private int shaderProgram;
|
|
|
|
|
private int vertShader;
|
|
|
|
|
private int fragShader;
|
|
|
|
|
private int ModelViewProjectionMatrix_location;
|
|
|
|
|
|
|
|
|
|
static final int COLOR_IDX = 0;
|
|
|
|
|
static final int VERTICES_IDX = 1;
|
|
|
|
|
int[] vboHandles;
|
|
|
|
|
|
|
|
|
|
public static void main(String[] s){
|
|
|
|
|
|
|
|
|
|
/* This demo are based on the GL2ES2 GLProfile that uses common hardware acceleration
|
|
|
|
|
* functionality of desktop OpenGL 3, 2 and mobile OpenGL ES 2 devices.
|
|
|
|
|
* JogAmp JOGL will probe all the installed libGL.so, libEGL.so and libGLESv2.so librarys on
|
|
|
|
|
* the system to find which one provide hardware acceleration for your GPU device.
|
|
|
|
|
* Its common to find more than one version of these librarys installed on a system.
|
|
|
|
|
* For example on a ARM Linux system JOGL may find
|
|
|
|
|
* Hardware accelerated Nvidia tegra GPU drivers in: /usr/lib/nvidia-tegra/libEGL.so
|
|
|
|
|
* Software rendered Mesa Gallium driver in: /usr/lib/arm-linux-gnueabi/mesa-egl/libEGL.so.1
|
|
|
|
|
* Software rendered Mesa X11 in: /usr/lib/arm-linux-gnueabi/mesa/libGL.so
|
|
|
|
|
* Good news!: JOGL does all this probing for you all you have to do are to ask for
|
|
|
|
|
* the GLProfile you want to use.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2ES2));
|
|
|
|
|
// We may at this point tweak the caps and request a translucent drawable
|
|
|
|
|
caps.setBackgroundOpaque(false);
|
|
|
|
|
GLWindow glWindow = GLWindow.create(caps);
|
|
|
|
|
|
|
|
|
|
/* You may combine the NEWT GLWindow inside existing Swing and AWT
|
|
|
|
|
* applications by encapsulating the glWindow inside a
|
|
|
|
|
* com.jogamp.newt.awt.NewtCanvasAWT canvas.
|
|
|
|
|
*
|
|
|
|
|
* NewtCanvasAWT newtCanvas = new NewtCanvasAWT(glWindow);
|
|
|
|
|
* JFrame frame = new JFrame("RAW GL2ES2 Demo inside a JFrame!");
|
|
|
|
|
* frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
|
|
|
|
* frame.setSize(width,height);
|
|
|
|
|
* 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);
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// In this demo we prefer to setup and view the GLWindow directly
|
|
|
|
|
// this allows the demo to run on -Djava.awt.headless=true systems
|
|
|
|
|
glWindow.setTitle("Raw GL2ES2 Demo");
|
|
|
|
|
glWindow.setSize(width,height);
|
|
|
|
|
glWindow.setUndecorated(false);
|
|
|
|
|
glWindow.setPointerVisible(true);
|
|
|
|
|
glWindow.setVisible(true);
|
|
|
|
|
|
|
|
|
|
// Finally we connect the GLEventListener application code to the NEWT GLWindow.
|
|
|
|
|
// GLWindow will call the GLEventListener init, reshape, display and dispose
|
|
|
|
|
// functions when needed.
|
|
|
|
|
glWindow.addGLEventListener(new RawGL2ES2demo() /* GLEventListener */);
|
|
|
|
|
Animator animator = new Animator();
|
|
|
|
|
animator.add(glWindow);
|
|
|
|
|
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));
|
|
|
|
|
|
|
|
|
|
/* The initialization below will use the OpenGL ES 2 API directly
|
|
|
|
|
* to setup the two shader programs that will be run on the GPU.
|
|
|
|
|
*
|
|
|
|
|
* Its recommended to use the jogamp/opengl/util/glsl/ classes
|
|
|
|
|
* import com.jogamp.opengl.util.glsl.ShaderCode;
|
|
|
|
|
* import com.jogamp.opengl.util.glsl.ShaderProgram;
|
|
|
|
|
* import com.jogamp.opengl.util.glsl.ShaderState;
|
|
|
|
|
* to simplify shader customization, compile and loading.
|
|
|
|
|
*
|
|
|
|
|
* You may also want to look at the JOGL RedSquareES2 demo
|
|
|
|
|
* 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
|
|
|
|
|
* to see how the shader customization, compile and loading is done
|
|
|
|
|
* using the recommended JogAmp GLSL utility classes.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// Make the shader strings compatible with OpenGL 3 core if needed
|
|
|
|
|
// GL2ES2 also includes the intersection of GL3 core
|
|
|
|
|
// The default implicit GLSL version 1.1 is now depricated in GL3 core
|
|
|
|
|
// GLSL 1.3 is the minimum version that now has to be explicitly set.
|
|
|
|
|
// This allows the shaders to compile using the latest
|
|
|
|
|
// desktop OpenGL 3 and 4 drivers.
|
|
|
|
|
if(gl.isGL3core()){
|
|
|
|
|
System.out.println("GL3 core detected: explicit add #version 130 to shaders");
|
|
|
|
|
vertexShaderString = "#version 130\n"+vertexShaderString;
|
|
|
|
|
fragmentShaderString = "#version 130\n"+fragmentShaderString;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create GPU shader handles
|
|
|
|
|
// 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[] { vertexShaderString };
|
|
|
|
|
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! vertex shader 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 vertex shader: " + new String(log));
|
|
|
|
|
System.exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Compile the fragmentShader String into a program.
|
|
|
|
|
String[] flines = new String[] { fragmentShaderString };
|
|
|
|
|
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! fragment shader 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 fragment shader: " + new String(log));
|
|
|
|
|
System.exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//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");
|
|
|
|
|
|
|
|
|
|
/* GL2ES2 also includes the intersection of GL3 core
|
|
|
|
|
* GL3 core and later mandates that a "Vector Buffer Object" must
|
|
|
|
|
* be created and bound before calls such as gl.glDrawArrays is used.
|
|
|
|
|
* The VBO lines in this demo makes the code forward compatible with
|
|
|
|
|
* OpenGL 3 and ES 3 core and later where a default
|
|
|
|
|
* vector buffer object is deprecated.
|
|
|
|
|
*
|
|
|
|
|
* Generate two VBO pointers / handles
|
|
|
|
|
* VBO is data buffers stored inside the graphics card memory.
|
|
|
|
|
*/
|
|
|
|
|
vboHandles = new int[2];
|
|
|
|
|
gl.glGenBuffers(2, vboHandles, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void reshape(GLAutoDrawable drawable, int x, int y, int z, int h) {
|
|
|
|
|
System.out.println("Window resized to width=" + z + " height=" + h);
|
|
|
|
|
width = z;
|
|
|
|
|
height = h;
|
|
|
|
|
|
|
|
|
|
// Get gl
|
|
|
|
|
GL2ES2 gl = drawable.getGL().getGL2ES2();
|
|
|
|
|
|
|
|
|
|
// Optional: Set viewport
|
|
|
|
|
// Render to a square at the center of the window.
|
|
|
|
|
gl.glViewport((width-height)/2,0,height,height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void display(GLAutoDrawable drawable) {
|
|
|
|
|
// Update variables used in animation
|
|
|
|
|
double t1 = System.currentTimeMillis();
|
|
|
|
|
theta += (t1-t0)*0.005f;
|
|
|
|
|
t0 = t1;
|
|
|
|
|
s = Math.sin(theta);
|
|
|
|
|
|
|
|
|
|
// Get gl
|
|
|
|
|
GL2ES2 gl = drawable.getGL().getGL2ES2();
|
|
|
|
|
|
|
|
|
|
// Clear screen
|
|
|
|
|
gl.glClearColor(1, 0, 1, 0.5f); // Purple
|
|
|
|
|
gl.glClear(GL2ES2.GL_STENCIL_BUFFER_BIT |
|
|
|
|
|
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,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
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Observe that the vertex data passed to glVertexAttribPointer must stay valid
|
|
|
|
|
// through the OpenGL rendering lifecycle.
|
|
|
|
|
// Therefore it is mandatory to allocate a NIO Direct buffer that stays pinned in memory
|
|
|
|
|
// and thus can not get moved by the java garbage collector.
|
|
|
|
|
// Also we need to keep a reference to the NIO Direct buffer around up untill
|
|
|
|
|
// we call glDisableVertexAttribArray first then will it be safe to garbage collect the memory.
|
|
|
|
|
// I will here use the com.jogamp.common.nio.Buffers to quicly wrap the array in a Direct NIO buffer.
|
|
|
|
|
FloatBuffer fbVertices = Buffers.newDirectFloatBuffer(vertices);
|
|
|
|
|
|
|
|
|
|
// Select the VBO, GPU memory data, to use for vertices
|
|
|
|
|
gl.glBindBuffer(GL2ES2.GL_ARRAY_BUFFER, vboHandles[VERTICES_IDX]);
|
|
|
|
|
|
|
|
|
|
// transfer data to VBO, this perform the copy of data from CPU -> GPU memory
|
|
|
|
|
int numBytes = vertices.length * 4;
|
|
|
|
|
gl.glBufferData(GL.GL_ARRAY_BUFFER, numBytes, fbVertices, GL.GL_STATIC_DRAW);
|
|
|
|
|
fbVertices = null; // It is OK to release CPU vertices memory after transfer to GPU
|
|
|
|
|
|
|
|
|
|
// Associate Vertex attribute 0 with the last bound VBO
|
|
|
|
|
gl.glVertexAttribPointer(0 /* the vertex attribute */, 3,
|
|
|
|
|
GL2ES2.GL_FLOAT, false /* normalized? */, 0 /* stride */,
|
|
|
|
|
0 /* The bound VBO data offset */);
|
|
|
|
|
|
|
|
|
|
// VBO
|
|
|
|
|
// gl.glBindBuffer(GL2ES2.GL_ARRAY_BUFFER, 0); // You can unbind the VBO after it have been associated using glVertexAttribPointer
|
|
|
|
|
|
|
|
|
|
gl.glEnableVertexAttribArray(0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float[] colors = { 1.0f, 0.0f, 0.0f, 1.0f, //Top color (red)
|
|
|
|
|
0.0f, 0.0f, 0.0f, 1.0f, //Bottom Left color (black)
|
|
|
|
|
1.0f, 1.0f, 0.0f, 0.9f //Bottom Right color (yellow) with 10% transparence
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
FloatBuffer fbColors = Buffers.newDirectFloatBuffer(colors);
|
|
|
|
|
|
|
|
|
|
// Select the VBO, GPU memory data, to use for colors
|
|
|
|
|
gl.glBindBuffer(GL2ES2.GL_ARRAY_BUFFER, vboHandles[COLOR_IDX]);
|
|
|
|
|
|
|
|
|
|
numBytes = colors.length * 4;
|
|
|
|
|
gl.glBufferData(GL.GL_ARRAY_BUFFER, numBytes, fbColors, GL.GL_STATIC_DRAW);
|
|
|
|
|
fbColors = null; // It is OK to release CPU color memory after transfer to GPU
|
|
|
|
|
|
|
|
|
|
// Associate Vertex attribute 1 with the last bound VBO
|
|
|
|
|
gl.glVertexAttribPointer(1 /* the vertex attribute */, 4 /* four possitions used for each vertex */,
|
|
|
|
|
GL2ES2.GL_FLOAT, false /* normalized? */, 0 /* stride */,
|
|
|
|
|
0 /* The bound VBO data offset */);
|
|
|
|
|
|
|
|
|
|
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.glDeleteBuffers(2, vboHandles, 0); // Release VBO, color and vertices, buffer GPU memory.
|
|
|
|
|
vboHandles = null;
|
|
|
|
|
gl.glDetachShader(shaderProgram, vertShader);
|
|
|
|
|
gl.glDeleteShader(vertShader);
|
|
|
|
|
gl.glDetachShader(shaderProgram, fragShader);
|
|
|
|
|
gl.glDeleteShader(fragShader);
|
|
|
|
|
gl.glDeleteProgram(shaderProgram);
|
|
|
|
|
System.exit(0);
|
|
|
|
|
}
|
|
|
|
|
}
|