2012-10-24 70 views
5

我有OpenGL渲染代码调用glDrawArrays,当OpenGL上下文是(自动/隐式获取)4.2,但一致地失败(GL_INVALID_OPERATION)与明确请求的OpenGL核心上下文3.2时,完美地工作。 (着色器总是设置的#Version在这两种情况下150,但这里不是重点,我怀疑。)为什么OpenGL的glDrawArrays()在核心配置文件3.2下失效,并且GL_INVALID_OPERATION失败,但不是3.3或4.2?

根据规格,有只有两个情况下,当(4,8)失败,GL_INVALID_OPERATION:

  • “如果一个非零缓冲区对象名字绑定到一个启用阵列和缓冲区对象的数据存储是当前映射” - 我不是在这一点上做的任何缓冲映射

  • “如果几何着色器处于活动状态,模式与[...]不兼容“ - 不可以,几何不可以着色器截至目前。

此外:

  1. 我已经验证&双重检查,它是唯一的(4,8)调用失败。同时重复检查传递给glDrawArrays()的所有参数在两个GL版本,缓冲区绑定下都是相同的。

  2. 这发生在3个不同的NVIDIA GPU和2个不同的操作系统(Win7和OSX,64位 - 当然,在OSX我们 3.2范围内,无4.2反正)。 (但是对于那个,我只能得到一个自动隐式的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个nvidia GPU上显示3.2核心配置文件失败,错误代码根据spec仅在两个具体的情况,据我所知,这些情况都不适用于此。

这里有什么问题?你有没有碰到过这个?任何想法,我一直想念?

+0

问题在哪里?听起来很像一个错误报告。 – zzzz

+4

“*根据规范,只有两个实例,当glDrawArrays()失败,并且GL_INVALID_OPERATION:*”一个很好的幻想,但不是真的。所有'glDraw *'调用都有*许多种方法可能会失败。他们并非全部列在每次平局之下。我试图[整理其中的许多](http://www.opengl.org/wiki/Vertex_Rendering#Causes_of_rendering_failure),但可能还有更多。 –

+0

@jnml啊,是的......当然在这样的线程隐含的问题始终是“什么可能是错在这里吗?你有没有碰到这个?任何想法我已经失踪了?”。相应地更新...... – metaleap

回答

1

我有一个疯狂的猜测。

据我所知,所有的OpenGL调用必须发生在同一个线程上。这个限制与goroutine不能很好地匹配,因为同一个goroutine可以在不同的线程上执行不同的点。

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

import "runtime" 

func main() { 
    runtime.LockOSThread() 

    ... 
} 

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

+0

够程及LockOSThread,这已经被照顾的... :) – metaleap

+0

问题更新:http://stackoverflow.com/questions/13062149/how-do -i-让 - 这 - 简单的OpenGL代码作品-IN-A-宽松-3-3和4-2瞩目 – metaleap

1

这不是只是DrawArrays,我在这里弄错了。不知怎的,我的呼唤glVertexAttribPointer的方式是这里的问题:在任何严格的核心配置文件,无论是3.2还是4.2 ... ...将进一步调查。在4.2非严格的情况下,没有问题。

+0

问题更新:http://stackoverflow.com/questions/13062149/how-做-I-MAKE-这-简单的OpenGL代码作品-IN-A-宽松-3-3和4-2瞩目 – metaleap