2017-06-08 7 views
-1

Ich versuche, ein Kamera-Bewegungssystem in das Programm zu implementieren, an dem ich gerade arbeite. Ich kann nicht herausfinden, wie man die Kamera in nicht-diskrete Einheiten bewegt, wenn ich die Kamera bewege, "springt" sie zur nächsten Position. Wie kann ich die Kamera ohne Sprünge bewegen?SDL OpenGL glatte Kamera Bewegung

CameraControlls Funktion:

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

Kamera Struktur:

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

Unklar was Sie fragen. Sie geben N Bilder pro Sekunde aus. Wenn also die Bewegung zwischen den Bildern n und n + 1 zu groß ist, würde dies als "Sprung" erscheinen. Sie benötigen eine höhere Bildwiederholfrequenz (häufig durch Anzeigefunktionen eingeschränkt), langsamere Bewegungen oder eine Art Bewegungsunschärfe. Es ist jedoch sehr unwahrscheinlich, dass es zu einem Problem wird, wenn sich Ihre Kamera nicht immer mit sehr hoher Geschwindigkeit (z. B. Hochgeschwindigkeitsrennen) bewegen sollte. – keltar

Antwort

1

ich denke, das wichtigste Ereignis des sdl nicht jeden Frame feuert, so dass Sie nicht die Kameraposition direkt von dort ändern sollte, weil die Kamera wird nicht jeden Frame aktualisieren.

würde ich einen boolean Variable MOVE_FORWARD erstellen, wenn die Vorwärts-Taste oder nicht

  • Im wichtigen Fall, dass Sie die MOVE_FORWARD Variable aktualisieren gedrückt darstellen.

    while (SDL_PollEvent(&e)) 
    { 
    .......... 
        case SDL_KEYDOWN: 
         switch (e.key.keysym.sym) 
         { 
         case SDLK_w: 
          MOVE_FORWARD=true; 
          break; 
    
  • In jedem Frame

    if (MOVE_FORWARD){pos+=0.3} 
    

diese Weise wird die Kamera aktualisiert seine Position in jedem Rahmen und nicht nur, wenn die Schlüssel-Ereignis ausgelöst


Sie die Position der Kamera aktualisieren

Sie könnten auch die Erstellung von Schlüsselstatusvariablen vermeiden, indem Sie SDL_GetKeyboardState(NULL) anstelle vonverwenden:

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

Sie müssen die Ereigniswarteschlange (Poll oder Pumpe) noch leeren oder SDL_GetKeyboardState erhält keine aktualisierten Werte. – keltar