我正在将 OpenGL 2 程序转换为 OpenGL 3,一次一小步。当前的步骤是摆脱立即模式,转而使用 VBO。我在正确放置所有 VBO 状态管理调用时遇到了困难。
假设我将有一堆对象,每个对象都有自己的用于顶点和元素数据的 VBO。每个对象都有一个加载函数,用于设置其 VBO 并将数据加载到其中;它有一个绘制函数,可以绑定(bind)其 VBO 并发出适当的绘制命令。为了防止对象相互干扰,我的主循环应该在调用绘制或加载之前调用PushClientAttrib(CLIENT_VERTEX_ARRAY_BIT)
,对吗? (当然还有 PopClientAttrib()
之后。)
当我推送/弹出该状态以保护我的加载函数时,该对象不会被绘制。似乎我需要在绘图函数中(重新)设置某些状态,但我不知道它可能是什么。
以下代码将新对象e
添加到场景中,让它调用其加载函数:
gl.PushClientAttrib(gl.CLIENT_VERTEX_ARRAY_BIT)
e.SceneAdded()
gl.PopClientAttrib()
以下是我如何调用每个对象的绘制函数:
gl.PushClientAttrib(gl.CLIENT_VERTEX_ARRAY_BIT)
gl.PushMatrix()
p.Paint()
gl.PopMatrix()
gl.PopClientAttrib()
这是对象的加载函数:
// Make the vertex & texture data known to GL.
gl.GenBuffers(1, &vboId)
gl.BindBuffer(gl.ARRAY_BUFFER, vboId)
gl.BufferData(gl.ARRAY_BUFFER,
gl.Sizeiptr(unsafe.Sizeof(gldata[0])*uintptr(len(gldata))),
gl.Pointer(&gldata[0].x), gl.STATIC_DRAW)
gl.VertexPointer(3, gl.DOUBLE, gl.Sizei(unsafe.Sizeof(gldata[0])),
gl.Pointer(unsafe.Offsetof(gldata[0].x)))
gl.TexCoordPointer(2, gl.DOUBLE, gl.Sizei(unsafe.Sizeof(gldata[0])),
gl.Pointer(unsafe.Offsetof(gldata[0].s)))
// Make the index data known to GL.
gl.GenBuffers(1, &iboId)
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, iboId)
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER,
gl.Sizeiptr(unsafe.Sizeof(sd.indices[0])*uintptr(len(sd.indices))),
gl.Pointer(&sd.indices[0]), gl.STATIC_DRAW)
最后,这是对象的绘制函数:
func draw() {
gl.BindBuffer(gl.ARRAY_BUFFER, vboId)
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, iboId)
gl.EnableClientState(gl.VERTEX_ARRAY)
gl.EnableClientState(gl.TEXTURE_COORD_ARRAY)
gl.DrawElements(gl.TRIANGLES, indexcount, gl.UNSIGNED_SHORT, nil)
}
需要明确的是,如果我将两个 EnableClientState
调用从绘制移至加载,并且如果我不使用 PushClientState
保护加载,则一切正常。
最佳答案
I'm converting my OpenGL 2 program to OpenGL 3
那么接下来
To keep the objects from interfering with each other, my main loop should call
PushClientAttrib(CLIENT_VERTEX_ARRAY_BIT)
before either draw or load is called, correct? (And of coursePopClientAttrib()
after.)
这不是一个明智的方法。 glPushAttrib 和 glPopAttrib 已弃用,即不应在 OpenGL-3 程序中使用。
此外,OpenGL 顶点数组不使用 glVertexPointer
,而是使用 glVertexAttribPointer
。属性指针状态可以在顶点数组对象中进行管理(我建议这样做),您可以绑定(bind)/取消绑定(bind)。
顺便说一句:当您为 OpenGL-2 编写内容时,为什么首先使用立即模式?自 OpenGL-1.1 引入顶点数组以来,不鼓励使用立即模式。 OpenGL-2 已经考虑删除即时模式。
关于opengl - VBO状态调用的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14251745/