2

OpenGL2プログラムをOpenGL3に変換しています。一度に1ステップずつです。現在のステップは、VBOを優先して即時モードを削除することです。私はすべてのVBO状態管理呼び出しの適切な配置につまずいています。

頂点データと要素データ用にそれぞれ独自のVBOを持つオブジェクトがたくさんあると仮定しましょう。各オブジェクトには、VBOを設定し、データをロードするロード機能があります。また、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)
}

明確にするために、2つのEnableClientState呼び出しを描画からロードに移動し、ロードをで保護しない場合PushClientState、すべてが正常に機能します。

4

2 に答える 2

2

OpenGL 2 プログラムを OpenGL 3 に変換しています

じゃあ次は

オブジェクトが互いに干渉しないようPushClientAttrib(CLIENT_VERTEX_ARRAY_BIT)にするには、ドローまたはロードが呼び出される前にメイン ループを呼び出す必要があります。(もちろんPopClientAttrib()その後も。)

正気のアプローチではありません。glPushAttrib と glPopAttrib は非推奨です。つまり、OpenGL-3 プログラムでは使用しないでください。

glVertexPointerまた、OpenGL 頂点配列はuse を使用しませんglVertexAttribPointer。属性ポインターの状態は、バインド/バインド解除できるVertex Array Objectで管理できます (お勧めします)。


ところで: OpenGL-2 用に書いたとき、そもそもなぜ即時モードを使用したのですか? 頂点配列が導入された OpenGL-1.1 以降、即時モードの使用は推奨されていません。そしてすでに OpenGL-2 では、即時モードを削除することが考慮されていました。

于 2013-01-10T15:52:34.127 に答える
0

私が実際に尋ねた質問に対する答えは、オブジェクトの draw 関数から gl.VertexPointer() とその仲間を呼び出す必要があるということです。私のメイン ループは、クライアントの頂点に関連するすべての状態をプッシュおよびポップするため、もちろん失われます。

私がほのめかした質問は、「古い GL2 プログラムを新しい GL3 コードに変換するにはどうすればよいですか?」ということです。それはここで非常にエレガントに答えられています。

于 2013-01-16T05:07:59.307 に答える