2024/04/14(日) [n年前の日記]
#1 [prog][cg_tools] OpenGLでモデルデータを読み込めそうか調べてる。その4
C/C++ とOpenGLで、何かしらのモデルデータを読み込んで描画したい。
wavefront形式(.obj)を読み込んで、C言語の配列の形で出力する Pythonスクリプトを書いてるところ。複数のマテリアルを割り当ててある場合は、頂点カラーにマテリアルの Kd 値を割り振るようにしてみた。
wavefront形式(.obj)を読み込んで、C言語の配列の形で出力する Pythonスクリプトを書いてるところ。複数のマテリアルを割り当ててある場合は、頂点カラーにマテリアルの Kd 値を割り振るようにしてみた。
◎ glDrawElements()はビミョーに使えない印象 :
OpenGL 1.1 の glDrawElements() について調べてる。
OpenGL 1.1 で頂点配列を使ってポリゴンを描画する場合、glDrawArrays() か glDrawElements() を使えるらしいのだけど。
頂点配列のインデックス値を渡して描画するほうが、頂点配列内の座標値が重複したりしないので、データ量は少なくて済む。実際、wavefront形式も、頂点座標群とは別に、面を構成する情報としてインデックス値群を持っているので、このメリットを意識したフォーマットになっている。
しかし各頂点には、頂点座標の他にも、法線情報(Normal情報)、テクスチャのUV座標、頂点カラー情報も持たせないといけないはずで…。
wavefront形式の場合、頂点配列、法線情報、テクスチャのUV座標のインデックス値が、別々の値になってる場面がほとんど。しかし、OpenGL の glDrawElements() のサンプルコードを見る限り、どうやら頂点、法線、UVで、別々のインデックス値を指定することはできないようで…。となると、wavefront形式が持っている面情報 = インデックス値列をそのまま OpenGL に流用することはできないようだなと…。
仕方ないので、Pythonスクリプト側で、頂点座標、法線情報、UV座標、頂点カラーを、全部配列にずらずらと展開してから出力してしまうことにした。それらの配列を使って、glDrawElements() ではなく、glDrawArrays() で描画する。
こういうデータの持ち方では、座標値が重複するのでデータ量はかなり増えてしまうけど、これはもうどうしようもないかなと…。いやまあ、glBegin() と glEnd() を使って、ポリゴンを1枚1枚ループを回して描画するようにすれば、wavefront形式が持ってる面情報をそのまま使うこともできるだろうけど、その代わり処理が遅くなってしまうはず。データは増えるけど処理が速いか、データは減るけど処理が遅いか、どっちを取るか、という話になるのだろうか。
本当に頂点配列を使うと処理は速くなるのかな。ベンチマークを取ったわけじゃないから確実なことは言えない気もする…。
OpenGL 1.1 で頂点配列を使ってポリゴンを描画する場合、glDrawArrays() か glDrawElements() を使えるらしいのだけど。
- glDrawArrays() ... 頂点配列を渡して描画する。
- glDrawElements() ... 頂点配列のインデックス値の配列を渡して描画する。
頂点配列のインデックス値を渡して描画するほうが、頂点配列内の座標値が重複したりしないので、データ量は少なくて済む。実際、wavefront形式も、頂点座標群とは別に、面を構成する情報としてインデックス値群を持っているので、このメリットを意識したフォーマットになっている。
しかし各頂点には、頂点座標の他にも、法線情報(Normal情報)、テクスチャのUV座標、頂点カラー情報も持たせないといけないはずで…。
wavefront形式の場合、頂点配列、法線情報、テクスチャのUV座標のインデックス値が、別々の値になってる場面がほとんど。しかし、OpenGL の glDrawElements() のサンプルコードを見る限り、どうやら頂点、法線、UVで、別々のインデックス値を指定することはできないようで…。となると、wavefront形式が持っている面情報 = インデックス値列をそのまま OpenGL に流用することはできないようだなと…。
仕方ないので、Pythonスクリプト側で、頂点座標、法線情報、UV座標、頂点カラーを、全部配列にずらずらと展開してから出力してしまうことにした。それらの配列を使って、glDrawElements() ではなく、glDrawArrays() で描画する。
こういうデータの持ち方では、座標値が重複するのでデータ量はかなり増えてしまうけど、これはもうどうしようもないかなと…。いやまあ、glBegin() と glEnd() を使って、ポリゴンを1枚1枚ループを回して描画するようにすれば、wavefront形式が持ってる面情報をそのまま使うこともできるだろうけど、その代わり処理が遅くなってしまうはず。データは増えるけど処理が速いか、データは減るけど処理が遅いか、どっちを取るか、という話になるのだろうか。
本当に頂点配列を使うと処理は速くなるのかな。ベンチマークを取ったわけじゃないから確実なことは言えない気もする…。
[ ツッコむ ]
以上、1 日分です。