0

since some time, I am stucked with a camera rotation problem in OpenGL.

I try to rotate the camera via mouse movement, but the camera is only flickering (the object which is spoted by the camera is flickering).

I initialize the camera as follows:

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

Here the Transform is the Transformation matrix. Since OpenGL is column major, it should be right?

The next part explains, what is happening before drawing a frame.

At first, I refresh the camera with the mouse movement, depending on the delta x and y of the last mousepointer position, the movement value can be positiv or negative:

void Camera::refresh(){

    delta_x = UserInputHandler::getMouseMotion()[0];
    delta_y = UserInputHandler::getMouseMotion()[1];

}

In the next step I am adjusting the camera in the scene. If the mouse moved along the x or y axis, I want to rotate the camera:

void Camera::adjust(){

    if(old_x != UserInputHandler::getMousePosition()[0]){

                // rotate around y axis
                rotateLocal_y(-1.0f*(delta_x));

                // save old mouse position
        old_x = UserInputHandler::getMousePosition()[0];
    }

    if(old_y != UserInputHandler::getMousePosition()[1]){

        rotateLocal_x(-1.0f*(delta_y));

        old_y = UserInputHandler::getMousePosition()[1];
    }

    // loading the calculated Transform matrix to a viewmatrix
    setView();
}

The rotation around the y axis is a matrix multiplication with a rotation matrix and the Transform matrix:

//rotate a matrix around y axis
void rotateMatrixf_y(float *aMatrix, float angle){

    float rotMatrix[] = {cos(angle),0,-1*sin(angle),0, 0, 1, 0, 0, sin(angle), 0, cos(angle), 0, 0, 0, 0, 1};
    multMatrixMatrix(aMatrix, rotMatrix);
}

Keeping in mind that OpenGL is column major, the multiplication function is created like this:

void multMatrixMatrix(float *m_a, float *m_b){
    // column major
    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], //0
                        m_a[1]*m_b[0]+m_a[5]*m_b[1]+m_a[9]*m_b[2]+m_a[13]*m_b[3], //1
                        m_a[2]*m_b[0]+m_a[6]*m_b[1]+m_a[10]*m_b[2]+m_a[14]*m_b[3], // 2
                        m_a[3]*m_b[0]+m_a[7]*m_b[1]+m_a[11]*m_b[2]+m_a[15]*m_b[3], // 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], //4
                        m_a[1]*m_b[4]+m_a[5]*m_b[5]+m_a[9]*m_b[6]+m_a[13]*m_b[7], //5
                        m_a[2]*m_b[4]+m_a[6]*m_b[5]+m_a[10]*m_b[6]+m_a[14]*m_b[7], // 6
                        m_a[3]*m_b[4]+m_a[7]*m_b[5]+m_a[11]*m_b[6]+m_a[15]*m_b[7], // 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], // 8
                        m_a[1]*m_b[8]+m_a[5]*m_b[9]+m_a[9]*m_b[10]+m_a[13]*m_b[11], //9 
                        m_a[2]*m_b[8]+m_a[6]*m_b[9]+m_a[10]*m_b[10]+m_a[14]*m_b[11], // 10
                        m_a[3]*m_b[8]+m_a[7]*m_b[9]+m_a[11]*m_b[10]+m_a[15]*m_b[11], // 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], // 12
                        m_a[1]*m_b[12]+m_a[5]*m_b[13]+m_a[9]*m_b[14]+m_a[13]*m_b[15], // 13
                        m_a[2]*m_b[12]+m_a[6]*m_b[13]+m_a[10]*m_b[14]+m_a[14]*m_b[15], // 14
                        m_a[3]*m_b[12]+m_a[7]*m_b[13]+m_a[11]*m_b[14]+m_a[15]*m_b[15] // 15

    };

     for(int i = 0; i<16;i++){
        m_a[i] = m_c[i];
     }

}

At this point, the matrix should be fine and loaded to OpenGL. The setView method was called in the adjust():

void Camera::setView() {


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

The functions are called in the complete scene like this:

int DrawGLScene(GLvoid){ // Here's Where We Do All The Drawing

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);         // Clear The Screen And The Depth Buffer


glMatrixMode(GL_MODELVIEW);
glLoadIdentity();                           // Reset The Current Modelview Matrix

glPushMatrix();
cam.refresh();
cam.adjust();

// distance between object and near plane
glTranslatef(0.0f, 0.0f,-30.0f);        

   // testwise rotating the drawn object
float rotX,rotY,rotZ;
rotX = -90.0f;
rotZ = 0.0f;
rotY = 0.0f;


MeshNode* aMeshNode = myMeshLoader.getMeshNode();

while(aMeshNode->next){

    Mesh aMesh = *aMeshNode->theMesh;
    FaceNode* aFaceNode = aMesh.getFirstFaceNode();

    while(aFaceNode->next){
        Face theFace = *aFaceNode->aFace;

        Vertex theFaceVertexA = aMesh.getVertexAt((*theFace.myVertices)[0]);
        Vertex theFaceVertexB = aMesh.getVertexAt((*theFace.myVertices)[1]);
        Vertex theFaceVertexC = aMesh.getVertexAt((*theFace.myVertices)[2]);

        glColor3f(1.0f,1.0f,1.0f);
        glBegin(GL_TRIANGLES);                      // Drawing Using Triangles
    //  glNormal3f(*theFace.myNormal[0],*theFace.myNormal[1],*theFace.myNormal[2]);
        glVertex3f( theFaceVertexA.position[0], theFaceVertexA.position[1], theFaceVertexA.position[2]);
        glVertex3f( theFaceVertexB.position[0], theFaceVertexB.position[1], theFaceVertexB.position[2]);
        glVertex3f( theFaceVertexC.position[0], theFaceVertexC.position[1], theFaceVertexC.position[2]);
        glEnd();                            // Finished Drawing The Triangle

        aFaceNode = aFaceNode->next;
    }

    aMeshNode = aMeshNode->next;
}
glPopMatrix();

return TRUE;                                // Everything Went OK

}

Here I select the Modelview matrix, then the load the identity matrix. Between a matrix push and pop is the camera refresh and adjustment (which includes the setView) then I set a tranform for the object I want to draw, followed by drawing the object.

Thats all. I played around a lot with some push and pops of the matrix, looked at the flipcode camera tutorial (http://www.flipcode.com/archives/OpenGL_Camera.shtml), but the flickering still remains. Does anybody have any ideas what could be wrong?

RBarryYoung
  • 55,398
  • 14
  • 96
  • 137
Knut
  • 136
  • 2
  • 11

2 Answers2

0

It could be depending on the fact that the DEPTH_TEST in your application is disable.

Alternatively it could be depending on the size of the Depth buffer that your device support.

Maurizio Benedetti
  • 3,557
  • 19
  • 26
  • Hi, Maurizio, I am enabling the DEPTH_TEST in an different init function. – Knut Jan 18 '12 at 17:12
  • Hey, I was thinking that the problem could be depending on the way you set the far and near plane in your frustum configuration. Let me explain it. If you have a 12 bit depth buffer and you set a near and far planes too distant from each other(for instance, near 0.01, far 100.000), the precision of the DEPTH TEST will be most probably compromised and you will see glitches in the handling of the DEPTH of the different faces. Try to decrease the difference between the near and far plane and I guess this should fix your problem. – Maurizio Benedetti Jan 20 '12 at 09:12
  • Hi, it was actually, the problem, that I used degrees instead of radiants, but your information about the z buffer is also very useful, thank you. – Knut Jan 21 '12 at 10:06
0

I found the problem, it is because I was using degrees and not radiants. So the rotation is either around 90 degrees or around 0 degrees, stupid but true!

Knut
  • 136
  • 2
  • 11