2017-06-08 12 views
-1

私は現在作業中のプログラムにカメラモーションシステムを実装しようとしています。離散していない単位でカメラを移動する方法を理解できないので、カメラを動かすと次の位置に「ジャンプ」します。私はどのようにジャンプせずにスムーズにカメラを移動することができます。SDL OpenGLスムーズカメラ移動

CameraControlls機能:

void CameraControlls() 
{ 

while (SDL_PollEvent(&e)) 
{ 
    if (e.type == SDL_QUIT) 
    { 
     exit(0); 
    } 

    switch (e.type) 
    { 
    case SDL_KEYDOWN: 
     switch (e.key.keysym.sym) 
     { 
     case SDLK_w: 
      cam.MoveForward(0.3f); 
      break; 
     case SDLK_s: 
      cam.MoveBackward(0.3f); 
      break; 
     case SDLK_d: 
      cam.MoveRight(0.2f); 
      break; 
     case SDLK_a: 
      cam.MoveLeft(0.2f); 
      break; 
     case SDLK_ESCAPE: 
      exit(0); 
      break; 
     case SDLK_RIGHT: 
      cam.Yaw(-0.01f); 
      break; 
     case SDLK_LEFT: 
      cam.Yaw(0.01f); 
      break; 
     case SDLK_DOWN: 
      cam.Pitch(0.01f); 
      break; 
     case SDLK_UP: 
      cam.Pitch(-0.01f); 
      break; 
     } 
     } 
    } 
} 

カメラの構造:

struct Camera 
{ 
public: 
Camera(glm::vec3& pos, float fov, float aspect, float zNear, float zFar) 
{ 
    this->pos = pos; 
    this->forward = glm::vec3(0.0f, 0.0f, 1.0f); 
    this->up = glm::vec3(0.0f, 1.0f, 0.0f); 
    this->projection = glm::perspective(fov, aspect, zNear, zFar); 
} 
inline glm::mat4 GetViewProjection() const 
{ 
    return projection * glm::lookAt(pos, pos + forward, up); 
} 
void MoveBackward(float amt) 
{ 
    pos -= forward*amt; 
} 
void MoveForward(float amt) 
{ 
    pos += forward * amt; 
} 
void MoveRight(float amt) 
{ 
    pos -= glm::cross(up, forward) * amt; 
} 
void MoveLeft(float amt) 
{ 
    pos += glm::cross(up, forward) * amt; 
} 
void Pitch(float angle) 
{ 
    glm::vec3 right = glm::normalize(glm::cross(up, forward)); 
    forward = glm::vec3(glm::normalize(glm::rotate(angle, right) * glm::vec4(forward, 0.0))); 
    up = glm::normalize(glm::cross(forward, right)); 
} 
void Yaw(float angle) 
{ 
    static const glm::vec3 UP(0.0f, 1.0f, 0.0f); 
    glm::mat4 rotation = glm::rotate(angle, UP); 
    forward = glm::vec3(glm::normalize(rotation * glm::vec4(forward, 0.0))); 
    up = glm::vec3(glm::normalize(rotation * glm::vec4(up, 0.0))); 
} 
    private: 
glm::mat4 projection; 
glm::vec3 pos; 
glm::vec3 forward; 
glm::vec3 up; 
}; 
+0

あなたが何を求めているのか不明です。 1秒間にNフレームを出力するので、フレームnとn + 1の間の動きが広すぎると、「ジャンプ」と思われます。より高いフレームレート(多くの場合、表示機能によってハード制限される)、より遅い動き、またはある種のモーションブラーが必要です。しかし、あなたのカメラが常に非常に高速(例えば、高速レーシング)で移動するはずがない場合、問題になることはほとんどありません。 – keltar

答えて

1

私はカメラので、あなたがそこから直接カメラの位置を変更すべきではありませんので、SDLのキーイベントは、すべてのフレームを発射されていないと思いますすべてのフレームを更新しないでください。

は、私はあなたがMOVE_FORWARD変数を更新キーイベントでは

  • を前方にキーが押された場合に表現したりしませんブール変数MOVE_FORWARDを作成します。あなたがカメラの位置を更新するすべてのフレームで

    while (SDL_PollEvent(&e)) 
    { 
    .......... 
        case SDL_KEYDOWN: 
         switch (e.key.keysym.sym) 
         { 
         case SDLK_w: 
          MOVE_FORWARD=true; 
          break; 
    
  • if (MOVE_FORWARD){pos+=0.3} 
    

この方法では、カメラは、フレームごとにその位置を更新していない場合にのみ、キーイベントが発生


の代わりにSDL_GetKeyboardState(NULL)を使用してキー状態変数を作成しないようにすることもできます:

Uint8* keystate = SDL_GetKeyState(NULL);  
if(keystate[SDL_SCANCODE_W]) 
{ 
    pos+=0.3; 
} 
+0

イベントキュー(ポーリングまたはポンプ)をまだフラッシュする必要があります.SDL_GetKeyboardStateは更新された値を取得しません。 – keltar

関連する問題