关于c ++:需要帮助在OpenGL中移动相机

need help moving a camera in OpenGL

我正在开发一个简单的OpenGL项目。我想让一个简单的相机在透视模式下移动。

我一直在读投影矩阵、GluLook和模型视图矩阵。我一直在读,我所要做的就是在投影矩阵中调用透视图,然后在模型视图矩阵中调用所有转换和相机移动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#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>
"
, 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
2
3
4
5
6
7
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0);
drawWorldAxis();
printf("eye at <%f, %f, %f>
"
, eye[0], eye[1], eye[2]);
fflush(stdout);

然后还有第二个问题:您正在重置drawWorldAxis的第一行中的模型矩阵。在这里,您可以删除glLoadIdentity调用,或者先将前一个矩阵推送到堆栈中:

1
2
3
4
5
6
7
8
9
10
11
12
13
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>
"
, eye[0], eye[1], eye[2]);
fflush(stdout);


感谢@bdl帮助解决此问题!这是我想要的正确代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#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>
"
, 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;
}