12

画像に見られるように

http://oi56.tinypic.com/ifu33k.jpg

一連の輪郭 (ポリゴン) を GL_LINE_STRIP として描画します。マウスの下で曲線(ポリゴン)を選択して、3Dで削除、移動などをしたいと思います。

私はどの方法を使うべきか疑問に思っています:

1.OpenGL のピッキングと選択を使用します。( glRenderMode(GL_SELECT) )

2.ピックレイを使用して手動衝突検出を使用し、レイが各ポリゴン内にあるかどうかを確認します。

4

7 に答える 7

19

GL_SELECT に対して強くお勧めします。この方法は非常に古く、新しい GL バージョンにはありません。最近のグラフィック カードでは問題が発生する可能性があります。ハードウェアでサポートされるとは思わないでください。おそらく、このモードが機能するのであれば、多くの GPU でこのモードのソフトウェア (ドライバー) フォールバックに遭遇するでしょう。自己責任 :)

代わりの方法を教えてください。

ソリッドで大きなオブジェクトの場合、次の方法で選択する古くて優れたアプローチがあります。

  • シザー テストを有効にして、カーソル位置の 1x1 ウィンドウに設定する
  • 照明、テクスチャリング、マルチサンプリングを使用せずに画面を描画し、「重要な」エンティティごとに一意の単色を割り当てます。この色は、選択するためのオブジェクト ID になります。
  • glReadPixels を呼び出して色を取得すると、選択したオブジェクトを識別するのに役立ちます
  • バッファをクリアし、はさみを通常のサイズにリセットし、シーンを通常どおりに描画します。

これにより、非常に信頼性の高い「オブジェクトごと」のピッキング方法が得られます。また、最小限のピクセル単位の操作で 1 ピクセルのみを描画およびクリアしても、パフォーマンスが大幅に低下することはありません。ドローコールの数に制限されています(ただし、ピクセルごとのデータとして色を渡すことができれば、これを単一のドローコールに最適化することは可能だと思います)。

RGB の色は 3 符号なしバイトですが、最後のバイトにフレームバッファのアルファ チャネルを追加で使用できるはずなので、合計で 4 バイトを取得します。オブジェクトへの 32 ビット ポインタを色彩。

または、専用のフレームバッファ オブジェクトを特定のピクセル フォーマットで作成することもできます (たとえば、 64 ビットが必要な場合GL_R32UIでも)。GL_RG32UI

上記は、厳密な幾何学的アプローチの優れた迅速な代替手段です (信頼性と実装時間の両方の点で)。

于 2010-10-30T16:52:13.593 に答える
6

新しい GPU では、GL_SELECT モードが非常に遅いことがわかりました。私は問題を解決するいくつかの異なる方法で遊んだ。

1 つ目は、CPU 衝突テストを行うことでした。これはうまくいきましたが、思ったほど速くはありませんでした。(gluUnproject を使用して) 画面にレイをキャストしてから、マウスが衝突しているオブジェクトを見つけようとすると、速度が確実に低下します。私が満足のいく速度を得た唯一の方法は、octree を使用して衝突テストの数を減らし、次にバウンディング ボックス衝突テストを行うことでした。ただし、この方法は完全なピクセルではありませんでした。

私が決めた方法は、最初にマウスの下にあるすべてのオブジェクトを見つけることでした (gluUnproject とバウンディング ボックスの衝突テストを使用)。通常は非常に高速です。次に、バックバッファーでマウスと衝突する可能性のある各オブジェクトを別の色でレンダリングしました。次に、glReadPixel を使用してマウスの下の色を取得し、それをオブジェクトにマップし直しました。glReadPixel は、フレーム バッファから読み取る必要があるため、呼び出しが遅くなります。ただし、フレームごとに 1 回実行されるため、時間はほとんどかかりません。必要に応じて、PBO にレンダリングすることで高速化できます。

ギアワ

于 2010-10-31T00:15:25.987 に答える
3

マンガ、インラインで返信する方法がわかりません...サインアップする必要があるかもしれません:)

まず最初に、間違ったアルゴリズムを提供してしまったことをお詫びしなければなりません。バック フェース カリングを行いました。しかし、必要なものは非常に似ているため、混乱しました... d'oh。

前に述べたように、カメラ位置をマウス ベクトルに取得します。

輪郭ごとに、すべての座標をペア (0-1、1-2、2-3、... n-0) でループし、以前のようにそれらから vec を作成します。つまり、輪郭を歩きます。

ここで、前に述べたようにペア間ではなく、これら 2 つのクロス prod (輪郭エッジからマウス vec) を実行します。すべてのペアに対して実行し、ベクトルをすべて加算します。

最後に、結果のベクトルの大きさを見つけます。結果がゼロの場合 (丸め誤差を考慮して)、向きに関係なく、形状の外側になります。向きに興味がある場合は、mag の代わりに、マウス ベクトルを使用して dot prod を実行し、向きを見つけて符号 +/- をテストできます。

これが機能するのは、アルゴがベクター ラインから各ポイントまでの距離を順番に検出するためです。それらを合計すると、外にいると、輪郭が閉じているため、すべて相殺されます。あなたの内側なら、それらはすべて要約します。その実際には、物理​​学における電磁界のガウスの法則...

http://en.wikipedia.org/wiki/Gauss%27s_law を参照し、「式の右辺は、S で囲まれた総電荷を電気定数で割ったものです」に注意してください。「囲まれた」という言葉に注意してください。つまり、ゼロです。囲まれていないことを意味します。

速度を上げるために、バウンディング ボックスを使用してその最適化を行うこともできます。

于 2010-11-01T15:04:49.177 に答える
1

過去に、GL_SELECT を使用して対象のピクセルに寄与したオブジェクトを特定し、必要に応じて計算ジオメトリを使用してオブジェクトとの正確な交差を取得しました。

于 2010-10-28T08:07:12.973 に答える
1

あなたがやりたいこととして私が読んだ線の内側のスペースではなく、レンダリングされた線のピクセルをクリックする必要があるため、線にとどまる場合は選択を使用できません。

Kosの答えを使用できますが、スペースをレンダリングするには、すべての輪郭を凸型に変換する必要があり、それを塗りつぶす必要があります。これは苦痛です。ですから、そうしないとうまくいくこともあれば、間違った答えを返すこともあると思います。

あなたがする必要があるのは、CPUを使用することです。ビューポートとパースペクティブ マトリックスからのビュー範囲があります。マウス座標を使用して、マウス ポインター ベクトルへのビューを生成します。輪郭のすべての座標もあります。

最初の輪郭の最初の座標を取得し、2 番目の座標へのベクトルを作成します。それらからベクトルを作成します。3番目の座標を取り、2から3までのベクトルを作成し、輪郭の周りをずっと繰り返し、最後に座標nから最後のものを再び0に戻します. 一連の各ペアについて、外積を見つけ、すべての結果を合計します。その最終的な合計ベクトルを取得したら、それを保持し、マウス ポインターの方向ベクトルでドット積を計算します。+ve の場合、マウスは輪郭の内側にあり、-ve の場合はそうではなく、0 の場合、輪郭の平面とマウスの方向は平行であると推測します。

輪郭ごとにこれを行うと、マウスによってどの輪郭がスパイクされているかがわかります。そのセットからどれを選ぶかはあなた次第です。最高の Z ?

大変な作業のように聞こえますが、それほど悪くはなく、正しい答えが得られます。さらに、すべての輪郭の境界ボックスを保持したい場合は、完全なベクトルの場合と同じ計算を行うことにより、マウス ベクトルからそれらを早期に取り除くことができますが、4 辺のみであり、内側にない場合は輪郭を作成できません。また。

于 2010-10-31T19:34:13.517 に答える
1

輪郭 (エッジ上) またはポリゴンの内部をクリックして選択することを期待していますか? 2 番目のアプローチは、内部をクリックして、最も密集したポリゴンを選択するように聞こえます。GL_SELECTレンダリング後GL_LINE_STRIP、インテリアがクリックに反応するようになるとは思いません。

これが真の等高線図である場合 (画像からはそうではないと思いますが、エッジが交差しているように見えます)、はるかに単純なアルゴリズムが利用可能になります。

于 2010-10-30T16:50:23.050 に答える
0

1 つ目は実装が簡単で、広く使用されています。

于 2010-10-28T07:45:57.597 に答える