【问题标题】:glDrawElements flicker and crashglDrawElements 闪烁并崩溃
【发布时间】:2009-12-05 19:29:47
【问题描述】:

我在使用 glDrawElements() 时遇到了一个可疑的错误。我正在尝试渲染简单的基元(主要是矩形)以加快文本等的绘制,但是当我调用 glDrawElements() 时,整个屏幕会在一帧左右闪烁黑色(不仅仅是我的窗口区域)。下一帧它会变回与以前相同的“Windows 颜色”。所以它闪烁了几秒钟,最终出现在一个消息框中

The NVIDIA OpenGL Driver encountered an unrecoverable error
and must close this application.

Error 12

在调用 glDrawElements() 之前我需要重置 GL 的任何设置吗?我知道这不是一些悬空的 glEnableClientState(),我检查了它(我曾经有一个,但后来 glDrawElements() 崩溃了)。

想一想,它几乎看起来像一些后台缓冲区错误......关于尝试什么的任何想法?

【问题讨论】:

    标签: visual-c++ opengl nvidia


    【解决方案1】:

    显然您正在混合 VBO 模式和 VA 模式。这是完全可能的,但必须小心使用。

    当你打电话时:

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    

    这意味着下次您使用glDrawElements(..., ..., ..., x) 渲染某些东西时,它将使用 x 作为索引数据上的指针,并且最后一次调用 glVertexPointer 指向顶点数据上的指针。

    如果您取消绑定当前 VBO 和 IBO(使用上述两个 glBindBuffer 调用),这意味着当使用相同的 glDrawElements 渲染时,x 将用作索引上的偏移量IBO 中的数据,最后一次调用 glVertexPointer 作为 VBO 中的顶点数据的偏移量。

    根据 x 和 glVertexPointer 的值,您可以使驱动程序崩溃,因为偏移量超出范围和/或基础数据的类型错误 (NaN)。

    所以为了回答你的问题,先用VBO模式画图,再用VA模式画图:

    1. 解除当前VBO的绑定
    2. 解除当前IBO的绑定
    3. glVertexPointer指定右顶点地址
    4. glDrawElements指定正确的索引地址

    然后就好了。

    【讨论】:

      【解决方案2】:

      呸!找到了。当我这样做时

      glBindBuffer(GL_ARRAY_BUFFER, 0);
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
      

      在渲染闪烁+崩溃之前停止。这是预期的行为吗?很抱歉浪费了时间和空间。

      【讨论】:

      • 就其本身而言,glBindBuffer(GL_ARRAY_BUFFER, 0) 不会影响对 glDrawElements 的调用(您必须调用 gl*Pointer 才能捕获 vbo)。回复glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0),有直接影响。你的指数在哪里?这个调用告诉 GL 它们在您自己的 client 内存中,并且 DrawElements 正在获取指向该内存的指针。如果您有一个非零值,那么 GL 会将 DrawElements 的参数视为当前 ELEMENT_ARRAY 内的 offset。在 vbos 中使用客户端指针作为偏移量通常是崩溃的好方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多