Skip to content

From glRotate to JOML

Kai Burjack edited this page Jan 26, 2017 · 15 revisions

Here we will show you how you can make use of JOML in your OpenGL application if you are using the fixed-function pipeline with its matrix stacks, such as GL_MODELVIEW and GL_PROJECTION.

If you are using OpenGL via a Java/OpenGL binding such as LWJGL or JOGL you are probably currently using the matrix stack operations glTranslate, glRotate, glScale, glMultMatrix, etc. With JOML you can continue using those functions!

But why would you want to use JOML now?

Execution speed

JOML executes the matrix operations much faster than OpenGL. This is due to the fact that JOML's matrix operations are implemented in pure Java and thus do not have to cross the JNI bridge between the Java and the native driver world. And the JVM is able to much better optimize pure Java code.

Making your way towards modern OpenGL

If you plan to use more "modern" OpenGL without the use of the fixed-function pipeline, but you still like its matrix stack, you can switch to using JOML today! JOML provides you with the same matrix functions known from OpenGL as well as from the OpenGL Utility Library "GLU".

Like with OpenGL's matrix stack, you can therefore build matrices out of simple affine transformations such as rotation, scaling and translation. Furthermore, you can use the GLU functions lookAt() and perspective() to build a camera transformation matrix.

How does it look like?

Imagine you have the following OpenGL code. The OpenGL method names depend on the binding in use. The following examples will use LWJGL 3:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(45.0f, 1.0f, 0.01f, 100.0f); <- actually not in LWJGL 3!
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(0.0f, 2.0f, 5.0f,  <- actually not in LWJGL 3!
//          0.0f, 0.0f, 0.0f,
//          0.0f, 1.0f, 0.0f);
glRotatef(45.0f, 0.0f, 0.0f, 1.0f);
glTranslatef(1.0f, 0.0f, 0.0f);
...draw call...
glPushMatrix();
glScalef(0.5f, 0.5f, 0.5f);
...draw call...
glPopMatrix();

Let's say you have switched to using shaders now instead of the fixed-function pipeline. With JOML you can still compose your transformation matrices in the same way like above. But now you would need to upload the final matrices as a shader uniform mat4:

FloatBuffer fb = <16 floats>;
MatrixStackf p = new MatrixStackf(1); // stack-depth = 1
MatrixStackf m = new MatrixStackf(2); // stack-depth = 2
p.identity();
p.perspective((float) Math.toRadians(45), 1.0f, 0.01f, 100.0f).get(fb);
glUniformMatrix4fv(projectionMatrix, false, fb);
m.identity();
m.lookAt(0.0f, 2.0f, 5.0f,
         0.0f, 0.0f, 0.0f,
         0.0f, 1.0f, 0.0f);
m.rotate((float)Math.toRadians(45.0f), 0.0f, 0.0f, 1.0f);
m.translate(1.0f, 0.0f, 0.0f).get(fb);
glUniformMatrix4fv(modelviewMatrix, false, fb);
...draw call...
m.pushMatrix();
m.scale(0.5f, 0.5f, 0.5f).get(fb);
glUniformMatrix4fv(modelviewMatrix, false, fb);
...draw call...
m.popMatrix();

You see that your code does not look that much different than before. But now you are officially using "modern" OpenGL and still have the benefits of the matrix stack known from legacy OpenGL and you can now implement that scene graph rendering engine of yours using JOML's matrix stack. :)