Skip to content

Instantly share code, notes, and snippets.

@xranby
Forked from anonymous/gist:11134970
Last active August 29, 2015 14:05
Show Gist options
  • Save xranby/42ffcd1d4298356dd177 to your computer and use it in GitHub Desktop.
Save xranby/42ffcd1d4298356dd177 to your computer and use it in GitHub Desktop.
wget http://jogamp.org/deployment/jogamp-current/archive/jogamp-all-platforms.7z
7z x jogamp-all-platforms.7z
wget https://gist.github.com/xranby/42ffcd1d4298356dd177/raw/aca00bd10252496a3c772914ede5a54cad0ed2f7/TextRendering.java
javac -cp ./jogamp-all-platforms/jar/gluegen-rt.jar:./jogamp-all-platforms/jar/jogl-all.jar:. TextRendering.java
java -cp ./jogamp-all-platforms/jar/gluegen-rt.jar:./jogamp-all-platforms/jar/jogl-all.jar:. TextRendering
import java.io.IOException;
import javax.media.opengl.GL4ES3;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
import com.jogamp.graph.curve.opengl.RegionRenderer;
import com.jogamp.graph.curve.opengl.RenderState;
import com.jogamp.graph.curve.opengl.TextRegionUtil;
import com.jogamp.graph.font.Font;
import com.jogamp.graph.font.FontFactory;
import com.jogamp.graph.geom.SVertex;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.math.geom.AABBox;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.PMVMatrix;
public class TextRendering implements GLEventListener{
private RenderState renderState;
private RegionRenderer renderer;
private TextRegionUtil textRenderUtil;
private Font font;
private int texSize[] = new int[] { 0 };
private String fps;
@Override
public void init(GLAutoDrawable drawable) {
GL4ES3 gl = drawable.getGL().getGL4ES3();
try {
font = FontFactory.get(FontFactory.UBUNTU).getDefault();
} catch (IOException e) {
e.printStackTrace();
}
renderState = RenderState.createRenderState(SVertex.factory());
renderer = RegionRenderer.create(renderState, RegionRenderer.defaultBlendEnable, RegionRenderer.defaultBlendDisable);
renderState.setHintMask(RenderState.BITHINT_BLENDING_ENABLED);
textRenderUtil = new TextRegionUtil(0);
gl.glClearColor(1f, 1f, 1f, 1f);
renderer.init(gl, 0);
renderer.reshapeOrtho(drawable.getSurfaceWidth(), drawable.getSurfaceHeight(), 0.1f, 1000f);
}
@Override
public void display(GLAutoDrawable drawable) {
GL4ES3 gl = drawable.getGL().getGL4ES3();
gl.glClear(GL4ES3.GL_COLOR_BUFFER_BIT | GL4ES3.GL_DEPTH_BUFFER_BIT);
renderState.attachTo(gl);
String text = "Hello World!";
int fontSize = 28;
AABBox textBox = font.getMetricBounds(text, fontSize);
float x = (drawable.getSurfaceWidth() - textBox.getWidth())/2;
float y = (drawable.getSurfaceHeight() - textBox.getHeight())/2;
float z = -1000f;
float position[] = new float[]{ x, y, z };
float color[] = new float[] { 0f, 1f, 0f, 1f};
renderString(gl, text, fontSize, color, position);
fps = Float.toString(drawable.getAnimator().getLastFPS());
AABBox fpsBox = font.getMetricBounds(fps, fontSize);
x = 0f;
y = (drawable.getSurfaceHeight() - fpsBox.getHeight());
z = -1000f;
position = new float[] { x, y, z };
color = new float[] { 1f, 0f, 0f, 1f };
renderString(gl, fps, fontSize, color, position);
renderState.detachFrom(gl);
}
private void renderString(GL4ES3 gl, String text, int fontSize, float color[], float position[]){
final PMVMatrix pmv = renderer.getMatrix();
pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
pmv.glLoadIdentity();
pmv.glTranslatef(position[0], position[1], position[2]);
renderState.setColorStatic(color[0], color[1], color[2], color[3]);
textRenderUtil.drawString3D(gl, renderer, font, fontSize, text, null, texSize);
}
@Override
public void dispose(GLAutoDrawable drawable) {
GL4ES3 gl = drawable.getGL().getGL4ES3();
renderer.destroy(gl);
}
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width,
int height) {
renderer.reshapeOrtho(drawable.getSurfaceWidth(), drawable.getSurfaceHeight(), 0.1f, 1000f);
}
public static void main(String args[]){
final GLProfile glp = GLProfile.get(GLProfile.GLES3);
final GLCapabilities caps = new GLCapabilities(glp);
caps.setSampleBuffers(true);
caps.setNumSamples(4);
final GLWindow glWindow = GLWindow.create(caps);
final Animator animator = new Animator(glWindow);
animator.setUpdateFPSFrames(1, null);
glWindow.addWindowListener(new WindowAdapter() {
@Override
public void windowDestroyNotify(WindowEvent arg0) {
new Thread() {
@Override
public void run() {
if (animator.isStarted())
animator.stop();
System.exit(0);
}
}.start();
}
});
glWindow.addGLEventListener(new TextRendering());
glWindow.setSize(800, 400);
glWindow.setVisible(true);
animator.start();
}
}
/* dedicated to @jan_ekholm */
/* renders an OpenGL ES 2 triangle using direct OpenGL calls without any specific API
then adds some JogAmp curve text using the graph API on top
wget https://gist.github.com/xranby/42ffcd1d4298356dd177/raw/ad26a8eaeb29c31d496eb0c2bf7ea8583edc1aa1/TriangleTextRendering.java
javac -cp ./jogamp-all-platforms/jar/gluegen-rt.jar:./jogamp-all-platforms/jar/jogl-all.jar:. TriangleTextRendering.java
java -Djogl.debug.DebugGL -cp ./jogamp-all-platforms/jar/gluegen-rt.jar:./jogamp-all-platforms/jar/jogl-all.jar:. TriangleTextRendering
*/
import java.io.IOException;
import javax.media.opengl.GL2ES2;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
import com.jogamp.graph.curve.opengl.RegionRenderer;
import com.jogamp.graph.curve.opengl.RenderState;
import com.jogamp.graph.curve.opengl.TextRegionUtil;
import com.jogamp.graph.font.Font;
import com.jogamp.graph.font.FontFactory;
import com.jogamp.graph.geom.SVertex;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.math.geom.AABBox;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.opengl.util.*;
import com.jogamp.common.nio.Buffers;
import java.nio.FloatBuffer;
public class TriangleTextRendering implements GLEventListener{
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" +
"} ";
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;
int[] vboHandles;
private int vboVertices, vboColors;
/* 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);
}
private RenderState renderState;
private RegionRenderer renderer;
private TextRegionUtil textRenderUtil;
private Font font;
private int texSize[] = new int[] { 0 };
private String fps;
@Override
public void init(GLAutoDrawable drawable) {
GL2ES2 gl = drawable.getGL().getGL2ES2();
try {
font = FontFactory.get(FontFactory.UBUNTU).getDefault();
} catch (IOException e) {
e.printStackTrace();
}
renderState = RenderState.createRenderState(SVertex.factory());
renderer = RegionRenderer.create(renderState, RegionRenderer.defaultBlendEnable, RegionRenderer.defaultBlendDisable);
renderState.setHintMask(RenderState.BITHINT_BLENDING_ENABLED);
textRenderUtil = new TextRegionUtil(0);
gl.glClearColor(1f, 1f, 1f, 1f);
renderer.init(gl, 0);
renderer.reshapeOrtho(drawable.getSurfaceWidth(), drawable.getSurfaceHeight(), 0.1f, 1000f);
// 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);
vboColors = vboHandles[0];
vboVertices = vboHandles[1];
}
@Override
public void display(GLAutoDrawable drawable) {
GL2ES2 gl = drawable.getGL().getGL2ES2();
gl.glClear(GL2ES2.GL_COLOR_BUFFER_BIT | GL2ES2.GL_DEPTH_BUFFER_BIT);
// Update variables used in animation
double t1 = System.currentTimeMillis();
theta += (t1-t0)*0.005f;
t0 = t1;
s = Math.sin(theta);
// 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
};
// 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, vboVertices);
// 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, vboColors);
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
gl.glDeleteBuffers(2, vboHandles, 0); // Release VBO, color and vertices, buffer GPU memory.
// Render Hello World on top
String text = "Hello World!";
int fontSize = 28;
AABBox textBox = font.getMetricBounds(text, fontSize);
float x = (drawable.getSurfaceWidth() - textBox.getWidth())/2;
float y = (drawable.getSurfaceHeight() - textBox.getHeight())/2;
float z = -1000f;
float position[] = new float[]{ x, y, z };
float color[] = new float[] { 0f, 1f, 0f, 1f};
renderString(gl, text, fontSize, color, position);
fps = Float.toString(drawable.getAnimator().getLastFPS());
AABBox fpsBox = font.getMetricBounds(fps, fontSize);
x = 0f;
y = (drawable.getSurfaceHeight() - fpsBox.getHeight());
z = -1000f;
position = new float[] { x, y, z };
color = new float[] { 1f, 0f, 0f, 1f };
renderString(gl, fps, fontSize, color, position);
renderer.enable(gl,false); // <---- this line makes it work
}
private void renderString(GL2ES2 gl, String text, int fontSize, float color[], float position[]){
final PMVMatrix pmv = renderer.getMatrix();
pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
pmv.glLoadIdentity();
pmv.glTranslatef(position[0], position[1], position[2]);
renderState.setColorStatic(color[0], color[1], color[2], color[3]);
textRenderUtil.drawString3D(gl, renderer, font, fontSize, text, null, texSize);
}
@Override
public void dispose(GLAutoDrawable drawable) {
GL2ES2 gl = drawable.getGL().getGL2ES2();
renderer.destroy(gl);
}
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width,
int height) {
renderer.reshapeOrtho(drawable.getSurfaceWidth(), drawable.getSurfaceHeight(), 0.1f, 1000f);
}
public static void main(String args[]){
final GLProfile glp = GLProfile.get(GLProfile.GLES3);
final GLCapabilities caps = new GLCapabilities(glp);
caps.setSampleBuffers(true);
caps.setNumSamples(4);
final GLWindow glWindow = GLWindow.create(caps);
final Animator animator = new Animator(glWindow);
animator.setUpdateFPSFrames(1, null);
glWindow.addWindowListener(new WindowAdapter() {
@Override
public void windowDestroyNotify(WindowEvent arg0) {
new Thread() {
@Override
public void run() {
if (animator.isStarted())
animator.stop();
System.exit(0);
}
}.start();
}
});
glWindow.addGLEventListener(new TriangleTextRendering());
glWindow.setSize(800, 400);
glWindow.setVisible(true);
animator.start();
}
}
@jan-ekholm
Copy link

When used as-is that test works perfectly with JOGL 2.2.0. When used together with other state and shaders I get a:

Exception in thread "main-Display-.macosx_nil-1-EDT-1-AWTAnimator" com.jogamp.opengl.util.AnimatorBase$UncaughtAnimatorException: javax.media.opengl.GLException: Caught GLException: Thread[main-Display-.macosx_nil-1-EDT-1-AWTAnimator,5,main] glGetError() returned the following error codes after a call to glUniform(<javax.media.opengl.GLUniformData> GLUniformData[name gcu_PMVMatrix01, location 0, size 4x4, count 2, data
0: [ 0,00333 0,00000 0,00000 -1,00000 ]
0: [ 0,00000 0,00333 0,00000 -1,00000 ]
0: [ 0,00000 0,00000 -0,00200 -1,00020 ]
0: [ 0,00000 0,00000 0,00000 1,00000 ]
,
1: [ 1,00000 0,00000 0,00000 209,44434 ]
1: [ 0,00000 1,00000 0,00000 283,70313 ]
1: [ 0,00000 0,00000 1,00000 -1000,00000 ]
1: [ 0,00000 0,00000 0,00000 1,00000 ]
,
]): GL_INVALID_OPERATION ( 1282 0x502), on thread main-Display-.macosx_nil-1-EDT-1-AWTAnimator
at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:84)
at com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:446)
at com.jogamp.opengl.util.Animator$MainLoop.run(Animator.java:198)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.media.opengl.GLException: Caught GLException: Thread[main-Display-.macosx_nil-1-EDT-1-AWTAnimator,5,main] glGetError() returned the following error codes after a call to glUniform(<javax.media.opengl.GLUniformData> GLUniformData[name gcu_PMVMatrix01, location 0, size 4x4, count 2, data
0: [ 0,00333 0,00000 0,00000 -1,00000 ]
0: [ 0,00000 0,00333 0,00000 -1,00000 ]
0: [ 0,00000 0,00000 -0,00200 -1,00020 ]
0: [ 0,00000 0,00000 0,00000 1,00000 ]
,
1: [ 1,00000 0,00000 0,00000 209,44434 ]
1: [ 0,00000 1,00000 0,00000 283,70313 ]
1: [ 0,00000 0,00000 1,00000 -1000,00000 ]
1: [ 0,00000 0,00000 0,00000 1,00000 ]
,
]): GL_INVALID_OPERATION ( 1282 0x502), on thread main-Display-.macosx_nil-1-EDT-1-AWTAnimator
at javax.media.opengl.GLException.newGLException(GLException.java:75)
at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1318)
at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1138)
at com.jogamp.newt.opengl.GLWindow.display(GLWindow.java:666)
at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:77)
... 3 more
Caused by: javax.media.opengl.GLException: Thread[main-Display-.macosx_nil-1-EDT-1-AWTAnimator,5,main] glGetError() returned the following error codes after a call to glUniform(<javax.media.opengl.GLUniformData> GLUniformData[name gcu_PMVMatrix01, location 0, size 4x4, count 2, data
0: [ 0,00333 0,00000 0,00000 -1,00000 ]
0: [ 0,00000 0,00333 0,00000 -1,00000 ]
0: [ 0,00000 0,00000 -0,00200 -1,00020 ]
0: [ 0,00000 0,00000 0,00000 1,00000 ]
,
1: [ 1,00000 0,00000 0,00000 209,44434 ]
1: [ 0,00000 1,00000 0,00000 283,70313 ]
1: [ 0,00000 0,00000 1,00000 -1000,00000 ]
1: [ 0,00000 0,00000 0,00000 1,00000 ]
,
]): GL_INVALID_OPERATION ( 1282 0x502),
at javax.media.opengl.DebugGL4bc.writeGLError(DebugGL4bc.java:29466)
at javax.media.opengl.DebugGL4bc.glUniform(DebugGL4bc.java:22451)
at com.jogamp.graph.curve.opengl.RenderState.updateUniformDataLoc(RenderState.java:292)
at com.jogamp.graph.curve.opengl.RenderState$ProgramLocal.update(RenderState.java:154)
at jogamp.graph.curve.opengl.VBORegionSPES2.useShaderProgram(VBORegionSPES2.java:208)
at jogamp.graph.curve.opengl.VBORegionSPES2.drawImpl(VBORegionSPES2.java:219)
at com.jogamp.graph.curve.opengl.GLRegion.draw(GLRegion.java:144)
at com.jogamp.graph.curve.opengl.TextRegionUtil.drawString3D(TextRegionUtil.java:185)
....

It would seem that the code assumes that the matrix uniform has location 0? I've loaded other shaders at this point and it should probably be something else and queried at runtime.

@jan-ekholm
Copy link

Running the updated sample on a desktop does not work too well either.

Changed the profile to GL4 and the shaders to 330, otherwise they would not compile.

    final GLProfile glp = GLProfile.get(GLProfile.GL4);

...
if(gl.isGL3core()){
System.out.println("GL3 core detected: explicit add #version 130 to shaders");
vertexShaderString = "#version 330 core\n"+vertexShaderString;
fragmentShaderString = "#version 330 core\n"+fragmentShaderString;
}

Running gives:

% java -Djogl.debug.DebugGL -cp ./jogamp-all-platforms/jar/gluegen-rt.jar:./jogamp-all-platforms/jar/jogl-all.jar:. TriangleTextRendering
GL3 core detected: explicit add #version 130 to shaders
Horray! vertex shader compiled
Horray! fragment shader compiled
Exception in thread "main-AWTAnimator" com.jogamp.opengl.util.AnimatorBase$UncaughtAnimatorException: javax.media.opengl.GLException: Caught GLException: Thread[main-AWTAnimator,5,main] glGetError() returned the following error codes after a call to glBindBuffer( 0x8892, 0x1): GL_INVALID_OPERATION ( 1282 0x502), on thread main-AWTAnimator
at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:84)
at com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:446)
at com.jogamp.opengl.util.Animator$MainLoop.run(Animator.java:198)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.media.opengl.GLException: Caught GLException: Thread[main-AWTAnimator,5,main] glGetError() returned the following error codes after a call to glBindBuffer( 0x8892, 0x1): GL_INVALID_OPERATION ( 1282 0x502), on thread main-AWTAnimator
at javax.media.opengl.GLException.newGLException(GLException.java:75)
at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1318)
at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1138)
at com.jogamp.newt.opengl.GLWindow.display(GLWindow.java:666)
at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:77)
... 3 more
Caused by: javax.media.opengl.GLException: Thread[main-AWTAnimator,5,main] glGetError() returned the following error codes after a call to glBindBuffer( 0x8892, 0x1): GL_INVALID_OPERATION ( 1282 0x502),
at javax.media.opengl.DebugGL4bc.writeGLError(DebugGL4bc.java:29466)
at javax.media.opengl.DebugGL4bc.glBindBuffer(DebugGL4bc.java:452)
at jogamp.opengl.util.glsl.GLSLArrayHandler.enableSimple(GLSLArrayHandler.java:157)
at jogamp.opengl.util.glsl.GLSLArrayHandler.enableState(GLSLArrayHandler.java:68)
at com.jogamp.opengl.util.GLArrayDataClient.enableBuffer(GLArrayDataClient.java:210)
at jogamp.graph.curve.opengl.VBORegionSPES2.drawImpl(VBORegionSPES2.java:227)
at com.jogamp.graph.curve.opengl.GLRegion.draw(GLRegion.java:144)
at com.jogamp.graph.curve.opengl.TextRegionUtil.drawString3D(TextRegionUtil.java:185)
at TriangleTextRendering.renderString(TriangleTextRendering.java:449)
at TriangleTextRendering.display(TriangleTextRendering.java:427)
at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:689)
at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:671)
at jogamp.opengl.GLAutoDrawableBase$2.run(GLAutoDrawableBase.java:441)
at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1284)
... 6 more

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment