2012-01-17 195 views
0

因为有一段时间,我在OpenGL中遇到了相机旋转问题。OpenGL相机旋转闪烁

我尝试通过鼠标移动来旋转摄像头,但摄像头只是闪烁(摄像头发现的物体闪烁)。

我初始化相机如下:

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

在这里,变换为变换矩阵。由于OpenGL是列专业,它应该是正确的?

下一部分将解释在绘制框架之前发生了什么。

起初,我刷新相机用鼠标移动,这取决于最后的MousePointer位置的Δx和y,运动值可以是positiv或负:

void Camera::refresh(){ 

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

} 

在下一步骤我我正在调整场景中的相机。如果鼠标沿着x或y轴移动时,我想旋转相机:

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

围绕y轴的旋转是一个矩阵乘以一个旋转矩阵和变换矩阵:

//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); 
} 
记住

牢记这OpenGL是列为主,创建这样的乘法功能:

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

} 

在这一点上,矩阵要细并载入到OpenGL的。该的setView方法被调用的调整():

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

功能被称为像这样完整的场景:

INT DrawGLScene(GLvoid){//这里我们做的所有图纸

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 

}

在这里,我选择模型变换矩阵,然后将负载的单位矩阵。 在矩阵的push和pop之间是相机刷新和调整(其中包括setView),然后我为要绘制的对象设置变形,然后绘制对象。

就是这样。我用矩阵的一些推动和弹出来玩了很多,看了一下flipcode相机教程(http://www.flipcode.com/archives/OpenGL_Camera.shtml),但闪烁仍然存在。有没有人有什么想法可能是错的?

回答

0

我发现问题,这是因为我使用的是度数而不是辐射量。所以这个旋转要么在90度左右,要么在0度左右,愚蠢但是真实!

0

这可能取决于应用程序中的DEPTH_TEST被禁用的事实。

或者,它可能取决于设备支持的深度缓冲区的大小。

+0

嗨,Maurizio,我在不同的初始化函数中启用DEPTH_TEST。 – Knut 2012-01-18 17:12:43

+0

嘿,我在想这个问题可能取决于你在你的平截头体配置中设置远近平面的方式。让我解释一下。如果你有一个12位深度的缓冲区,并且你设置了一个距离彼此太远(例如,接近0.01,远远100.000)的近平面和远平面,深度测试的精度很可能会受到影响,你会看到处理不同面孔的深度。尝试减少近平面和远平面之间的差异,我想这应该解决您的问题。 – 2012-01-20 09:12:39

+0

嗨,实际上,问题是我使用度数而不是辐射量,但是关于z缓冲区的信息也非常有用,谢谢。 – Knut 2012-01-21 10:06:44