From 452d46341d43b80c46ba2ff4cd163a68fda159ec Mon Sep 17 00:00:00 2001 From: Stefano Date: Fri, 29 Mar 2024 15:40:47 +0100 Subject: [PATCH] First test version using imgui example --- src/devices/keyboard-joypad/CMakeLists.txt | 1 + .../keyboard-joypad/KeyboardJoypad.cpp | 211 +++++++++++++++++- src/devices/keyboard-joypad/KeyboardJoypad.h | 9 +- .../KeyboardJoypadLogComponent.cpp | 11 + src/vendor/dearimgui/CMakeLists.txt | 3 +- 5 files changed, 223 insertions(+), 12 deletions(-) create mode 100644 src/devices/keyboard-joypad/KeyboardJoypadLogComponent.cpp diff --git a/src/devices/keyboard-joypad/CMakeLists.txt b/src/devices/keyboard-joypad/CMakeLists.txt index 4c22ddb..6cb1c06 100644 --- a/src/devices/keyboard-joypad/CMakeLists.txt +++ b/src/devices/keyboard-joypad/CMakeLists.txt @@ -15,6 +15,7 @@ yarp_prepare_plugin(keyboardJoypad set(yarp_keyboard-joypad_SRCS KeyboardJoypad.cpp + KeyboardJoypadLogComponent.cpp ) set(yarp_keyboard-joypad_HDRS diff --git a/src/devices/keyboard-joypad/KeyboardJoypad.cpp b/src/devices/keyboard-joypad/KeyboardJoypad.cpp index 187716e..b44c213 100644 --- a/src/devices/keyboard-joypad/KeyboardJoypad.cpp +++ b/src/devices/keyboard-joypad/KeyboardJoypad.cpp @@ -6,57 +6,258 @@ * BSD-2-Clause license. See the accompanying LICENSE file for details. */ +#define GL_GLEXT_PROTOTYPES +#define GL3_PROTOTYPES +#define GL_SILENCE_DEPRECATION + +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + #include #include #include +class yarp::dev::KeyboardJoypad::Impl +{ +public: + GLFWwindow* window = nullptr; + + std::atomic_bool need_to_close{false}, closed{false}; + + std::mutex mutex; + + //---TO BE REMOVED + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + //--- + + static void GLMessageCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei, const GLchar* message, const void*) { + yCError(KEYBOARDJOYPAD, "GL CALLBACK: %s source = 0x%x, type = 0x%x, id = 0x%x, severity = 0x%x, message = %s", + (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""), + source, type, id, severity, message); + } + + static void glfwErrorCallback(int error, const char* description) { + yCError(KEYBOARDJOYPAD, "GLFW error %d: %s", error, description); + } + +}; + yarp::dev::KeyboardJoypad::KeyboardJoypad() : yarp::dev::DeviceDriver(), yarp::os::PeriodicThread(0.01, yarp::os::ShouldUseSystemClock::Yes) { + m_pimpl = std::make_unique(); } yarp::dev::KeyboardJoypad::~KeyboardJoypad() { + this->stop(); } bool yarp::dev::KeyboardJoypad::open(yarp::os::Searchable& cfg) { - return false; + // Start the thread + if (!this->start()) { + yCError(KEYBOARDJOYPAD) << "Thread start failed, aborting."; + this->close(); + return false; + } + + return true; } bool yarp::dev::KeyboardJoypad::close() { - return false; + this->askToStop(); + return true; } bool yarp::dev::KeyboardJoypad::threadInit() { - return false; + std::lock_guard lock(m_pimpl->mutex); + + glfwSetErrorCallback(&KeyboardJoypad::Impl::glfwErrorCallback); + if (!glfwInit()) { + yCError(KEYBOARDJOYPAD, "Unable to initialize GLFW"); + return false; + } + + m_pimpl->window = glfwCreateWindow(1280, 720, "YARP OpenXr Device Window", nullptr, nullptr); + if (!m_pimpl->window) { + yCError(KEYBOARDJOYPAD, "Could not create window"); + return false; + } + + glfwMakeContextCurrent(m_pimpl->window); + glfwSwapInterval(1); + + // Initialize the GLEW OpenGL 3.x bindings + // GLEW must be initialized after creating the window + glewExperimental = GL_TRUE; + GLenum err = glewInit(); + if (err != GLEW_OK) { + yCError(KEYBOARDJOYPAD) << "glewInit failed, aborting."; + return false; + } + yCInfo(KEYBOARDJOYPAD) << "Using GLEW" << (const char*)glewGetString(GLEW_VERSION); + + glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_OTHER, GL_DEBUG_SEVERITY_NOTIFICATION, 0, NULL, GL_FALSE); //This is to ignore message 0x20071 about the use of the VIDEO memory + + glDebugMessageCallback(&KeyboardJoypad::Impl::GLMessageCallback, NULL); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + glEnable(GL_DEBUG_OUTPUT); + + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + + // Setup Platform/Renderer backends + ImGui_ImplGlfw_InitForOpenGL(m_pimpl->window, true); + ImGui_ImplOpenGL3_Init(); + + return true; } void yarp::dev::KeyboardJoypad::threadRelease() { + if (m_pimpl->closed) + return; + + std::lock_guard lock(m_pimpl->mutex); + + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + + if (m_pimpl->window) + { + glfwDestroyWindow(m_pimpl->window); + glfwTerminate(); + m_pimpl->window = nullptr; + } + + m_pimpl->closed = true; } void yarp::dev::KeyboardJoypad::run() { + if (m_pimpl->closed) + { + return; + } + { + std::lock_guard lock(m_pimpl->mutex); + m_pimpl->need_to_close = glfwWindowShouldClose(m_pimpl->window); + } + + if (!m_pimpl->need_to_close) + { + std::lock_guard lock(m_pimpl->mutex); + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + glfwPollEvents(); + + // Start the Dear ImGui frame + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (m_pimpl->show_demo_window) + ImGui::ShowDemoWindow(&m_pimpl->show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &m_pimpl->show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &m_pimpl->show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&m_pimpl->clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGuiIO& io = ImGui::GetIO(); + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (m_pimpl->show_another_window) + { + ImGui::Begin("Another Window", &m_pimpl->show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + m_pimpl->show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + int display_w, display_h; + glfwGetFramebufferSize(m_pimpl->window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(m_pimpl->clear_color.x * m_pimpl->clear_color.w, m_pimpl->clear_color.y * m_pimpl->clear_color.w, m_pimpl->clear_color.z * m_pimpl->clear_color.w, m_pimpl->clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + + glfwSwapBuffers(m_pimpl->window); + + } + else + { + this->close(); + } + + } bool yarp::dev::KeyboardJoypad::startService() { + //To let the device driver knowing that it need to poll updateService continuosly return false; } bool yarp::dev::KeyboardJoypad::updateService() { - return false; + //To let the device driver that we are still alive + return !m_pimpl->closed; } bool yarp::dev::KeyboardJoypad::stopService() { - return false; + return this->close(); } bool yarp::dev::KeyboardJoypad::getAxisCount(unsigned int& axis_count) diff --git a/src/devices/keyboard-joypad/KeyboardJoypad.h b/src/devices/keyboard-joypad/KeyboardJoypad.h index df0bc68..bfccff6 100644 --- a/src/devices/keyboard-joypad/KeyboardJoypad.h +++ b/src/devices/keyboard-joypad/KeyboardJoypad.h @@ -9,8 +9,7 @@ #ifndef YARP_DEV_KEYBOARDJOYPAD_H #define YARP_DEV_KEYBOARDJOYPAD_H -#include -#include +#include #include #include @@ -64,10 +63,8 @@ class yarp::dev::KeyboardJoypad : public yarp::dev::DeviceDriver, private: - std::atomic_bool m_closed{ false }; - - std::mutex m_mutex; - + class Impl; + std::unique_ptr m_pimpl; }; diff --git a/src/devices/keyboard-joypad/KeyboardJoypadLogComponent.cpp b/src/devices/keyboard-joypad/KeyboardJoypadLogComponent.cpp new file mode 100644 index 0000000..a704aac --- /dev/null +++ b/src/devices/keyboard-joypad/KeyboardJoypadLogComponent.cpp @@ -0,0 +1,11 @@ +/* + * Copyright (C) 2021 Istituto Italiano di Tecnologia (IIT) + * All rights reserved. + * + * This software may be modified and distributed under the terms of the + * BSD-2-Clause license. See the accompanying LICENSE file for details. + */ + +#include + +YARP_LOG_COMPONENT(KEYBOARDJOYPAD, "yarp.device.keyboard.joypad") diff --git a/src/vendor/dearimgui/CMakeLists.txt b/src/vendor/dearimgui/CMakeLists.txt index a44c976..dbede74 100644 --- a/src/vendor/dearimgui/CMakeLists.txt +++ b/src/vendor/dearimgui/CMakeLists.txt @@ -11,8 +11,9 @@ endif() include(FetchContent) set(imgui_TAG v1.90.4) -set(IMGUI_BUILD_GLFW_BINDING ON) set(imgui-feedstock_TAG 7f402e0ac895620420310a7e4791860a2dc6e79d) +set(IMGUI_BUILD_GLFW_BINDING ON) +set(IMGUI_BUILD_OPENGL3_BINDING ON) FetchContent_Declare( imgui