0

太陽と惑星のある惑星系を描くために、このコードをCで書きました

glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,0.0);
glMatrixMode(GL_MODELVIEW_MATRIX);
glPushMatrix();
glutWireSphere(1.0, 20, 16);
glLoadIdentity();
glRotatef((GLfloat) year ,0.0,1.0,0.0);
glTranslatef(2.0, 0.0, 0.0);
glRotatef((GLfloat) day, 0.0, 1.0, 0.0);
glutWireSphere(0.2, 10, 8);
glPopMatrix();
glutSwapBuffers();

しかし、コードをコンパイルして実行すると、2 番目の球体がビューに表示されません。y の値を大きくすると、中心球の後ろにあるときに回転の半分が表示され、再びビューから外れます。また、球のサイズも予想よりも大きくなります。glLoadIdentity() の呼び出しをコメント アウトすると、すべて正常に動作します。私の知る限り、glLoadIdentity() は現在の Matrix(ModelView_Matrix) を単位行列でロードして、すべての平行移動と回転の効果が逆になるようにしますが、この場合、呼び出されたときに描画されるオブジェクトが、回転がない場合に異なる方法で表示されるのはなぜですかまたはその呼び出しの前に変換が実行されていますか?

4

2 に答える 2

1

ModelView マトリックスに他の変換があると思われます。すでに ID に設定されている場合、ID を読み込んでも動作は変わりません。

あなたが提供したコードは、ローカル モデルの変換を設定するだけです。適用される射影またはビューの変換がないため、これらは別の場所で行う必要があります。おそらく初期化時。

事前のビュー変換がなければ、最初の球はビューと同じ位置に描画されます。つまり、カメラは球の内側にあります。

于 2013-03-19T09:39:20.880 に答える
1

あなたの問題は、次のものを使用する方法に関連していると思わglPushMatrixglPopMatrixますglLoadIdentity

モデルビュー スタックに行列Aがあるとします。ここで を使用し、基本的にAglPushMatrixを保存して後で復元します。プッシュ/ポップ ブロック内で、前述のモデルビュー行列Aを使用して、GLUT に球を描画するよう指示します。

ここで を呼び出すとglLoadIdentityAの以前の状態は、を呼び出すまで失われ、 AglPopMatrixの以前の状態が復元されます。

つまり、後の変換呼び出しはglLoadIdentity、 の前の行列の状態ではなく単位行列に基づいていglPushMatrixます。

あなたがやりたいことは、太陽系を描くことです。おそらく次のようなことをするのが最善でしょう:

glPushMatrix();
    /* Transformations positioning the sun */
    /* Draw the sun */
    glPushMatrix();
        /* Transformations for getting from the sun to the planet */
        /* Draw the planet */
    glPopMatrix();
glPopMatrix();

余談ですが、固定機能のパイプライン ( glTranslate、glRotate、glPushMatrix など) はかなり前から廃止されています (約 10 年?) 。

編集:

質問を読み直していて、別のことが気になりました。

year惑星が太陽の周りを公転している場所をday指定し、植物が自身の極軸を中心にどれだけ回転するかを指定すると仮定すると、変換の正しい順序は次のようになります。

  1. dayy 軸を中心に回転
  2. 翻訳
  3. yeary 軸を中心に回転

(現在、あなたは逆の方法でそれを行っています。これが、あなたが経験している奇妙な振る舞いを説明している可能性があります。こちらも参照してください。)

JasonD のコメントによると、あなたの変身順序は最初は正しかったとのことですが、それでも背景を知っていれば問題ありません。;)

于 2013-03-17T10:13:40.253 に答える