下記のコードは、内部にカメラ付きキューブを描画しています。 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;
}