From 977d377fe505bd3666ead40f71f3874cfea7c581 Mon Sep 17 00:00:00 2001 From: Menno Date: Tue, 25 May 2021 14:38:35 +0200 Subject: [PATCH] [FEATURE] working gui buttons --- src/gui/gui_element.cpp | 81 ++++++++++++++++++++++++++++++++++ src/gui/gui_element.h | 82 +++++++++++++++++++++++++++++++++++ src/gui/gui_texture.h | 20 --------- src/main.cpp | 12 +++-- src/renderEngine/Renderer.cpp | 10 ++--- src/renderEngine/Renderer.h | 4 +- src/toolbox/toolbox.h | 13 +++++- wk2_fps.vcxproj | 3 +- wk2_fps.vcxproj.filters | 7 ++- 9 files changed, 197 insertions(+), 35 deletions(-) create mode 100644 src/gui/gui_element.cpp create mode 100644 src/gui/gui_element.h delete mode 100644 src/gui/gui_texture.h diff --git a/src/gui/gui_element.cpp b/src/gui/gui_element.cpp new file mode 100644 index 0000000..0c8b579 --- /dev/null +++ b/src/gui/gui_element.cpp @@ -0,0 +1,81 @@ +#include +#include "gui_element.h" + +#include + +namespace gui +{ + InteractableGui::InteractableGui(int default_texture, glm::vec2 position, glm::vec2 scale) + : GuiTexture(default_texture, position, scale) + { + this->default_texture = default_texture; + + minXY = glm::vec2(position.x - scale.x, position.y - scale.y); + maxXY = glm::vec2(position.x + scale.x, position.y + scale.y); + } + + void InteractableGui::Update(GLFWwindow* window) + { + if (IsHoveringAbove(window) && glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS) + { + if (clicked_texture != 0) + { + texture = clicked_texture; + } else + { + texture = default_texture; + } + + if (!is_clicking) + { + OnClick(); + is_clicking = true; + } + } else + { + if (is_clicking) + { + is_clicking = false; + } + } + } + + bool InteractableGui::IsHoveringAbove(GLFWwindow* window) + { + double x_pos, y_pos; + glfwGetCursorPos(window, &x_pos, &y_pos); + + const float x_rel = (x_pos / SCALED_WIDTH / DEFAULT_WIDTH) * 2.0f - 1.0f; + const float y_rel = -((y_pos / SCALED_HEIGHT / DEFAULT_HEIGHT) * 2.0f - 1.0f); + + if (x_rel >= minXY.x && x_rel <= maxXY.x && + y_rel >= minXY.y && y_rel <= maxXY.y) + { + if (hover_texture != 0) + { + texture = hover_texture; + } else + { + texture = default_texture; + } + + if (!is_hovering) + { + OnEnter(); + is_hovering = true; + } + + return true; + } + + texture = default_texture; + + if (is_hovering) + { + OnExit(); + is_hovering = false; + } + + return false; + } +} diff --git a/src/gui/gui_element.h b/src/gui/gui_element.h new file mode 100644 index 0000000..ccfa363 --- /dev/null +++ b/src/gui/gui_element.h @@ -0,0 +1,82 @@ +#pragma once + +#include "../toolbox/toolbox.h" +#include + +namespace gui +{ + /* + * Structure for representing a gui item to display on the screen + * + * texture = The texture for the gui + * position = The center position of the gui + * scale = The size (scale) of the gui + */ + struct GuiTexture + { + int texture; + glm::vec2 position; + glm::vec2 scale; + + GuiTexture(int texture, glm::vec2 position, glm::vec2 scale): texture(texture), position(position), scale(scale) + { + scale.x /= (WINDOW_WIDTH / WINDOW_HEIGT); + } + }; + + + /* + * This class represents a gui item which can be interacted with + */ + class InteractableGui : public GuiTexture + { + private: + int default_texture; + int clicked_texture = 0; + int hover_texture = 0; + + bool is_hovering = false; + bool is_clicking = false; + + glm::vec2 minXY; + glm::vec2 maxXY; + + public: + InteractableGui(int default_texture, glm::vec2 position, glm::vec2 scale); + + void Update(GLFWwindow* window); + + virtual void OnClick() = 0; + virtual void OnEnter() = 0; + virtual void OnExit() = 0; + + void SetClickedTexture(int texture) { clicked_texture = texture; } + void SetHoverTexture(int texture) { hover_texture = texture; } + + private: + bool IsHoveringAbove(GLFWwindow* window); + }; + + /* + * This class represents a button + */ + class Button : public InteractableGui + { + private: + void (*on_click_action)(); + void (*on_enter_action)(); + void (*on_exit_action)(); + + public: + Button(int default_texture, glm::vec2 position, glm::vec2 scale) : InteractableGui(default_texture, position, scale) {} + + void SetOnClickAction(void (*fun)()) { on_click_action = fun; } + void SetOnEnterAction(void (*fun)()) { on_enter_action = fun; } + void SetOnExitAction(void (*fun)()) { on_exit_action = fun; } + + protected: + void OnClick() override { if (on_click_action != nullptr) on_click_action(); } + void OnEnter() override { if (on_enter_action != nullptr) on_enter_action(); } + void OnExit() override { if (on_exit_action != nullptr) on_exit_action(); } + }; +} diff --git a/src/gui/gui_texture.h b/src/gui/gui_texture.h deleted file mode 100644 index 2e06d0c..0000000 --- a/src/gui/gui_texture.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include - -namespace gui -{ - /* - * Structure for representing a gui item to display on the screen - * - * texture = The texture for the gui - * position = The center position of the gui - * scale = The size (scale) of the gui - */ - struct GuiTexture - { - int texture; - glm::vec2 position; - glm::vec2 scale; - }; -} diff --git a/src/main.cpp b/src/main.cpp index 546afea..f50e7a7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,8 @@ #include #include #define STB_IMAGE_IMPLEMENTATION +#include + #include "stb_image.h" #include @@ -79,9 +81,11 @@ int main(void) shaders::GuiShader gui_shader; gui_shader.Init(); - std::vector guis; - gui::GuiTexture gui = { render_engine::loader::LoadTexture("res/Mayo.png"), glm::vec2(0.5f, 0.5f), glm::vec2(0.25f, 0.25f) }; - guis.push_back(gui); + std::vector guis; + gui::Button button(render_engine::loader::LoadTexture("res/Mayo.png"), glm::vec2(0.5f, 0.0f), glm::vec2(0.25f, 0.25f)); + button.SetHoverTexture(render_engine::loader::LoadTexture("res/Texture.png")); + button.SetClickedTexture(render_engine::loader::LoadTexture("res/Mayo.png")); + guis.push_back(&button); // Main game loop @@ -91,6 +95,8 @@ int main(void) const double delta = UpdateDelta(); camera.Move(window); + button.Update(window); + // Render render_engine::renderer::Prepare(); diff --git a/src/renderEngine/Renderer.cpp b/src/renderEngine/Renderer.cpp index 7a6559b..a91a5ec 100644 --- a/src/renderEngine/Renderer.cpp +++ b/src/renderEngine/Renderer.cpp @@ -82,7 +82,7 @@ namespace render_engine glBindVertexArray(0); } - void Render(std::vector& guis, shaders::GuiShader& shader) + void Render(std::vector& guis, shaders::GuiShader& shader) { shader.Start(); @@ -98,13 +98,13 @@ namespace render_engine glDisable(GL_DEPTH_TEST); // Render each gui to the screen - for (gui::GuiTexture& gui : guis) - { + for (gui::GuiTexture* gui : guis) + { // Bind the texture of the gui to the shader glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, gui.texture); + glBindTexture(GL_TEXTURE_2D, gui->texture); - glm::mat4 matrix = toolbox::CreateModelMatrix(gui.position, gui.scale); + glm::mat4 matrix = toolbox::CreateModelMatrix(gui->position, gui->scale); shader.LoadModelMatrix(matrix); glDrawArrays(GL_TRIANGLE_STRIP, 0, quad.vertex_count); diff --git a/src/renderEngine/Renderer.h b/src/renderEngine/Renderer.h index ed6d1d7..8f4cef3 100644 --- a/src/renderEngine/Renderer.h +++ b/src/renderEngine/Renderer.h @@ -1,6 +1,6 @@ #pragma once -#include "../gui/gui_texture.h" +#include "../gui/gui_element.h" #include "../entities/entity.h" #include "../shaders/entity_shader.h" #include "../shaders/gui_shader.h" @@ -38,6 +38,6 @@ namespace render_engine @param guis: A list with all the GUI textures you want to render @param shade: The shader the GUI textures need to be rendered with */ - void Render(std::vector& guis, shaders::GuiShader& shader); + void Render(std::vector& guis, shaders::GuiShader& shader); } } \ No newline at end of file diff --git a/src/toolbox/toolbox.h b/src/toolbox/toolbox.h index fde57aa..f8bcef6 100644 --- a/src/toolbox/toolbox.h +++ b/src/toolbox/toolbox.h @@ -5,9 +5,18 @@ namespace toolbox { - #define WINDOW_WIDTH 1400.0f - #define WINDOW_HEIGT 800.0f + // Window macro's + #define DEFAULT_WIDTH 1920 + #define DEFAULT_HEIGHT 1080 + // Change these macros to change the window size + #define WINDOW_WIDTH 1400.0f + #define WINDOW_HEIGT 800.0f + + #define SCALED_WIDTH (WINDOW_WIDTH/DEFAULT_WIDTH) + #define SCALED_HEIGHT (WINDOW_HEIGT/DEFAULT_HEIGHT) + // + /* * @brief: This function will create a model matrix * diff --git a/wk2_fps.vcxproj b/wk2_fps.vcxproj index 13e3572..ba5c3c5 100644 --- a/wk2_fps.vcxproj +++ b/wk2_fps.vcxproj @@ -21,6 +21,7 @@ + @@ -34,7 +35,7 @@ - + diff --git a/wk2_fps.vcxproj.filters b/wk2_fps.vcxproj.filters index 552a987..a4bf002 100644 --- a/wk2_fps.vcxproj.filters +++ b/wk2_fps.vcxproj.filters @@ -45,6 +45,9 @@ Source Files + + Source Files + @@ -80,10 +83,10 @@ Header Files - + Header Files - + Header Files