我正在将我的 OpenGL 2 程序转换为 OpenGL 3,一次一小步。当前的步骤是摆脱立即模式以支持 VBO。我绊倒了所有 VBO 状态管理调用的正确放置。
假设我将有一堆对象,每个对象都有自己的 VBO 用于顶点和元素数据。每个对象都有一个加载函数,用于设置它的 VBO 并将数据加载到其中;它有一个绘图函数,可以绑定它的 VBO 并发出适当的绘图命令。为了防止对象相互干扰,我的主循环应该在调用PushClientAttrib(CLIENT_VERTEX_ARRAY_BIT)
draw或load 之前调用,对吗?(当然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
调用从 draw 移动到 load,并且如果我不使用 保护 load PushClientState
,那么一切正常。