diff --git a/CMakeLists.txt b/CMakeLists.txt index 03d97a2..f6d55b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,9 @@ add_executable(tests_opengl src/DataHandling/Texture.h src/DataHandling/Model3D.cpp src/DataHandling/Model3D.h - src/types.h) + src/types.h + src/KeyStateManager.cpp + src/KeyStateManager.h) target_link_directories(tests_opengl PRIVATE src) diff --git a/src/KeyStateManager.cpp b/src/KeyStateManager.cpp new file mode 100644 index 0000000..788ab67 --- /dev/null +++ b/src/KeyStateManager.cpp @@ -0,0 +1,79 @@ +// +// Created by trotfunky on 07/10/2019. +// + +#include "KeyStateManager.h" +#include + +std::map KeyStateManager::ascii_keys_status = {}; +std::map KeyStateManager::special_keys_status = {}; + +void KeyStateManager::register_glut_callbacks() +{ + glutKeyboardFunc(KeyStateManager::key_press); + glutKeyboardUpFunc(KeyStateManager::key_up); + glutSpecialFunc(KeyStateManager::special_key_press); + glutSpecialUpFunc(KeyStateManager::special_key_up); +} + +bool KeyStateManager::is_key_pressed(unsigned char key) +{ + if (ascii_keys_status.find(key) == ascii_keys_status.end()) + { + return false; + } + return ascii_keys_status.at(key); +} + +bool KeyStateManager::is_special_key_pressed(int key) +{ + if (special_keys_status.find(key) == special_keys_status.end()) + { + return false; + } + return special_keys_status.at(key); +} + +void KeyStateManager::key_press(unsigned char event_key, int mouse_x, int mouse_y) +{ + update_key(event_key,true); +} + +void KeyStateManager::key_up(unsigned char event_key, int mouse_x, int mouse_y) +{ + update_key(event_key,false); +} + +void KeyStateManager::special_key_press(int event_key, int mouse_x, int mouse_y) +{ + update_special_key(event_key,true); +} + +void KeyStateManager::special_key_up(int event_key, int mouse_x, int mouse_y) +{ + update_special_key(event_key,false); +} + +void KeyStateManager::update_key(unsigned char event_key, bool new_status) +{ + if (ascii_keys_status.find(event_key) != ascii_keys_status.end()) + { + ascii_keys_status.at(event_key) = new_status; + } + else + { + ascii_keys_status.insert({event_key,new_status}); + } +} + +void KeyStateManager::update_special_key(int event_key, bool new_status) +{ + if (special_keys_status.find(event_key) != special_keys_status.end()) + { + special_keys_status.at(event_key) = new_status; + } + else + { + special_keys_status.insert({event_key,new_status}); + } +} diff --git a/src/KeyStateManager.h b/src/KeyStateManager.h new file mode 100644 index 0000000..cb0693a --- /dev/null +++ b/src/KeyStateManager.h @@ -0,0 +1,41 @@ +// +// Created by trotfunky on 07/10/2019. +// + +#ifndef TESTS_OPENGL_KEYSTATEMANAGER_H +#define TESTS_OPENGL_KEYSTATEMANAGER_H + +#include +#include + + +/// Handles the key events from glut and keep the status of keys up to date. +/// "Static class" +class KeyStateManager { +public: + KeyStateManager() = delete; + + static void register_glut_callbacks(); + + // FIXME: Not happy with having two functions : char auto promoted to int if same name + static bool is_key_pressed(unsigned char key); + static bool is_special_key_pressed(int key); + + // Glut callbacks for input events + static void key_press(unsigned char event_key, int mouse_x, int mouse_y); + static void key_up(unsigned char event_key, int mouse_x, int mouse_y); + static void special_key_press(int event_key, int mouse_x, int mouse_y); + static void special_key_up(int event_key, int mouse_x, int mouse_y); + +private: + // The maps are used to keep track of the keys which were pressed or released during runtime. + static std::map ascii_keys_status; + static std::map special_keys_status; + + // These functions are called by *_press and *_up to update their values + static void update_key(unsigned char event_key, bool new_status); + static void update_special_key(int event_key, bool new_status); +}; + + +#endif //TESTS_OPENGL_KEYSTATEMANAGER_H diff --git a/src/main.cpp b/src/main.cpp index e3a126b..0ce588c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,15 +4,38 @@ #include "displayers.h" #include "DataHandling/Texture.h" #include "DataHandling/Model3D.h" - +#include "KeyStateManager.h" volatile unsigned long long int timer_ticks = 0; static Texture tree_texture; static Model3D raptor; static Texture raptor_texture; +void manage_inputs() +{ + if (KeyStateManager::is_key_pressed(' ')) + { + glClearColor(0.5,0,0,1); + } + else + { + glClearColor(0,0,0,1); + } + + if (KeyStateManager::is_special_key_pressed(GLUT_KEY_RIGHT)) + { + timer_ticks += 5; + } + if (KeyStateManager::is_special_key_pressed(GLUT_KEY_LEFT)) + { + timer_ticks -= 5; + } +} + void display() { + manage_inputs(); + float angleY = 1*timer_ticks; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -54,6 +77,7 @@ int main(int argc, char** argv) // Generate window with GLUT glutInitDisplayMode(GLUT_RGB| GLUT_DEPTH | GLUT_DOUBLE); glutCreateWindow("Hello"); + glutIgnoreKeyRepeat(true); // Init OpenGL glClearColor(0,0,0,1); @@ -96,6 +120,7 @@ int main(int argc, char** argv) glutIdleFunc(display); glutTimerFunc(50,update_angle,0); + KeyStateManager::register_glut_callbacks(); // Enters main loop, managed by GLUT glutMainLoop();