PC's JOGL Blog

Learning the Java JOGL OpenGL Bindings

Wednesday, June 28, 2006

Simple Application

Step 1 - Create a frame



There are two types of OpenGL "windows" in JOGL, a GLCanvas and a GLJPanel. The GLJPanel is for use with the normal Java2D API while the GLCanvas is a high performace version. To create an OpenGL window first create a Frame and the simply add a GLCanvas to it.
Frame frame = new Frame("PBuffers") ;
GLCanvas canvas = new GLCanvas() ;
canvas.addGLEventListener(this);
frame.add(canvas);
frame.setSize(640, 480);

The application is notified of OpenGL events via 4 simple callbacks that are called following the registration of the GLEventListener listener via the canvas.addGLEventListener(this) call. It's easier to use the GLU functions with can be called from the GLU object.

Step 2 - Initilize the OpenGL context


The init() method is called when the windows is first created. The display() function is only called when the display needs to be repainted so the Animator class be used to update the display periodically.

public void init(GLAutoDrawable drawable) 
{
final GL gl = drawable.getGL();
gl.setSwapInterval(0);
animator = new Animator(canvas);
animator.setRunAsFastAsPossible(true) ;
animator.start() ;
}

Step 3 - Add a display callback


The display() method is called when the window needs to be updated and is where all the OpenGL drawing should take place.

public void display(GLAutoDrawable drawable) 
{
GL gl = drawable.getGL() ;
}

Step 4 - Add a reshape callback


The reshape() method is called when the window size changes. This callback is called once when the application is started.

public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) 
{
GL gl = drawable.getGL();
float h = (float) width / (float) height;
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective( 40.0, h, 1.00, 100.0 );
}

Step 5 - Add a displayChanged callback


The displayChanged() method is called then the display is changed.

public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) 
{
}

Notes:

  • If the GLUT objects appear to be rendered back to front (or inside out) then try gl.glEnable(GL.GL_CW) as GLUT polygons are rendered in clock-wise order.

  • Setup light sources with all options as LIGHT0 has defaults that the others lights do not appear to have.

    gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, light2pos, 0);
    gl.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, light2amb, 0);
    gl.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, light2diff, 0);
    gl.glLightfv(GL.GL_LIGHT1, GL.GL_SPECULAR, light2spec, 0);
    gl.glEnable(GL.GL_LIGHT1);


Friday, June 23, 2006

What happened to my frame rate!


Ok, I don't mean to boast, but I do have a pretty good graphics card… it’s a NVidia 6800. My PC is no slouch either, and I’ve got plenty of memory, so when I started up the gears.java demo I was expecting a pretty high frame. However, it just didn’t look right. I added some code to the display() function (which gets called to display each frame) and I was getting 60FPS... Hold the phone!!!!
if(nFrame++ > 200) {
if(nLastUpdate != 0) {
long nTimeMS = System.currentTimeMillis() - nLastUpdate ;
System.out.println(nFrame + " in " + nTimeMS + "msec (" +
nFrame * 1000 / nTimeMS + " FPS)") ;
}
nFrame = 0 ;
nLastUpdate = System.currentTimeMillis() ;
}

60FPS…um… that is my monitor refresh rate (I’ve got an LCD). Ahhh, now I remember… Vertical retrace! To stop frames from tearing while being display most OpenGL implementations pause and wait for the monitors Vertical Retrace Interrupt before updating the image. Usually, it’s a pain to turn this off in OpenGL but in JOGL it’s easy. If you want to pull the maximum frame rate just set the "swap interval" to 0 in the init() function.

public void init(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
gl.setSwapInterval(0);

}

1100 FPS … That’s better, now that’s what I like to see!

Development Environment

I use Eclipse for all my Java development. In fact which all it's difference plugins Eclipse is pretty a pretty good development environment for most things, I also use it for PHP, ASP and C/C++ on Linux. I found the following website by Martin John Baker that does a good job of describing the setting up of the Eclipse IDE enviroment for JOGL. Basically, for setting up a simple Java JOGL Application
  1. Download the "jogl.jar" and the platform native libraries like "jogl-natives-macosx-universal.jar".
  2. Create a new Java project.
  3. In "project | Properties | Java Build Path" add the "jogl.jar" library.
  4. Then the tricky bit, add the native libraries. They come is a "jar" from the JOGL website so you may have to extract the DLL's (so's for linux, etc) from the JAR and place them in a new directory. Then just add the path as described in the Martin's web page. i.e. Select the "Native library location" and set it to the location of your DLL's.



  5. Add some code. I used the "gears.java" class from the demos that come with JOGL.

Thursday, June 22, 2006

Links

Useful links for developing JOGL application.

Introduction

After years of writing OpenGL applications in C or C++ I have finally decided to try my hand at one of the many Java OpenGL API's. I have been programming in Java for many years, but I never really thought about using it for OpenGL, as I always thought it would be too slow. One of my mates at work was using LWJGL to do some stuff and I was pretty impressed by what he could do using Java, so I thought it's about time to give it a go.

I have decided to try JOGL for a number of reasons, but mainly because it seems to have better support for OpenGL 2.0 and all those neat OpenGL extensions that make modern 3D graphics look so good and seems to have a bit better Java community support. I could be wring, that's what I'm here to find out. So, I have set up this Blog to record my notes and programs, however, my hope is that you (yes YOU!) may also find this useful or even be able to help me out with suggestions or your experience. Anyway, we'll see how I go...