4

このトピックに関する他の質問を既に確認しましたが、それらの解決策はうまくいきませんでした。私は少し途方に暮れています。GLEventListener 実装には次の関数があります。

public void init(GLAutoDrawable gl) {
    GL2 gl2 = gl.getGL().getGL2();

    gl2.glMatrixMode(GL2.GL_PROJECTION);
    gl2.glLoadIdentity();
    GLU glu = GLU.createGLU(gl2);
    glu.gluPerspective(45.0f, 1, 0.1f,100.0f);
    gl2.glMatrixMode(GL2.GL_MODELVIEW);
    gl2.glLoadIdentity();
    gl2.glViewport(0, 0, width, height);
    gl2.glEnable(GL.GL_DEPTH_TEST);
}

private void render(GLAutoDrawable drawable) {

    GL2 gl = drawable.getGL().getGL2();
    GLU glu = GLU.createGLU(gl);

    gl.glClear(GL.GL_COLOR_BUFFER_BIT);
    gl.glMatrixMode(GL2.GL_MODELVIEW);
    gl.glLoadIdentity();
    glu.gluLookAt(5,  0, 20, 
                  0, 30,  0, 
                  0,  1,  0);

    gl2.glPushMatrix();
    gl2.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );                
    gl2.glLoadIdentity();
    gl2.glTranslatef(x, y, z);        
    gl2.glBegin( GL2.GL_QUADS );
        gl2.glColor3f( 1, 0, 0 );

        //24 glVertex3f calls & some colour changes go here.
        gl2.glVertex3f(...)

    gl2.glEnd();
    gl2.glPopMatrix();

    gl.glFlush();
}

gluLookAt() マトリックスにどのような値を入れても、ビューは変わりません。私はまだ立方体の同じ面を見ていることになります。

何か案は?

ありがとう

4

1 に答える 1

6

編集:元の質問の編集に応答します。人々はそれが有用であると思うので、以下の元のテキストを残します。

あなたの問題はあなたのキューブ描画コードにあると思います。以下の解説を確認してください:glLoadIdentity呼び出しはあなたが期待することを正確に実行しています-キューブをあなたの前に強制します:

gl2.glPushMatrix();     
gl2.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );
/** Try removing the following glLoadIdentity call below.
  * That call was blowing out the MODELVIEW matrix - it's removing your 
  * gluLookAt call and returning to the identity.
  * As a result, the cube will always be right there in front of you.
  */
// gl2.glLoadIdentity();
gl2.glTranslatef(x, y, z);
gl2.glBegin( GL2.GL_QUADS );
gl2.glColor3f( 1, 0, 0 ); //24 glVertex3f calls & some colour changes go here.
gl2.glVertex3f(...)
gl2.glEnd();
gl2.glPopMatrix(); 

これは、関連する呼び出しが何をするかについての非常に簡単な説明です。詳細については、ドキュメントを参照してください。

gl2.glPushMatrix(); // This preserves current MODEL_VIEW matrix so you can get back here.
                    // Think of it as a checkpoint save in a game.
                    // Most of your objects will be wrapped in push and pop.
gl2.glLoadIdentity(); // This erases the MODEL_VIEW and replaces it with an identity.
                      // This un-does your previous gluLookAt call.  You will rarely use
                      // this inside an object (but it's not impossible).
                      // Does not apply here so don't use.
gl2.glTranslatef(x, y, z); // This is what puts your object out in space for you to find
                           // as opposed to putting it at the origin.  Most objects will
                           // have a translate (and likely a rotate as well).
                           // Note that the order of operations matters:
                           // translate and then rotate != rotate and then translate.
// QUAD strip code with vertices and colors - you're okay with these.
gl2.glPopMatrix(); // This brings back the MODEL_VIEW that you originally saved by pushing
                   // it.

OpenGLのマトリックスコードの優れている点は、理解できるサンプルコードのポートフォリオを取得すると、それを常に参照できることです。当時、 IrisGLからOpenGLに切り替えたとき、ユーティリティを移植するのに少し時間がかかり、それから振り返ることはありませんでした。

オリジナル:キューブ描画コードを追加する必要があります-キューブを(0、30、0)の近くに配置している場合、コードが要求どおりに動作している可能性が高くなります。

OpenGL FAQを確認すると、実行していることに関連する可能性のある特定の質問と回答があります。8.080gluLookAtが機能しないのはなぜですか。 本当に良い休憩はないので、答え全体を引用しますが、OpenGL FAQにアクセスしてください、答えはそこにある可能性があります:

これは通常、誤った変換が原因で発生します。

3番目と4番目のパラメーターとしてzNearとzFarを使用してProjectionマトリックススタックでgluPerspective()を使用していると仮定すると、ModelViewマトリックススタックにgluLookAtを設定し、ジオメトリがzNearとzFarの間に収まるようにパラメーターを渡す必要があります。

表示変換を理解しようとしているときは、通常、単純なコードを試してみるのが最善です。原点を中心とした単位球を見ようとしているとしましょう。次のように変換を設定する必要があります。

 glMatrixMode(GL_PROJECTION);
 glLoadIdentity(); 
 gluPerspective(50.0, 1.0, 3.0, 7.0); 
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity(); 
 gluLookAt(0.0, 0.0, 5.0,
           0.0, 0.0, 0.0,
           0.0, 1.0, 0.0);

Projection変換とModelView変換がどのように連携するかに注意することが重要です。

この例では、Projectionトランスフォームはアスペクト比1.0の50.0度の視野を設定します。zNearクリッピング平面は目の前で3.0ユニットであり、zFarクリッピング平面は目の前で7.0ユニットです。これにより、Zボリューム距離は4.0単位になり、単位球に十分なスペースが確保されます。

ModelViewトランスフォームは、目の位置を(0.0、0.0、5.0)に設定し、ルックアットポイントは単位球の中心の原点です。目の位置は、視点から5.0単位離れていることに注意してください。目の前の5.0単位の距離は、プロジェクション変換で定義されているZボリュームの中央にあるため、これは重要です。gluLookAt()呼び出しが目を(0.0、0.0、1.0)に置いた場合、原点までの距離は1.0になります。これは、球をビューボリュームに含めるのに十分な長さではなく、zNearクリッピングプレーンによってクリップされます。

同様に、目を(0.0、0.0、10.0)に配置すると、視点までの距離が10.0の場合、単位球は目から10.0単位離れ、7.0単位に配置されたzFarクリッピング平面のはるか後ろになります。

これで混乱した場合は、OpenGLレッドブックまたはOpenGL仕様の変換について読んでください。オブジェクトの座標空間、目の座標空間、クリップの座標空間を理解すると、上記が明確になります。また、小さなテストプログラムで実験してください。メインのアプリケーションプロジェクトで正しい変換を取得するのに問題がある場合は、より単純なジオメトリで問題を再現しようとする小さなコードを書くことが教育的である可能性があります。

于 2011-02-24T16:08:38.337 に答える