【问题标题】:glColor not actually changing OpenGL's colorglColor 实际上并没有改变 OpenGL 的颜色
【发布时间】:2011-11-29 18:29:30
【问题描述】:

我遇到了一个特别烦人的问题。在某些情况下,对 glColor 的调用似乎被忽略了,导致对象以不正确的颜色显示。

可以在here找到一个显示此问题的 Qt 项目。

当你运行程序时,你在屏幕上看到的只是两个从一个角度看的盒子状物体。左边的对象是调用glCallList(boxModel1); 渲染的,右边的对象是调用glCallList(boxModel2); 渲染的。这两个显示列表是由明显标题的方法创建的。

对于boxModel1boxModel2,我使用一个名为squareModel 的显示列表来渲染框的侧面。我这样做是因为虽然这种情况下的方形模型很简单,但我的实际程序中的 squareModel 要复杂得多,法线会发生变化等等。

问题与createManyRectangles 方法有关。当使用足够小的数字(对我来说是 2715)调用它时,颜色会正常显示:一个蓝色框和一个红色框。当数字很高(我是 2716)时,颜色会被忽略,两个框都呈现为白色。

谁能解释一下这里发生了什么?

【问题讨论】:

    标签: c++ qt opengl


    【解决方案1】:

    所有渲染都是通过显示列表完成的,但是当我在显示列表中指定颜色以及在调用显示列表之前指定颜色时都会出现问题。

    显示列表不是独立的。他们不会在更改 OpenGL 状态后恢复。如果 DL 更改了 OpenGL 状态,那么这将是 OpenGL 的状态DL 执行之后。

    你只是没有发布足够的代码来明确地说任何事情;这只是最可能的解释。在您可以发布可重现的案例之前,没有真正的方法可以提供帮助。

    【讨论】:

    • 我不明白这有什么帮助。我从来没有明确地为每个图元指定我想要的颜色,无论是在显示列表中还是在它之前。我的问题是我调用了glColor,在下一行代码中,OpenGL 的颜色没有改变。
    • @Elliott:您没有发布任何会重现该问题的代码。所以我要继续说的是你说的。除了驱动程序错误之外,最可能的解释是您的显示列表在您使用glGetFloatv 回读之前更改了状态。您在检查 OpenGL 错误吗?
    • 我更新了我的驱动程序,它仍然发生。没有 OpenGL 错误。至于更改颜色的显示列表,getFloatv 调用紧跟在glColor4f 调用之后的行上,所以没有什么可以改变它。我意识到,在没有看到代码的情况下进行修复真的很难。我正在开发一个可重现的版本,但它是一个相当大的程序。
    • 我添加了一个可重现的项目。希望这会有所帮助。
    • 下载并编译给定项目。 makeManyRectangles(100000) ; 不会产生错误的显示...
    【解决方案2】:

    我有一个类似的问题,我用不同的颜色绘制了很多点,然后绘制了一个蓝色线框立方体。 (我在我的项目中使用了 GLUT。)

    最初我的代码如下所示:

    glBegin(GL_POINTS);
    
        for(int i=0;i<N;i++)
         {
          glColor3f(R[i],G[i],B[i]);
          glVertex3f(X[i],Y[i],Z[i]);
         }
    
    glEnd();
    glColor3f(0.0f, 0.0f, 1.0f);
    glutWireCube(2.0f);
    

    但是,这导致了一个闪烁的立方体,它不断地从帧到帧将其颜色更改为一些不可预测的颜色,就好像最后一个 glColor3f 被忽略了一样。

    解决方案:我将立方体的 glColor3f 放在 glEnd() 之前。

    glBegin(GL_POINTS);
    
        for(int i=0;i<N;i++)
         {
          glColor3f(R[i],G[i],B[i]);
          glVertex3f(X[i],Y[i],Z[i]);
         }
    
    glColor3f(0.0f, 0.0f, 1.0f);    // <= Changed only the position of this line
    glEnd();
    glutWireCube(2.0f);
    

    我不知道为什么,但这解决了我的问题。现在我得到一个蓝色线框立方体,并且不再忽略 glColor3f...

    干杯,

    大卫

    【讨论】:

    • 看来这种东西是意料之中的。在这之后,我做了很多研究,结果发现整个固定功能管道(即调用glBegin,glVertex等)已被弃用,大多数显卡甚至不再支持它在硬件上,软件就开发时间而言,实现的优先级可能要低得多。
    【解决方案3】:

    尝试使用glIntercept 运行您的程序。这允许您记录每个 OpenGL 调用。比较 2715 和 2716 矩形数之间的输出。如果有任何差异,它应该会引导您朝着正确的方向前进。

    编辑

    由于您的实际 OpenGL 调用看起来没问题,这可能是您提到的驱动程序问题。您可以尝试不同的环境(视频卡、PC 等),因为正如图腾指出的那样,他没有遇到您的问题。或许您可以提供一些有关您的环境的信息?

    尝试在没有显示列表的情况下渲染矩形,看看是否有帮助。在您将使用glCallList 的地方,改为重做OpenGL 调用序列。如果这样可以解决问题,您将知道您的应用或驱动程序中的显示列表管理存在问题。

    另外,如果显示列表成为问题,您真的需要使用显示列表吗?一段时间以来,它们的使用越来越少,有利于 VBO。也许你可以用它“解决”你的显示列表问题。

    【讨论】:

    • 我运行它。这是 2715 的输出:link。这是 2716 的输出:link。请注意,我删除了大部分“许多矩形”调用以节省空间,但我只删除了相同的部分。唯一的区别是设置上下文时的内存地址,交换缓冲区时的内存地址,以及添加了一个 glColor 和四个 glVertex 调用。换句话说,没有任何人不希望出现的差异。我如何解释这个?驱动程序错误?
    • 我看了你的输出,不幸的是你是对的......我看不出 OpenGL 调用的顺序有什么问题。
    • 作为临时妥协,我能够通过删除方形显示列表来解决问题。相反,它只是一个创建正方形的方法,并且该方法在显示列表被调用的地方被调用。从长远来看,我肯定会看看 vbos。感谢您对 glintercept 程序的帮助,它很快缩小了可能的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    • 1970-01-01
    • 2016-03-30
    • 1970-01-01
    • 2021-08-04
    相关资源
    最近更新 更多