SDL用于使用现代OpenGL进行导航的键盘和鼠标事件

时间:2015-01-31 17:47:35

标签: c++ macos opengl sdl

我在使用现代OpenGL在SDL中实现某些事件时遇到了一些麻烦。你能帮我吗?

我已经关注了这些人的教程 http://youtu.be/ftiKrP3gW3k?list=PLEETnX-uPtBXT9T-hD0Bj31DSnwio-ywh直到教程3.5网格。此外,我现在正尝试在我的代码中实现这些人http://youtu.be/f-vxvZGI8R0?list=PL0AB023E769342AFE键盘和鼠标导航,并且#34; 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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

我在Display类中的display.update()函数中添加了SDL_Event,如下所示:

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循环中调用update函数。鼠标单击和ESCAPE可以正常工作但是(w,a,s,d)不起作用。我是无名的SDL2,在这个更新中我找不到(看看Camera :: control),而是有一个名为

的函数
        const Uint8 *state = SDL_GetKeyboardState(NULL); 

我认为那里的问题。我该如何修复,所以按键w,a,s,d也能正常工作?

/ K