2015-01-31 155 views
0

我在使用现代OpenGL实现SDL中的某些事件时遇到了一些麻烦。你们能帮我吗?SDL使用现代OpenGL导航的键盘和鼠标事件

我跟着这个家伙教程 http://youtu.be/ftiKrP3gW3k?list=PLEETnX-uPtBXT9T-hD0Bj31DSnwio-ywh,直到教程3.5网格。此外,我现在试图实现这个家伙http://youtu.be/f-vxvZGI8R0?list=PL0AB023E769342AFE键盘和鼠标导航上我从“ThebennyBox”家伙的代码。

我用一台MacBook Air 13'

到目前为止,我有这样的代码在main.cpp中:

#include <GL/glew.h> 
#include <GL/glfw3.h> 
#include <OpenGL/glext.h> 
#include <iostream> 
#include "Display.h" 
#include "Shader.h" 
#include "Mesh.h" 
#include "Camera.h" 

int main(){ 
Camera camera; 

Uint32 start; 
SDL_Event event; 
//glew 1.50 which glGenVertexArrays doesnt work without the 
//glewExperimental flag. so it is glew version dependent 
glewExperimental = GL_TRUE; 

//Create Window with SDL 
Display display(800, 600, "OpenGL Terrain"); 

//Create the vertices we want to draw 
Vertex vertices[] = { Vertex(glm::vec3(-0.5,-0.5,0)), 
         Vertex(glm::vec3(0,0.5,0)), 
         Vertex(glm::vec3(0.5,-0.5,0))}; 

//Send the vertices to GPU with mesh function 
Mesh mesh(vertices, sizeof(vertices)/sizeof(vertices[0])); 

//Create vertex and fragment shaders 
Shader shader("../shaders/shader"); 

//render 
while(!display.IsClosed()){ 
    //Clear the window 
    display.Clear(0.0f,0.15f,0.23f,1.0f); 

    //Bind the shaders 
    shader.Bind(); 

    //Draw the vertices 
    mesh.Draw(); 

    //Show it all 
    display.Update(); 

    //Call to functions of the Camera Class 
    camera.Control(0.2,0.2,false); 
    camera.updateCamera(); 
} 

return 0; 
} 

这Camera.cpp

#include "Camera.h" 


bool Camera::mouseInsideOfWindow = false; 

Camera::Camera() { 

    Camera::cameraPositionX = 0.0f; 
    Camera::cameraPositionY = 0.0f; 
    Camera::cameraPositionZ = 5.0f; 
    Camera::cameraPitch = 0.0f; 
    Camera::cameraYaw = 0.0f; 


} 
void Camera::lockCamera(){ 
    //Put some restriction for the view 
    if(cameraPitch > 90.0f){cameraPitch = 90.0f;} 
    if(cameraPitch < -90.0f){cameraPitch = -90.0f;} 
    if(cameraYaw < 0.0f){cameraYaw += 360.0f;} 
    if(cameraYaw > 360.0f){cameraYaw -= 360.0f;} 
} 
void Camera::moveCamera(float distance, float direction){ 
    //convert the radius to angles 
    float rad = (cameraYaw+direction)*M_PI/180.0f; 
    cameraPositionX -= sin(rad)*distance; 
    cameraPositionZ -= cos(rad)*distance; 
} 
    void Camera::moveCameraUp(float distance, float direction){ 
    float rad = (cameraPitch+direction)*M_PI/180.0f; 
    cameraPositionY += sin(rad)*distance; 
} 
void Camera::Control(float moveVelocity,float mouseVelocity,bool mouseInsideWindow){ 

    //if the mouse is inside the window 
    if(mouseInsideWindow){ 
    //std::cout << "Innan " << std::endl; 
    int centerWindowX = 400; 
    int centerWindowY = 300; 
    SDL_ShowCursor(SDL_DISABLE); // dont show the mouse curser 
    int tempX, tempY; 

    SDL_GetMouseState(&tempX,&tempY); // get the points where the mouse is 
    cameraYaw += mouseVelocity*(centerWindowX-tempX); // calculate yaw 
    cameraPitch += mouseVelocity*(centerWindowY-tempY); // calculate pitch 
    lockCamera(); // lock the view 
    // Put back the curser in center 
    SDL_WarpMouseInWindow(NULL,centerWindowX,centerWindowY); 

    const Uint8 *state = SDL_GetKeyboardState(NULL); 
    //Move the Camera 
    if(state[SDLK_w]){ 
     std::cout << "W" << std::endl; 
     if(cameraPitch != 90 && cameraPitch != -90){ 
      moveCamera(moveVelocity,0.0); 
      moveCameraUp(moveVelocity,0.0); 
     } 
    } 
    else if(state[SDLK_s]){ 
     std::cout << "S" << std::endl; 
     if(cameraPitch != 90 && cameraPitch != -90){ 
      moveCamera(moveVelocity,180.0); 
      moveCameraUp(moveVelocity,180.0); 
     }    
    } 
    if(state[SDLK_a]){ 
     std::cout << "A" << std::endl; 
     moveCamera(moveVelocity,90.0); 
    } 
    else if (state[SDLK_d]){ 
     std::cout << "D" << std::endl; 
     moveCamera(moveVelocity,270.0); 
    } 

    //Close the window 

} 
//Rotate the Camera 
    glRotatef(-cameraPitch,1.0,0.0,0.0); 
    glRotatef(-cameraYaw,0.0,1.0,0.0); 

} 
void Camera::updateCamera(){ 
    glTranslatef(-cameraPositionX,-cameraPositionY,cameraPositionZ); 
} 
Camera::~Camera() {} 

所以我不确定我错过了什么。我有一种感觉,这与SDL_event有关?我需要做些什么来解决这个问题?

基本上我想要的是可以随(w,s,a,d)移动并使用鼠标指示。

我需要添加剩余的代码吗?请有人可以帮我吗?

我让自己明白了吗?否则请询问。

p.s.窗口中的简单三角形示例工作正常,但不是导航。

/K

+0

你在哪里投票事件? – Prismatic 2015-01-31 18:25:29

+0

这就是问题所在,它认为。我不知道在哪里或如何去做。你能帮我吗? – Kahin 2015-01-31 18:35:42

回答

1

在SDL你一般轮询事件,这样你的应用程序能够对输入做出反应像鼠标或键盘操作。

目前你在你的主循环渲染:

//render 
while(!display.IsClosed()){ 
    // draw stuff 
} 

您需要轮询在这个循环事件来说: :

SDL_Event e; 
if(SDL_PollEvent(&e) != 0) { 
    // handle your event here 
} 

您链接到了这个视频作者的YouTube页面https://www.youtube.com/watch?v=bzZa_pg9_-A

你也可以看一下学习SDL的流行方式的lazyfoo教程: http://lazyfoo.net/tutorials/SDL/03_event_driven_programming/index.php

0

我加入了SDL_Event到display.update()函数在显示类是这样的:

void Display::Update(){ 
    SDL_GL_SwapWindow(m_window); 
    SDL_Event event; 

while(SDL_PollEvent(&event)){ 
    switch(event.type){ 
     case SDL_QUIT: 
       m_isClosed = true; 
       break; 
     case SDL_MOUSEBUTTONDOWN: 
       mouseInsideOfWindow = true; 
       SDL_ShowCursor(SDL_DISABLE); 
       break; 
     case SDL_KEYDOWN: 
      if(event.key.keysym.sym == SDLK_q){ 
       mouseInsideOfWindow = false; 
       SDL_ShowCursor(SDL_ENABLE); 
       break; 
      } 
      if(event.key.keysym.sym == SDLK_ESCAPE){ 
       m_isClosed = true; 
       break; 
      } 


      if(event.key.keysym.sym == SDLK_w){ 

       //Do I do something here? look at Camera::control() function!!! 
      } 
    } 
} 

} 

和更新函数被调用在main.cpp中while循环。它在鼠标单击和ESCAPE时正常工作,但(w,a,s,d)不起作用。我是幕后SDL2,并在此更新我找不到(看照相机:控制),而是有一个名为

 const Uint8 *state = SDL_GetKeyboardState(NULL); 

功能,我认为这个问题在那里。我该如何解决这个问题,w,a,s,d这些键是否也适用?

/K