有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java OpenGL矩阵乘法导致奇数浮点行为

我有一个用LWJGL for java编写的基本OpenGL程序。在阅读了为什么使用俯仰、偏航和横摇变量是个坏主意之后,我才开始研究旋转矩阵。但是,由于矩阵更难处理,我正在编写一个函数,该函数将偏航、俯仰和横摇转换为旋转矩阵,然后与Modelview矩阵相乘。我的代码如下:

public static void loadRotationalMatrix(double pitch, double yaw, double roll)
{
    FloatBuffer Ry = ByteBuffer.allocateDirect(16 * Double.SIZE).asFloatBuffer();
    FloatBuffer Rx = ByteBuffer.allocateDirect(16 * Double.SIZE).asFloatBuffer();
    FloatBuffer Rz = ByteBuffer.allocateDirect(16 * Double.SIZE).asFloatBuffer();

    Rx.put(new float[]
        {
            1, 0, 0, 0,
            0, (float) cos(pitch), (float) sin(pitch), 0,
            0, (float) -sin(pitch), (float) cos(pitch), 0,
            0, 0, 0, 1
        });
    Ry.put(new float[]
        {
            (float) cos(yaw), 0, (float) -sin(yaw),  0,
            0, 1, 0, 0,
            (float) sin(yaw), 0, (float) cos(yaw), 0,
            0, 0, 0, 1
        });
    Rz.put(new float[]
        {
            (float) cos(roll), (float) sin(roll), 0, 0,
            (float) -sin(roll), (float) cos(roll), 0, 0, 
            0, 0, 1, 0,
            0, 0, 0, 1
        });

    GL11.glMultMatrix(Rx);
    GL11.glMultMatrix(Ry);
    GL11.glMultMatrix(Rz);
}

首先,我将0, 0, 0传递给这个函数,我希望它对渲染场景没有影响。然而,在函数调用之后,我正在绘制的简单正方形消失了。为了调试,我使用glGetFloat访问modelview矩阵并查看发生了什么

这就是事情变得奇怪的地方(至少对我来说):在调用我的函数之前,检索到的存储modelview矩阵的FloatBuffer

4.6006E-41, 0.0, 0.0, 0.0, 0.0, 4.6006E-41, 0.0, 0.0, 0.0, 0.0, 4.6006E-41, 0.0, 0.0, 0.0, 0.0, 4.6006E-41, 

或者,更具可读性

4.6006E-41, 0.0, 0.0, 0.0, 
0.0, 4.6006E-41, 0.0, 0.0, 
0.0, 0.0, 4.6006E-41, 0.0, 
0.0, 0.0, 0.0, 4.6006E-41, 

一切都正常呈现

在我呼叫后,矩阵变为

0.0, 0.0, 0.0, 0.0, 
0.0, 0.0, 0.0, 0.0, 
0.0, 0.0, 0.0, 0.0, 
0.0, 0.0, 0.0, 0.0, 

我的测试方块消失了

发生了什么事?我的矩阵是否创建错误?关于glMultMatrix有什么我不明白的吗?是否需要启用或禁用某些内容?为什么普通矩阵中有那些奇怪的浮点数?它不是应该是身份矩阵吗(带1的)

编辑:

如果使用BufferUtils.createFloatBuffer(16 * Float.SIZE);而不是ByteBuffer.allocateDirect(16 * Float.SIZE).asFloatBuffer();,则所提到的字节排序问题将消失,4.6006E-41的变为1.0。然而,矩阵仍然从恒等式转换为纯零


共 (1) 个答案

  1. # 1 楼答案

    (这实际上是一个扩展注释,带有代码)

    这里肯定有字节顺序问题。我运行了以下命令:

    public class Test {
      public static void main(String[] args) {
        float f = (float)4.6006E-41;
        System.out.println(Integer.toHexString(Float.floatToIntBits(f)));
      }
    }
    

    输出803f

    浮点1.0是大端字节0x3f800000