使用视锥体时OpenGL远剪裁

时间:2018-01-02 16:36:50

标签: 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

2 个答案:

答案 0 :(得分:3)

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)

  

参数:

     
      
  • leftright

         

    指定左右垂直剪裁平面的坐标。

  •   
  • bottomtop

         

    指定底部和顶部水平剪裁平面的坐标。

  •   
  • nearValfarVal

         

    指定近深度和远深度剪裁平面的距离   两个距离必须为正。

  •   

尝试使用0.1100.0

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

答案 1 :(得分:3)

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

glFrustum(-100.0, 100.0, -100.0, 100.0, 100.0, -100.0);
除了设置GL_INVALID_VALUE错误状态外,

没有任何影响

OpenGL 2.0 specification中所述,第2.11节和第34节;协调转换":

  

有关

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

坐标(l, b, −n)^T(r, t, −n)^T   指定近剪裁上的点   映射到窗口左下角和右上角的平面,   分别(假设眼睛位于(0, 0, 0)^T)。 f给出距离   从眼睛到远剪裁平面。 如果nf小于或等于零,   l等于rb等于t,或n等于f错误{{ 1}}结果

尝试设置一个投影,其中一个近或远的平面位于后面相机没有任何意义,并且在渲染过程中会导致很多数学怪异(即除以零)对于位于相机平面上的顶点,因此不允许使用。

由于此函数因错误而失败,因此您使用单位矩阵作为投影矩阵,并最终得到正交投影。

现在写完了所有这些,我必须让你知道所有这一切都已经过时了。不推荐使用固定功能管道和GL矩阵堆栈,包括INVALID_VALUEglFrustumglLoadIdendity等函数以及使用glRotate / glBegin的立即模式渲染, 已被删除形成几乎十年之前的OpenGL核心配置文件。在2018年尝试学习这些东西是一个非常糟糕的主意,我强烈建议你学习现代OpenGL。