2016-08-28 19 views
-3

下記のコードは、内部にカメラ付きキューブを描画しています。 escapeキーを押すとき、または右、左、上、下の矢印キーを押したときにプログラムがイベントを捕まえない理由を理解できません。GLFWのキープレスイベントをキャッチできません

内部key_callback私はstd::cout << key << std::endl;を追加しました。コンソールには押されたキーの識別子が表示されますが、何かキーを押すたびにコンソールに何も表示されません。ビジネスの

#include <cstdlib> 
#include <iostream> 
#include <vector> 
#include <array> 
#include <chrono> 

using timer = std::chrono::high_resolution_clock; 

#ifdef _WIN32 
#include <GL/glew.h> 
#else 
#define GLFW_INCLUDE_GLCOREARB 
#define GL_GLEXT_PROTOTYPES 
#endif 
#define PI 3.1415926535897932384626433832795f 
#include <GLFW/glfw3.h> 
#include "lodepng.hpp" 
#define GLM_FORCE_RADIANS 
#include "glm/glm.hpp" 
#include "glm/gtx/norm.hpp" 
#include "glm/gtx/rotate_vector.hpp" 
#include "glm/gtc/matrix_transform.hpp" 

#if defined(_MSC_VER) 
#pragma comment(lib,"user32") 
#pragma comment(lib,"gdi32") 
#pragma comment(lib,"opengl32") 
#pragma comment(lib,"glew32") 
#pragma comment(lib,"glfw3") 
#endif 

glm::vec3 camera_position(0.0f, 0.0f, 6.0f); 
glm::vec3 camera_direction(0.0f, 0.0f, -1.0f); 
glm::vec3 camera_up(0.0f, 1.0f, 0.0f); 

using timer = std::chrono::high_resolution_clock; 
timer::time_point start_time, last_time; 
float t = 0.0; 
float dt = 0.0; 
bool translate_forward = false; 
bool translate_backward = false; 
bool translate_right = false; 
bool translate_left = false; 
bool rotate_up = false; 
bool rotate_down = false; 
bool rotate_right = false; 
bool rotate_left = false; 
bool rotate_z_left = false; 
bool rotate_z_right = false; 
bool sky_on = true; 
bool sun_visible = true; 
bool earth_visible = true; 
bool moon_visible = true; 

#define SCREEN_WIDTH 640 
#define SCREEN_HEIGHT 480 

GLuint tex_flag; 

static void error_callback(int error, const char* description) 
{ 
    std::cerr << description << std::endl; 
} 

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) 
{ 
    std::cout << key << std::endl; 
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) 
     glfwSetWindowShouldClose(window, GL_TRUE); 
    if (key == GLFW_KEY_UP) 
    { 
     if (action) 
      rotate_up = true; 
     else 
      rotate_up = false; 
    } 
    if (key == GLFW_KEY_DOWN) 
    { 
     if (action) 
      rotate_down = true; 
     else 
      rotate_down = false; 
    } 
    if (key == GLFW_KEY_RIGHT) 
    { 
     if (action) 
      rotate_right = true; 
     else 
      rotate_right = false; 
    } 
    if (key == GLFW_KEY_LEFT) 
    { 
     if (action) 
      rotate_left = true; 
     else 
      rotate_left = false; 
    } 
} 

// Shader sources 
const GLchar* vertexSource = 
#if defined(__APPLE_CC__) 
"#version 150 core\n" 
#else 
"#version 130\n" 
#endif 
"in vec3 position;" 
"in vec3 color;" 
"in vec2 coord;" 
"out vec3 Color;" 
"out vec2 Coord;" 
"uniform mat4 model;" 
"uniform mat4 view;" 
"uniform mat4 projection;" 
"void main() {" 
" Color = color;" 
" Coord = coord;" 
" gl_Position = projection * view * model * vec4(position, 1.0);" 
"}"; 
const GLchar* fragmentSource = 
#if defined(__APPLE_CC__) 
"#version 150 core\n" 
#else 
"#version 130\n" 
#endif 
"in vec3 Color;" 
"in vec2 Coord;" 
"out vec4 outColor;" 
"uniform sampler2D textureSampler;" 
"void main() {" 
" outColor = vec4(Color, 1.0)*texture(textureSampler, Coord);" 
"}"; 
const GLfloat vertices[] = { 
    // Position    Color    Texcoords 
    -0.5f, 0.5f, -0.5f, 0.15f, 0.33f, 0.55f, .25f, 0.0f, // 0 
    0.5f, 0.5f, -0.5f,  0.15f, 0.33f, 0.55f, 0.5f, 0.0f, // 1 

    -0.5f, 0.5f, -0.5f, 0.15f, 0.33f, 0.55f, 0.0f, 1.f/3.f, // 2 
    -0.5f, 0.5f, 0.5f, 0.15f, 0.33f, 0.55f, .25f, 1.f/3.f, // 3 

    0.5f, 0.5f, 0.5f,  1.0f, 1.0f, 1.0f, 0.5f, 1.f/3.f, // 4 
    0.5f, 0.5f, -0.5f,  1.0f, 1.0f, 1.0f, .75f, 1.f/3.f, // 5 

    -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.f/3.f, // 6 
    -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 2.f/3.f, // 7 

    -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, .25f, 2.f/3.f, // 8 
    0.5f, -0.5f, 0.5f,  1.0f, 1.0f, 1.0f, 0.5f, 2.f/3.f, // 9 

    0.5f, -0.5f, -0.5f,  1.0f, 1.0f, 1.0f, .75f, 2.f/3.f, // 10 
    -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 2.f/3.f, // 11 

    -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, .25f, 1.0f, // 12 
    0.5f, -0.5f, -0.5f,  1.0f, 1.0f, 1.0f, 0.5f, 1.0f, // 13 
}; 


const GLuint elements[] = { 
    0, 3, 4, 0, 4, 1, 
    2, 7, 8, 2, 8, 3, 
    3, 8, 9, 3, 9, 4, 
    4, 9,10, 4,10, 5, 
    5,10,11, 5,11, 6, 
    8,12,13, 8,13, 9 
}; 

GLuint vao; 
GLuint vbo; 
GLuint ibo; 
GLuint shaderProgram; 
GLuint textures[1]; 

float t = 0; 

void check(int line) 
{ 
    GLenum error = glGetError(); 
    while (error != GL_NO_ERROR) 
    { 
     switch (error) 
     { 
     case GL_INVALID_ENUM: std::cout << "GL_INVALID_ENUM : " << line << std::endl; break; 
     case GL_INVALID_VALUE: std::cout << "GL_INVALID_VALUE : " << line << std::endl; break; 
     case GL_INVALID_OPERATION: std::cout << "GL_INVALID_OPERATION : " << line << std::endl; break; 
     case GL_OUT_OF_MEMORY: std::cout << "GL_OUT_OF_MEMORY : " << line << std::endl; break; 
     default: std::cout << "Unrecognized error : " << line << std::endl; break; 
     } 
     error = glGetError(); 
    } 
} 

void initialize_shader() 
{ 
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); 
    glShaderSource(vertexShader, 1, &vertexSource, NULL); 
    glCompileShader(vertexShader); 

    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 
    glShaderSource(fragmentShader, 1, &fragmentSource, NULL); 
    glCompileShader(fragmentShader); 

    shaderProgram = glCreateProgram(); 
    glAttachShader(shaderProgram, vertexShader); 
    glAttachShader(shaderProgram, fragmentShader); 
    glBindFragDataLocation(shaderProgram, 0, "outColor"); 
    glLinkProgram(shaderProgram); 

    glDeleteShader(vertexShader); 
    glDeleteShader(fragmentShader); 
} 
void destroy_shader() 
{ 
    glDeleteProgram(shaderProgram); 
} 

void initialize_vao() 
{ 
    glGenVertexArrays(1, &vao); 
    glBindVertexArray(vao); 

    glGenBuffers(1, &vbo); 
    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 

    glGenBuffers(1, &ibo); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW); 

    // shaderProgram must be already initialized 
    GLint posAttrib = glGetAttribLocation(shaderProgram, "position"); 
    glEnableVertexAttribArray(posAttrib); 
    glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0); 

    GLint colAttrib = glGetAttribLocation(shaderProgram, "color"); 
    glEnableVertexAttribArray(colAttrib); 
    glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat))); 

    GLint cooAttrib = glGetAttribLocation(shaderProgram, "coord"); 
    glEnableVertexAttribArray(cooAttrib); 
    glVertexAttribPointer(cooAttrib, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(6 * sizeof(GLfloat))); 
} 

void destroy_vao() 
{ 
    glDeleteBuffers(1, &ibo); 
    glDeleteBuffers(1, &vbo); 

    glDeleteVertexArrays(1, &vao); 
} 

void initialize_texture() 
{ 
    glGenTextures(1, &textures[0]); 

    std::vector<unsigned char> image; 
    unsigned width, height; 

    unsigned error = lodepng::decode(image, width, height, "cube3.png"); 
    if (error) std::cout << "decode error " << error << ": " << lodepng_error_text(error) << std::endl; 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, textures[0]); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.data()); 
    // shaderProgram must be already initialized 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
} 

void destroy_texture() 
{ 
    glDeleteTextures(1, &textures[0]); 
} 

void update_camera() 
{ 
    glm::vec3 right = glm::cross(camera_direction, camera_up); 
    glm::vec3 left = glm::cross(right, camera_up); 
    if (translate_forward) 
    { 
     camera_position += camera_direction*dt; 
    } 
    if (translate_backward) 
    { 
     camera_position -= camera_direction*dt; 
    } 
    if (translate_right) 
    { 
     camera_position += right * dt; 
    } 
    if (translate_left) 
    { 
     camera_position -= right * dt; 
    } 
    if (rotate_up) 
    { 
     camera_direction = glm::rotate(camera_direction, dt, right); 
     camera_up = glm::rotate(camera_up, dt, right); 
    } 
    if (rotate_down) 
    { 
     camera_direction = glm::rotate(camera_direction, -dt, right); 
     camera_up = glm::rotate(camera_up, -dt, right); 
    } 
    if (rotate_right) 
    { 
     camera_direction = glm::rotate(camera_direction, -dt, camera_up); 
    } 
    if (rotate_left) 
    { 
     camera_direction = glm::rotate(camera_direction, dt, camera_up); 
    } 

    if (rotate_z_left) 
    { 
     camera_direction = glm::rotate(camera_direction, dt, left); 
     camera_up = glm::rotate(camera_up, dt, left); 
    } 
    if (rotate_z_right) 
    { 
     camera_direction = glm::rotate(camera_direction, -dt, left); 
     camera_up = glm::rotate(camera_up, -dt, left); 
    } 
} 

void draw(GLFWwindow* window) 
{ 
    t = (timer::now() - start_time).count() * (float(timer::period::num)/float(timer::period::den)); 
    dt = (timer::now() - last_time).count() * (float(timer::period::num)/float(timer::period::den)); 
    update_camera(); 
    last_time = timer::now(); 
    int width, height; 
    glfwGetFramebufferSize(window, &width, &height); 

    glViewport(0, 0, width, height); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glm::mat4 projection = glm::perspective(PI/4, 1.f/1.f, 1.0f, 10.0f); 
    glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, -1.3f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f)); 
    glm::mat4 model = glm::rotate(glm::mat4(1.f), PI, glm::vec3(0.0f, 1.0f, 0.0f)); 

    glUseProgram(shaderProgram); 
    glUniform1i(glGetUniformLocation(shaderProgram, "textureSampler"), tex_flag); 

    glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, &projection[0][0]); 
    glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "view"), 1, GL_FALSE, &view[0][0]); 
    glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, &model[0][0]); 
    glBindVertexArray(vao); 
    glDrawElements(GL_TRIANGLES, 6 * 2 * 3, GL_UNSIGNED_INT, 0); // facce * triangoli per faccia * vertici per triangolo 
} 

int main(int argc, char const *argv[]) 
{ 
    GLFWwindow *window; 
    glfwSetErrorCallback(error_callback); 
    tex_flag = 0; 
    if (!glfwInit()) 
     return EXIT_FAILURE; 

#if defined(__APPLE_CC__) 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); 
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 
#else 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); 
#endif 
    window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Project", NULL, NULL); 

    if (!window) 
    { 
     glfwTerminate(); 
     exit(EXIT_FAILURE); 
    } 
    glfwMakeContextCurrent(window); 
    glfwSwapInterval(1); 
#if defined(_MSC_VER) 
    glewExperimental = true; 
    if (glewInit() != GL_NO_ERROR) 
    { 
     glfwTerminate(); 
     exit(EXIT_FAILURE); 
    } 
#endif 

    glfwSetKeyCallback(window, key_callback); 

    initialize_shader(); check(__LINE__); 
    initialize_vao(); check(__LINE__); 
    initialize_texture(); check(__LINE__); 

    //start = timer::now(); 
    glEnable(GL_DEPTH_TEST); check(__LINE__); 
    while (!glfwWindowShouldClose(window)) 
    { 
     draw(window); check(__LINE__); 

     glfwSwapBuffers(window); 
     glfwPollEvents(); 
    } 

    destroy_vao(); check(__LINE__); 
    destroy_shader(); check(__LINE__); 
    destroy_texture(); check(__LINE__); 

    glfwDestroyWindow(window); 

    glfwTerminate(); 
    return EXIT_SUCCESS; 
} 

答えて

2

まずオーダーあなたのような問題を追い詰めることは、表面積を最小限に抑え、まだ問題行動を保持できる限りプログラムを削減します。あなたのコードスニペットは、最小値完全な検証可能な例(MCVE)を構成しません。私はMCVEにそれをストリップダウン:

#include <cstdlib> 
#include <iostream> 
#include <GLFW/glfw3.h> 

static void error_callback(int error, const char* description) 
{ 
    std::cerr << description << std::endl; 
} 

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) 
{ 
    std::cout << key << std::endl; 
} 

int main(int argc, char const *argv[]) 
{ 
    GLFWwindow *window; 
    glfwSetErrorCallback(error_callback); 
    if (!glfwInit()) 
     return EXIT_FAILURE; 

    window = glfwCreateWindow(100, 100, "Project", NULL, NULL); 

    if (!window) 
    { 
     glfwTerminate(); 
     exit(EXIT_FAILURE); 
    } 
    glfwMakeContextCurrent(window); 
    glfwSwapInterval(1); 
    glfwSetKeyCallback(window, key_callback); 

    while (!glfwWindowShouldClose(window)) 
    { 
     glfwSwapBuffers(window); 
     glfwPollEvents(); 
    } 

    glfwDestroyWindow(window); 

    glfwTerminate(); 
    return EXIT_SUCCESS; 
} 

私はあなたの特定の問題を再現するためにできない午前、この最小限の例を考えます。すなわち、私はこれからキーイベントを取得しています。

これは、問題がコード内の他の場所、つまりまたはのいずれかに存在することを意味します。これは、特定のシステムおよび開発環境に関するものです。このため、MCVEは非常に重要です(特に、の最小値はです)。それは実際の原因を特定する唯一の方法です。

私の提案は次のとおりです。重要なイベントがまだ報告されていないか確認してください。もしそうなら、あなたのシステムには問題があり、コードには問題はありません。そうしないと、機能のレイヤーが破損するまでレイヤー単位で再追加することができます。

関連する問題