Load an Matrix4f into a FloatBuffer, so my shader can use it

Viewed 1176

I created a Matrix4f which is a orthogonal perspective for my shader. To store upload the matrix for the shader, it needs to be stored in a FloatBuffer. When I want to put the matrix into the FloatBuffer, I get a error from JOML, my maths library. (I use LWJGL3) Here are the errors:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.joml.MemUtil$MemUtilUnsafe 
(file:/C:/Dev/Java/Learn%20OpenGL/lib/joml-1.9.6.jar) to field 
java.nio.Buffer.address
WARNING: Please consider reporting this to the maintainers of 
org.joml.MemUtil$MemUtilUnsafe
WARNING: Use --illegal-access=warn to enable warnings of further illegal 
reflective access operations
WARNING: All illegal access operations will be denied in a future release

That's my code:

matrix4f =  new Matrix4f().ortho(-2.0f, 2.0f, -1.5f, 1.5f, 1.0f, 1.0f);

FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16);
matrix4f.get(matrixBuffer);

GL20.glUniformMatrix4fv(Shader.getLocation(shader, "transformationMatrix"), false, matrixBuffer);
1 Answers

Updated based on the comment:

The error was caused by making the address field of the java.nio.Buffer class accessible, in order to use it for filling the buffer using the Unsafe class.

This was fixed via this commit, and thus, should be resolved in the latest versions of JOML. So you should update to the latest version, if possible.


Two workarounds for the old version:

  1. There is a startup option for JOML that disables the use of the Unsafe class. So you could pass joml.nounsafe=true to your application. But the flag is largely undocumented, and it's not entirely clear which implications this will have.

  2. Another workaround would be to manually move the data from the matrix to the buffer:

    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    import java.nio.FloatBuffer;
    
    import org.joml.Matrix4f;
    
    public class JomlMatrixToBuffer
    {
        public static void main(String[] args)
        {
            Matrix4f matrix4f =
                new Matrix4f().ortho(-2.0f, 2.0f, -1.5f, 1.5f, -1.0f, 1.0f);
    
            FloatBuffer matrixBuffer = createFloatBuffer(16);
            matrix4f.get(matrixBuffer);
    
            System.out.println("Result:");
            for (int i = 0; i < matrixBuffer.capacity(); i++)
            {
                System.out.println(matrixBuffer.get(i));
            }
        }
    
        private static void matrixToBuffer(Matrix4f m, FloatBuffer dest)
        {
            matrixToBuffer(m, 0, dest);
        }
        private static void matrixToBuffer(Matrix4f m, int offset, FloatBuffer dest)
        {
            dest.put(offset, m.m00());
            dest.put(offset + 1, m.m01());
            dest.put(offset + 2, m.m02());
            dest.put(offset + 3, m.m03());
            dest.put(offset + 4, m.m10());
            dest.put(offset + 5, m.m11());
            dest.put(offset + 6, m.m12());
            dest.put(offset + 7, m.m13());
            dest.put(offset + 8, m.m20());
            dest.put(offset + 9, m.m21());
            dest.put(offset + 10, m.m22());
            dest.put(offset + 11, m.m23());
            dest.put(offset + 12, m.m30());
            dest.put(offset + 13, m.m31());
            dest.put(offset + 14, m.m32());
            dest.put(offset + 15, m.m33());
        }
    
        private static FloatBuffer createFloatBuffer(int size)
        {
            return ByteBuffer.allocateDirect(size << 2)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer();
        }
    }
    

    But that's not so nice, because you're doing manually what JOML is already doing internally when not using Unsafe.

Related