1

私は OpenGL をもう一度試していますが、後でレンダリングされるクラスをどのように設計するのか疑問に思っています。現在、形状は 1 種類しかないため、 の最初のインスタンスが作成されたときに呼び出されるShape静的な VAO メンバーを持つクラスを作成しました。今、方法があります:glGenVertexArrays(1, &vao)Shapevoid Shape::render()

void Shape::render()
{
  glBindVertexArray(vao);
  glDrawArrays(GL_TRIANGLES, foo, bar);
}

これは良い方法ですか?つまり、実際のプログラムでのすべてのインスタンスShapeが描画されると、 bind が繰り返し呼び出されますが、現在既にバインドされているShape::vao場合、実際には何もしないと思います。vaoその推測は正しいですか?

glBindVertexArray(0)また、の最後にを呼び出すチュートリアルを少し前に見ましたrender()。多くの形状がある場合、パフォーマンスが低下する可能性はありませんか?

4

1 に答える 1

4

しかし、vao が既にバインドされている場合、実際には何もしないと思います。その推測は正しいですか?

はい。正確性に関する限り、既にバインドされているものを再バインドすることは問題ではありません。

ただし、パフォーマンスがわずかに低下する可能性があります。この場合、合理的な GL 実装はおそらくあまり効果がありませんが、それでも GL ライブラリへの呼び出しがあり、何もしない前にスレッドの現在のコンテキストを見つける必要があります。そのため、現在の VAO を自分の側でキャッシュし、GL が実際に変更された場合にのみ GL を呼び出すと、さらに良い結果が得られる可能性があります。しかし、それはプロファイリング/ベンチマークだけが教えてくれるものです。数千または数百万のインスタンスがある場合、それは実際の問題になる可能性があります-OTOH、インスタンスごとに個別のドローコールがある場合はとにかくめちゃくちゃです-その場合はインスタンス化されたレンダリングを検討する必要があります.

また、render() の最後で glBindVertexArray(0) を呼び出すチュートリアルを少し前に見ました。多くの形状がある場合、パフォーマンスが低下する可能性はありませんか?

はい。ほとんどのチュートリアルでは、ある程度の「クリーンさ」のためにこれを行っていますが、ほとんどの場合、実際には時間の無駄です。デフォルトのフレームバッファである FBO 0 のように、いくつかの GL オブジェクトのバインドを解除することは、「バインド解除」状態で何かを実行できる (そして実際にそうするつもりである) 場合にのみ有用な操作です。VAO の場合、コア プロファイルでは、VAO 0 はまったく役に立たず、描画する前にいずれかをバインドする必要があります。

于 2014-08-03T01:10:10.800 に答える