1
votes

*THIS HAS BEEN SOLVED Well, the problem is that in LWJGL I made a basic FPS camera using glTranslatef and glRotatef. It acts like it should at first, but when I move the camera it starts rotating around a pivot from where the camera originally was! Here's my code (Without the imports and such) :

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));
            }
        }
    }
}

}

There's a Block class as well:

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();
}

}

2

2 Answers

1
votes

That is because you need to flip the calls. So it is like:

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

and not like this:

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

The reason is that you rotate the camera, and then you translate the camera. This gives the effect you are seeing, since it rotates using camera_rot, and then it translates according to camera_x, camera_y, camera_z.

Edit

You need to change this:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

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

Into this:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

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

So when you've done that you will realize that your cameras position and rotation will be stuck. That is because each time you call tick()

You call:

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

What that does is resetting the position and rotation, and that is why the camera "gets stuck".

So you need to change that so the values increment or decrement and not just stay at -1, 0 and 1.

0
votes

There may be some mess with coordinates since they are also rotated. You can try rotating your (camera_x, camera_y, camera_z) vector, but I'd recommend you to use GLU.gluLookAt(). It does all the work for you, you just have to do some simple vector math to evaluate eye point, reference point and up vector from your camera_x, camera_y, camera_z and camera_rot values.

You can read gluLookAt specification and learn about Up vector.

UPD: Also I tried to mess with glTranslate* and glRotate* a bit, here is what I got:

    while (!Display.isCloseRequested()) {
        //clear:
        GL11.glLoadIdentity();
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

        GL11.glRotatef(90.0f, -1.0f, 0.0f, 0.0f); //with z axis looking up we get Oxy plane being wrong oriented, it is a little odd for me and I prefer to set z axis vertical ))
        //rotate and translate:
        GL11.glRotatef(camera_rot, 0.0f, 0.0f, 1.0f); //rotate
        GL11.glTranslatef(camera_x, camera_y, camera_z); //translate

        /* draw here */

        //process input:
        float move = 0.0f;
        float strife = 0.0f;
        if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
            strife -= 0.1f;
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
            strife += 0.1f;
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
            move += 0.1f;
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_S)) {
            move -= 0.1f;
        }
        //we move relatively to the direction we are looking
        camera_x -= strife * Math.cos(Math.toRadians(rotp)) + move * Math.sin(Math.toRadians(rotp));
        camera_y -= - strife * Math.sin(Math.toRadians(rotp)) + move * Math.cos(Math.toRadians(rotp));
        camera_rot += Mouse.getDX();
        //Display stuff
        Display.update();
        Display.sync(60);
    }

This code works well for me.