【问题标题】:LWJGL Camera rotating around point?LWJGL 相机绕点旋转?
【发布时间】:2013-09-04 20:05:46
【问题描述】:

*已解决 好吧,问题是在 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();
}

}

【问题讨论】:

    标签: java camera rotation lwjgl point


    【解决方案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。

    【讨论】:

    • 我什至无法测试它,自己查看然后修复它,因为我们看不到您的Block class
    • 好的,我会贴出块类。
    • 哇!谢谢!顺便说一句,喜欢你的视频。
    • 不客气!哇,你刚刚访问了我的网站,然后又访问了我的 YouTube,并看到了我的一些视频吗?
    • 不,我已经看了一段时间了。
    【解决方案2】:

    坐标可能会有些混乱,因为它们也会被旋转。您可以尝试旋转 (camera_x, camera_y, camera_z) 向量,但我建议您使用 GLU.gluLookAt()。 它为您完成所有工作,您只需做一些简单的矢量数学运算,即可根据您的 camera_x、camera_y、camera_z 和 camera_rot 值计算视点、参考点和向上矢量。

    您可以阅读gluLookAt specificationlearn about Up vector

    UPD:我也试着弄乱一下 glTranslate* 和 glRotate*,这就是我得到的:

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

    这段代码很适合我。

    【讨论】:

    • 每当我尝试使用它时,一切都在不停闪烁,我无法移动,即使使用不同的控制系统。
    • Vallentin 已经提到您将每帧的凸轮位置设置为 0 并且忘记调用 glLoadIdentity()。这就解释了为什么你会被困在这个位置上。
    猜你喜欢
    • 2023-03-12
    • 1970-01-01
    • 2010-09-22
    • 2013-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2012-12-27
    相关资源
    最近更新 更多