#include #include "glcxx.hpp" #include "GL3/gl3w.h" #include #include #include using namespace std; #define WIDTH 800 #define HEIGHT 800 std::shared_ptr program; std::shared_ptr box_buffer; std::shared_ptr box_array; static struct { GLint size; GLint color; GLint position; } uniforms; int color = 0; GLfloat size = 0.2; GLfloat position[2] = {0.0, 0.0}; GLfloat colors[][4] = { {1.0, 0.7, 0.0, 1.0}, {0.0, 0.5, 1.0, 1.0}, {1.0, 1.0, 0.0, 1.0}, {0.2, 0.2, 1.0, 1.0}, }; bool init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glViewport(0, 0, WIDTH, HEIGHT); try { program = glcxx::Program::create( glcxx::Shader::create_from_file(GL_VERTEX_SHADER, "box.v.glsl"), glcxx::Shader::create_from_file(GL_FRAGMENT_SHADER, "box.f.glsl"), "coord", 0); uniforms.size = program->get_uniform_location("size"); uniforms.color = program->get_uniform_location("color"); uniforms.position = program->get_uniform_location("position"); box_buffer = glcxx::Buffer::create(GL_ARRAY_BUFFER, GL_STATIC_DRAW, {-1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0}); box_array = glcxx::Array::create(); box_array->bind(); box_buffer->bind(); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), NULL); } catch (glcxx::Error & e) { cerr << "glcxx error: " << e.what() << endl; return false; } return true; } void display(SDL_Window * window) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); program->use(); box_array->bind(); glUniform4fv(uniforms.color, 1, colors[color]); glUniform2fv(uniforms.position, 1, position); glUniform1f(uniforms.size, size); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); SDL_GL_SwapWindow(window); } int main(int argc, char *argv[]) { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS)) { printf("Failed to initialize SDL!\n"); return 1; } atexit(SDL_Quit); SDL_Window * window = SDL_CreateWindow(argv[0], SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_OPENGL); if (!window) { printf("Failed to create window!\n"); SDL_Quit(); return 2; } (void)SDL_GL_CreateContext(window); if (gl3wInit()) { cerr << "Failed to initialize GL3W" << endl; return 2; } if (!gl3wIsSupported(3, 0)) { cerr << "OpenGL 3.0 is not supported!" << endl; return 2; } if (!init()) { return 2; } int n_joysticks = SDL_NumJoysticks(); std::list game_controllers; for (int i = 0; i < n_joysticks; i++) { if (SDL_IsGameController(i)) { SDL_GameController * game_controller = SDL_GameControllerOpen(i); if (game_controller == nullptr) { cerr << "Failed to open game controller " << i << ": " << SDL_GetError() << endl; return 2; } game_controllers.push_back(game_controller); } } cout << "Found " << n_joysticks << " joystick devices, " << game_controllers.size() << " of which are game controllers" << endl; display(window); SDL_Event event; bool exit = false; for (;;) { while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) exit = true; else if (event.type == SDL_KEYDOWN) { if (event.key.keysym.sym == SDLK_ESCAPE) exit = true; } else if (event.type == SDL_CONTROLLERAXISMOTION) { std::cerr << "motion!" << std::endl; } else if (event.type == SDL_CONTROLLERBUTTONDOWN) { std::cerr << "button!" << std::endl; } } if (exit) break; display(window); } for (auto game_controller : game_controllers) { SDL_GameControllerClose(game_controller); } return 0; }