需要帮助在 OpenGL 中移动相机

need help moving a camera in OpenGL

我正在处理一个简单的 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 轴的三行,并且当按下键时,相机应该移动并开始从更多的角度观察 origin/coordinate 轴和更激烈的角度。

这里出了什么问题?我一直在用头撞墙,想弄清楚为什么什么都没有动。只有当我将 gluLookAt 调用放入投影矩阵时它才会改变,我一直被告知这是一个糟糕的主意。

在设置 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);

感谢@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;
}