Sunday, September 14, 2008

OpenGL with Java

Q: I want to fool around with OpenGL using Java... what do I do?

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 get started with JOGL, go to the JOGL home page and check out the downloads section. From there you can grab the latest stable release.

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()");
}
}

Saturday, September 6, 2008

First Post

Welcome to my blog! More to come...