2016-10-07 17 views
5

私は目的がOpenGLで(例えばGL_ARRAY_BUFFERなど)結合点のあるものを理解していません。私の理解では、glGenBuffers()は、GPUメモリのどこかに位置する頂点バッファオブジェクトへのポインタの種類を作成します。だから、OpenGLでポイントをバインドする目的は?

glGenBuffers(1, &bufferID) 

は、私は今、グラフィックスカードの1つの頂点オブジェクトに、ハンドル、bufferIDがあることを意味します。

glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW) 

しかし、なぜ:今、私は、次のステップは、私はポイントを結合するので、同じようglBufferData()機能を使用してダウンデータを送信することを使用できるように、結合ポイント

glBindBuffer(GL_ARRAY_BUFFER, bufferID) 

にbufferIDをバインドするだろう知っています代わりにデータを送信する場所を指定するのにbufferIDを使用できませんでしたか?その後

glBufferData(bufferID, sizeof(data), data, GL_STATIC_DRAW) 

私もちょうど今までIDは、私はドロー機能が描きたい方VBOにする置く描画関数を呼び出す:ような何か。次のようなものがあります。

glDrawArrays(bufferID, GL_TRIANGLES, 0, 3) 

glBindBuffersで間接化する余分なステップが必要なのはなぜですか。

+0

"*これは、バッファIDを1つの頂点オブジェクトに割り当てることを意味します。*" 1つのバッファオブジェクト*に。 「頂点オブジェクト」のようなものはありません。 –

+1

"代わりにデータを送信する場所を指定するのにbufferIDを使用できないのはなぜですか?" ... ['ARB_direct_state_access'](https://www.opengl.org/wiki/Direct_State_Access)? – genpfault

答えて

9

OpenGLの使用は2つの結合点をオブジェクト:レンダリングプロセスの一部として使用されるオブジェクトを指定するために、及びオブジェクトを変更できるようにします。それはかつてのためにそれらを使用するのはなぜ

は単純です:OpenGLのレンダリングできるようにするには、オブジェクトの多くを必要とします。

はあなたの過度に単純化した例を考えてみましょう:

glDrawArrays(bufferID, GL_TRIANGLES, 0, 3) 

APIは私が別の頂点属性は別々のバッファから来てみましょうしないこと。確かに、あなたはglDrawArrays(GLint count, GLuint *object_array, ...)を提案するかもしれません。しかし、どのように特定のバッファオブジェクトを特定の頂点属性に接続しますか?または、バッファ0から2つの属性があり、バッファ1から3つ目の属性を持つ方法はありますか?それらは現在のAPIで今できることです。しかし、あなたの提案した人はそれを処理することはできません。などのプログラム/パイプラインオブジェクト、テクスチャオブジェクト、UBOs、SSBOs、変換フィードバック・オブジェクト、クエリーオブジェクトに指定された必要なすべてのオブジェクトを持つ:

とにも、それはあなたがレンダリングする必要がある多く他のオブジェクトを脇に置いています単一のコマンドは基本的に実行不可能であり(パフォーマンスコストを除いて)

そしてAPIは新しい種類のオブジェクトを追加する必要がありますたびに、あなたはglDraw*機能の新しいバリエーションを追加する必要があります。そして、今、over a dozen such functionsがあります。あなたの方法は数百私たちに与えているだろう。あなたが言うの

はので、代わりに、OpenGLは方法を定義し、「私はレンダリング次回は、そのプロセスのために、このように、このオブジェクトを使用しています。」これが、オブジェクトをバインドすることが意味するものです。


しかし、なぜ私はちょうど私が代わりにデータを送信したい場所specifiyするbufferIDを使うことができませんでしたか?

これは、それが使用されることを言っていないオブジェクトを変更の目的のためにオブジェクトを結合についてです。それは...別の問題です。

明らかな答えは、「OpenGL API(4.5まで)にはあなたがそれをさせる機能を持っていないため、できません」ということです。しかし、私はむしろ、OpenGLにはそのようなAPIがない(4.5まで、なぜglNamedBufferStorageなどが存在するのか)疑問だと疑う。

実際、4.5がそのような機能を持つという事実は、4.5より前のOpenGLのバインドオブジェクトから変更APIへの理由がないことを証明しています。これは、1.0からOpenGL APIの進化によってもたらされた「決定」でした。繰り返す。

実際、OpenGLが行ったすべての悪い決定は、APIの中で最も抵抗の少ない経路をとることにまでさかのぼることができます。しかし、私は逃げる。

OpenGL 1.0では、オブジェクトの種類は1つだけでした:表示リストオブジェクト。つまり、テクスチャもオブジェクトに格納されていませんでした。テクスチャを切り替えるたびにテクスチャ全体をglTexImage*Dで再指定する必要がありました。それはそれを再アップロードすることを意味します。これで、各テクスチャの作成を表示リストにラップすることができ、その表示リストを実行してテクスチャを切り替えることができました。そしてうまくいけば、ドライバーはあなたがそれをやっていることを理解して、代わりにビデオメモリーなどを適切に割り当てます。

だから、1.1が登場したとき、OpenGL ARBは気が狂ったように愚かなことを実感しました。そこで、テクスチャオブジェクトを作成しました。テクスチャオブジェクトは、テクスチャのメモリストレージとその内部のさまざまな状態の両方をカプセル化します。テクスチャを使用したいときは、バインドしました。しかし、悩みがあった。つまり、の変更方法はです。

を参照してください。1.0には、glTexImage*D,glTexParamterなどのような既存の機能が多数ありました。これらは、テクスチャの状態を変更します。今、ARBは同じことをするがテクスチャオブジェクトをパラメータとして取る新しい機能を追加することができました。テクスチャオブジェクトを使用する人としなかった人:

は、しかし、それは2つの陣営にすべてのOpenGLのユーザーを分割を意味します。つまり、テクスチャオブジェクトを使用する場合は、すべてのの既存のコードを変更してテクスチャを書き直す必要がありました。現在のテクスチャでglTexParameterコールをいくつか作成した関数があった場合は、その関数を変更して新しいテクスチャオブジェクト関数を呼び出さなければなりません。しかし、でもは、あなたが操作するテクスチャオブジェクトをパラメータとして取るように、それを呼び出す関数を変更する必要があります。

そして(それはあなたが使用していたライブラリの一部であったため)その関数はあなたに属していなかった場合、その後、あなたもを行うことができませんでし

だから、ARBは周りと単純にはテクスチャは文脈かにバインドされたかどうか。に基づいて異なる動作を持っているこれらの古い機能を維持することを決定しました1がバインドされた場合には、glTexParameterの/ etcではなく、コンテキストの通常のテクスチャよりも、バインドされたテクスチャを変更します。

the general paradigm shared by almost all OpenGL objectsを確立し、この1つの決定。

ARB_vertex_buffer_objectは同じ理由でこのパラダイムを使用しました。さまざまなgl*Pointer機能(glVertexAttribPointerなど)がバッファーに対してどのように機能するかに注目してください。バッファーをGL_ARRAY_BUFFERにバインドしてから、それらの関数の1つを呼び出して属性配列を設定する必要があります。バッファがそのスロットにバインドされると、関数はそれを取り出し、ポインタを、*Pointer関数が呼び出されたときにバインドされたバッファへのオフセットとして扱います。

なぜですか?同じ理由から:互換性の容易さ(またはあなたがそれを見たいかどうかによって怠惰を促進する) ATI_vertex_array_objectは、gl*Pointer関数の新しいアナログを作成する必要がありました。一方、ARB_vertex_buffer_objectは既存のエントリポイントをピギーバックしただけです。

ユーザーは、glVertexPointerからglVertexBufferOffsetまたは他の機能を使用することから変更する必要はありませんでした。頂点情報を設定する関数を呼び出す前にバッファをバインドするしかありませんでした(もちろん、バイトオフセットへのポインタを変更する)。

また、バッファオブジェクトからのインデックスを使用してレンダリングするために、束の種類の関数を追加する必要がないことを意味します。

これは短期間では悪い考えではありませんでした。しかし、ほとんどの短期的な意思決定と同様に、それは時間の経過とともにあまり合理的ではなくなり始めます。

もちろん、GL 4.5/ARB_direct_state_accessへのアクセス権があれば、元々やっていたはずのやり方をすることができます。

+0

この歴史的なプロセスベースの説明をありがとう。 OpenGLを使い始めたときにあなたが消化しなければならない、あまりにも曖昧で冗長で複雑なナンセンスは、設計合理性のいくつかが説明されたときに最終的には意味を持ち始めます。それは見た目にコードをもっときれいにするわけではありませんが、APIをどのようにナビゲートするかを理解するのに役立ちます。 – user69513

関連する問題