首页 > 解决方案 > 将 Matrix4f 加载到 FloatBuffer 中,以便我的着色器可以使用它

问题描述

我创建了一个 Matrix4f,它是我的着色器的正交透视图。要存储着色器的上传矩阵,需要将其存储在 FloatBuffer 中。当我想将矩阵放入 FloatBuffer 时,我的数学库 JOML 出现错误。(我使用 LWJGL3)以下是错误:

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

那是我的代码:

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);

标签: javalwjgl

解决方案


根据评论更新:

该错误是由于使类的address字段java.nio.Buffer可访问,以便使用它来使用Unsafe该类填充缓冲区而引起的。

这是通过此提交修复的,因此应该在最新版本的 JOML 中解决。因此,如果可能,您应该更新到最新版本。


旧版本的两种解决方法:

  1. JOML 有一个启动选项,它禁用Unsafe该类的使用。所以你可以传递joml.nounsafe=true给你的应用程序。但是该标志在很大程度上是无证的,而且还不完全清楚这会产生什么影响。

  2. 另一种解决方法是手动将数据从矩阵移动到缓冲区:

    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();
        }
    }
    

    但这不是很好,因为您正在手动执行 JOML 在不使用Unsafe.


推荐阅读