/* Clavier et rotation CC BY-SA Edouard.Thiel@univ-amu.fr - 24/12/2024 */ #include #include class MyApp { bool m_ok = false; GLFWwindow* m_window = nullptr; double m_angle = 0; void displayGL() { std::cout << __func__ << std::endl; glClear (GL_COLOR_BUFFER_BIT); glLoadIdentity(); glRotated (m_angle, 0, 0, 1); glRectd (-0.5, -0.5, 0.5, 0.5); } static void on_reshape_func (GLFWwindow* window, int width, int height) { std::cout << __func__ << " " << width << " " << height << std::endl; MyApp* that = static_cast(glfwGetWindowUserPointer (window)); std::cout << "Test userPointer: " << (window == that->m_window ? "ok" : "bad") << std::endl; glViewport(0, 0, width, height); } static void on_key_func (GLFWwindow* window, int key, int scancode, int action, int mods) { std::cout << __func__ << " " << key << " " << scancode << " " << action << " " << mods << std::endl; // action = GLFW_PRESS ou GLFW_REPEAT ou GLFW_RELEASE if (action == GLFW_RELEASE) return; MyApp* that = static_cast(glfwGetWindowUserPointer (window)); // Attention le clavier est géré en QWERTY : 'A' -> GLFW_KEY_Q // on traduit la touche en AZERTY avec une méthode ad-hoc. int trans_key = translate_qwerty_to_azerty (key, scancode); switch (trans_key) { case GLFW_KEY_A : std::cout << "A" << std::endl; break; case GLFW_KEY_B : std::cout << "B" << std::endl; break; case GLFW_KEY_C : std::cout << "C" << std::endl; break; case GLFW_KEY_D : std::cout << "D" << std::endl; break; case GLFW_KEY_E : std::cout << "E" << std::endl; break; case GLFW_KEY_F : std::cout << "F" << std::endl; break; case GLFW_KEY_G : std::cout << "G" << std::endl; break; case GLFW_KEY_H : std::cout << "H" << std::endl; break; case GLFW_KEY_I : std::cout << "I" << std::endl; break; case GLFW_KEY_J : std::cout << "J" << std::endl; break; case GLFW_KEY_K : std::cout << "K" << std::endl; break; case GLFW_KEY_L : std::cout << "L" << std::endl; break; case GLFW_KEY_M : std::cout << "M" << std::endl; break; case GLFW_KEY_N : std::cout << "N" << std::endl; break; case GLFW_KEY_O : std::cout << "O" << std::endl; break; case GLFW_KEY_P : std::cout << "P" << std::endl; break; case GLFW_KEY_Q : std::cout << "Q" << std::endl; break; case GLFW_KEY_R : std::cout << "R" << std::endl; break; case GLFW_KEY_S : std::cout << "S" << std::endl; break; case GLFW_KEY_T : std::cout << "T" << std::endl; break; case GLFW_KEY_U : std::cout << "U" << std::endl; break; case GLFW_KEY_V : std::cout << "V" << std::endl; break; case GLFW_KEY_W : std::cout << "W" << std::endl; break; case GLFW_KEY_X : std::cout << "X" << std::endl; break; case GLFW_KEY_Y : std::cout << "Y" << std::endl; break; case GLFW_KEY_Z : std::cout << "Z" << std::endl; break; case GLFW_KEY_SPACE : that->m_angle++; break; case GLFW_KEY_ESCAPE : that->m_ok = false; break; } } static int translate_qwerty_to_azerty (int key, int scancode) { // https://www.glfw.org/docs/latest/group__keys.html // QWERTY -> AZERTY switch (key) { case GLFW_KEY_Q : return GLFW_KEY_A; case GLFW_KEY_A : return GLFW_KEY_Q; case GLFW_KEY_W : return GLFW_KEY_Z; case GLFW_KEY_Z : return GLFW_KEY_W; case GLFW_KEY_SEMICOLON : return GLFW_KEY_M; } // Détection des différences non corrigées const char* name = glfwGetKeyName (key, scancode); if (name != NULL) { int capital = toupper(name[0]); if (capital != key) { std::cout << __func__ << " DIFF " << capital << " " << key << std::endl; } } return key; } static void on_error_func (int error, const char* description) { std::cerr << "Error: " << description << std::endl; } public: MyApp() { if (!glfwInit()) { std::cerr << "GLFW: initialization failed" << std::endl; return; } glfwSetErrorCallback (on_error_func); m_window = glfwCreateWindow (640, 480, "Keyboard rotate", NULL, NULL); if (!m_window) { std::cerr << "GLFW: window creation failed" << std::endl; return; } // Les callbacks pour GLFW étant statiques, on mémorise l'instance glfwSetWindowUserPointer (m_window, this); glfwSetWindowSizeCallback (m_window, on_reshape_func); glfwSetKeyCallback (m_window, on_key_func); glfwMakeContextCurrent (m_window); m_ok = true; } void run() { while (m_ok && !glfwWindowShouldClose (m_window)) { displayGL(); glfwSwapBuffers (m_window); glfwWaitEvents(); } } ~MyApp() { if (m_window) glfwDestroyWindow (m_window); glfwTerminate(); } }; // MyApp int main() { MyApp app; app.run(); }