使用平截头体时 OpenGL 远剪裁

OpenGL far clipping when using frustum

我正在使用 GLFW + OpenGL 尝试制作“旋转立方体”。虽然大部分都在工作,但我在远平面上有裁剪。我已经尝试将截锥体的值更改为非常大的数字,但它似乎没有效果。

int main(void) {
    if (!glfwInit()) exit(EXIT_FAILURE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
    glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
    GLFWwindow* window = glfwCreateWindow(640, 360, "3dTest", NULL, NULL);
    if (!window) {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);   // Grey Background
    float rotqube = 0;
    while (!glfwWindowShouldClose(window)) {
        // clear color and depth buffer for new frame
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // set up camera
        glViewport(0, 0, 640, 360);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glFrustum(-100.0, 100.0, -100.0, 100.0, 100.0, -100.0);

        // position camera
        glTranslatef(0.0f, 0.0f, -2.0f);    // Translate Into The Screen 2.0 Units
        glRotatef(rotqube, 0.0f, 1.0f, 0.0f);   // Rotate The cube around the Y axis
        glRotatef(rotqube, 1.0f, 1.0f, 1.0f);

        glBegin(GL_QUADS);      // Draw The Cube Using quads
        glColor3f(0.0f, 1.0f, 0.0f);    // Color Blue
        glVertex3f(1.0f, 1.0f, -1.0f);  // Top Right Of The Quad (Top)
        glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Quad (Top)
        glVertex3f(-1.0f, 1.0f, 1.0f);  // Bottom Left Of The Quad (Top)
        glVertex3f(1.0f, 1.0f, 1.0f);   // Bottom Right Of The Quad (Top)
        ...
        glColor3f(1.0f, 0.0f, 1.0f);    // Color Violet
        glVertex3f(1.0f, 1.0f, -1.0f);  // Top Right Of The Quad (Right)
        glVertex3f(1.0f, 1.0f, 1.0f);   // Top Left Of The Quad (Right)
        glVertex3f(1.0f, -1.0f, 1.0f);  // Bottom Left Of The Quad (Right)
        glVertex3f(1.0f, -1.0f, -1.0f); // Bottom Right Of The Quad (Right)
        glEnd();            // End Drawing The Cube

        rotqube += 0.3f;

        //Swap buffer and check for events
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwDestroyWindow(window);
    glfwTerminate;
    exit(EXIT_SUCCESS);
    return 0;
}

这是它的样子:

glFrustum(-100.0, 100.0, -100.0, 100.0, 100.0, -100.0);
                                               ^ wat

glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal):

Parameters:

  • left, right:

    Specify the coordinates for the left and right vertical clipping planes.

  • bottom, top:

    Specify the coordinates for the bottom and top horizontal clipping planes.

  • nearVal, farVal:

    Specify the distances to the near and far depth clipping planes.
    Both distances must be positive.

尝试 0.1100.0:

glFrustum(-100.0, 100.0, -100.0, 100.0, 0.1, 100.0);

您根本没有使用透视投影。您的来电

glFrustum(-100.0, 100.0, -100.0, 100.0, 100.0, -100.0);

除了设置 GL_INVALID_VALUE 错误状态外,没有任何影响

如第 2.11 节 OpenGL 2.0 specification 所述 "Coordinate Transformations":

For

void Frustum( double l, double r, double b, double t, double n, double f );

the coordinates (l, b, −n)^T and (r, t, −n)^T specify the points on the near clipping plane that are mapped to the lower left and upper right corners of the window, respectively (assuming that the eye is located at (0, 0, 0)^T). f gives the distance from the eye to the far clipping plane. If either n or f is less than or equal to zero, l is equal to r, b is equal to t, or n is equal to f, the error INVALID_VALUE results.

尝试在近平面或远平面之一位于相机后面的位置设置投影没有丝毫意义,并且会在渲染过程中导致大量数学异常(即相机平面上的顶点除以零),因此是不允许的。

由于此函数因错误而失败,您正在使用单位矩阵作为投影矩阵,并以正交投影结束。

既然写了这么多,我必须让你知道所有这些都已经完全过时了。固定功能管道和 GL 矩阵堆栈,包括 glFrustumglLoadIdendityglRotate 和使用 glBegin/glEnd 的即时模式渲染等功能已弃用, 已从 OpenGL 的核心配置文件中删除 差不多 十年前。在 2018 年尝试学习这些东西是一个非常糟糕的主意,我强烈建议您改为学习现代 OpenGL。