From 0db274b099110b8678b9c584c65b056c66bc7059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Bastian?= Date: Wed, 14 Feb 2018 11:18:36 +0100 Subject: [PATCH] Control pause and speed with keyboard Keys: space for toggle pause, < and > for speed control, 0 to reset speed --- main_bounce.cpp | 1 + periodic_updates.cpp | 28 +++++++++++++++++++++++++++- periodic_updates.hpp | 2 ++ render/GlutRender.cpp | 14 ++++++++++++++ render/GlutRender.hpp | 10 ++++++++++ 5 files changed, 54 insertions(+), 1 deletion(-) diff --git a/main_bounce.cpp b/main_bounce.cpp index b7f5cac..60b8d74 100644 --- a/main_bounce.cpp +++ b/main_bounce.cpp @@ -21,6 +21,7 @@ int main(int argc, char** argv) { render.add_surface(ball.get_surface(), bbox); render.set_idle_func(periodic_update); + render.add_kb_handler(periodic_kb_handler); init_periodic_static(&ball); render.run(); diff --git a/periodic_updates.cpp b/periodic_updates.cpp index 853f725..38f35f1 100644 --- a/periodic_updates.cpp +++ b/periodic_updates.cpp @@ -8,6 +8,9 @@ static Ball* _ball = nullptr; static std::chrono::time_point _last_time, _init_clocks; +static bool is_paused = false; +static double speed_factor = 1.; + void init_periodic_static(Ball* ball) { _last_time = std::chrono::steady_clock::now(); _init_clocks = std::chrono::steady_clock::now(); @@ -23,9 +26,32 @@ double ellapsed_double( } void periodic_update() { + if(is_paused) + return; + + printf("%lf\n", speed_factor); auto now = std::chrono::steady_clock::now(); - _ball->update_pos(ellapsed_double(_last_time, now)); + _ball->update_pos(speed_factor * ellapsed_double(_last_time, now)); _last_time = now; glutPostRedisplay(); } + +void periodic_kb_handler(unsigned char key, int, int) { + if(key == ' ') { + if(is_paused) + _last_time = std::chrono::steady_clock::now(); + is_paused = !is_paused; + } + else if(key == '<') { + speed_factor -= .1; + if(speed_factor <= 0.05) + speed_factor = .1; + } + else if(key == '>') { + speed_factor += .1; + } + else if(key == '0') { + speed_factor = 1.; + } +} diff --git a/periodic_updates.hpp b/periodic_updates.hpp index 761977d..fd1d0b4 100644 --- a/periodic_updates.hpp +++ b/periodic_updates.hpp @@ -4,3 +4,5 @@ void init_periodic_static(Ball* ball); void periodic_update(); + +void periodic_kb_handler(unsigned char key, int, int); diff --git a/render/GlutRender.cpp b/render/GlutRender.cpp index 0bdf988..8cb55d6 100644 --- a/render/GlutRender.cpp +++ b/render/GlutRender.cpp @@ -29,6 +29,7 @@ void GlutRender::init(int* argc, char** argv, // ==== Callbacks ==== glutDisplayFunc(display_handle); glutReshapeFunc(reshape_handle); + glutKeyboardFunc(kb_evt_handle); // ==== Lighting ==== GLfloat light0_pos[] = {10., 15., 10.}; @@ -89,6 +90,10 @@ void GlutRender::set_idle_func(void (*func)(void)) { glutIdleFunc(func); } +void GlutRender::add_kb_handler(GlutRender::kb_handler_t handler) { + kb_handlers.push_back(handler); +} + void GlutRender::reshape(int wid, int hei) { if (hei == 0) hei = 1; @@ -191,9 +196,18 @@ void GlutRender::display() { glutSwapBuffers(); } +void GlutRender::on_kb_evt(unsigned char key, int x, int y) { + for(auto& handler: kb_handlers) { + handler(key, x, y); + } +} + void GlutRender::reshape_handle(int wid, int hei) { get_instance().reshape(wid, hei); } void GlutRender::display_handle() { get_instance().display(); } +void GlutRender::kb_evt_handle(unsigned char key, int x, int y) { + get_instance().on_kb_evt(key, x, y); +} diff --git a/render/GlutRender.hpp b/render/GlutRender.hpp index a245fa8..f1d3e09 100644 --- a/render/GlutRender.hpp +++ b/render/GlutRender.hpp @@ -5,9 +5,12 @@ #include "../Mesh.hpp" #include "../Implicit.hpp" #include +#include class GlutRender { public: + typedef std::function kb_handler_t; + static GlutRender& get_instance(); GlutRender(GlutRender const&) = delete; @@ -24,6 +27,8 @@ class GlutRender { void set_idle_func(void (*func)(void)); + void add_kb_handler(kb_handler_t handler); + private: struct SurfaceDetails { SurfaceDetails(ImplicitSurface* surf, const Cuboid& box): @@ -46,13 +51,18 @@ class GlutRender { protected: void reshape(int wid, int hei); void display(); + void on_kb_evt(unsigned char key, int x, int y); static void reshape_handle(int wid, int hei); static void display_handle(); + static void kb_evt_handle(unsigned char key, int x, int y); + private: //attr std::function rand_color; std::set meshes; std::set surfaces; + + std::vector kb_handlers; };