OpenGLでVertex Bufferを使いながらマウスで選択を行うプログラムを書いてみたが
はじめに
3Dモデルビューアを作っていると当然欲しくなる機能として、 頂点をマウスで選択する機能があります。 まあ、これは頂点に限らず面でもオブジェクト単位でもかまわないわけなんだけれども、そういう機能が欲しくなりますよね。 そういう機能のことを「ピック」とか言うらしいです。
ぐぐろう!
ぐぐると、
glRenderMode(GL_SELECT)して、gluPickMatrixを使って頑張ろう!
みたいなことが書いてあるんだけれども、Vertex Bufferとか使って高速に書く実装をしている人にとっては選択できるのはせいぜいオブジェクト単位で、面単位や点単位で選択することができず、かなり不便ですよね。
しかもこの関数、ゆくゆくは廃止されるとかで使うのに不安しか感じませんね。
実装してみよう!
とはいえ、この方法を使って実装することもできるはず。というわけで、点単位でPushNameして全部glVertex3fで書いてみました。
が、やはり遅すぎて使い物になりません。
そこで
じゃあどうすんねん!ってことになるわけなんですが、超ウラワザとして以下のような実装で同様の機能を実現することができます。
- 各頂点(面)に順番に色(インデックスの代わり)をつけ、全部描画してしまう。
- とりあえず描画する(選択対象物しか描画しない)
- マウス位置に描画された色を見る。
- そこの色=選択された面の色
- 描画した内容を消し、ちゃんとした描画を行う
色のつけ方などは
uint index = 1000; BYTE *color = (BYTE *)malloc(sizeof(BYTE)*3); memcpy_s(color,3,&index,3); /* ここで色をセットする */ free(color)
で、高速につけることができますし、マウスの下の色を見てからインデックスに変換するのも逆の処理をするだけなので割りと便利です。 あーでもエンディアンとかには気をつけないといけないかもしれない。
欠点
欠点としては、一度描画するので、完全に点が重なってしまっている場合などは後ろの点が選択できないことが挙げられます。
gluPickMatrixなら、後ろの点までちゃんと選択できるので、ようは使い分けが必要というわけです。
プログラム
なんかこの記事書いてみたは良いものの、需要があるのかすごく謎なので、リクエストがあれば考えますが、とりあえずプログラムは載せません。
大したことやってないしね。