3

OpenGLで正十二面体を作成しました。(ウィキペディアの画像のように) 顔を透明にしたかったのですが、これは常に機能するとは限りません。OpenGLのドキュメントを掘り下げた後、「透明な面を後ろから前に並べ替える必要がある」ようです。うーん。それ、どうやったら出来るの?

glRotatef() を呼び出して座標系を回転させますが、面の参照座標は同じままです。回転効果は、私の renering コードの「外側」に適用されます。

座標に変換を適用すると、他のすべてが動かなくなります。

この場合、どうすれば顔を並べ替えることができますか?

[編集]なぜこれが起こるのか知っています。解決策がどのように見えるかわかりません。誰かが正しい OpenGL 呼び出しまたはサンプル コードを教えてもらえますか? 座標変換がいつ終了するかを知っており、面の頂点の座標を持っています。顔の中心座標を計算する方法を知っています。Z値でソートする必要があることを理解しています。Vector3f を現在のビュー マトリックス (または座標系を回転させるもの) で変換するにはどうすればよいですか?

ビューを回転させるコード:

    glRotatef(xrot, 1.0f, 0.0f, 0.0f);
    glRotatef(yrot, 0.0f, 1.0f, 0.0f);
4

4 に答える 4

3

OpenGL のドキュメントに「透明な面を並べ替える」とある場合、それは「描画する順序を変更する」ことを意味します。面自体のジオメトリを変換するのではなく、正しい順序で面を描画するようにします。つまり、カメラから最も離れたところから最初に、最後にカメラに最も近いようにして、フレーム バッファで色が正しくブレンドされるようにします。

これを行う 1 つの方法は、透明な面ごとにカメラからの代表的な距離 (たとえば、カメラの中心からその中心までの距離) を計算し、この代表的な距離で透明な面のリストを並べ替えることです。

OpenGL はZ バッファリング手法を使用するため、これを行う必要があります。

(「顔の中心の距離で並べ替える」という手法は少し素朴で、顔が大きい場合やカメラに近い場合に間違った結果につながることを付け加えておきます。しかし、それは簡単で、あなたを得るでしょうZ ソートへのより洗練されたアプローチについては、後で心配する十分な時間があります。)


更新: アーロン、あなたは上記を理解していることを示すために投稿を明確にしましたが、各面の適切な Z 値を計算する方法はわかりません。そうですか?私は通常、カメラから問題の顔までの距離を測定することでこれを行います. つまり、カメラがどこにあるのかわからないということですか?

これが問題の正しい説明である場合は、OpenGL FAQ 8.010を参照してください。

OpenGLに関する限り、カメラはありません。より具体的には、カメラは常に眼空間座標 (0., 0., 0.) に配置されます。

更新: おそらく問題は、モデルビュー マトリックスによってポイントを変換する方法がわからないことですか? それが問題である場合は、 OpenGL FAQ 9.130を参照してください。

ModelView マトリックスを掛けて、点を目の座標空間に変換します。次に、原点からの距離を計算します。

glGetFloatv(GL_MODELVIEW_MATRIX, dst)モデルビュー マトリックスを 16 個の float のリストとして取得するために使用します。乗算は自分で行う必要があると思います。私の知る限り、OpenGL はこのための API を提供していません。

于 2009-02-19T14:38:15.537 に答える
0

通常の世界座標に関連して、後ろから前にそれぞれの顔を描いてみましたか? 多くの場合、一部の OpenGL ドキュメントの文言は奇妙に思えます。回転を気にせずに正しい順番で描画できれば、回転を加えたときに自動的に動くのではないかと思います。OpenGL は、行列を回転するときに面の並べ替えを処理する場合があります。

または、描画するときに現在のマトリックスを取得し ( glGetMatrix() )、どの面が回転する背面/前面になるかに応じて描画アルゴリズムを並べ替えることができます。

于 2009-02-19T14:37:03.933 に答える
0

その引用がすべてを物語っています。顔を並べ替える必要があります。

このような単純なオブジェクトを描画する場合、Z バッファーを使用して背面を最初にレンダリングし、次に前面をレンダリングすることができます (異なる Z バッファー比較関数で 2 回レンダリングすることにより)。

しかし、通常は、オブジェクトを変換してから面を並べ替えるだけです。メモリ内のオブジェクトの表現だけを変換し、並べ替えによって描画順序を決定し、必要に応じて変換を使用して、元の座標でその順序で描画します (実行した並べ替えと一致する必要があります)。実際のアプリケーションでは、おそらく暗黙的に変換を行うでしょう。シーンを BSP ツリー、Quad ツリー、R ツリー、またはその他のツリーとして保存し、さまざまな方向からツリーをたどるだけです。

面を比較する関数である「is-obsucred-by」関数(最初に隠されている面を描画する必要があるため)は順序付けではないため、並べ替えの部分は難しい場合があることに注意してください。サイクルが存在する可能性があります (面 A が B を覆い隠し、&& 面 B が A を覆い隠します)。この場合、おそらく面の 1 つを分割してループを壊します。

編集:

に渡す座標を取得して頂点の z 座標を取得し、glVertex3f()1 を追加して 4D (同次座標) にし、モデルビュー マトリックスで変換し、射影マトリックスで変換してから、透視分割を行います。詳細は、第 2 章のセクション「座標変換」の OpenGL 仕様にあります。

ただし、実際に変換を行うための API はありません。OpenGL でできることは、プリミティブを描画し、レンダラーにそれらの描画方法 (たとえば、それらの変換方法) を伝えることだけです。座標などを簡単に変換することはできません (IIUC には OpenGL に変換された座標をバッファーに書き込むように指示する方法がありますが、これはそれほど簡単ではありません)。実際のオブジェクトや座標などを操作するのに役立つライブラリが必要な場合は、ある種のシーングラフ ライブラリ (OpenInventor など) の使用を検討してください。

于 2009-02-19T14:37:42.993 に答える