私は最近、オリジナルのOGLレッドブックを渡した人からチュートリアルサイトへのこのリンクを与えられました。3番目のヘッダーは、典型的なレンダリングメソッドとしてglBegin()とglEnd()を忘れるようにはっきりと述べています。Redbookの方法で学びましたが、VBOにはいくつかの利点があります。これは本当に進むべき方法ですか?その場合、レンダーコードと後続のシェーダーをVBOと後続のデータ型に簡単に変換する方法はありますか?
私は最近、オリジナルのOGLレッドブックを渡した人からチュートリアルサイトへのこのリンクを与えられました。3番目のヘッダーは、典型的なレンダリングメソッドとしてglBegin()とglEnd()を忘れるようにはっきりと述べています。Redbookの方法で学びましたが、VBOにはいくつかの利点があります。これは本当に進むべき方法ですか?その場合、レンダーコードと後続のシェーダーをVBOと後続のデータ型に簡単に変換する方法はありますか?
回答:
最新のOpenGLのVBOを使用する方法では、固定機能のもの(glBegin / glEndおよびその間のものを含む)は3.0から廃止され、3.1から削除されました。
OpenGL Core Profile、OpenGL ES 2.0+およびWebGLを使用すると、古いものにアクセスすることすらできません。
古いものを最初に学ぶ方が少し簡単だからだと思う人もいますが、あなたが学ぶものはほとんど役に立たず、それからあなたは学ばなければならないものです。
ただし、VBOだけではなく、すべてにシェーダーを使用し、マトリックス変換を自分で行う(またはGLMを使用する)必要があります。
古いものを使用する唯一の理由は、2.0より前のOpenGLをターゲットにしたい場合です。2003年にリリースされました。1.5であるが、シェーダーではなくVBOをサポートする必要がある、本当にくだらない組み込みのネットブックチップセットがいくつかあります。または、固定機能パイプラインに基づくOpenGL ES 1.x(たとえば、古いiPhoneで使用されています)。またはOpenGL SC(安全性が重要なシステム用)。
次の一般的に使用される関数はすべて非推奨です。
opengl-tutorial.orgチュートリアルでは、私はOpenGLを学ぶ行くための最善の方法だと思うものを持っています。彼らはいくつかのレガシーな互換性のものに依存していますが、実際にはあなたにそれを教えません。たとえば、シェーダーなしで何もレンダリングすることは想定されていませんが、機能します。また、行列演算(回転、変換など)を自分で処理する必要がありますが、デフォルトでは基本的なフラット2Dビューポートを取得できます。
廃止されたものを回避することに加えて、OpenGLのコーディングをより優れたものにする関数がたくさんありますが、それらの多くでは、OpenGLの新しい3.x +バージョンと互換性のあるハードウェアが必要かどうかを判断する必要があります。
何らかの理由で古いOpenGLをサポートする必要がある場合は、可能な場合はVBOを使用できますが、使用できない場合は、glBegin / glEndを使用し、頂点データをループするフォールバックを提供します。
一方、古いレンダリングコードをアップコンバートするための実際の「簡単な」方法はありません。おそらく、頂点を配列/ベクトルに追加し、glEndが呼び出されたときにVBOにそれをダンプして描画する関数の独自のバージョンを実装できます。しかし、それはすべてのフレームでそれを行うので非常に非効率的です(一度だけ行うチェックを入れない限り、それはアニメーション化されたオブジェクトでは機能しません)、おそらくVBOに切り替えるだけの作業になるでしょう。もしあなたがたくさんのコードを持っていたら、そのアプローチはうまくいくと思います。
VBOを使用すると、一般に2つの大きな利点があります。
利点1は完全に静的なデータに関連しており、GPUにより最適なメモリに頂点データを保持できることに由来します。
利点2は動的データに関連しており、レンダリングに使用する前の任意の時点で頂点データを指定できるため、パイプラインを改善できます。
3番目の利点は、描画呼び出しのバッチ処理から得られますが、旧式の頂点配列でも共有されるため、VBO専用ではありません。GPUへのデータの送信(またはGPUに既にあるデータの使用)は、多くの点でディスクI / Oおよびネットワークトラフィックに似ています-いくつかの大きなバッチがある場合、多くの小さなバッチよりも効率的です。
良い(100%正確ではありませんが、アイデアを得るのに十分な)これは、ある都市から別の都市に50人を連れて行かなければならないバスドライバーである場合です。それらを一度に1つずつロードし、50回の個別の旅行を行うことができます-これはglBegin / glEndです。代わりに、50個すべてをバスに乗せて、1回旅行するだけです。これは、頂点配列またはVBOでバッチ処理します(VBOの場合、50人が既にバスに乗っています;))。
しかし、これには代償が伴いますが、ここでの代償は、必要なときに頂点データを指定する機能を失うことです。まあ、OK、あなたはそれを行うことができます(いくつかの追加の作業を伴います)が、コードから完全なパフォーマンスを得ることはできません。代わりに、頂点データ、その使用方法、更新方法(および更新する必要がある場合)、シェーダーでアニメーションを実行できるかどうか(したがって、データを静的に保つことができるかどうかを検討する必要があります-VBOは本当にシェーダーを必要とします多くのアニメーションケースが適切に機能するかどうか)または各フレームの頂点データを再指定する必要があるかどうか、後者の場合は効率的な更新戦略など。これを行わず、単純な変換を実装するだけでは、非常に高いリスクがあります最終結果が実際に遅くなるためだけの多くの作業で!
これは、最初に遭遇したときは非常に多くの作業のように見えますが、実際にはそうではありません。このような思考モードに入ると、信じられないほど簡単で、ほとんど自然に来ることが実際にわかります。しかし、最初の数回の試行を台無しにするかもしれません。もしそうなら落胆するべきではありません-台無しにすることはあなたが間違ったことから学ぶ機会です。
いくつかの最終的な考え。
モデルデータをVBOに簡単にロードできる形式にすることで、このプロセス全体が非常に簡単になります。つまり、少なくとも最初は(そしてプロセスに慣れるまでは)、より複雑な形式やエキゾチックな形式を避ける必要があります。学習するときはできる限りシンプルで基本的なものにしてください。そうすれば、問題が発生する可能性が減り、問題が発生した場合にエラーを探す場所が減ります。
最適化/圧縮されたglBegin / glEnd実装よりも多くのメモリを使用するVBO実装を見ると、人々は時々先送りされます(「無駄」と呼ばれることもあります)。そのようにならないでください。極端な場合を除いて、メモリ使用量は、実際にはないことが重要。ここでは明らかにトレードオフです-大幅に高いパフォーマンスと引き換えに、潜在的に高いメモリ使用量を受け入れます。また、メモリは使用する安価で豊富なリソースであるという考え方を開発するのに役立ちます。パフォーマンスは違います。
そして最後に、古い栗-それがすでに十分に速いなら、あなたの仕事は終わっています。目標のフレームレートを達成している場合、一時的な条件に余裕がある場合は、それで十分であり、次のステップに進むことができます。あなたは実際にそれを必要としないもの(そこにいる、それをしている、まだtrapに陥る)から余分な10%を絞って多くの時間とエネルギーを無駄にすることができるので、常にあなた自身の時間の最も最適な使用が何であるかを考えてください-プログラマーの時間は、パフォーマンスよりも安価で豊富であるためです!