我最近用C ++开始使用openGL。我在C ++方面没有那么多经验,但在其他语言方面有很好的经验。
我正在努力控制相机FPS风格以开始一个小游戏,并在我学习的同时逐一添加内容。我知道这个问题经常被问到,我通过很多教程/论坛阅读。
我用gluLookAt()做得很好;但我看到它不是控制FPS相机的最佳方式。我最近一直在使用矩阵堆栈而且我有点迷失了。
我有一个代码工作,但我的旋转似乎是围绕中心轴或类似的东西。我也得到了一些与Gimbal Locking有关的奇怪控制。我有他们的经验,一旦我有足够好的东西就会使用它们。
我试图保留最重要的代码并保留其余的,渲染和主要代码。鼠标和键盘控件按预期工作:
void renderScene(void) {
if(init==1){
glTranslatef(0.0f,-1.0f,-5.0f);
init = 0;
}
// Clear Color and Depth BuffersWDW
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset transformations
//glLoadIdentity();
// Set the camera
glTranslatef(-deltaStrafe,0,-deltaMove);
glRotatef(Pitch,1.0f,0.0f,0.0f);
glRotatef(Yaw,0.0f,1.0f,0.0f);
// Draw ground
glColor3f(0.9f, 0.9f, 0.9f);
glBegin(GL_QUADS);
glVertex3f(-50.0f, 0.0f, -50.0f);
glVertex3f(-50.0f, 0.0f, 50.0f);
glVertex3f( 50.0f, 0.0f, 50.0f);
glVertex3f( 50.0f, 0.0f, -50.0f);
glEnd();
// Draw 36 SnowMan
for(int i = -3; i < 3; i++)
for(int j=-3; j < 3; j++) {
glPushMatrix();
glTranslatef(i*10.0,0,j * 10.0);
if(i==j){
drawSnowMan();
}
else{
drawTree();
}
glPopMatrix();
}
glutSwapBuffers();
printConsole();
}
和主要功能:
int main(int argc, char **argv) {
// init GLUT and create window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(780,0);
glutInitWindowSize(800,800);
glutCreateWindow("Physic Engine");
// register callbacks
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
glutIdleFunc(renderScene);
// OpenGL init
glEnable(GL_DEPTH_TEST);
// enter GLUT event processing cycle
glutMainLoop();
return 1;
}
谢谢!
编辑:将建议的轮换/翻译顺序更改为:
glRotatef(Yaw,0.0f,1.0f,0.0f);
glRotatef(Pitch,1.0f,0.0f,0.0f);
glTranslatef(-deltaStrafe,0,-deltaMove);
但是我的相机不能在自己的轴上旋转。它们似乎围绕中心轴旋转,如果我不移动,我会向(0,0,0)倾斜。如何围绕摄像机轴旋转作为标准FPS?感谢。
答案 0 :(得分:0)
你做的是翻译然后旋转。
旋转相机,翻译相机,然后绘制场景。旋转始终应用于原点,因此如果旋转然后平移,则应用旋转,然后平移旋转的参照系。
出于类似的原因,您还应该颠倒俯仰和偏航的顺序。
你也应该限制音高,使你不能向上或向下旋转超过90度,否则可能会迷失方向。
此外,除非您在任意轴上应用旋转,否则不需要四元数。