我正在将我的OpenGL 2程序转换为OpenGL 3,一次只有一个小步骤。当前的步骤是摆脱即时模式,转而使用VBO。我对所有VBO状态管理调用的正确位置感到困惑。
假设我要有一堆对象,每个对象都有用于顶点和元素数据的自己的VBO。每个对象都有一个加载函数,用于设置其VBO并将数据加载到其中。它具有绑定其VBO并发出适当的draw命令的draw函数。为了防止对象相互干扰,我的主循环应该在调用PushClientAttrib(CLIENT_VERTEX_ARRAY_BIT)draw或load之前调用,对吗?(当然还有PopClientAttrib()。)
当我推送/弹出该状态以保护我的加载功能时,不会绘制该对象。似乎需要在我的绘图函数中设置一些状态,但是我无法弄清楚它可能是什么。
这是将新对象添加e到场景中的代码,让它调用其加载功能:
gl.PushClientAttrib(gl.CLIENT_VERTEX_ARRAY_BIT)
e.SceneAdded()
gl.PopClientAttrib()
这就是我调用每个对象的draw函数的方式:
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,那么一切都会正常进行。
相关分类