0
votes

I am trying to write a own rotation function for a camera in OpenGL, but I can't get it to run. My camera is mainly from flipcode, with some minor changes:

Camera code:

Camera::Camera(float x, float y, float z) {
    memset(Transform, 0, 16*sizeof(float));
    Transform[0] = 1.0f;
    Transform[5] = 1.0f;
    Transform[10] = 1.0f;
    Transform[15] = 1.0f;
    Transform[12] = x; Transform[13] = y; Transform[14] = z;

    Left=&Transform[0];
    Up=&Transform[4];
    Forward=&Transform[8];
    Position=&Transform[12];

    old_x = 0;
    old_y = 0;
}

The view is set before every rendered frame:

void Camera::setView() {

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    float viewmatrix[16]={//Remove the three - for non-inverted z-axis
                          Transform[0], Transform[4], -Transform[8], 0,
                          Transform[1], Transform[5], -Transform[9], 0,
                          Transform[2], Transform[6], -Transform[10], 0,

                          -(Transform[0]*Transform[12] +
                          Transform[1]*Transform[13] +
                          Transform[2]*Transform[14]),

                          -(Transform[4]*Transform[12] +
                          Transform[5]*Transform[13] +
                          Transform[6]*Transform[14]),

                          //add a - like above for non-inverted z-axis
                          (Transform[8]*Transform[12] +
                          Transform[9]*Transform[13] +
                          Transform[10]*Transform[14]), 1};
    glLoadMatrixf(viewmatrix);
}

Now to my problem, the rotation. Consider for example rotation around the y-axis. This is the rotation matrix stack:

// deg is the angle it is not working in degree or radiant
void Camera::rotateLocal_y(float deg){
    glMatrixMode(GL_MODELVIEW);

    glPushMatrix();
    glLoadMatrixf(Transform);

    rotateMatrixf_y(Transform, deg);



    glGetFloatv(GL_MODELVIEW_MATRIX, Transform);
    glPopMatrix();
}

So next I am going to show the rotation function:

//rotate a matrix around y axis
void rotateMatrixf_y(float *aMatrix, float angle){
    //                                  x                   y               z                       t
    float rotMatrix[] = {cos(angle),0,-1*sin(angle),0, 0, 1, 0, 0, sin(angle), 0, cos(angle), 0, 0, 0, 0, 1};

     multMatrixMatrix(rotMatrix,aMatrix);

}

And finally the matrix multiplication function:

void multMatrixMatrix(float* m_a, float* m_b){
    float m_c[16] = {m_a[0]*m_b[0]+m_a[4]*m_b[1]+m_a[8]*m_b[2]+m_a[12]*m_b[3],
                    m_a[0]*m_b[4]+m_a[4]*m_b[5]+m_a[8]*m_b[6]+m_a[12]*m_b[7],
                    m_a[0]*m_b[8]+m_a[4]*m_b[9]+m_a[8]*m_b[10]+m_a[12]*m_b[11],
                    m_a[0]*m_b[12]+m_a[4]*m_b[13]+m_a[8]*m_b[14]+m_a[12]*m_b[15],

                    m_a[1]*m_b[0]+m_a[5]*m_b[1]+m_a[9]*m_b[2]+m_a[13]*m_b[3],
                    m_a[1]*m_b[4]+m_a[5]*m_b[5]+m_a[9]*m_b[6]+m_a[13]*m_b[7],
                    m_a[1]*m_b[8]+m_a[5]*m_b[9]+m_a[9]*m_b[10]+m_a[13]*m_b[11],
                    m_a[1]*m_b[12]+m_a[5]*m_b[13]+m_a[9]*m_b[14]+m_a[13]*m_b[15],

                    m_a[2]*m_b[0]+m_a[6]*m_b[1]+m_a[10]*m_b[2]+m_a[14]*m_b[3],
                    m_a[2]*m_b[4]+m_a[6]*m_b[5]+m_a[10]*m_b[6]+m_a[14]*m_b[7],
                    m_a[2]*m_b[8]+m_a[6]*m_b[9]+m_a[10]*m_b[10]+m_a[14]*m_b[11],
                    m_a[2]*m_b[12]+m_a[6]*m_b[13]+m_a[10]*m_b[14]+m_a[14]*m_b[15],

                    m_a[3]*m_b[0]+m_a[7]*m_b[1]+m_a[11]*m_b[2]+m_a[15]*m_b[3],
                    m_a[3]*m_b[4]+m_a[7]*m_b[5]+m_a[11]*m_b[6]+m_a[15]*m_b[7],
                    m_a[3]*m_b[8]+m_a[7]*m_b[9]+m_a[11]*m_b[10]+m_a[15]*m_b[11],
                    m_a[3]*m_b[12]+m_a[7]*m_b[13]+m_a[11]*m_b[14]+m_a[15]*m_b[15]
    };

    m_b =  m_c;

}

I though this must be it, but it seems as if something is fundamentaly wrong. It is not moving at all. the camera is properly set. The method order is: cam.rotate then cam.setView.

Flipcodes originial rotate function:

void Camera::rotateLoc(float deg, float x, float y, float z) {

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadMatrixf(Transform);

    glRotatef(deg, x,y,z);

    glGetFloatv(GL_MODELVIEW_MATRIX, Transform);
    glPopMatrix();
}
1
Since you're using C++, have you considered using GLM for your vector and matrix math needs?R. Martinho Fernandes
@ Ali: I want to try it this way. When I used just glRotatef for x and y, a rotation around the z axis also occured. @Martinho: NoKnut

1 Answers

2
votes

Your code is pretty messy and incomplete.

I think your problem is here :

glPushMatrix();
glLoadMatrixf(Transform);                    // give the Transform matrix to GL (why?)

rotateMatrixf_y(Transform, deg);             // modify the Transform matrix

glGetFloatv(GL_MODELVIEW_MATRIX, Transform); // (3) retrieve the original Tranform matrix
glPopMatrix();

(3) just undoes whatever changes you've been doing in 'Transform' by calling 'rotateMatrixf_y'.

The flipcode code you added is using OpenGL to update the Tranform matrix, by calling glRotatef' and reading back the result, which is fine. In your method code, you should just remove every reference to OpenGL and just keep the call to rotateMatrixf_y, which does all the work in its own.

Do you really understand what's the use of the GL matrix stack ? You should perhaps go back to the basics by either using only GL functions or using your own, but get to know why it works in either way before mixing the uses.