5

我有调用 glDrawArrays 的 OpenGL 渲染代码,当 OpenGL 上下文(自动/隐式获得)4.2 时,它可以完美地工作,但在显式请求的 OpenGL 核心上下文 3.2 时始终失败(GL_INVALID_OPERATION)。(在这两种情况下,着色器总是设置为#version 150,但我怀疑这不是重点。)

根据规范,当 glDrawArrays() 因 GL_INVALID_OPERATION 失败时,只有两种情况:

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

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

此外:

  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 核心配置文件会导致窗口创建失败,但这是一个完全不同的问题...)

对于它的价值,这里是从渲染循环中摘录的相关例程,在 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”结构只是两个实例,一个是简单的立方体,另一个是简单的金字塔。重要的是,整个绘图循环完美无缺,当查询 GL 以查找 3.3 和 4.2 下的错误时,没有报告任何错误,但在 3 个具有显式 3.2 核心配置文件的 nvidia GPU 上失败,错误代码根据规范仅在两种具体情况,据我所知,没有一种情况适用于此。

这里有什么问题?你遇到过这种情况吗?有什么想法我一直在想念吗?

4

2 回答 2

1

我有一个疯狂的猜测。

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

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

import "runtime"

func main() {
    runtime.LockOSThread()

    ...
}

您看到不一致结果的原因可能是实现差异。

于 2012-10-24T20:33:49.697 回答
1

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

于 2012-10-25T04:57:24.620 回答