A: Since the OpenGL API is written in C, you'll need to choose a Java wrapper. A good place to start is JOGL -- the Java OpenGL project.
- JOGL is presently the most popular wrapper, as it is the reference implementation for JSR 231 ("Java Binding for the OpenGL API").
- JOGL translates the OpenGL API in a direct way and is not hidden behind a convensional object oriented paradigm.
- From an programming standpoint, this is a huge win because it makes code written with JOGL visually similar to code written with the C API.
- This is good because it keeps the API light nimble (which is what a graphics API should be).
- Most importantly, the code examples in the Red Book easily are translatable to JOGL.
To use JOGL, simply include the jogl.jar and gluegen-rt.jar files in your Java project.
Below is a simple JOGL example inspired by first.c in the Red Book.
package com.jason.gl.first;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.media.opengl.GLCanvas;
public class First {
public static void main(String[] args) {
Frame frame = createFrame();
frame.setVisible(true);
}
private static Frame createFrame() {
Frame frame = new Frame("First OpenGL");
frame.setSize(600, 350);
frame.setLocation(200, 100);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.add(createCanvas());
return frame;
}
private static GLCanvas createCanvas() {
GLCanvas canvas = new GLCanvas();
canvas.addGLEventListener(new FirstRenderer());
return canvas;
}
}
package com.jason.gl.first;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
public class FirstRenderer implements GLEventListener {
@Override
public void init(GLAutoDrawable drawable) {
final long START_NS = System.nanoTime();
final GL gl = drawable.getGL();
System.out.println("Version Information");
System.out.println(" " + gl.glGetString(GL.GL_VERSION));
/* select clearing color */
gl.glClearColor(0f, 0f, 0f, 0f);
/* initialize viewing values */
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
final long END_NS = System.nanoTime();
System.out.println(String.format("init finished in %.2f ms",
((END_NS - START_NS) / 1000000d)));
}
@Override
public void display(GLAutoDrawable drawable) {
final long START_NS = System.nanoTime();
final GL gl = drawable.getGL();
/* clear all pixels */
gl.glClear(GL.GL_COLOR_BUFFER_BIT);
/*
* draw white polygon (rectangle) with corners at (0.25, 0.25, 0.0) and
* (0.75, 0.75, 0.0)
*/
gl.glColor3f(1.0f, 1.0f, 1.0f);
gl.glBegin(GL.GL_POLYGON);
gl.glVertex3f(0.25f, 0.25f, 0.0f);
gl.glVertex3f(0.75f, 0.25f, 0.0f);
gl.glVertex3f(0.75f, 0.75f, 0.0f);
gl.glVertex3f(0.25f, 0.75f, 0.0f);
gl.glEnd();
/*
* don't wait! start processing buffered OpenGL routines
*/
gl.glFlush();
final long END_NS = System.nanoTime();
System.out.println(String.format("display finished in %.2f ms",
((END_NS - START_NS) / 1000000d)));
}
@Override
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged,
boolean deviceChanged) {
System.out.println("displayChanged()");
}
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width,
int height) {
System.out.println("reshape()");
}
}
