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

时间:2013-02-13 22:18:44

标签: java opengl lwjgl rotational-matrices

我有一个用LWJGL编写的基本OpenGL程序。在阅读了为什么使用音高,偏航和滚动变量这是一个坏主意后,我才开始研究旋转矩阵。然而,由于矩阵更难以处理,我正在编写一个函数,它采用偏航,俯仰和滚动并将它们转换为旋转矩阵,然后与模型视图矩阵相乘。我的代码如下:

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来访问模型视图矩阵,看看发生了什么。

这就是事情变得奇怪的地方(至少对我而言):在我调用我的函数之前,存储模型视图矩阵的检索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 个答案:

答案 0 :(得分:2)

(这是一个扩展的评论,带代码)

这里肯定存在字节顺序问题。我运行了以下内容:

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

并得到输出803f

Float 1.0是big-endian 0x3f800000。