3

擬似コード:

void draw()
{
    Vertex* vertices = scene.GetVertexArray();
    glEnableClientState(...);
    glVertexPointer(..., vertices);
    glDrawArrays(...);
    glDisableClientState(...);
    delete vertices;
}

古い OpenGL 実装をサポートしたいので、VBO は使用していません。

glDrawArrays を呼び出した後、次のことを行います。

  • 頂点配列の割り当てを解除delete vertices;(" ")
  • おそらくいくつかの頂点を変更します

ただし、GL は glDrawArrays を非同期で自由に実行でき、完了するまで配列の割り当てを解除したり変更したりするのは安全ではありません。

それを確実にするために glFinish を実行できますが、アプリの速度が低下します。

では、頂点配列を自由に解放/変更できるのはいつですか?

4

1 に答える 1

6

OpenGLは、実際に一部のメモリにアクセスする関数が戻ってきたら、その内容を変更または割り当て解除できることを保証します。それらの機能は次のとおりです。

  • glDrawArrays(戻った後、メモリgl {Normal、Color、TexCoord、Attrib、Vertex} Pointerが破棄できるように設定されていました)
  • glDrawElements(戻った後、メモリgl {Normal、Color、TexCoord、Attrib、Vertex} Pointerがに設定され、要素配列を破棄できます)
  • glTexImage(メモリデータが指す)
  • glTexSubImage(メモリデータが指す)
  • glBufferData(メモリデータが指す)
  • glBufferSubData(メモリデータが指す)

gl {Normal、Color、TexCoord、Attrib、Vertex} Pointerはポインタを設定するだけで、コピーを作成しないことを知っておくことが重要です。ただし、ある種のデータのコピーは、glDrawElementsおよびglDrawArrays呼び出しによって作成されます(ドライバーによっては、物理コピーはすぐには作成されませんが、メモリ管理はコピーオンライト方式に合わせて調整されます—バッファーが変更されない場合またはユーザープログラムによって割り当てが解除されると、重要な帯域幅とCPUサイクルが節約されます)。

于 2011-05-01T11:49:20.687 に答える