需要帮助在 OpenGL 中移动相机
Posted
技术标签:
【中文标题】需要帮助在 OpenGL 中移动相机【英文标题】:need help moving a camera in OpenGL 【发布时间】:2015-11-01 23:54:26 【问题描述】:我正在开发一个简单的 OpenGL 项目。 我想要一个简单的相机在透视模式下移动。
我一直在阅读有关投影矩阵、gluLookAt 和模型视图矩阵的信息。我一直在阅读,我应该做的就是在投影矩阵中调用透视图,然后在模型视图矩阵中进行所有转换和相机移动。
#include "GLheaders.h"
void drawWorldAxis()
glLoadIdentity();
glBegin(GL_LINES);
glNormal3f(0, 0, 1);
glColor3ub(255, 0, 0);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glColor3ub(0, 255, 0);
glVertex3f(0,0,0);
glVertex3f(0,1,0);
glColor3ub(0, 0, 255);
glVertex3f(0,0,0);
glVertex3f(0,0,1);
glEnd();
void keyboard(unsigned char key, int x, int y)
glutPostRedisplay();
static float eye[3] = .5, .5, .5;
#include <stdio.h>
void display()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(55.0, 1, .1, 10000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawWorldAxis();
printf("eye at <%f, %f, %f>\n", eye[0], eye[1], eye[2]);
fflush(stdout);
gluLookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0);
eye[0] += .1;
eye[1] += .1;
glFlush();
glutSwapBuffers();
void reshape(int w, int h)
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(55.0, 1, -1, 10000);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
int main(int argc, char** argv)
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE| GLUT_DEPTH);
glutInitWindowSize(400,400);
glutCreateWindow("Tiny Test");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glEnable(GL_NORMALIZE);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
return EXIT_SUCCESS;
我希望这段代码显示代表世界坐标系的 x、y 和 z 轴的三行,并且当按下键时,相机应该移动并开始从越来越大的角度查看原点/坐标轴.
这里出了什么问题?我一直把头撞到墙上,试图弄清楚为什么什么都没有动。只有当我将 gluLookAt 调用放在投影矩阵中时它才会改变,我一直被告知这是一个糟糕的主意。
【问题讨论】:
【参考方案1】:坐标十字是在你设置lookAt矩阵之前绘制的,因此矩阵没有效果。
您必须更改顺序,以便在绘制时矩阵已经存在:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0);
drawWorldAxis();
printf("eye at <%f, %f, %f>\n", eye[0], eye[1], eye[2]);
fflush(stdout);
那么还有第二个问题:你正在重置drawWorldAxis
第一行的模型矩阵。在这里,您可以删除glLoadIdentity
调用或先将前一个矩阵压入堆栈:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0);
glPushMatrix();
drawWorldAxis();
glPopMatrix();
printf("eye at <%f, %f, %f>\n", eye[0], eye[1], eye[2]);
fflush(stdout);
【讨论】:
谢谢!这引导我去我需要去的地方! loadIdentity 也在制作它,所以我没有看到世界轴,因为lookAt 也没有应用于它。清除 loadIdentity,重新排序似乎可以解决问题!【参考方案2】:感谢@BDL 帮助解决此问题!这是我想要的正确代码
#include "GLheaders.h"
void drawWorldAxis()
glBegin(GL_LINES);
glNormal3f(0, 0, 1);
glColor3ub(255, 0, 0);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glColor3ub(0, 255, 0);
glVertex3f(0,0,0);
glVertex3f(0,1,0);
glColor3ub(0, 0, 255);
glVertex3f(0,0,0);
glVertex3f(0,0,1);
glEnd();
void keyboard(unsigned char key, int x, int y)
glutPostRedisplay();
static float eye[3] = -.1, -.1, 1;
#include <stdio.h>
void display()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(55.0, 1, .1, 10000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
printf("eye at <%f, %f, %f>\n", eye[0], eye[1], eye[2]);
fflush(stdout);
gluLookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0);
drawWorldAxis();
eye[0] += .1;
eye[1] += .1;
glFlush();
glutSwapBuffers();
void reshape(int w, int h)
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(55.0, 1, -1, 10000);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
int main(int argc, char** argv)
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE| GLUT_DEPTH);
glutInitWindowSize(400,400);
glutCreateWindow("Tiny Test");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glEnable(GL_NORMALIZE);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
return EXIT_SUCCESS;
【讨论】:
以上是关于需要帮助在 OpenGL 中移动相机的主要内容,如果未能解决你的问题,请参考以下文章