Java OpenGL Math Library (JOML)

Hi everyone,

Since LWJGL 3 removed most of the functionality of the maths library, I thought I’d have a go at creating a Java-based equivalent to the C-based GLM library. Although a conceptual port of the GLM library already exists, I had some issues in getting it to work properly (lots of black screens). The library is fairly bare-bones at the moment, containing the most commonly-used functions, but it should be enough to get people started. I’m happy to take requests to extend it as well if you come across anything missing that you feel would be useful to others.

For reasons of flexibility, every function has an instance and static method (where it makes sense to do so). The instance method modifies the object itself (so myMatrix.transpose() will modify myMatrix directly), and the static method is more in line with what we had in LWJGL 2.9.x where you specify a source and a target matrix (so Matrix4f.transpose(myMatrix, newMatrix) will not modify myMatrix, and stores the results in newMatrix instead).

I’ve also avoided using local object declarations within the library, with the exception of lookAt which really needs it (at least until I have time to go through it step by step). It makes the code hard to read, but at least you know it’s not going to generate hundreds or thousands of collectible objects every frame, depending on what you’re doing :slight_smile:

The library currently covers:

- Float and double precision 3x3 and 4x4 matrices and 2/3 component Vectors
- Quaternions
- Surface mathematics (calculating the normal, tangent, binormal)
- Camera mathematics (including versions of GLM's perspective, ortho and lookAt methods)
- Transformation utilities (such as generating a transformation matrix from supplied location, rotation and scale)

I’ll add to the library over time, but if you have any other requests then drop me a PM or reply to this thread. You can download the source and the library here:

Java OpenGL Math Library

Feel free to use the code however you want. Modify it, use it as a base, copy/paste bits, anything you like :slight_smile: Hope someone finds this useful!

Commit History:

25th February 2015

  • Kai has started adding double-precision alternatives to the float-based Matrix and Vector classes
  • Added MatrixUtils for creating commonly-used matrices like the model matrix

18th February 2015

  • New SurfaceMath class. Currently allows you to calculate the normal, tangent and binormal of a surface
  • Surfaces are defined by 3 vertices and, in the case of the tangent and binormal, their corresponding UV coordinates
  • Removed the normal method from Vector3f as SurfaceMath is a better home for it.
  • New Vector2f class for 2D calculations

17th February 2015

  • Added Quaternion.lookAt to generate a rotation towards at point B from point A (Thanks to SHC for suggesting it)
  • Method allows for specification of the forward and up Vectors, or to use the defaults

16th February 2015

  • Added Quaternion class for handling rotations

11th February 2015

  • Fixed an issue with lookAt (thanks to Kai for the fix)

10th February 2015

  • Added static alias-unsafe methods (mulFast, invertFast, transposeFast) which only work if the source and target matrices are different objects
  • Added overloads for most static methods to take a FloatBuffer as the destination and write into it directly
  • Removed the call to rewind() from the store() instance method in Matrix4f
  • Re-wrote lookAt to remove local Vector3fs (only local primitive floats are used). The code is now almost totally illegible but initial testing suggests it works
  • Some other minor optimisations (such as removing calls to set() from methods that don’t require it)

9th February 2015

  • Added alias safety, thanks Kai for pointing that one out

8th February 2015

  • Initial Build

Never, ever support degrees. The idea of degrees is that it takes the sun exactly 360 days to travel around the earth. And that’s exactly how useful they are.

And it doesn’t even do that.

But degrees have a use in that they are what people know about. They are what people learn about and hence what most of us think about intuitively with angles. So why not have a degrees to radians method so that people can use their intuitive knowledge in, for example, initial conditions. Yes you should discourage people from using degrees but you shouldn’t prevent them entirely.

You’re missing my point. If any user wants to manipulate degrees AT RUNTIME PROCESSING for some reason…they can but it’s their responsibility to do the conversion themselves. And “degrees” is more natural is mostly myth. That’s only true for very large angles. Burdening a library with extra useless functionality doesn’t meaningfully help anyone.

Note everyone would agree if some library had: getDistanceMeters, getDistanceFeet, getDistanceYards, getDistanceMiles, getDistanceInHoursForAEuropeanLadenSwallowToFly. Yo, just do one.

Because that’s included already in java.lang.Math, and one shouldn’t duplicate core library functions like that.

Relevant post on angles.

Additionally angles are usefully avoidable in the first place.

Yes. Vectors, matrices, quaternions are all better than angles in every respect. Certainly for a computer. As with most complex things in maths, learning about them is the hard part but once you have, then they make things so much more simple and general case.

I disagree. Certainly most people would be fine with pi/3, pi/2, pi etc. but once you go to more complex multiples than that then you have to think about it to figure out how big the angle actually is. Or at least I do. And I am studying engineering which is practically maths. I wouldn’t be surprised if they dropped you marks if you tried to solve a problem in degrees instead of radians.

Then there’s the argument of whether radians should be expressed in terms of pi or tau.
And if we use matrices we have to work out whether we’re using row- or column-major.

It would be much easier if people could agree on one standard.

Hi guys, sorry for the delay in responding, it has been a busy couple of days.

Thanks for the feedback to all of you, I have to admit that I don’t come from a mathematical background so I’m kind of learning as I go along. So would you recommend removing the functions to do with degrees and radians as well and work only with vectors? I originally included them as I wanted this library to be accessible to all, but since I’m planning to work on some higher level utility functions at some point I suppose it doesn’t matter if the the lower level library imposes a best practice approach.

With regards to the matrices, I appreciate that some people prefer column-major and others row-major (was a pain in the arse when doing research since they often didn’t indicate what they were working in). I’ve chosen column-major since that’s how OpenGL prefers it and it means it doesn’t have to do any transposition, hopefully my comments make this very clear.

less pain when you have both versions (column and row major) around (like glm does) :slight_smile:

Thank you so much for this! This makes OpenGL programming so much more convenient :smiley:

Quick update. I’ve changed the link on the first post to point to the new repository location, which is at:

This is the new working repository, so if you’re using the library then make sure you visit this to ensure you have the latest version :wink:

I have added some more bits and pieces including a MatrixUtils class which currently provides a quick and easy way to generate a transformation (or model) matrix using a supplied position and scale Vector, and a Quaternion rotation.

Kai over at the LWJGL forums has also started producing double-precision versions of the Vector and Matrix classes.

Doubles are for serious computing.

Or, you know, a large range of values.

For tools…sure. There are existing libraries. Runtime: You don’t need doubles.

(EDIT: the extra precision is more often the interesting part…not the wider range)

hide your errors better :wink:

By large range of values, I meant that you might have relatively large values (= a wider range of values) but you still need high precision, so we’re basically saying the same thing.

No. They are different. Give a common (not strawman) example. I’ll freely admit that examples do exist, but they are uncommon needs in terms of a game runtime.

WRT: error – ok, but you’re just hiding the problem.

You might need doubles for a big planet. :wink:
There, each vertex (on a chunked lod patch) could be displaced by a noise function, which is a function of the world-space position.
Now, the interesting thing about doubles is not the wide range (magnitude) of values, but, as others stated here, the precision.
And yes, there is a difference.
Higher precision means you can have very large magnitudes (but magnitudes really do not matter with IEEE 754, because you can normalize) and still have small differences between them.
Like you can differentiate between the large (in magnitude) values 100000000.0002 and 100000000.0001. But, no matter how you normalize these values, you still have two non-zero digits at both ends of a long list of zeroes, no matter where the decimal separator is. So in IEEE 754 you need a big mantissa for that. :slight_smile:
Or in other words, you need a small ULP (unit in the last place).
Yes, of course during rendering, single-precision would be used by translating each terrain lod patch with model-space origin (0, 0) within the vertex shader into its view-space position.
So, the need for double-precision during rendering would be eliminated by subtracting the camera world-space position by each lod patch world-space position, which will give lod patch view-space position.
And here, you would not need both magnitude and low ulp, because as magnitude increases (distance to camera) then also precision (ulp) is less relevant.
But I agree that this might be uncommon for games.