Hei!
In my project I need to basically draw a large number of rectangles on the screen. Starting out, over a year ago, I accepted advice that Jogl was the way to go as opposed to Java 2D. Now I want to get some numbers, hard evidence if you like, that Jogl performs better, and Java 2D doesn’t perform to satisfaction.
I’ve written a simple bemchmark application that draws an increasing amount of rectangles on the screen, and halts when the time taken to draw a screen goes above 1 s. I’m using GLCanvas as my drawable and I’m listing the code for my GLEventListener below.
I compare the final amount of rectangles that the application could draw within one second. Java2D manages around 800, while Jogl manages in excess of 15000 rectangles.
I have limited experience with graphics programming, and would thus like some comments regarding the “fairness” of this test. Does it unintentionally favour one library over the other, or are the results relatively comparable?
The code for the Java2D implementation can be made available by request.
package aaa;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
import javax.swing.JFrame;
public class JoglDrawer implements GLEventListener {
private GL gl;
private GLU glu = new GLU();
private JFrame f;
private double objectThickness = Integer.MAX_VALUE;
private double objectLength = Integer.MAX_VALUE;
private int width;
private int height;
private int n;
private int oldAmount;
private int amount;
private long drawingTime;
public JoglDrawer(JFrame f) {
this.f = f;
}
public void init(GLAutoDrawable drawable) {
this.gl = ((GLAutoDrawable)drawable).getGL();
gl.glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
objectLength = drawable.getWidth();
objectThickness = drawable.getHeight();
}
public void display(GLAutoDrawable drawable) {
n++;
long start = System.currentTimeMillis();
this.gl = drawable.getGL();
gl.glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
height = drawable.getHeight();
width = drawable.getWidth();
oldAmount = amount;
amount = (int)(width / (objectLength + 1) * (height / (objectThickness + 1)));
int i = 0;
int x = 0, y = 0;
while (i++ < amount) {
while (x < width-(objectLength+1)) {
drawRectangle(x, y, (int)(x+objectLength), (int)(y+objectThickness));
x += objectLength + 1;
}
x = 0;
y += objectThickness + 1;
}
//Drawing complete
long stop = System.currentTimeMillis();
drawingTime = stop - start;
check();
String title = "" + 1 / ((double)drawingTime / 1000) + " FPS";
f.setTitle(title);
drawingTime = 0;
}
private void check() {
if (drawingTime > 1000) {
System.out.println("Rendered "+oldAmount+" squares of size "+objectLength+"px by "+objectThickness+"px in less than 1s");
f.dispose();
System.exit(0);
}
objectLength -= objectLength*.01; //Reduce size by a hundredth
objectThickness -= objectThickness*.01;
}
private void drawRectangle(int x1, int y1, int x2, int y2) {
gl.glBegin(GL.GL_QUADS);
gl.glColor3f(.25f, .50f, .50f);
gl.glVertex2i(x1, y2);
gl.glVertex2i(x2, y2);
gl.glVertex2i(x2, y1);
gl.glVertex2i(x1, y1);
gl.glEnd();
}
public void displayChanged(GLAutoDrawable arg0, boolean arg1, boolean arg2) {
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width,
int height) {
this.gl = drawable.getGL();
gl.glMatrixMode( GL.GL_PROJECTION );
gl.glLoadIdentity();
glu.gluOrtho2D(0, width, 0, height);
}
}