glDrawArrays上的OpenGL Segfaulting

Posted

技术标签:

【中文标题】glDrawArrays上的OpenGL Segfaulting【英文标题】:OpenGL Segfaulting on glDrawArrays 【发布时间】:2012-05-18 01:06:39 【问题描述】:

我正在使用 Code::Blocks (C++) 和 MinGW 在 Windows 上的 OpenGL 中制作游戏。所有的绘图和逻辑都很好,游戏完美运行。直到,突然,它没有。在 随机 一段时间后,游戏会出现 Segfaults。与 GL 段错误一样,堆栈跟踪是无用的。我得到的唯一一件事是段错误发生在供应商的 OpenGL 实现中。我已经在不同供应商的多个显卡上对此进行了测试,他们都这样做了,所以问题出在我身上。

我通过 gDEBugger 运行了程序,得到了同样无用的堆栈跟踪。哈哈。我也使用了 GLIntercept,但没有任何反应。因此,我着手以手动方式查找段错误(BuGLe 拒绝编译...),并且基本上将跟踪消息写入日志。我已将其范围缩小为对 glDrawArrays 的一次调用。我在互联网上进行了很多探索,并尝试了很多我找到的修复方法。

因为这个游戏没有为可移植性而编码,所以我一直在犹豫是否要在 wine 和 valgrind 中运行它。在我弄乱那个美妙的混乱之前,如果您能查看我的代码并找到错误,我将不胜感激。 (我敢肯定这是显而易见的……)

(注意:为了便于阅读,我已经删除了所有的跟踪线)

void PlayerShip::Render()

    glPushMatrix(); //Save the current state

    glTranslatef(m_PosX, m_PosY, 0);
    glRotatef(vect.Rotation - 90, 0, 0, 1); //Matrixes are applied in reverse order


    double xl = m_SizeX / 2, yl = m_SizeY / 2; //Get values to add/subract to the midpoint for the corners
    glEnable(GL_TEXTURE_2D); //Redundant
    TextureManager::Inst()->BindTexture(TexIDs::Playership01); //Bind the texture

    glEnableClientState(GL_VERTEX_ARRAY); //These enables and disables are redundant here
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);

    GLdouble* Verts;
    Verts = new GLdouble[12]  -xl, -yl, -.5,    xl, -yl, -.5,
                           xl,  yl, -.5,    -xl, yl, -.5; //Calculate quad vertices
    GLdouble* Texs;
    Texs = new GLdouble[8] 0, 0,    1, 0,   1, 1,    0, 1; //Calculate texture vertices

    glVertexPointer(3, GL_DOUBLE, 0, Verts);
    glTexCoordPointer(2, GL_DOUBLE, 0, Texs);

    glDrawArrays(GL_QUADS, 0, 12);

    delete [] Verts;
    delete [] Texs;

    glPopMatrix();

有趣的是,这段代码可以工作......一段时间。我已经打印了所有变量的值,它们都是正确的,指针不为空,在整个代码中间隔的 glGetError 调用总是返回 NO_ERROR。坦率地说,我很茫然。

给任何建议我做一些不同事情的人的说明:我需要使用顶点数组来支持旧版 (1.4) GL 实现,并且我将我的数组声明为指针,以便我可以(将来)将它们重用于一次绘制多个图元(例如,从船上排出废气)

【问题讨论】:

【参考方案1】:

glDrawArrays 的最后一个参数应该是 4(元素数),而不是 12(浮点数)。

您正在尝试绘制 12 个元素(= 36 个浮点数),并访问超出数组的边界。

【讨论】:

哇。我觉得我好笨。知道为什么它会渲染一段时间,然后分段吗? 只有在它试图访问的内存区域中存在其他东西时才可能出现段错误。如果它是可用空间,内存边界检查可能不会注意到它。这可以解释它的随机性。 有道理,因为它在内存较少的系统上故障更快...多亏了你,我可以睡得安稳了...至少今晚。 还是这样吗?文档here 指出count 是“要呈现的索引 的数量。”

以上是关于glDrawArrays上的OpenGL Segfaulting的主要内容,如果未能解决你的问题,请参考以下文章

我可以在调用 glDrawArrays 后删除 OpenGL 顶点数组吗?

调用 glDrawArrays() 时的 OpenGL VBO Segfault

不同形状的OpenGL glDrawArrays

OpenGL - 为 glDrawArrays 自动生成索引/步幅参数

OpenGL 3.3 - glDrawArrays 后的无效操作错误 (1282)

在 Opengl ES 中在 FBO 上调用多个 glReadPixels 和 glDrawArrays