1

*これは解決済みです。問題は、LWJGL で glTranslatef と glRotatef を使用して基本的な FPS カメラを作成したことです。最初はそのように動作しますが、カメラを動かすと、カメラが元あった場所からピボットを中心に回転し始めます! ここに私のコードがあります(インポートなどはありません):

public class Main {
public static float camera_x,camera_y,camera_z,camera_rot;
public static ArrayList<Block>blocks = new ArrayList<Block>();
public Main(){

    try{
        Display.setDisplayMode(new DisplayMode(800,600));
        Display.setTitle("Voxel");
        Display.create();
    }catch(LWJGLException e){
        e.printStackTrace();
    }
    //Init
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective((float)45,800f/600f,0.1f,1000.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glShadeModel(GL_SMOOTH);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);

    glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    generateWorld();
    glTranslatef(0,15,0);
    float dt,time,lastTime = 0;
    Mouse.setGrabbed(true);
    while(!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
        time = Sys.getTime();
        dt = (time - lastTime)/1000.0f;
        lastTime = time;

        render();
        tick();
        Display.update();
        Display.sync(60);

    }

    Display.destroy();
    System.exit(0);
}
public void tick(){
    camera_x = 0;
    camera_y = 0;
    camera_z = 0;
    camera_rot = 0;

    if(Keyboard.isKeyDown(Keyboard.KEY_W)){
        camera_z = +1;
    }
    else if(Keyboard.isKeyDown(Keyboard.KEY_S)){
        camera_z = -1;
    }
    if(Keyboard.isKeyDown(Keyboard.KEY_A)){
        camera_x = +1;
    }
    else if(Keyboard.isKeyDown(Keyboard.KEY_D)){
        camera_x = -1;
    }

    if(Keyboard.isKeyDown(Keyboard.KEY_SPACE)){
        camera_y = -1;
    }
    else if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)){
        camera_y = +1;
    }

    while(Keyboard.next()){
    if(Keyboard.isKeyDown(Keyboard.KEY_R)){
        generateWorld();
    }

    }



    //Updating all of the blocks
    for(int i=0; i < blocks.size(); i++){
        blocks.get(i).tick();
    }

    camera_rot += Mouse.getDX();

}
public void render(){

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);




    glRotatef(camera_rot, 0f, 1f, 0f);    
    glTranslatef(camera_x, camera_y, camera_z);

    for(int i=0; i < blocks.size(); i++){
        blocks.get(i).render();
    }





}
public static void main(String[] arguments){

    new Main();

}
public void generateWorld(){
    blocks.clear();
    int heightlevel = 0;
    Random r = new Random();
    for(int i=0; i < 50; i++){
        for(int j=0; j < 50; j++){
            if(r.nextBoolean() == false){
                heightlevel -= 4;
            }
            else{
                heightlevel += 4;
            }
            blocks.add(new Block((i*4)-64,-8+ heightlevel,(j*4)-64,4,4,4));
            float y = -8+heightlevel;
            for(int k = 0; k < 10; k++){
                blocks.add(new Block((i*4)-64,y - (k*4),(j*4)-64,4,4,4));
            }
        }
    }
}

}

Block クラスもあります。

public class Block {
public float x,y,z,width,height,depth,shade;
public Random rand;
public Block(float xx,float yy,float zz,float ww,float hh,float dd){
    x = xx;
    y = yy;
    z = zz;
    width = ww;
    height = hh;
    depth = dd;
    rand = new Random();
    shade = (rand.nextFloat()+0.2f);

}
public void tick(){

}
public void render(){


    glBegin(GL_QUADS);
    glColor3f(0,shade,0);

    //Front
    glTexCoord2f(0,0);
    glVertex3f(x,y,z);
    glTexCoord2f(1,0);
    glVertex3f(x+width,y,z);
    glTexCoord2f(1,1);
    glVertex3f(x+width,y+height,z);
    glTexCoord2f(0,1);
    glVertex3f(x,y+height,z);
    //Back
    glVertex3f(x,y,z+depth);
    glVertex3f(x+width,y,z+depth);
    glVertex3f(x+width,y+height,z+depth);
    glVertex3f(x,y+height,z+depth);
    //Left
    glVertex3f(x,y,z);
    glVertex3f(x,y,z+depth);
    glVertex3f(x,y+height,z+depth);
    glVertex3f(x,y+height,z);
    //Right
    glVertex3f(x+width,y,z);
    glVertex3f(x+width,y,z+depth);
    glVertex3f(x+width,y+height,z+depth);
    glVertex3f(x+width,y+height,z);
    //Top
    glVertex3f(x,y,z);
    glVertex3f(x+width,y,z);
    glVertex3f(x+width,y,z+depth);
    glVertex3f(x,y,z+depth);
    //Bottom
    glVertex3f(x,y+height,z);
    glVertex3f(x+width,y+height,z);
    glVertex3f(x+width,y+height,z+depth);
    glVertex3f(x,y+height,z+depth);

    glEnd();
}

}

4

2 に答える 2

1

これは、呼び出しを反転する必要があるためです。したがって、次のようになります。

glRotatef(camera_rot, 0f, 1f, 0f);    
glTranslatef(camera_x, camera_y, camera_z);

このようではありません:

glTranslatef(camera_x, camera_y, camera_z);
glRotatef(camera_rot, 0f, 1f, 0f);

その理由は、カメラを回転させてから、カメラを平行移動させるためです。を使用して回転しcamera_rot、 に従って移動するため、これにより、見ている効果が得られcamera_x, camera_y, camera_zます。

編集

これを変更する必要があります:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glRotatef(camera_rot, 0f, 1f, 0f);
glTranslatef(camera_x, camera_y, camera_z);

これに:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

glRotatef(camera_rot, 0f, 1f, 0f);
glTranslatef(camera_x, camera_y, camera_z);

そのため、それを行うと、カメラの位置と回転が動かなくなることに気付くでしょう。それはあなたが電話するたびにtick()

あなたが呼ぶ:

camera_x = 0;
camera_y = 0;
camera_z = 0;
camera_rot = 0;

それは位置と回転をリセットすることであり、それがカメラが「動けなくなる」理由です。

そのため、-1、0、1 にとどまらず、値が増減するように変更する必要があります。

于 2013-09-01T23:23:40.243 に答える