我在 opengl 3D 中遇到运动问题

I'm having a problem with movement in opengl 3D

我在 OpenGL 中遇到问题,当我按 W、A、S、D 时一切正常,但是当我按 space 或 shift 时,它发生了:

立方体在屏幕结束前消失。根据 xrot 和 yrot 的值,另一个轴会出现此问题。

我是 openGL 3D 的初学者,我不知道为什么会这样。

代码:

float xrot = 100.0f;
float yrot = -100.0f;

float tra_x = 0.0f;
float tra_y = 0.0f;
float tra_z = 0.0f;

GLFWwindow* window;
void drawBox()
{
    glEnable(GL_TEXTURE_2D);
    glBegin(GL_QUADS);
    glEnable(3553);

    glBegin(GL_QUADS);

    glColor3f(1.0f, 0.0f, 0.0f);
    // FRONT
    glVertex3f(-0.5f, -0.5f, 0.5f);
    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex3f(0.5f, -0.5f, 0.5f);
    glVertex3f(0.5f, 0.5f, 0.5f);
    glColor3f(1.0f, 0.0f, 0.0f);
    glVertex3f(-0.5f, 0.5f, 0.5f);
    // BACK
    glVertex3f(-0.5f, -0.5f, -0.5f);
    glVertex3f(-0.5f, 0.5f, -0.5f);
    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex3f(0.5f, 0.5f, -0.5f);
    glVertex3f(0.5f, -0.5f, -0.5f);

    glColor3f(0.0f, 1.0f, 0.0f);
    // LEFT
    glVertex3f(-0.5f, -0.5f, 0.5f);
    glVertex3f(-0.5f, 0.5f, 0.5f);
    glColor3f(0.0f, 0.0f, 1.0f);
    glVertex3f(-0.5f, 0.5f, -0.5f);
    glColor3f(1.0f, 0.0f, 0.0f);
    glVertex3f(-0.5f, -0.5f, -0.5f);
    // RIGHT
    glVertex3f(0.5f, -0.5f, -0.5f);
    glVertex3f(0.5f, 0.5f, -0.5f);
    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex3f(0.5f, 0.5f, 0.5f);
    glColor3f(0.0f, 0.0f, 1.0f);
    glVertex3f(0.5f, -0.5f, 0.5f);

    glColor3f(0.0f, 0.0f, 1.0f);
    // TOP
    glVertex3f(-0.5f, 0.5f, 0.5f);
    glVertex3f(0.5f, 0.5f, 0.5f);
    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex3f(0.5f, 0.5f, -0.5f);
    glVertex3f(-0.5f, 0.5f, -0.5f);
    glColor3f(1.0f, 0.0f, 0.0f);
    // BOTTOM
    glVertex3f(-0.5f, -0.5f, 0.5f);
    glColor3f(0.0f, 0.0f, 1.0f);
    glVertex3f(-0.5f, -0.5f, -0.5f);
    glVertex3f(0.5f, -0.5f, -0.5f);
    glVertex3f(0.5f, -0.5f, 0.5f);
    glEnd();
}

void display(void)
{
    glDisable(GL_BLEND);

    glShadeModel(GL_SMOOTH);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepth(1.0);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glRotatef(yrot, -1.0f, 0.0f, 0.0f);
    glRotatef(xrot, 0.0f, 1.0f, 0.0f);

    glTranslatef(-tra_x, tra_y, -tra_z);

    drawBox();

    glFlush();
    glfwSwapBuffers(window);

}
void framebuffer_resize_callback(GLFWwindow* window, int fbW, int fbH)
{
    glViewport(0, 0, fbW, fbH);
}
int main(void)
{   
    if (!glfwInit())
        return -1;

    glfwWindowHint(GLFW_SAMPLES, 2);
    window = glfwCreateWindow(640, 480, "Test", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }
    glfwSetFramebufferSizeCallback(window, framebuffer_resize_callback);
    glfwMakeContextCurrent(window);

    glClearColor(0.93f, 0.93f, 0.93f, 0.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glClearDepth(1.0f);

    while (!glfwWindowShouldClose(window))
    {
        display();
        if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
            tra_x += 0.1f;
        }
        if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
            tra_x -= 0.1f;
        }

        if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
            tra_z -= 0.1f;
        }
        if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
            tra_z += 0.1f;
        }

        if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) {
            tra_y += 0.1f;
        }

        if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) {
            tra_y -= 0.1f;
        }
        glfwPollEvents();
    }
}

对象被 Orthographic projection. The projection matrix defines the volume (clip space) which is projected on to 2 dimensional viewport. Actually you don't set a projection matrix, thus the projection is the Identity matrix 的票价平面剪裁。因此,view space、clip space 和 normalized device space 是相同的,并且 viewing volume 是一个独特的立方体,左侧、底部、附近 (-1, -1, -1) 和 (1, 1, 1) 的右、上、远。因此,近平面为 -1,远平面为 1。所有超出此 space 的几何体都被剪裁。
使用glOrtho定义一个更大比例的片段space。例如:

void display(void)
{
    // [...]

    # set projection matrix
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-1, 1, -1, -1, -10, 10); // near = -10, far = 10

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    // [...]

或者您可以使用 Perspective projection. At perspective projection the viewing volume is a [Frustum](https://en.wikipedia.org/wiki/Viewing_frustum。因此,您必须在近平面和远平面之间沿负 z 轴移动对象。

通过gluPerspective and move the object in between then near and far plane by gluLookAt创建透视投影:

void display(void)
{
    // [...]

    # set projection matrix
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    //glOrtho(-1, 1, -1, -1, -10, 10); // near = -10, far = 10
    gluPerspective(90.0, 480.0/640.0, 0.1, 20.0) 

    // set view matrix
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0, 0, 5.0, 0, 0, 0, 0, 1.0, 0); 

    // [...]

What exactly are eye space coordinates?