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

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