最も正しい答えは、それをどのようにプログラムするかに依存しますが、これは心配するのが良いことです。GPUは非常に高速になりましたが、GPU RAMとの間の帯域幅はそうではなく、最もイライラするボトルネックになります。
そのデータはGPUメモリに一度だけ送信され、永遠にそこに座っていますか?
できれば、はい。レンダリング速度を上げるには、フレームごとに再送信するのではなく、できるだけ多くのデータをGPUに配置する必要があります。VBOは、まさにこの目的を果たします。静的と動的の両方のVBOがあり、前者は静的モデルに最適であり、後者は頂点がすべてのフレームを変更するモデル(パーティクルシステムなど)に最適です。ただし、ダイナミックVBOの場合でも、フレームごとにすべての頂点を再送信する必要はありません。変化しているものだけです。
建物の場合、頂点データはそこにあり、変更されるのはマトリックス(モデル/ワールド、投影、ビュー)だけです。
パーティクルシステムの場合、そのシステムに存在するパーティクルの最大数を格納するのに十分な大きさの動的VBOを作成しました。各フレームは、そのフレームから放出されたパーティクルのデータと、いくつかのユニフォームを送信します。それがすべてです。描画するとき、そのVBOで開始点と終了点を指定できるため、パーティクルデータを削除する必要はありません。それらを描かないでください。
モデルが各フレームで実際にレンダリングされるとき、GPUプロセッサはGPUメモリから毎回そのデータをフェッチする必要がありますか?つまり、2つのモデルをそれぞれ複数回レンダリングした場合、最初のモデルを複数回レンダリングしてから2番目のモデルを複数回レンダリングするか、最初のモデルを1回だけレンダリングし、2番目のモデルを1回だけレンダリングして、そのようにインターリーブし続けましたか?
1つではなく複数の描画呼び出しを送信するという行為は、はるかに大きな制限です。インスタンス化されたレンダリングを確認してください。それはあなたを大いに助け、この質問に対する答えを役に立たなくするかもしれません。まだ解決していないドライバの問題がいくつかありましたが、機能するようになれば問題は解決しました。
明らかにグラフィックカードのRAMは限られています-1フレームのレンダリングに必要なすべてのモデルデータを保持できない場合、フレームごとにCPU RAMから(一部)を取得し続けると思いますが、それは正しいですか?
GPU RAMを使い果たしたくありません。その場合は、変更しないように変更してください。あなたが使い果たした非常に仮説的なシナリオでは、おそらく何らかの形でクラッシュするでしょうが、私はそれが起こるのを見たことがないので、正直に知りません。
私は1つの区別を忘れていました:データをGPUに送信し、現在のバッファを設定/バインドします。後者はデータフローを引き起こしますか?
重要なデータフローはありません。それにはいくらかコストがかかりますが、それはあなたが書くコードのすべての行に当てはまります。費用がいくらになるか、また、プロファイリングの目的を確認してください。
初期化によるバッファ作成
Raxvanの答えは良さそうですが、正確ではありません。OpenGLでは、バッファーを作成してもスペースは予約されません。データを渡さずにスペースを確保したい場合は、glBufferDataを呼び出して、nullを渡すことができます。(ここの注意事項セクションを参照してください。)
バッファデータの更新
glBufferData、またはそのような他の関数を意味していると思いますか?これが実際のデータ転送が発生する場所です。(最後の段落で言ったように、nullを渡さない限り。)
バッファーをアクティブとしてバインドします(次の描画呼び出しでこのバッファーをレンダリングすることをAPIに伝える方法であり、それ自体では何もしませんか?)
はい。ただし、それ以上のことができます。たとえば、VAO(頂点配列オブジェクト)をバインドしてからVBOをバインドすると、そのVBOはVAOにバインドされます。後で、そのVAOを再度バインドし、glDrawArraysを呼び出すと、描画するVBOがわかります。
多くのチュートリアルでは、すべてのVBOに対してVAOを作成する必要がありますが、これはそれらの使用目的ではないと言われていることに注意してください。おそらく、1つのVAOを作成し、同じ属性を持つすべてのVBOで使用する必要があります。私はまだこれを試していませんので、それが良いか悪いかを確実に言うことはできません。
API描画呼び出し
ここで何が起こるかは非常に簡単です(私たちの観点から)。VAOをバインドした後、glDrawArraysを呼び出します。開始点とカウントを指定すると、その範囲内のすべての頂点に対して頂点シェーダーが実行され、その出力がラインに渡されます。ただし、そのプロセス全体は別のエッセイです。