Question

I have a basic OpenGL program written in LWJGL for java. I'm just starting to look into rotation matrices after reading up on why it's a bad idea to use pitch, yaw and roll variables. However, as matrices are more difficult to work with, I am writing a function that takes yaw, pitch and roll and converts them into a rotation matrix, which is then multiplied with the Modelview matrix. My code is as follows:

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

To begin, I passed 0, 0, 0 to this function, which I expected to have no effect on the rendered scene. However, the simple square I was drawing disappeared after the function call. To debug, I used glGetFloat to access the modelview matrix and see what happened.

This is where things get strange (for me at least): before I call my function, the retrieved FloatBuffer storing the modelview matrix is

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, 

or, more readable,

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, 

and everything renders normally.

After my call, the matrix becomes

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, 

and my test square disappears.

What is happening? Are my matrices created incorrectly? Is there something I do not understand about glMultMatrix? Is there something I need to enable or disable? Why does the normal matrix have those weird floats in it? Isn't it supposed to be the identity matrix (with 1's)?

EDIT:

If BufferUtils.createFloatBuffer(16 * Float.SIZE); is used instead of ByteBuffer.allocateDirect(16 * Float.SIZE).asFloatBuffer();, the the byte-ordering problems mentioned go away and the 4.6006E-41's becomes 1.0 as expected. However, the matrix still transforms from the identity to pure zeroes.

Was it helpful?

Solution

(This is really an extended comment, with code)

There is definitely a byte order problem here. I ran the following:

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

and got output 803f

Float 1.0 is big-endian 0x3f800000.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top