OpenGL相机旋转闪烁
一段时间以来,我一直被OpenGL中的相机旋转问题所困扰 我试图通过鼠标移动来旋转相机,但是相机只是在闪烁,而被相机捕捉到的物体在闪烁 我按如下方式初始化相机:OpenGL相机旋转闪烁,opengl,matrix,camera,rotation,camera-matrix,Opengl,Matrix,Camera,Rotation,Camera Matrix,一段时间以来,我一直被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; T
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是以列为主的,那么它应该是对的吗
下一部分将解释在绘制框架之前发生的事情
首先,我用鼠标移动刷新相机,根据最后一个鼠标指针位置的delta x和y,移动值可以是正值或负值:
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是column major,乘法函数的创建方式如下:
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];
}
}
在完整场景中调用的函数如下所示:
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];
}
}
int DrawGLSceneGLvoid{//这里是我们绘制所有图形的地方
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
}
这里我选择Modelview矩阵,然后加载标识矩阵。
在矩阵推送和弹出之间是相机刷新和调整,其中包括setView,然后我为要绘制的对象设置变换,然后绘制对象
就这些。我玩了很多关于矩阵的推拉和弹出,看了flipcode相机教程,但闪烁仍然存在。有人知道什么地方可能出错吗?这可能取决于应用程序中的深度测试被禁用这一事实
或者,这可能取决于设备支持的深度缓冲区的大小。我发现了问题,因为我使用的是度,而不是辐射度。所以旋转要么是90度左右,要么是0度左右,愚蠢但真实 嗨,Maurizio,我正在另一个init函数中启用DEPTH_测试。嗨,我想问题可能取决于你在平截头体配置中设置远平面和近平面的方式。让我解释一下。如果您有一个12位深度缓冲区,并且您将近平面和远平面设置得彼此太远(例如,近0.01、远100.000),则深度测试的精度很可能会受到影响,并且您将在处理不同面的深度时看到小故障。试着减少近平面和远平面之间的差异,我想这应该可以解决你的问题。嗨,事实上,问题是,我使用了度而不是弧度,但是你关于z缓冲区的信息也非常有用,谢谢。