ImGui agregado, ejercicio 1 en proceso

parent fd5b260e
...@@ -5,10 +5,11 @@ set(CMAKE_CXX_STANDARD 20) ...@@ -5,10 +5,11 @@ set(CMAKE_CXX_STANDARD 20)
file( GLOB MY_FILES *.cpp ) file( GLOB MY_FILES *.cpp )
file( GLOB GLAD_FILES glad/src/*.c ) file( GLOB GLAD_FILES glad/src/*.c )
file( GLOB IMGUI_FILES imgui/src/*.cpp)
add_executable(PAG_p1 ${MY_FILES} ${GLAD_FILES}) add_executable(PAG_p1 ${MY_FILES} ${GLAD_FILES} ${IMGUI_FILES})
target_include_directories(PAG_p1 PUBLIC glad/include) target_include_directories(PAG_p1 PUBLIC glad/include imgui/include )
find_package(opengl_system) find_package(opengl_system)
find_package(glfw3) find_package(glfw3)
......
/**
* @file GUI.cpp
* @author dpp00022
*
* @date 2025/08/17
*
* @brief Implementación de la clase GUI
*/
#include "GUI.h"
#include <imgui.h>
#include <imgui_impl_opengl3.h>
PAG::GUI* PAG::GUI::instancia = nullptr;
PAG::GUI::GUI() { }
PAG::GUI::~GUI() { }
/**
* Devuelve la instancia única de la clase.
* @return Una referencia a la instancia única.
*/
PAG::GUI &PAG::GUI::getInstancia() {
if (!instancia) {
instancia = new GUI;
}
return *instancia;
}
/**
* @brief Función a llamar una sola vez durante la inicialización del programa
*
* Esta función inicializa el contexto de ImGui, el enlace a las E/S y los
* conectores con OpenGL3 y GLFW.
*
* @param window
*/
void PAG::GUI::inicializarGUI(GLFWwindow* window) {
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init();
}
/**
* @brief Función que prepara un nuevo frame. Se debe llamar antes de dibujar las figuras OpenGL.
*
* Llama a las funciones NewFrame de ImGui y dibuja pero no renderiza los elementos de la GUI.
*/
void PAG::GUI::prepararNuevoFrame() {
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// Aquí van las instrucciones de dibujado de ventanas
ImGui::SetNextWindowPos( ImVec2(10, 10), ImGuiCond_Once );
if( ImGui::Begin("Mensajes") ) {
// La ventana está desplegada
ImGui::SetWindowFontScale ( 1.0f ); // Escalamos el texto si fuera necesario
// Pintamos los controles
}
// Si la ventana no está desplegada, Begin devuelve false
ImGui::End ();
}
/**
* @brief Función que renderiza un nuevo frame. Se debe llamar después de dibujar las figuras OpenGL.
*
* Llama a las funciones de renderizado de ImGui. Por supuesto, antes se debe haber llamado a la
* preparación de nuevo frame de esta misma clase.
*/
void PAG::GUI::renderizarNuevoFrame() {
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData( ImGui::GetDrawData() );
}
/**
* @brief Función a llamar una sola vez durante la finalización del programa
*
* Esta función libera los recursos de ImGui. Importante llamarla antes de
* destruir la ventana de GLFW.
*/
void PAG::GUI::destruirGUI() {
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
/**
* Función para realizar la llamada de callback cuando se interactúa con un botón del ratón.
* @param button Botón con el que se ha interactuado.
* @param pulsado true si está siendo pulsado, false si está siendo soltado.
*/
void PAG::GUI::callback_raton(int button, bool pulsado) {
ImGuiIO& io = ImGui::GetIO();
io.AddMouseButtonEvent(button, pulsado);
}
/**
* @file GUI.h
* @author dpp00022
*
* @date 2025/08/17
*
* @brief Declaración de la clase GUI
*/
#ifndef PAG_P1_GUI_H
#define PAG_P1_GUI_H
#include <imgui_impl_glfw.h>
namespace PAG {
/**
* @brief Clase encargada de encapsular la gestión de la interfaz de
* usuario de nuestra aplicación OpenGL.
*
* Esta clase coordina el renderizado de las ventanas de Dear Imgui. Se implementa
* aplicando el patrón de diseño Singleton. Está pensada para que las
* funciones de renderizado hagan llamadas a sus métodos.
*/
class GUI {
static GUI* instancia;
GUI();
public:
virtual ~GUI();
static GUI& getInstancia();
void inicializarGUI(GLFWwindow* window);
void prepararNuevoFrame();
void renderizarNuevoFrame();
void destruirGUI();
void callback_raton(int button, bool pulsado);
};
}
#endif //PAG_P1_GUI_H
\ No newline at end of file
/**
* @file Renderer.cpp
* @author algarcia
*
* @date 2021/08/06
*
* @brief Implementación de la clase Renderer
*/
#include <GL/gl.h>
#include "Renderer.h"
PAG::Renderer* PAG::Renderer::instancia = nullptr;
PAG::Renderer::Renderer() { }
PAG::Renderer::~Renderer() { }
/**
* Devuelve la instancia única de la clase.
* @return Una referencia a la instancia única.
*/
PAG::Renderer& PAG::Renderer::getInstancia() {
if (!instancia) {
instancia = new Renderer;
}
return *instancia;
}
/**
* @brief Función a llamar cuando se necesite refrescar la ventana.
*
* Esta función limpia los buffers de color y de profundidad de
* OpenGL. No intercambia los buffers.
*/
void PAG::Renderer::refrescar() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
/**
* @brief Función a llamar cuando se cambie de tamaño la ventana.
*
* Esta función actualiza el viewport de OpenGL.
*/
void PAG::Renderer::refrescar_tamanio_framebuffer(int width, int height) {
glViewport(0, 0, width, height);
}
/**
* @file Renderer.h
* @author algarcia
*
* @date 2021/08/06
*
* @brief Declaración de la clase Renderer
*/
#ifndef PAG_P1_RENDERER_H
#define PAG_P1_RENDERER_H
/**
* Espacio de nombres para las prácticas de Programación de Aplicaciones
* Gráficas
*/
namespace PAG {
/**
* @brief Clase encargada de encapsular la gestión del área de dibujo
* OpenGL
*
* Esta clase coordina el renderizado de las escenas OpenGL. Se implementa
* aplicando el patrón de diseño Singleton. Está pensada para que las
* funciones callback hagan llamadas a sus métodos.
*/
class Renderer {
static Renderer* instancia;
Renderer();
public:
virtual ~Renderer();
static Renderer& getInstancia();
void refrescar();
void refrescar_tamanio_framebuffer(int width, int height);
};
}
#endif //PAG_P1_RENDERER_H
\ No newline at end of file
This diff could not be displayed because it is too large.
// dear imgui: Platform Backend for GLFW
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..)
// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
// Implemented features:
// [X] Platform: Clipboard support.
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only).
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Resizing cursors requires GLFW 3.4+! Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Multiple Dear ImGui contexts support.
// Missing features or Issues:
// [ ] Touch events are only correctly identified as Touch on Windows. This create issues with some interactions. GLFW doesn't provide a way to identify touch inputs from mouse inputs, we cannot call io.AddMouseSourceEvent() to identify the source. We provide a Windows-specific workaround.
// [ ] Missing ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct GLFWwindow;
struct GLFWmonitor;
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks);
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks);
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool install_callbacks);
IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown();
IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame();
// Emscripten related initialization phase methods (call after ImGui_ImplGlfw_InitForOpenGL)
#ifdef __EMSCRIPTEN__
IMGUI_IMPL_API void ImGui_ImplGlfw_InstallEmscriptenCallbacks(GLFWwindow* window, const char* canvas_selector);
//static inline void ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback(const char* canvas_selector) { ImGui_ImplGlfw_InstallEmscriptenCallbacks(nullptr, canvas_selector); } } // Renamed in 1.91.0
#endif
// GLFW callbacks install
// - When calling Init with 'install_callbacks=true': ImGui_ImplGlfw_InstallCallbacks() is called. GLFW callbacks will be installed for you. They will chain-call user's previously installed callbacks, if any.
// - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call individual function yourself from your own GLFW callbacks.
IMGUI_IMPL_API void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window);
IMGUI_IMPL_API void ImGui_ImplGlfw_RestoreCallbacks(GLFWwindow* window);
// GFLW callbacks options:
// - Set 'chain_for_all_windows=true' to enable chaining callbacks for all windows (including secondary viewports created by backends or by user)
IMGUI_IMPL_API void ImGui_ImplGlfw_SetCallbacksChainForAllWindows(bool chain_for_all_windows);
// GLFW callbacks (individual callbacks to call yourself if you didn't install callbacks)
IMGUI_IMPL_API void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused); // Since 1.84
IMGUI_IMPL_API void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered); // Since 1.84
IMGUI_IMPL_API void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y); // Since 1.87
IMGUI_IMPL_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
IMGUI_IMPL_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c);
IMGUI_IMPL_API void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor* monitor, int event);
// GLFW helpers
IMGUI_IMPL_API void ImGui_ImplGlfw_Sleep(int milliseconds);
IMGUI_IMPL_API float ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window);
IMGUI_IMPL_API float ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor);
#endif // #ifndef IMGUI_DISABLE
// dear imgui: Renderer Backend for modern OpenGL with shaders / programmatic pipeline
// - Desktop GL: 2.x 3.x 4.x
// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
// Implemented features:
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
// [x] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset) [Desktop OpenGL only!]
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
// About WebGL/ES:
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
// - This is done automatically on iOS, Android and Emscripten targets.
// - For other targets, the define needs to be visible from the imgui_impl_opengl3.cpp compilation unit. If unsure, define globally or in imconfig.h.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
// About GLSL version:
// The 'glsl_version' initialization parameter should be nullptr (default) or a "#version XXX" string.
// On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version 300 es"
// Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of imgui_impl_opengl3.cpp.
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);
IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
// (Optional) Called by Init/NewFrame/Shutdown
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
IMGUI_IMPL_API void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex);
// Configuration flags to add in your imconfig file:
//#define IMGUI_IMPL_OPENGL_ES2 // Enable ES 2 (Auto-detected on Emscripten)
//#define IMGUI_IMPL_OPENGL_ES3 // Enable ES 3 (Auto-detected on iOS/Android)
// You can explicitly select GLES2 or GLES3 API by using one of the '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line.
#if !defined(IMGUI_IMPL_OPENGL_ES2) \
&& !defined(IMGUI_IMPL_OPENGL_ES3)
// Try to detect GLES on matching platforms
#if defined(__APPLE__)
#include <TargetConditionals.h>
#endif
#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__))
#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es"
#elif defined(__EMSCRIPTEN__) || defined(__amigaos4__)
#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100"
#else
// Otherwise imgui_impl_opengl3_loader.h will be used.
#endif
#endif
#endif // #ifndef IMGUI_DISABLE
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
#include <glad/glad.h> #include <glad/glad.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include "GUI.h"
#include "Renderer.h"
//TODO: Cambiar yPos por un atributo de Renderer
double* yPos = nullptr; double* yPos = nullptr;
// - Esta función callback será llamada cuando GLFW produzca algún error // - Esta función callback será llamada cuando GLFW produzca algún error
...@@ -13,8 +17,8 @@ void error_callback(int errno, const char* desc) { ...@@ -13,8 +17,8 @@ void error_callback(int errno, const char* desc) {
// - Esta función callback será llamada cada vez que el área de dibujo // - Esta función callback será llamada cada vez que el área de dibujo
// OpenGL deba ser redibujada. // OpenGL deba ser redibujada.
void refresh_window_callback(GLFWwindow *window) { void refresh_window_callback(GLFWwindow *window) {
// - Borra los buffers (color y profundidad) // Llamada al método refrescar del Renderer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); PAG::Renderer::getInstancia().refrescar();
// - GLFW usa un doble buffer para que no haya parpadeo. Esta orden // - GLFW usa un doble buffer para que no haya parpadeo. Esta orden
// intercambia el buffer back (en el que se ha estado dibujando) por el // intercambia el buffer back (en el que se ha estado dibujando) por el
...@@ -27,7 +31,7 @@ void refresh_window_callback(GLFWwindow *window) { ...@@ -27,7 +31,7 @@ void refresh_window_callback(GLFWwindow *window) {
// - Esta función callback será llamada cada vez que se cambie el tamaño // - Esta función callback será llamada cada vez que se cambie el tamaño
// del área de dibujo OpenGL. // del área de dibujo OpenGL.
void framebuffer_size_callback(GLFWwindow *window, int width, int height) { void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
glViewport(0, 0, width, height); PAG::Renderer::getInstancia().refrescar_tamanio_framebuffer(width, height);
std::cout << "Resize callback called" << std::endl; std::cout << "Resize callback called" << std::endl;
} }
...@@ -45,9 +49,11 @@ void key_callback(GLFWwindow *window, int key, int scancode, int action, int mod ...@@ -45,9 +49,11 @@ void key_callback(GLFWwindow *window, int key, int scancode, int action, int mod
void mouse_button_callback(GLFWwindow *window, int button, int action, int mods) { void mouse_button_callback(GLFWwindow *window, int button, int action, int mods) {
if (action == GLFW_PRESS) { if (action == GLFW_PRESS) {
std::cout << "Pulsado el botón " << button << std::endl; std::cout << "Pulsado el botón " << button << std::endl;
PAG::GUI::getInstancia().callback_raton(button, true);
} }
else if (action == GLFW_RELEASE) { else if (action == GLFW_RELEASE) {
std::cout << "Soltado el botón " << button << std::endl; std::cout << "Soltado el botón " << button << std::endl;
PAG::GUI::getInstancia().callback_raton(button, false);
} }
} }
...@@ -134,6 +140,9 @@ int main() { ...@@ -134,6 +140,9 @@ int main() {
// No tiene por qué ejecutarse en cada paso por el ciclo de eventos. // No tiene por qué ejecutarse en cada paso por el ciclo de eventos.
glEnable ( GL_DEPTH_TEST ); glEnable ( GL_DEPTH_TEST );
// Inicializamos la GUI a través de ImGui
PAG::GUI::getInstancia().inicializarGUI(window);
// Inicializamos la variable yPos que controla la posición actual de la rueda del // Inicializamos la variable yPos que controla la posición actual de la rueda del
// ratón para mostrar el color correspondiente // ratón para mostrar el color correspondiente
yPos = new double; yPos = new double;
...@@ -143,6 +152,10 @@ int main() { ...@@ -143,6 +152,10 @@ int main() {
// ventana principal deba cerrarse. Por ejemplo, si el usuario pulsa el // ventana principal deba cerrarse. Por ejemplo, si el usuario pulsa el
// botón de cerrar la ventana (la X). // botón de cerrar la ventana (la X).
while (!glfwWindowShouldClose(window)) { while (!glfwWindowShouldClose(window)) {
PAG::GUI::getInstancia().prepararNuevoFrame();
// Renderizado de figuras OpenGL
PAG::GUI::getInstancia().renderizarNuevoFrame();
// - Obtiene y organiza los eventos pendientes, tales como pulsaciones de // - Obtiene y organiza los eventos pendientes, tales como pulsaciones de
// teclas o de ratón, etc. Siempre al final de cada iteración del ciclo // teclas o de ratón, etc. Siempre al final de cada iteración del ciclo
// de eventos y después de glfwSwapBuffers(window); // de eventos y después de glfwSwapBuffers(window);
...@@ -158,6 +171,7 @@ int main() { ...@@ -158,6 +171,7 @@ int main() {
yPos = nullptr; yPos = nullptr;
} }
PAG::GUI::getInstancia().destruirGUI(); // - Cerramos y destruimos la interfaz de usuario.
glfwDestroyWindow ( window ); // - Cerramos y destruimos la ventana de la aplicación. glfwDestroyWindow ( window ); // - Cerramos y destruimos la ventana de la aplicación.
window = nullptr; window = nullptr;
glfwTerminate (); // - Liberamos los recursos que ocupaba GLFW. glfwTerminate (); // - Liberamos los recursos que ocupaba GLFW.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment