2

エージェントが複数の方向 (北、南...) に移動できる 3D ゲームを作成しました。

正常に動作しますが、別の形状 (ピラミッド) をコードに追加すると、エージェントを移動すると、ピラミッドが一緒に移動します。つまり、エージェント (別名カメラ) の動きに固執します。

形状を静的にする方法はありますか?

線を有効にするgl2.glLoadIdentity();と、ピラミッドがカメラにくっつきます。無効gl2.glLoadIdentity();にすると、ピラミッドが表示されなくなります。

コード:

クラス: Pyramid.java

import javax.media.opengl.GL2;


public class Pyramid {


    private int m_pyramid;


    public void createPyramid(GL2 gl2) 
    {
        m_pyramid = gl2.glGenLists(1);
        gl2.glNewList(m_pyramid, GL2.GL_COMPILE);

        //  set texture parameters
        gl2.glTexParameteri ( GL2.GL_TEXTURE_2D,GL2.GL_TEXTURE_WRAP_T,GL2.GL_LINEAR_MIPMAP_LINEAR);
        gl2.glTexParameteri( GL2.GL_TEXTURE_2D,GL2.GL_TEXTURE_WRAP_S,GL2.GL_LINEAR_MIPMAP_LINEAR);

        gl2.glBegin(GL2.GL_TRIANGLES); // of the pyramid

        // Font-face triangle
        gl2.glTexCoord3f(1.0f, 0.0f, 0.0f);  // Red
        gl2.glVertex3d(0.0f, 1.0f, 0.0f);
        gl2.glTexCoord3f(0.0f, 1.0f, 0.0f);  // Green
        gl2.glVertex3d(-1.0f, -1.0f, 1.0f);
        gl2.glTexCoord3f(0.0f, 0.0f, 1.0f);  // Blue
        gl2.glVertex3d(1.0f, -1.0f, 1.0f);

        // Right-face triangle
        gl2.glTexCoord3f(1.0f, 0.0f, 0.0f);  // Red
        gl2.glVertex3d(0.0f, 1.0f, 0.0f);
        gl2.glTexCoord3f(0.0f, 0.0f, 1.0f);  // Blue
        gl2.glVertex3d(1.0f, -1.0f, 1.0f);
        gl2.glTexCoord3f(0.0f, 1.0f, 0.0f);  // Green
        gl2.glVertex3d(1.0f, -1.0f, -1.0f);

        // Back-face triangle
        gl2.glTexCoord3f(1.0f, 0.0f, 0.0f);  // Red
        gl2.glVertex3d(0.0f, 1.0f, 0.0f);
        gl2.glTexCoord3f(0.0f, 1.0f, 0.0f);  // Green
        gl2.glVertex3d(1.0f, -1.0f, -1.0f);
        gl2.glTexCoord3f(0.0f, 0.0f, 1.0f);  // Blue
        gl2.glVertex3d(-1.0f, -1.0f, -1.0f);

        // Left-face triangle
        gl2.glTexCoord3f(1.0f, 0.0f, 0.0f);  // Red
        gl2.glVertex3d(0.0f, 1.0f, 0.0f);
        gl2.glTexCoord3f(0.0f, 0.0f, 1.0f);  // Blue
        gl2.glVertex3d(-1.0f, -1.0f, -1.0f);
        gl2.glTexCoord3f(0.0f, 1.0f, 0.0f);  // Green
        gl2.glVertex3d(-1.0f, -1.0f, 1.0f);

        gl2.glEnd(); // of the pyramid
        gl2.glEndList();

    }

}

WorldController.java

class WorldController extends GLCanvas implements GLEventListener, KeyListener 
{
    private Point3D m_agent , m_center , m_coordinate1 , m_coordinate2 , m_coordinate3;
    private GLU m_glu = new GLU();
    private Pyramid m_pyra = new Pyramid();

        public WorldController ()
    {
        this.addGLEventListener(this);

        //  initialize m_agent and axis
        this.m_agent = new Point3D(750,200,1200);
        this.m_coordinate1 = new Point3D(1,0,0);
        this.m_coordinate2 = new Point3D(0,1,0);
        this.m_coordinate3 = new Point3D(0,0,1);
        this.m_center = new Point3D(0,0,0);
    }

        @Override
    public void init (GLAutoDrawable gLDrawable) 
    {

        GL2 gl2 = gLDrawable.getGL().getGL2(); // get the OpenGL graphics context
        gl2.glEnable(GL2.GL_TEXTURE_2D);          // get GL Utilities
        gl2.glShadeModel(GL2.GL_SMOOTH);
        gl2.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl2.glClearDepth(1.0f);
        gl2.glEnable(GL2.GL_DEPTH_TEST);
        gl2.glDepthFunc(GL2.GL_LEQUAL);
        gl2.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
        gl2.glShadeModel(GL_SMOOTH); // blends colors nicely, and smoothes out lighting


        // bind the pyramid with the current GL2
        this.m_pyra.createPyramid(gl2);

        /**
         * Creating the listener 
         */
        ((Component) gLDrawable).addKeyListener(this);

    }


        @Override
    public void display(GLAutoDrawable gLDrawable)
    {
        final GL2 gl2 = gLDrawable.getGL().getGL2();
        gl2.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
        gl2.glLoadIdentity();

        //  set m_center and look at
        m_center.setPoint(m_agent.getX() - m_coordinate3.getX() , 
                   m_agent.getY() - m_coordinate3.getY() ,
                   m_agent.getZ() - m_coordinate3.getZ());

        m_glu.gluLookAt(m_agent.getX(),m_agent.getY(),m_agent.getZ(),
                      m_center.getX(),m_center.getY(),m_center.getZ(),
                      m_coordinate2.getX(),m_coordinate2.getY(),m_coordinate2.getZ());


        /**
         * pyramid 
         */

        gl2.glPushMatrix();
        // gl2.glLoadIdentity(); 
        gl2.glTranslatef(-2f, 0.0f, -10.0f); // translate left and into the screen
        gl2.glRotatef(anglePyramid, 0.1f, 1.0f, -0.1f); // rotate about the y-axis
        gl2.glCallList(5);
        gl2.glPopMatrix();   // <-- and here?
        anglePyramid += speedPyramid;

    }


    @Override
    public void reshape(GLAutoDrawable gLDrawable,int x,int y,int width,int height) 
    {

        GL2 gl2 = gLDrawable.getGL().getGL2(); // get the OpenGL 2 graphics context
        if(height <= 0) height = 1;            // prevent divide by zero

        float aspect = (float)width / (float)height;
        gl2.glMatrixMode(GL_PROJECTION);
        gl2.glLoadIdentity();
        m_glu.gluPerspective(50.0f, aspect, 1.0, 10000.0);
        gl2.glMatrixMode(GL_MODELVIEW);
        gl2.glLoadIdentity();
    }
}

移動中のエージェントの写真を次に示します。 ここに画像の説明を入力

ここに画像の説明を入力

問題を説明するライブビデオ: http://www.youtube.com/watch?v=zCBqx69b_e4&feature=youtu.be

4

2 に答える 2

3

表示機能から表示リストを生成するコードを削除することをお勧めします。init 関数またはオブジェクトの初期化に使用する関数の中に入れます。

次に、オブジェクト (ピラミッド) を構築するために重要な生成コード、変換、および定義のみをこの生成コード内に配置します。ワールド システムへの配置に関連する変換をその中に入れないでください。一度だけ生成する必要があることを覚えておいてください。リスト名が有効な間は、フレームバッファに表示するために何度も呼び出すだけで済みます。

表示リスト内に glLoadIdentity() を置かないでください。モデル ビュー マトリックスがリセットされます。もちろん、それはあなたが望むものではありません。モデル ビュー マトリックスの内容を保持するには、glPushMatrix および glPopMatrix 関数呼び出しを使用して、マトリックス スタック サブシステムを使用できます。

したがって、あなたのコードに関しては、次の変更をお勧めします。

@Override
public void init (GLAutoDrawable gLDrawable) 
{

    GL2 gl2 = gLDrawable.getGL().getGL2(); // get the OpenGL graphics context
    gl2.glEnable(GL2.GL_TEXTURE_2D);          // get GL Utilities
    gl2.glShadeModel(GL2.GL_SMOOTH);
    gl2.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    gl2.glClearDepth(1.0f);
    gl2.glEnable(GL2.GL_DEPTH_TEST);
    gl2.glDepthFunc(GL2.GL_LEQUAL);
    gl2.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
    gl2.glShadeModel(GL_SMOOTH); // blends colors nicely, and smoothes out lighting
    ((Component) gLDrawable).addKeyListener(this);

    // ADDED HERE, OR IN ANY POSITION THAT MAKE MORE SENSE
    int pyramid = gl2.glGenLists(1);
    gl2.glNewList(pyramid, GL2.GL_COMPILE);
    // gl2.glLoadIdentity();  // reset the model-view matrix  <-- TAKE THIS OFF
    gl2.glBegin(GL2.GL_TRIANGLES); // of the pyramid

    // Font-face triangle
    gl2.glTexCoord3f(1.0f, 0.0f, 0.0f);  // Red
    gl2.glVertex3d(0.0f, 1.0f, 0.0f);
    gl2.glTexCoord3f(0.0f, 1.0f, 0.0f);  // Green
    gl2.glVertex3d(-1.0f, -1.0f, 1.0f);
    gl2.glTexCoord3f(0.0f, 0.0f, 1.0f);  // Blue
    gl2.glVertex3d(1.0f, -1.0f, 1.0f);

    // Right-face triangle
    gl2.glTexCoord3f(1.0f, 0.0f, 0.0f);  // Red
    gl2.glVertex3d(0.0f, 1.0f, 0.0f);
    gl2.glTexCoord3f(0.0f, 0.0f, 1.0f);  // Blue
    gl2.glVertex3d(1.0f, -1.0f, 1.0f);
    gl2.glTexCoord3f(0.0f, 1.0f, 0.0f);  // Green
    gl2.glVertex3d(1.0f, -1.0f, -1.0f);

    // Back-face triangle
    gl2.glTexCoord3f(1.0f, 0.0f, 0.0f);  // Red
    gl2.glVertex3d(0.0f, 1.0f, 0.0f);
    gl2.glTexCoord3f(0.0f, 1.0f, 0.0f);  // Green
    gl2.glVertex3d(1.0f, -1.0f, -1.0f);
    gl2.glTexCoord3f(0.0f, 0.0f, 1.0f);  // Blue
    gl2.glVertex3d(-1.0f, -1.0f, -1.0f);

    // Left-face triangle
    gl2.glTexCoord3f(1.0f, 0.0f, 0.0f);  // Red
    gl2.glVertex3d(0.0f, 1.0f, 0.0f);
    gl2.glTexCoord3f(0.0f, 0.0f, 1.0f);  // Blue
    gl2.glVertex3d(-1.0f, -1.0f, -1.0f);
    gl2.glTexCoord3f(0.0f, 1.0f, 0.0f);  // Green
    gl2.glVertex3d(-1.0f, -1.0f, 1.0f);


    gl2.glEnd(); // of the pyramid
    gl2.glEndList();

    // END HERE
}


@Override
public void display(GLAutoDrawable gLDrawable)
{
    final GL2 gl2 = gLDrawable.getGL().getGL2();
    gl2.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
    gl2.glLoadIdentity();

    // agent and center settings
    m_center.setPoint(m_agent.getX() - m_coordinate3.getX() , 
               m_agent.getY() - m_coordinate3.getY() ,
               m_agent.getZ() - m_coordinate3.getZ());

    m_glu.gluLookAt(m_agent.getX(),m_agent.getY(),m_agent.getZ(),
                  m_center.getX(),m_center.getY(),m_center.getZ(),
                  m_coordinate2.getX(),m_coordinate2.getY(),m_coordinate2.getZ());


     /**
     * pyramid 
     */

    glPushMatrix();  // <-- did you note this function here?

    gl2.glTranslatef(-2f, 0.0f, -10.0f); // translate left and into the screen
    gl2.glRotatef(anglePyramid, 0.1f, 1.0f, -0.1f); // rotate about the y-axis

    gl2.glCallList(pyramid);
    glPopMatrix();   // <-- and here?
    anglePyramid += speedPyramid;

カメラをどのように制御しているかを示していないと、これで問題が完全に解決されるわけではありません。ただし、コードに示されているように glPushMatrix と glPopMatrix を配置してみてください

Ps。コードをもう一度調べた後、次のコードに注目しました。

 // agent and center settings
    m_center.setPoint(m_agent.getX() - m_coordinate3.getX() , 
               m_agent.getY() - m_coordinate3.getY() ,
               m_agent.getZ() - m_coordinate3.getZ());

    m_glu.gluLookAt(m_agent.getX(),m_agent.getY(),m_agent.getZ(),
                  m_center.getX(),m_center.getY(),m_center.getZ(),
                  m_coordinate2.getX(),m_coordinate2.getY(),m_coordinate2.getZ());

m_center.setPoint の目的は何ですか? この関数は何をしますか? あなたの問題はここにあると思います。

于 2013-05-17T21:03:49.787 に答える