2015-06-20 54 views
1

我的OpenGL應用程序出現問題,您可以在this gif中清楚地看到問題。基本上我想按照光標指向的方向移動,但這不會發生,而是「前進」方向保持不變。如何在OpenGL中更新「前進」運動

例如,如果我轉動180°並按下「w」向前走,反而向後走。我正在談論走路,因爲我試圖複製第一人稱相機,就像在FPS遊戲中一樣。

下在這裏你可以看到我到目前爲止已經編寫的代碼:

#include <GL\glew.h> 
#include <GL\freeglut.h> 
#include <iostream> 
#include <cstdlib> 
#include "imageLoader.h" 

using namespace std; 

float _angleY = 0.0f; 
float _angleX = 0.0f; 
bool about_y = true; 

float oldMouseX; 
float oldMouseY; 

int valid = 0; 

float posX = 0.0; 
float posZ = 0.0; 

// actual vector representing the camera's direction 
float lx = 0.0f, lz = -1.0f; 

// XZ position of the camera 
float x = 0.0f, z = 5.0f; 

// the key states. These variables will be zero 
// when no key is being presses 
float deltaAngle = 0.0f; 
float deltaMove = 0; 

int xOrigin = -1; 

// angle of rotation for the camera direction 
float angle = 0.0f; 

void mouseMove(int x, int y) { 
    // this will only be true when the left button is down 
    if (xOrigin >= 0) { 

     // update deltaAngle 
     deltaAngle = (x - xOrigin) * 0.001f; 

     // update camera's direction 
     lx = sin(angle + deltaAngle)*2; 
     lz = -cos(angle + deltaAngle)*2; 
    } 
} 

void mouseButton(int button, int state, int x, int y) { 
    // only start motion if the left button is pressed 
    if (button == GLUT_LEFT_BUTTON) { 
     // when the button is released 
     if (state == GLUT_UP) { 
      angle += deltaAngle; 
      xOrigin = -1; 
     } 
     else {// state = GLUT_DOWN 
      xOrigin = x; 
     } 
    } 
} 

void handleKeys(unsigned char key, int x, int y){ 
    switch (key) 
    { 
     case 'w': 
      posZ+=4; 
      cout << "FORWARD\n"; 
      break; 
     case 's': 
      posZ-=4; 
      cout << "BACK\n"; 
      break; 
     case 'd': 
      posX-=4; 
      cout << "RIGHT\n"; 
      break; 
     case 'a': 
      posX+=4; 
      cout << "LEFT\n"; 
      break; 
     case 27: 
      exit(0); 
      break; 
    } 
} 

//initializes 3d rendering 
void initRendering(){ 
    glEnable(GL_DEPTH_TEST); //permits one object to show up behind another one 
    glEnable(GL_COLOR_MATERIAL); 
    glEnable(GL_LIGHTING); //enables the lighting function 
    glEnable(GL_LIGHT0); //enables light num. 1 
    glEnable(GL_LIGHT1); //enables light num. 2 
    glEnable(GL_NORMALIZE); 
    Image* image = loadBMP("bricks.bmp"); 
    _textureId = loadTexture(image); 
    delete image; 
} 

//handles the resize of the window 
void handleResize(int w, int h){ 
    glViewport(0, 0, w, h); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluPerspective(45.0, double(w)/double(h), 1.0, 800.0); 
} 

void computePos(float deltaMove) { 
    x += deltaMove * lx * 0.1f; 
    z += deltaMove * lz * 0.1f; 
} 

//draws the 3D sccene 
void drawScene(){ 
    cout << "ANGLE: "<<angle<<"\n"; 
    if (deltaMove){ 
     computePos(deltaMove); 
    } 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    // Set the camera 
    gluLookAt(x, 1.0f, z, 
     x + lx, 1.0f, z + lz, 
     0.0f, 1.0f, 0.0f); 

    glTranslatef(posX, 0.0f, posZ); 

    //HERE WE ADD THE AMBIENT LIGHT 
    GLfloat ambientColor[] = { 0.3f, 0.3f, 0.3f, 1.0f }; //the first 3 floats represent the              //RGB intensity of the light 
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor); 

    //HERE WE ADD THE POSITIONED LIGHT (WHITE INTENSE) 
    GLfloat lightColor0[] = { 0.5f, 0.5f, 0.5f, 1.0f }; //LIGHT0 color 
    GLfloat lightPos0[] = { 4.0f, 0.0f, 8.0f, 1.0f }; //LIGHT0 position is (4,0,8) 
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0); //sets color/intensity of the light 
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightPos0); //sets position of the light 

    //HERE WE ADD THE DIRECTIONAL LIGHT (RED) 
    GLfloat lightColor1[] = { 0.5f, 0.2f, 0.2f, 1.0f }; //LIGHT1 color 
    GLfloat lightPos1[] = { -1.0f, 0.5f, 0.5f, 0.0f }; //LIGHT1 is coming from (-1,0.5,0.5) 
                 //NOTE: we just have to put the 4th 
                 //parameter to 0.0f to make it directional 

    glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor1); //sets color/intensity of the light 
    glLightfv(GL_LIGHT1, GL_DIFFUSE, lightPos1); //sets position of the light 

    glColor3f(1.0f, 1.0f, 0.0f); //we set the cube color 

    glEnable(GL_TEXTURE_2D); 
    glBindTexture(GL_TEXTURE_2D, _textureId); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    //HERE WE DEFINE COORDINATES FOR THE CUBE 
    glBegin(GL_QUADS); 

    //Front 
    glNormal3f(0.0f, 0.0f, 1.0f); 
    glTexCoord2f(0.0f, 0.0f); 
    glVertex3f(-40.5f, -40.0f, 40.5f); 
    glTexCoord2f(1.0f, 0.0f); 
    glVertex3f(40.5f, -40.0f, 40.5f); 
    glTexCoord2f(1.0f, 1.0f); 
    glVertex3f(40.5f, 40.0f, 40.5f); 
    glTexCoord2f(0.0f, 1.0f); 
    glVertex3f(-40.5f, 40.0f, 40.5f); 

    //Right 
    glNormal3f(1.0f, 0.0f, 0.0f); 
    glTexCoord2f(0.0f, 0.0f); 
    glVertex3f(40.5f, -40.0f, -80.5f); 
    glTexCoord2f(0.0f, 1.0f); 
    glVertex3f(40.5f, 40.0f, -80.5f); 
    glTexCoord2f(1.0f, 1.0f); 
    glVertex3f(40.5f, 40.0f, 40.5f); 
    glTexCoord2f(1.0f, 0.0f); 
    glVertex3f(40.5f, -40.0f, 40.5f); 

    //Back 
    glNormal3f(0.0f, 0.0f, -1.0f); 
    glTexCoord2f(0.0f, 1.0f); 
    glVertex3f(-40.5f, -40.0f, -80.5f); 
    glTexCoord2f(0.0f, 0.0f); 
    glVertex3f(-40.5f, 40.0f, -80.5f); 
    glTexCoord2f(1.0f, 0.0f); 
    glVertex3f(40.5f, 40.0f, -80.5f); 
    glTexCoord2f(1.0f, 1.0f); 
    glVertex3f(40.5f, -40.0f, -80.5f); 

    //Left 
    glNormal3f(-1.0f, 0.0f, 0.0f); 
    glTexCoord2f(0.0f, 0.0f); 
    glVertex3f(-40.5f, -40.0f, -80.5f); 
    glTexCoord2f(1.0f, 0.0f); 
    glVertex3f(-40.5f, -40.0f, 40.5f); 
    glTexCoord2f(1.0f, 1.0f); 
    glVertex3f(-40.5f, 40.0f, 40.5f); 
    glTexCoord2f(0.0f, 1.0f); 
    glVertex3f(-40.5f, 40.0f, -80.5f); 

    glEnd(); 

    glutSwapBuffers(); 
} 

//main loop of the program 
void update(int value){ 
    glutPostRedisplay(); 
    glutTimerFunc(25, update, 0); 
} 
+0

也許你應該以你所尋找的方式走?我的意思是,如果你變成180度,那麼前進就會落後。 – outoftime

+0

對不起,也許我對我的問題不是很清楚。假設你正在看着你,你開始走路,你走這條路,一切都很酷。然後你將身體轉向右邊,然後再次開始行走,但不是右轉,而是身體向前移動的方向移動。這幾乎是發生了什麼。 – Andrew

+0

就像我悲傷,你需要走向你面對的方向。 – outoftime

回答

1

您應該創建的direction載體。每次移動鼠標時,都應根據角度重新評估。方向矢量應該是unit circle上的矢量。

假設你有方向向量direction = (0.4X, 0.6Z)(數字可以不真實,但讓它成爲爲例),然後前進,你應該通過velocity = 4標量相乘,所以矢量velocity = (1.6X, 2.4Z)。其意思是posX += 1.6, posZ += 2.4;

如果您需要向右轉,將其旋轉90度,然後乘以速度標量。

要旋轉方向矢量,您可以使用函數sincos,因爲它是單位圓上的位置。

向後和向左移動可以使用負速度。