GLCanvas versus GLJPanel

Hello,

I appear to get more draws per second (FPS?) when using GLCanvas rather than GLJPanel (with -Dsun.java2d.opengl=true)

With GLCanvas:
Run 1) draws per second: 227.9862
Run 2) draws per second: 223.8353
Run 3) draws per second: 227.15656

With GLJPanel:
Run 1) draws per second: 181.63368
Run 2) draws per second: 174.60318
Run 3) draws per second: 176.43361

I am running XP with jre1.6.0_01 (installed from jdk6 site yesterday), and have jogl-1.1.0-pre-20070128-windows-i586

Also, I’ve noticed a significant FPS increase switching from jdk 1.5.0 to 1.6

Here is my code (which I borrowed from Nehe’s Lesson 11 Jogl port)…draws per second are displayed after the Frame is closed. I switch between GLCanvas and GLJPanel by commenting/uncommenting the appropriate class-level canvas declaration.

Am I missing something that would make GLJPanel run slower? Are others seeing this?

Thanks,

David


import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLJPanel;
import javax.media.opengl.glu.GLU;

import com.sun.opengl.util.Animator;

import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;


public class TestRender implements GLEventListener {

	// The Array For The Points On The Grid Of Our "Wave"
	float[][][] points = new float[45][45][3];

	int wiggle_count = 0; // Counter Used To Control How Fast Flag Waves

	float xrot; // X Rotation ( NEW )

	float yrot; // Y Rotation ( NEW )

	float zrot; // Z Rotation ( NEW )

	float hold;

	int[] textures = new int[1]; // Storage for one texture ( NEW )

	static int draws = -1;

	static long startTime;

	//Switch this to GLCanvas or GLJPanel
	static GLCanvas canvas = new GLCanvas (new GLCapabilities());
	//static GLJPanel canvas = new GLJPanel (new GLCapabilities());
	
	private GLU glu = new GLU();

	public static void main(String[] args) {

		boolean bQuit = false;

		Frame frame = new Frame("Jogl 3d Shape/Rotation");

		canvas.addGLEventListener(new TestRender());

		frame.add(canvas);
		frame.setSize(640, 480);
		frame.setUndecorated(false);

		//Animator animator = new Animator(canvas);
		//animator.start();
		
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				long runTime = System.currentTimeMillis() - startTime;
				System.out.println("draws per second: " + (float) draws / runTime * 1000);
				System.exit(0);
			}
		});
		
		frame.setVisible(true);

		startTime = System.currentTimeMillis();
		while (!bQuit) {
			canvas.display();
		}
	}

	public void init(GLAutoDrawable glDrawable) {

		GL gl = glDrawable.getGL();

		gl.glShadeModel(GL.GL_SMOOTH); // Enables Smooth Color Shading
		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // This Will Clear The
													// Background Color To Black
		gl.glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
		gl.glEnable(GL.GL_DEPTH_TEST); // Enables Depth Testing
		gl.glDepthFunc(GL.GL_LEQUAL); // The Type Of Depth Test To Do
		gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); // Really
																	// Nice
																	// Perspective
																	// Calculations
		gl.glPolygonMode(GL.GL_BACK, GL.GL_FILL); // Back Face Is Solid
		gl.glPolygonMode(GL.GL_FRONT, GL.GL_LINE); // Front Face Is Made Of
													// Lines

		for (int x = 0; x < 45; x++) {
			for (int y = 0; y < 45; y++) {
				points[x][y][0] = ((x / 5.0f) - 4.5f);
				points[x][y][1] = ((y / 5.0f) - 4.5f);
				points[x][y][2] = (float) (Math
						.sin((((x / 5.0f) * 40.0f) / 360.0f) * 3.141592654 * 2.0f));
			}
		}
	}

	public void display(GLAutoDrawable glDrawable) {
		GL gl = glDrawable.getGL();
		int x, y;
		float float_x, float_y, float_xb, float_yb;

		// Clear The Screen And The Depth Buffer
		gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

		gl.glLoadIdentity(); // Reset The View

		gl.glTranslatef(0.0f, 0.0f, -12.0f);

		gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);
		gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);
		gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f);

		gl.glBindTexture(GL.GL_TEXTURE_2D, textures[0]);

		

		for (int i = 0; i < 5; i++) {
			gl.glPushMatrix();
			
			gl.glTranslatef((float) i - 2.0f,0, 0);
			
			gl.glBegin(GL.GL_QUADS);
			
			for (x = 0; x < 44; x++) {
				for (y = 0; y < 44; y++) {
					float_x = (float) (x) / 44.0f;
					float_y = (float) (y) / 44.0f;
					float_xb = (float) (x + 1) / 44.0f;
					float_yb = (float) (y + 1) / 44.0f;

					gl.glVertex3f(points[x][y][0], points[x][y][1],
							points[x][y][2]);

					gl.glVertex3f(points[x][y + 1][0], points[x][y + 1][1],
							points[x][y + 1][2]);

					gl.glVertex3f(points[x + 1][y + 1][0],
							points[x + 1][y + 1][1], points[x + 1][y + 1][2]);

					gl.glVertex3f(points[x + 1][y][0], points[x + 1][y][1],
							points[x + 1][y][2]);
				}
			}
			gl.glEnd();
			
			gl.glPopMatrix();
		}

		xrot += .3f;
		yrot += .2f;
		zrot += .4f;

		draws++;
	}

	public void reshape(GLAutoDrawable glDrawable, int x, int y, int w, int h) {
		if (h == 0)
			h = 1;
		GL gl = glDrawable.getGL();

		// Reset The Current Viewport And Perspective Transformation
		gl.glViewport(0, 0, w, h);

		gl.glMatrixMode(GL.GL_PROJECTION); // Select The Projection Matrix
		gl.glLoadIdentity(); // Reset The Projection Matrix

		// Calculate The Aspect Ratio Of The Window
		glu.gluPerspective(45.0f, (float) w / (float) h, 0.1f, 100.0f);

		gl.glMatrixMode(GL.GL_MODELVIEW); // Select The Modelview Matrix
		gl.glLoadIdentity(); // Reset The ModalView Matrix
	}

	public void displayChanged(GLAutoDrawable glDrawable, boolean b, boolean b1) {
	}
}



With JDK 6 there is new interoperability between JOGL and the OpenGL pipeline for Java 2D, which explains why the GLJPanel performs much better with JDK 6 and -Dsun.java2d.opengl=true. This is described in the thread “Java2D/JOGL Interoperability Demo” on this board as well as in Chris Campbell’s blog postings also linked from one of the sticky threads here. You probably need to still expect that the heavyweight GLCanvas is still going to yield better performance, but the Java 2D / JOGL bridge should narrow the performance gap considerably.