2

我正在将我的 OpenGL 2 程序转换为 OpenGL 3,一次一小步。当前的步骤是摆脱立即模式以支持 VBO。我绊倒了所有 VBO 状态管理调用的正确放置。

假设我将有一堆对象,每个对象都有自己的 VBO 用于顶点和元素数据。每个对象都有一个加载函数,用于设置它的 VBO 并将数据加载到其中;它有一个绘图函数,可以绑定它的 VBO 并发出适当的绘图命令。为了防止对象相互干扰,我的主循环应该在调用PushClientAttrib(CLIENT_VERTEX_ARRAY_BIT)drawload 之前调用,对吗?(当然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,那么一切正常。

4

2 回答 2

2

我正在将我的 OpenGL 2 程序转换为 OpenGL 3

那么接下来

为了防止对象相互干扰,我的主循环应该在调用PushClientAttrib(CLIENT_VERTEX_ARRAY_BIT)draw 或 load 之前调用,对吗?(当然PopClientAttrib()之后。)

不是一个理智的方法。glPushAttrib 和 glPopAttrib 已被弃用,即不应在 OpenGL-3 程序中使用。

OpenGL 顶点数组也不使用glVertexPointeruse glVertexAttribPointer。属性指针状态可以在Vertex Array Object中管理(我建议这样做) ,您可以绑定/取消绑定。


BTW:当您为 OpenGL-2 编写代码时,您为什么首先使用即时模式?自从 OpenGL-1.1 引入顶点数组以来,不鼓励使用立即模式。并且已经使用 OpenGL-2 考虑删除即时模式。

于 2013-01-10T15:52:34.127 回答
0

我实际问的问题的答案是 gl.VertexPointer() 和朋友需要从对象的绘制函数中调用。我的主要循环是推送和弹出与客户端顶点相关的所有状态,所以这当然会丢失。

我暗示的问题是,“如何将旧的 GL2 程序转换为新的 GL3 代码?” 这在这里得到了非常优雅的回答。

于 2013-01-16T05:07:59.307 回答