我正在将我的OpenGL 2程序转换为OpenGL 3,这是一次一小步。目前的步骤是摆脱立即模式,转而支持维也纳国际组织。我对所有VBO状态管理调用的正确放置感到磕磕绊。
让我们假设我将拥有一堆对象,每个对象都有自己的顶点和元素数据的VBO。每个对象都有一个加载函数,用于设置其VBO并将数据加载到它们中;它有一个绘制函数,绑定其VBO并发出适当的绘图命令。为了防止对象相互干扰,我的主循环应该在调用draw 或 load之前调用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
调用从draw移到加载,如果我不用PushClientState
来保护加载,那么一切正常。
答案 0 :(得分:2)
我正在将我的OpenGL 2程序转换为OpenGL 3
那么以下
为了防止对象相互干扰,我的主循环应该在调用draw或load之前调用
PushClientAttrib(CLIENT_VERTEX_ARRAY_BIT)
,对吗? (当然还有PopClientAttrib()
。)
不是一个理智的方法。 glPushAttrib和glPopAttrib已弃用,即不应在OpenGL-3程序中使用。
OpenGL顶点数组也不使用glVertexPointer
使用glVertexAttribPointer
。可以在顶点数组对象中管理(我建议)属性指针状态,您可以绑定/取消绑定。
顺便说一句:当你为OpenGL-2写作时,你为什么一开始就使用立即模式?自OpenGL-1.1引入顶点数组以来,不鼓励使用立即模式。已经使用OpenGL-2,它被认为是删除了立即模式。
答案 1 :(得分:0)
我实际问过的问题的答案是gl.VertexPointer()和朋友需要从对象的绘图函数中调用。我的主循环是推送和弹出与客户端顶点相关的所有状态,所以当然会丢失。
我暗示的问题是,"如何将旧的GL2程序转换为新的GL3代码?"这非常优雅地回答here。