为什么OpenGL的glDrawArrays()在Core Profile 3.2下使用GL_INVALID_OPERATION失败,而不是3.3或4.2?

时间:2012-10-24 14:43:00

标签: opengl go opengl-3 vertex-buffer vertex-array

我有一个调用glDrawArrays的OpenGL渲染代码,当OpenGL上下文(自动/隐式获取)时,它可以完美地运行4.2但是一致地失败(GL_INVALID_OPERATION)具有明确请求的OpenGL核心上下文3.2。 (在两种情况下,着色器始终设置为#version 150,但这与我怀疑的点不同。)

根据规范,当glDrawArrays()因GL_INVALID_OPERATION失败时,只有两个实例:

  • “如果非零缓冲区对象名称绑定到已启用的数组并且缓冲区对象的数据存储当前已映射” - 此时我没有进行任何缓冲区映射

  • “如果几何着色器处于活动状态且模式与[...]不兼容” - nope,目前没有几何着色器。

此外:

  1. 我已经验证过&仔细检查它是否只有glDrawArrays()调用失败。还要仔细检查传递给glDrawArrays()的所有参数在GL版本,缓冲区绑定下是否相同。

  2. 这发生在3个不同的nvidia GPU和2个不同的操作系统中(Win7和OSX,都是64位 - 当然,在OSX中我们 3.2上下文,无论如何都不是4.2 )。

  3. 集成的“Intel HD”GPU不会发生这种情况,但对于那个,我只得到一个自动隐式3.3上下文(尝试通过GLFW明确强制使用此GPU的3.2核心配置文件但这是一个完全不同的问题......)

  4. 对于它的价值,这里是Golang中从渲染循环中摘录的相关例程:

    func (me *TMesh) render () {
        curMesh = me
        curTechnique.OnRenderMesh()
        gl.BindBuffer(gl.ARRAY_BUFFER, me.glVertBuf)
        if me.glElemBuf > 0 {
            gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, me.glElemBuf)
            gl.VertexAttribPointer(curProg.AttrLocs["aPos"], 3, gl.FLOAT, gl.FALSE, 0, gl.Pointer(nil))
            gl.DrawElements(me.glMode, me.glNumIndices, gl.UNSIGNED_INT, gl.Pointer(nil))
            gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0)
        } else {
            gl.VertexAttribPointer(curProg.AttrLocs["aPos"], 3, gl.FLOAT, gl.FALSE, 0, gl.Pointer(nil))
            /* BOOM! */
            gl.DrawArrays(me.glMode, 0, me.glNumVerts)
        }
        gl.BindBuffer(gl.ARRAY_BUFFER, 0)
    }
    

    当然,这是更大的渲染循环的一部分,尽管现在整个“* TMesh”构造只是两个实例,一个是简单的立方体,另一个是简单的金字塔。重要的是整个绘图循环完美无缺,在3.3和4.2下查询GL时没有报告错误,但是3个具有显式3.2核心配置文件的nvidia GPU失败并且错误代码根据规范只调用了两个具体的情况,据我所知,这里没有一个适用于此。

    这里有什么问题?你碰到过这个吗?我不知道的任何想法?

2 个答案:

答案 0 :(得分:1)

我有一个疯狂的猜测。

据我了解,所有OpenGL调用必须在同一个线程上进行。这个限制与goroutine不能很好地混合,因为相同的goroutine可以在执行的不同点上运行在不同的线程上。

要解决这个问题,在初始化OpenGL之前,你需要在启动时立即将主goroutine(或任何执行OpenGL调用的goroutine)锁定到当前线程。

import "runtime"

func main() {
    runtime.LockOSThread()

    ...
}

您看到不一致结果的原因可以通过实施差异来解释。

答案 1 :(得分:1)

这不是 DrawArrays ,我在这里弄错了。不知何故,我调用 glVertexAttribPointer 的方式就是问题所在:在任何严格的核心配置文件中,无论是3.2还是4.2 ......都会进一步调查。在4.2非严格的上下文中,没问题。