java left logo
java middle logo
java right logo
 

Home arrow Other API Tips
 
 
Main Menu
Home
Java Tutorials
Book Reviews
Java SE Tips
Java ME Tips
Java EE Tips
Other API Tips
Java Applications
Java Libraries
Java Games
Java Network
Java Forums
Java Blog




Most Visited Tips
Java SE Tips
Java ME Tips
Java EE Tips
Other API Tips
Java Applications
Java Libraries
Java Games
Book Reviews
Top Rated Tips
Java SE Tips
Java ME Tips
Java EE Tips
Other API Tips
Java Applications
Java Libraries
Java Games
Book Reviews


Statistics
Registered Users: 4090
Java SE Tips: 614
Java ME Tips: 202
Java EE Tips: 183
Other API Tips: 779
Java Applications: 298
Java Libraries: 209
Java Games: 16
Book Reviews:
 
 
 
Introduction to JOGL E-mail
User Rating: / 17
PoorBest 

This Tech Tip reprinted with permission by java.sun.com

As it's name implies, JOGL, the Java APIs for OpenGL, is a Java programming language binding for the OpenGL 3D graphics API. JOGL is designed to provide hardware-supported 3D graphics to applications written in Java technology. This tip will show you how to use JOGL to include basic two-dimensional and three-dimensional graphics in an application. JOGL is available under the Berkeley Software Distribution (BSD) license on java.net. Because JOGL is a light Java wrapper around the standard OpenGL API, the examples and text in this tip, for the most part, don't cover basic information on OpenGL.

To install JOGL, download the latest version from the jogl documents and files page. You'll find various release builds on the page. This tip was tested against the November 19, 2004 1.1b07 release build. You will need to download and install two sets of files. The article, Jumping into JOGL by Chris Adamson describes what files you need to download and where to put them on your machine. Note that the platform-specific files are in a jar file. You'll need to expand the jar file, and then put the platform-specific files in a directory where your runtime can find them.

After you install JOGL, you can use it to provide an application with hardware-accelerated 3D graphics. Let's start with an application that uses JOGL to display a red square that spins in the center of a black region. The example program, JOGLRotatingSquare, is shown later in this tip. The Constructor for JOGLRotatingSquare outlines the steps that are taken to set up the application:

   JOGLRotatingSquare() {
     GLCanvas canvas = getGLCanvas();
     canvas.addGLEventListener(new RotatingSquareListener());
     Animator anim = new Animator(canvas);
     addCanvasToFrame(canvas);
     anim.start();
    }

The example begins by obtaining an object of type GLCanvas through the getGLCanvas() method. It then creates and attaches a GLEventListener to the object. Then it creates an Animator object that does the animation for the scene, adds the GLCanvas object to the frame, and finally starts the animation.

The getGLCanvas() method starts by configuring a GLCapabilities object, an object that specifies the OpenGL capabilities that the rendering context must support. For example, here is how you would request that hardware acceleration be supported in the rendering context:

   GLCapabilities capabilities = new GLCapabilities();
   capabilities.setHardwareAccelerated(true);

Then the method passes the GLCapabilities object into a factory to obtain a GLCanvas. GLCanvas implements the GLDrawable interface, an interface that provides OpenGL rendering support. The GLCanvas object is used to render the scene:

   private GLCanvas getGLCanvas() {
     GLCapabilities capabilities = new GLCapabilities();
     return GLDrawableFactory.getFactory().
                           createGLCanvas(capabilities);
   }

The GLEventListener performs most of the work. In JOGLRotatingSquare, the listener is implemented as an inner class. The listener must implement the methods init(), display(), displayChanged(), and reshape().

The init() method is called by the drawable immediately after the OpenGL context is initialized for the first time. The init() method is where you do your basic environment set up. For example, you can set up the erasing and drawing color. In the JOGLRotatingSquare example, erasing and drawing color are both initially set to black:

    public void init(GLDrawable drawable) {
      GL gl = drawable.getGL();
      gl.glClearColor(0.0f0.0f0.0f1.0f)//erasing color
      gl.glColor3f(0.0f0.0f0.0f)// drawing color
    }

The displayChanged() method is called with the display mode or display device changes. In the JOGLRotatingSquare example, the displayChanged() method body is empty:

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

The reshape() method is called during the first repaint after the component is resized. This includes the first time the component appears on the screen. In the JOGLRotatingSquare example, the reshape() method is used to set GLCanvas to fit the viewable area and to recenter the square if the Frame is resized:

   public class VarGreeter3 {
   public void reshape(GLDrawable drawable,
                        int x,
                        int y,
                        int width,
                        int height) {
      GL gl = drawable.getGL();
      gl.glViewport(00, width, height);
      gl.glMatrixMode(GL.GL_PROJECTION);
      gl.glLoadIdentity();
      gl.glOrtho(-width, width, -height, height, -11);
    }

The display() method is called to initiate the OpenGL rendering. It is also the method called by the Animator object to update the display.

In the JOGLRotatingSquare program, the display() method clears the screen, redraws the square, and performs a rotation equal to the current value of angle. This rotates the square quickly in a counter clockwise direction.

   public void display(GLDrawable drawable) {
      GL gl = drawable.getGL();
      gl.glClear(GL.GL_COLOR_BUFFER_BIT);
      drawRedCenteredSquare(gl);
      angle++;
      gl.glMatrixMode(GL.GL_MODELVIEW);
      gl.glLoadIdentity();
      gl.glRotatef(angle, 001);
    }

The parameters to the glRotatef() method are an angle and three other floats that indicate the axis on which the rotation takes place. In this example, the rotation is about the z-axis. This is equivalent to a counter-clockwise rotation in the x-y plane.

Here is the entire code listing for JOGLRotatingSquare:

   import net.java.games.jogl.GLCanvas;
   import net.java.games.jogl.GLCapabilities;
   import net.java.games.jogl.GLDrawableFactory;
   import net.java.games.jogl.Animator;
   import net.java.games.jogl.GL;
   import net.java.games.jogl.GLEventListener;
   import net.java.games.jogl.GLDrawable;
   
   import java.awt.Frame;
   import java.awt.event.WindowAdapter;
   import java.awt.event.WindowEvent;
   
   public class JOGLRotatingSquare {
   
     private static float angle = 0;
     private static final int SIZE = 160;
   
     JOGLRotatingSquare() {
       GLCanvas canvas = getGLCanvas();
       canvas.addGLEventListener(new RotatingSquareListener());
       Animator anim = new Animator(canvas);
       addCanvasToFrame(canvas, anim);
       anim.start();
     }
   
     private void addCanvasToFrame(
      GLCanvas canvas, final Animator anim) {
       Frame f = new Frame("JOGL Rotating Square");
       f.setSize(600400);
       f.add(canvas);
       f.setVisible(true);
       f.addWindowListener(new WindowAdapter() {
           public void windowClosing(WindowEvent e) {
             anim.stop();
             System.exit(0);
           }
         });
     }
   
     private GLCanvas getGLCanvas() {
       GLCapabilities capabilities = new GLCapabilities();
       return GLDrawableFactory.getFactory().
                             createGLCanvas(capabilities);
     }
 

     public static void main(String[] args) {
       new JOGLRotatingSquare();
     }
 
     private void drawRedCenteredSquare(GL gl) {
       gl.glColor3f(100);
       gl.glRecti(-SIZE / 2, -SIZE / 2, SIZE / 2, SIZE / 2);
       gl.glColor3f(0.0f0.0f0.0f);
     }
   
     class RotatingSquareListener implements GLEventListener {
   
       public void init(GLDrawable drawable) {
         GL gl = drawable.getGL();
         gl.glClearColor(0.0f0.0f0.0f1.0f)//erasing color
         gl.glColor3f(0.0f0.0f0.0f)// drawing color
       }
   
       public void display(GLDrawable drawable) {
         GL gl = drawable.getGL();
         gl.glClear(GL.GL_COLOR_BUFFER_BIT);
         drawRedCenteredSquare(gl);
         angle++;
         gl.glMatrixMode(GL.GL_MODELVIEW);
         gl.glLoadIdentity();
         gl.glRotatef(angle, 001);
       }
   
       public void reshape(GLDrawable drawable,
                           int x,
                           int y,
                           int width,
                           int height) {
         GL gl = drawable.getGL();
         gl.glViewport(00, width, height);
         gl.glMatrixMode(GL.GL_PROJECTION);
         gl.glLoadIdentity();
         gl.glOrtho(-width, width, -height, height, -11);
       }
   
       public void displayChanged(GLDrawable drawable,
                                  boolean modeChanged,
                                  boolean deviceChanged) {
       }
     }
   }

Compile and run JOGLRotatingSquare. You should see a red square that spins in the center of a black region.

jogl

If you increase the size of the Frame, the square will recenter and the animation will slow. You can also slow the animation further by replacing the last line of the display() method with the line

   gl.glRotatef(angle/16001);

You can experiment with values other than 16.

The method drawRedCenteredSquare() uses one of the family of specific methods for drawing a rectangle. It first specifies that the current color is red. It then draws a rectangle centered at the origin with sides of length equal to SIZE. Finally, it resets the current color to black:

   private void drawRedCenteredSquare(GL gl) {
     gl.glColor3f(100);
     gl.glRecti(-SIZE / 2, -SIZE / 2, SIZE / 2, SIZE / 2);
     gl.glColor3f(0.0f0.0f0.0f);
   }

This works because the square is drawn in the x-y plane. In other words, the method ignores the third dimension. Another way to draw the rectangle is as follows:

   private static void drawRedCenteredSquare(GL gl) {
       gl.glColor3f(100);
       gl.glBegin(GL.GL_QUADS);
       gl.glTexCoord2f(00);
       gl.glVertex3f(-SIZE / 2, SIZE / 20);
       gl.glTexCoord2f(01);
       gl.glVertex3f(-SIZE / 2, -SIZE / 20);
       gl.glTexCoord2f(11);
       gl.glVertex3f(SIZE / 2, -SIZE / 20);
       gl.glTexCoord2f(10);
       gl.glVertex3f(SIZE / 2, SIZE / 20);
       gl.glEnd();
       gl.glColor3f(0.0f0.0f0.0f);
     }

Here the four vertices of a square are explicitly set. This approach seems a bit more verbose than the previous approach, but it will be useful in the next example (which moves from two to three dimensions). There is not much more work to be done in three dimensions than there was in two. First, you need to change the last line of the reshape() method so that the visible range in the z direction is increased to include the entire cube. If you omit this step, you will only see the horizontal slice of the cube that is within one unit of the x-y plane. Here is the revised line:

   gl.glOrtho(-width, width, -height, height, -SIZE, SIZE);

Next, change the end of the display() method to tilt the cube so that the corner is facing forward. Then rotate the cube on a diagonal. Here is the new end of the display() method:

      gl.glRotatef(-80110);
      gl.glRotatef(angle /161, -11);
      drawCenteredCube(gl);

Last, you will need to revise the method that draws the square as described above. The new method draws a square that would be the nearest face of the cube:

   private void drawSquareFace(GL gl) {
     gl.glBegin(GL.GL_QUADS);
     gl.glTexCoord2f(00);
     gl.glVertex3f(-SIZE / 2, -SIZE / 2, SIZE / 2);
     gl.glTexCoord2f(01);
     gl.glVertex3f(-SIZE / 2, SIZE / 2, SIZE / 2);
     gl.glTexCoord2f(11);
     gl.glVertex3f(SIZE / 2, SIZE / 2, SIZE / 2);
     gl.glTexCoord2f(10);
     gl.glVertex3f(SIZE / 2, -SIZE / 2, SIZE / 2);
     gl.glEnd();
   }

The addition to the three-dimensional version is the following method, drawCenteredCube(). It actually only draws three faces of the cube because that is all that a viewer will see in this example.

  private void drawCenteredCube(GL gl) {
    gl.glColor4f(1000);
    drawSquareFace(gl);
    gl.glColor4f(1100);
    gl.glRotatef(90100);
    drawSquareFace(gl);
    gl.glColor4f(0010);
    gl.glRotatef(90010);
    drawSquareFace(gl);
    gl.glColor3f(0.0f0.0f0.0f);
  }

First the color is set to red and a face is drawn. Then the model is rotated 90 degrees. The color is changed to yellow, and a second face is drawn. The model is then rotated 90 degrees in another direction so that the three faces meet at a single vertex. The color is changed to blue and the third face is drawn.

Here is the entire code listing:

   import net.java.games.jogl.GLCanvas;
   import net.java.games.jogl.GLCapabilities;
   import net.java.games.jogl.GLDrawableFactory;
   import net.java.games.jogl.Animator;
   import net.java.games.jogl.GL;
   import net.java.games.jogl.GLEventListener;
   import net.java.games.jogl.GLDrawable;
   
   import java.awt.Frame;
   import java.awt.event.WindowAdapter;
   import java.awt.event.WindowEvent;
   
   public class JOGLRotatingCube {
   
     private static final int SIZE = 160;
   
     private static float angle = 0;
   
     JOGLRotatingCube() {
       GLCanvas canvas = getGLCanvas();
       canvas.addGLEventListener(new RotatingCubeListener());
       Animator anim = new Animator(canvas);
       addCanvasToFrame(canvas, anim);
       anim.start();
     }
   
     private void addCanvasToFrame(
      GLCanvas canvas, final Animator anim) {
       Frame f = new Frame("JOGL Rotating Half - Cube");
       f.setSize(600400);
       f.add(canvas);
       f.setVisible(true);
       f.addWindowListener(new WindowAdapter() {
           public void windowClosing(WindowEvent e) {
             anim.stop();
             System.exit(0);
           }
         });
     }
   
     private GLCanvas getGLCanvas() {
       GLCapabilities capabilities = new GLCapabilities();
       return GLDrawableFactory.getFactory().
                             createGLCanvas(capabilities);
     }
   
     public static void main(String[] args) {
       new JOGLRotatingCube();
     }
   
   
     private void drawCenteredCube(GL gl) {
       gl.glColor4f(1000);
       drawSquareFace(gl);
       gl.glColor4f(1100);
       gl.glRotatef(90100);
       drawSquareFace(gl);
       gl.glColor4f(0010);
       gl.glRotatef(90010);
       drawSquareFace(gl);
       gl.glColor3f(0.0f0.0f0.0f);
     }
   
     private void drawSquareFace(GL gl) {
       gl.glBegin(GL.GL_QUADS);
       gl.glTexCoord2f(00);
       gl.glVertex3f(-SIZE / 2, -SIZE / 2, SIZE / 2);
       gl.glTexCoord2f(01);
       gl.glVertex3f(-SIZE / 2, SIZE / 2, SIZE / 2);
       gl.glTexCoord2f(11);
       gl.glVertex3f(SIZE / 2, SIZE / 2, SIZE / 2);
       gl.glTexCoord2f(10);
       gl.glVertex3f(SIZE / 2, -SIZE / 2, SIZE / 2);
       gl.glEnd();
     }
   
     class RotatingCubeListener implements GLEventListener {
   
       public void init(GLDrawable drawable) {
         GL gl = drawable.getGL();
         gl.glClearColor(0.0f0.0f0.0f1.0f)//erasing color
         gl.glColor3f(0.0f0.0f0.0f)// drawing color
       }
   
       public void display(GLDrawable drawable) {
         GL gl = drawable.getGL();
         gl.glClear(GL.GL_COLOR_BUFFER_BIT);
   
         angle++;
         gl.glMatrixMode(GL.GL_MODELVIEW);
         gl.glLoadIdentity();
         gl.glRotatef(-80110);
         gl.glRotatef(angle /161, -11);
         drawCenteredCube(gl);
       }
   
       public void reshape(GLDrawable drawable,
                           int x,
                           int y,
                           int width,
                           int height) {
         GL gl = drawable.getGL();
         gl.glViewport(00, width, height);
         gl.glMatrixMode(GL.GL_PROJECTION);
         gl.glLoadIdentity();
         gl.glOrtho(-width, width, -height, height, -SIZE, SIZE);
       }
   
       public void displayChanged(GLDrawable drawable,
                                  boolean modeChanged,
                                  boolean deviceChanged) {
       }
     }
   }

Compile and run JOGLRotatingCube. You should see a rotating multicolored cube.

jogl

In these examples you have seen how to quickly get up and running with JOGL. In the first example, you added a rectangle to a GLCanvas and animated it. In the second example, you extended this to creating three faces of a cube and rotated them about the common vertex. You can experiment with extending these examples by adding the other faces to the cube or by adding different shapes to the two dimensional example.

Copyright (c) 2004-2005 Sun Microsystems, Inc.
All Rights Reserved.


 Related Tips

 
< Prev

Page 1 of 0 ( 0 comments )

You can share your information about this topic using the form below!

Please do not post your questions with this form! Thanks.


Name (required)


E-Mail (required)

Your email will not be displayed on the site - only to our administrator
Homepage(optional)



Comment Enable HTML code : Yes No



 
       
         
     
 
 
 
   
 
 
java bottom left
java bottom middle
java bottom right
RSS 0.91 FeedRSS 1.0 FeedRSS 2.0 FeedATOM FeedOPML Feed

Home - About Us - Privacy Policy
Copyright 2005 - 2008 www.java-tips.org
Java is a trademark of Sun Microsystems, Inc.