c++ - 使用平截头体时 OpenGL 远剪裁

标签 c++ opengl 3d glfw

我正在使用 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;
}

这是它的样子:

This is what it looks like

最佳答案

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

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

除了设置 GL_INVALID_VALUE 错误状态外,没有任何效果

OpenGL 2.0 specification 中所述,第 2.11 节“坐标变换”:

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。

关于c++ - 使用平截头体时 OpenGL 远剪裁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48064618/

相关文章:

c++ - 什么时候出队大小调用不是线程安全的?

c++ - 请指出这个字符串反转函数有什么问题?

c++ - 为什么 CERT 标准 PRE00-CPP 说 "Avoid defining macros"

c++ - 使用 BOOST ASIO 在异步服务器中发送局部变量

javascript - 使用 ThreeJS 获取球体纹理的点击位置

c++ - 使用 VAO 和 VBO 在 3.2 中绘制 OpenGL 直线和正方形

C++ OpenGL 坐标转换

opengl - 统一点数组和管理片段着色器坐标系

c# - OpenCV:基本矩阵和 SolvePnPRansac 的投影矩阵完全不同

javascript - 拖动时围绕对象旋转相机