3

オンラインのチュートリアルなどから OpenGL と C++ を使用して 3 人称カメラ システムを作成しましたが、特定の問題を把握できないようです。マウスの動きを使用して向きを変えると、カメラがキャラクターの周りを回転するのではなく、キャラクターがカメラの周りを回転し、キャラクターがその場で向きを変えます。キャラクターをその場でターンさせるにはどうすればよいですか?

// variables ..

void checkMouse(){
    if (mouseXPos > SCREEN_WIDTH/2){
        // turn right
        yrot += abs(mouseXPos - SCREEN_WIDTH/2) * .005;
    } else if (mouseXPos < SCREEN_WIDTH/2){
        // turn left
        yrot -= abs(mouseXPos - SCREEN_WIDTH/2) * .005;
    }
    if (mouseYPos > SCREEN_HEIGHT/2){
        // look up
        xrot += abs(mouseYPos - SCREEN_HEIGHT/2) * .005;
    } else if (mouseYPos < SCREEN_HEIGHT/2){
        // look down
        xrot -= abs(mouseYPos - SCREEN_HEIGHT/2) * .005;
    }
}

void checkKeys(){
    if(keys['t'] == true){
        wireframe=!wireframe;
        if(wireframe){
            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        }
        else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }

    if (keys['w'] == true){
        float xrotrad, yrotrad;
        yrotrad = (yrot / 180 * 3.141592654f);
        xrotrad = (xrot / 180 * 3.141592654f); 
        xpos += float(sin(yrotrad)) * 10 ;
        zpos -= float(cos(yrotrad)) * 10 ;
    }

    if (keys['s'] == true){
        float xrotrad, yrotrad;
        yrotrad = (yrot / 180 * 3.141592654f);
        xrotrad = (xrot / 180 * 3.141592654f); 
        xpos -= float(sin(yrotrad)) * 10;
        zpos += float(cos(yrotrad)) * 10;
    }

    if (keys['a'] == true){
        float yrotrad;
        yrotrad = (yrot / 180 * 3.141592654f);
        xpos -= float(cos(yrotrad)) * 10;
        zpos -= float(sin(yrotrad)) * 10;
    }

    if (keys['d'] == true){
        float yrotrad;
        yrotrad = (yrot / 180 * 3.141592654f);
        xpos += float(cos(yrotrad)) * 10;
        zpos += float(sin(yrotrad)) * 10;
    }
}

void renderScene(){

    // Clear framebuffer & depth buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Reset Modelview matrix       
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    // Set view position & direction
    gluLookAt(0,0,5,  0,0,-1,  0,1,0);

    checkKeys();
    checkMouse();

    // 3rd person object
    // draw body
    glPushMatrix();
    glRotatef(xrot,1.0,0.0,0.0); // keeps object on ground level rather than always in front of camera
    glTranslatef(0,-90,-400.0); // keep object 400 away from camera
    glRotatef(-90,0.0,1.0,0.0);
    glutSolidCube(20);
    glPopMatrix();

    // CAMERA
    glRotatef(xrot,1.0,0.0,0.0);  //rotate our camera on the x-axis (left and right)
        glRotatef(yrot,0.0,1.0,0.0);  //rotate our camera on the y-axis (up and down)
    glTranslated(-xpos,-ypos-200,-zpos);

    // rest of world
    glPushMatrix();
    glutSolidCube(30);
    glPopMatrix();

    // ..

    glDisable(GL_TEXTURE_2D);
    // Swap double buffer for flicker-free animation
    glutSwapBuffers();

}

void updateScene(){

    // Wait until at least 16ms passed since start of last frame
    // Effectively caps framerate at ~60fps
    while(timeGetTime()-lastTickCount<16);
    lastTickCount=timeGetTime();

    // Draw the next frame
    glutPostRedisplay();

}

void keypress (unsigned char key, int x, int y) {

    keys[key] = true;

    // Test if user pressed ESCAPE (ascii 27)
    // If so, exit the program
    if(key==27){
        exitScene();
    }
}

void keypressup (unsigned char key, int x, int y) {

    keys[key] = false;
    wheel_turn = 0;
}

void mouseMovement(int x, int y) {

    mouseXPos = x;
    mouseYPos = y;
}

void mouseClick(int button, int state, int x, int y){
    if (button == GLUT_LEFT_BUTTON){
        if (state == GLUT_DOWN)
            lButton = true;
        else
            lButton = false;
    }
}

void setupScene(){

    forwards = 0;
    strafe = 0;
    turn = 0;

    std::cout<<"Initializing scene..."<<std::endl;

    //Set up Lighting Stuff
    glLightfv(GL_LIGHT0, GL_POSITION, left_light_position);
    glLightfv(GL_LIGHT0, GL_AMBIENT, white_light);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
    glShadeModel(GL_SMOOTH);

    glEnable(GL_DEPTH_TEST);
}

void exitScene(){

    std::cout<<"Exiting scene..."<<std::endl;

    // Close window
    glutDestroyWindow(windowId);

    // Free any allocated memory

    // Exit program
    exit(0);
}

void setViewport(int width, int height) {

    // Work out window ratio, avoid divide-by-zero
    if(height==0)height=1;
    float ratio = float(width)/float(height);

    // Reset projection matrix
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // Fill screen with viewport
    glViewport(0, 0, width, height);

    // Set a 45 degree perspective
    gluPerspective(45, ratio, .1, 200000);

}

int main(int argc, char *argv[]){

    // Initialise OpenGL
    glutInit(&argc, argv); 

    // Set window position, size & create window
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowPosition(50,50);
    glutInitWindowSize(SCREEN_WIDTH,SCREEN_HEIGHT);
    windowId = glutCreateWindow("3rd person cam");

    // Set GLUT callback functions
    glutReshapeFunc(setViewport);
    glutDisplayFunc(renderScene);
    glutIdleFunc(updateScene);
    glutKeyboardFunc(keypress);
    glutKeyboardUpFunc(keypressup);
    glutPassiveMotionFunc(mouseMovement); //check for mouse movement
    glutMotionFunc(mouseMovement);
    glutMouseFunc(mouseClick);
    // Setup OpenGL state & scene resources (models, textures etc)
    setupScene();

    // Show window & start update loop
    glutMainLoop();    

    return 0;

}
4

1 に答える 1

4

あなたはカメラをそれ自体の周りで回転させています—それはあなたが頭を回すのと似ています。関心のあるオブジェクトを中心に回転しながら、カメラの位置を変更したいとします。

1.カメラの位置を見つける

  • これについては「球座標」を調べてください
  • 水平角は、マウスのx移動に基づいて(0と2 * PI)の間で変化する必要があります
  • マウスのy移動に基づいて、頂角を(0とPI)の間で変化させる必要があります
  • 見つかった(x、y、z)位置を値でスケーリングして、カメラとオブジェクトの間の距離を変えることができます
  • この見つかった位置にオブジェクトの位置を追加します
  • これで、オブジェクトの周囲に有効なカメラ位置ができました

2.ビューマトリックスを検索します

  • gluLookAtと呼ばれる便利なglutメソッドがあります。それを使用して、最終的なカメラマトリックスを見つけてください。必要なもの(カメラの位置、オブジェクトの位置、ワールドアップ(0,1,0))
于 2012-12-04T22:47:52.420 に答える