【问题标题】:flickering while rendering a 3D object (.obj file) using OpenGL使用 OpenGL 渲染 3D 对象(.obj 文件)时闪烁
【发布时间】:2011-12-12 00:41:13
【问题描述】:

在尝试使用 OpenGL(和 GLFW 库)渲染 3D 对象时,模型会出现大量闪烁。我正在使用我自己编写的库读取.obj 文件。

下面写的是我的渲染函数: 不幸的是,为了了解面和顶点是如何输入的,我必须提供我所有的代码,这些代码是链接的: 压缩代码以及可执行文件和示例.objSource

我正在使用来自here 的 .obj 文件来测试程序。目前,该程序不支持法线和纹理,这不是问题,因为网站上的大多数模型都没有它们。此外,(现在)它仅从“123.obj”读取,因此该文件不应命名为其他任何名称。而且它只接受一个空格,不超过这个。

 float render()
    {
        glfwSetTime(0.0f);
        int win_width;
        int win_height;
        glfwGetWindowSize(&win_width, &win_height);
        float win_aspect = (float)win_width / (float)win_height;
        glViewport(0, 0, win_width, win_height);

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(90, win_aspect, 0, 100.0);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(0, 0, 50.0, 0, 0, 0, 0.0, 1.0, 0.0);

        glEnable(GL_DEPTH);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_COLOR_MATERIAL);
        glEnable(GL_NORMALIZE); 
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glRotatef(angle , 0 , 1, 0);
        glColor3f(0.0f, 0.0f, 0.0f);
        int index = 0;
        for(int a = 0; a < faces.size(); a++)
        {
            if(faces[a].vertices.size() == 3)
            {
                glBegin(GL_TRIANGLES);
            }
            else
            {
                glBegin(GL_QUADS);
            }
            for(int b = 0; b < faces[a].vertices.size(); b++)
            {
                index = faces[a].vertices[b];
                glVertex3f(vertices[index].Dimensions[_x], vertices[index].Dimensions[_y], vertices[index].Dimensions[_z]);
            }
            glEnd();
        }
        glfwSwapBuffers();
        return (float)glfwGetTime();

【问题讨论】:

  • 我也在想同样的事情。我认为 glfwSwapBuffers() 做了双重缓冲?
  • 闪烁听起来像是双缓冲的问题。您使用 glfwSwapBuffers(),但您确定要绘制的上下文启用了双缓冲吗?
  • 可能是驱动问题?您是否尝试过更新驱动程序?
  • 驱动程序是最新的。而且 glfw 总是有双缓冲窗口。
  • 只是一个想法。 fps限制呢。如果它不受限制,那么您的渲染速度可能 > 1000fps。这会导致很多闪烁/抽搐等。最好做60fps这样的恒定帧渲染。

标签: c++ windows opengl glfw wavefront


【解决方案1】:

问题来了

gluPerspective(90, win_aspect, 0, 100.0);

您不能将 0 设置为近剪辑,将其设置为更大的值,例如 0.1 或 1.0。

gluPerspective(90, win_aspect, 1.0, 100.0);

nearclip 为 0 时,您的所有深度都映射到 z = 1,然后您开始进行 z 战斗。

编辑:如果您有兴趣,这里有一些关于透视深度的理论:

对于距相机 x 的给定距离,您的透视变换会输出一个特定的深度值 z。在远剪辑处,该值将是最大值 1,在近剪辑处,它将为 0。 然而,在这些值之间,关系并不像您所期望的那样是线性的。曲线类似于下图:

Diagram

当您将近剪辑设置为 0 时,您的曲线会严重扭曲,因此现在所有距离都映射到 z = 1。

由于这一切,您还应该尽量保持比率远:近小于 10000:1

【讨论】:

  • 我的另一个(小)问题是:如果我只想旋转或平移这个特定的模型,这是否意味着我必须遍历每个顶点并增加它,或者是否有更简单的方式?
  • 是的,有一个更简单的方法。在您的循环之前,添加一个 glPushMatrix();,然后执行所有的旋转和平移(glTranslate(...)、glRotate(...))。绘制完该模型后,编写 glPopMatrix();。这一切都恢复到 glPushMatrix 之前的样子。
  • 另外,如何围绕自己的轴旋转对象?我试过了,但没有任何效果:|。我试图平移到它的中心,然后让它围绕 x 轴旋转,但这仍然使对象在该点周围的半径内移动,而我只是希望它旋转。
  • 图表链接不再有效。 :( 这个答案虽然解决了我几个月来一直存在的问题。
猜你喜欢
  • 2014-04-06
  • 1970-01-01
  • 1970-01-01
  • 2012-09-28
  • 2013-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-13
相关资源
最近更新 更多