Skip to content

Common Pitfalls

Kai Burjack edited this page Jan 18, 2018 · 9 revisions

Below you will find very common problems and solutions when working the first time with JOML, especially when migrating from other libraries which worked differently.

Angles are always in radians

Any parameter in any method representing an angle will always be in radians. This includes the parameters in methods like Matrix4f.rotate(angle, ...) and Matrix4f.perspective(fovY, ...).

So, the following will not produce the desired result:

Matrix4f m = new Matrix4f().perspective(60.0f, aspect, near, far);

Use Math.toRadians() instead:

Matrix4f m = new Matrix4f().perspective((float) Math.toRadians(60.0f), aspect, near, far);

Methods without a dest parameter modify this and return this

The following will not produce the desired result:

if (shouldMoveRight)
  position = position.add(forward.cross(up).mul(speed));
if (shouldMoveLeft)
  position = position.sub(forward.cross(up).mul(speed));
if (shouldMoveUp)
  position = position.add(up.mul(speed));
if (shouldMoveDown)
  position = position.sub(up.mul(speed));

The problem with the above code is that the forward and up vectors are being modified, since the cross and mul method calls modify this and this in that context is forward and up, respectively.

Instead use the overloads with explicit dest parameters like in following code:

Vector3f forward = new Vector3f(...);
Vector3f up = new Vector3f(...);
Vector3f position = new Vector3f(0);
Vector3f tmp = new Vector3f();
float speed = 2.0f;
if (shouldMoveRight)
  position.add(forward.cross(up, tmp).mul(speed));
if (shouldMoveLeft)
  position.sub(forward.cross(up, tmp).mul(speed));
if (shouldMoveUp)
  position.add(up.mul(speed, tmp));
if (shouldMoveDown)
  position.sub(up.mul(speed, tmp));

This prevents forward and up from being modified. Here, the result will be written to a temporary tmp vector which will also be the returned object of the cross and mul calls. Also, the reassignment of position in every line was superfluous, since the add and sub calls operate on position and return position (remember that method overloads that do not take a dest parameter will always modify and return this).

Matrix memory layout is column-major

When it comes to serializing matrix elements into a linear data structure such as an array or a NIO buffer, some matrix/vector math libraries use row-major memory layout and some other libraries use column-major layout. JOML uses the latter. This is also the memory layout expected by OpenGL.

That means, the following code will not do what you intended it to do:

glMatrixUniform4fv(matrixLocation, true, matrix.get(arrayOrBuffer));

Instead, use false as the transpose parameter argument:

glMatrixUniform4fv(matrixLocation, false, matrix.get(arrayOrBuffer));
Clone this wiki locally