diff --git a/assets/shaders/rect_f_shader.glsl b/assets/shaders/rect_f_shader.glsl new file mode 100644 index 0000000..cf009cf --- /dev/null +++ b/assets/shaders/rect_f_shader.glsl @@ -0,0 +1,9 @@ +#version 460 + +out vec4 color; + +uniform vec4 inColor; + +void main(void) { + color = inColor; +} \ No newline at end of file diff --git a/assets/shaders/rect_v_shader.glsl b/assets/shaders/rect_v_shader.glsl new file mode 100644 index 0000000..217484a --- /dev/null +++ b/assets/shaders/rect_v_shader.glsl @@ -0,0 +1,11 @@ +#version 460 + +layout (location = 0) in vec2 pos; + + +uniform mat4 model_matrix; +uniform mat4 proj_matrix; + +void main(void) { + gl_Position = proj_matrix * model_matrix * vec4(pos, 0.0, 1.0); +} diff --git a/include/Cubed/render/renderer.hpp b/include/Cubed/render/renderer.hpp index ca1fa35..0a3aa56 100644 --- a/include/Cubed/render/renderer.hpp +++ b/include/Cubed/render/renderer.hpp @@ -12,6 +12,7 @@ #include "Cubed/shader.hpp" #include "Cubed/ui/image.hpp" #include "Cubed/ui/label.hpp" +#include "Cubed/ui/rect.hpp" #include #include @@ -33,7 +34,7 @@ public: void render_world(ClientWorld& world); void render_lable(const Label& label); void render_image(const Image& image); - + void render_rect(const Rect& rect); void begin_render_ui(); void end_render_ui(); diff --git a/include/Cubed/shader.hpp b/include/Cubed/shader.hpp index c46fd11..e7894d4 100644 --- a/include/Cubed/shader.hpp +++ b/include/Cubed/shader.hpp @@ -40,6 +40,9 @@ public: } else if constexpr (is_same_v) { glUniformMatrix4fv(loc(location), 1, GL_FALSE, glm::value_ptr(value)); + + } else if constexpr (is_same_v) { + glUniform4fv(loc(location), 1, glm::value_ptr(value)); } else { static_assert(always_false
::value, "Unknown Type"); } diff --git a/include/Cubed/ui/column_layout.hpp b/include/Cubed/ui/column_layout.hpp index aa7ce19..923a816 100644 --- a/include/Cubed/ui/column_layout.hpp +++ b/include/Cubed/ui/column_layout.hpp @@ -12,6 +12,9 @@ public: void update(float dt) override; + float width() const override; + float height() const override; + void set_spacing(int spacing); // No need for parent node pointer; do not modify children's anchors and // scale. diff --git a/include/Cubed/ui/main_menu_ui_manager.hpp b/include/Cubed/ui/main_menu_ui_manager.hpp index c278c99..ac412ca 100644 --- a/include/Cubed/ui/main_menu_ui_manager.hpp +++ b/include/Cubed/ui/main_menu_ui_manager.hpp @@ -25,7 +25,8 @@ public: private: MainMenuScene& m_scene; - std::unordered_map> m_widgets; + std::unique_ptr m_root_widget; + std::unordered_map m_widgets; bool handle_mouse_move_event(const MouseMoveEvent& e); bool handle_mouse_button_event(const MouseButtonEvent& e); bool handle_window_resize_event(const WindowResizeEvent& e); diff --git a/include/Cubed/ui/rect.hpp b/include/Cubed/ui/rect.hpp new file mode 100644 index 0000000..f6d2a3a --- /dev/null +++ b/include/Cubed/ui/rect.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include "Cubed/ui/color.hpp" +#include "Cubed/ui/widget.hpp" +namespace Cubed { +class Rect : public Widget { +public: + Rect(const Rect&) = delete; + Rect(Rect&&) = delete; + Rect& operator=(const Rect&) = delete; + Rect& operator=(Rect&&) = delete; + Rect(Widget* parent); + ~Rect(); + + void update(float dt) override; + void render(Renderer& renderer) override; + + float width() const override; + float height() const override; + float alpha() const; + + Rect& set_width(float width); + Rect& set_height(float height); + + Rect& set_fill(bool fill); + + Rect& set_scale(float scale); + Rect& set_color(Color color); + Rect& set_alpha(float alpha); + + Color color() const; + +private: + Color m_color = Color::WHITE; + float m_width = 0.0f; + float m_height = 0.0f; + float m_scale = 1.0f; + float m_alpha = 1.0f; + bool m_fill = false; +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/ui/widget.hpp b/include/Cubed/ui/widget.hpp index 77944d0..6891e19 100644 --- a/include/Cubed/ui/widget.hpp +++ b/include/Cubed/ui/widget.hpp @@ -21,8 +21,8 @@ public: virtual Widget& set_offset(glm::ivec2 offset); virtual void set_window_size(int width, int height); // Returns the final display size - virtual float width() const; - virtual float height() const; + virtual float width() const = 0; + virtual float height() const = 0; virtual glm::vec2 pos() const; virtual bool handle_key_event(const KeyEvent& e); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eac6f63..5a1196a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -68,4 +68,5 @@ target_sources(${PROJECT_NAME} ui/main_menu_ui_manager.cpp scene/main_menu_scene.cpp ui/column_layout.cpp + ui/rect.cpp ) \ No newline at end of file diff --git a/src/render/renderer.cpp b/src/render/renderer.cpp index 9c68f68..290ac92 100644 --- a/src/render/renderer.cpp +++ b/src/render/renderer.cpp @@ -157,6 +157,26 @@ void Renderer::render_world(ClientWorld& world) { m_world_renderer.render(world); } +void Renderer::render_rect(const Rect& rect) { + + auto& shader = get_shader("rect"); + shader.use(); + shader.set_loc("proj_matrix", m_ui_proj_matrix); + auto pos = rect.pos(); + glm::mat4 model_matrix = + glm::translate(glm::mat4(1.0f), glm::vec3(pos.x, pos.y, 0.0f)) * + glm::scale(glm::mat4(1.0f), + glm::vec3(rect.width(), rect.height(), 1.0f)); + shader.set_loc("model_matrix", model_matrix); + + auto color = color_value(rect.color()); + shader.set_loc("inColor", + glm::vec4(color.x, color.y, color.z, rect.alpha())); + + m_vao[3].bind(); + glDrawArrays(GL_TRIANGLES, 0, 6); +} + void Renderer::render_lable(const Label& label) { const auto& shader = get_shader("text"); diff --git a/src/render/shader_manager.cpp b/src/render/shader_manager.cpp index 3d36ba2..3669b7e 100644 --- a/src/render/shader_manager.cpp +++ b/src/render/shader_manager.cpp @@ -33,6 +33,8 @@ void ShaderManager::init() { "shaders/player_f_shader.glsl"); register_shader("player_depth", "shaders/depth_player_shader.glsl", "shaders/depth_player_fragment_shader.glsl"); + register_shader("rect", "shaders/rect_v_shader.glsl", + "shaders/rect_f_shader.glsl"); } void ShaderManager::register_shader(const std::string& name, diff --git a/src/ui/column_layout.cpp b/src/ui/column_layout.cpp index 563d776..0609a67 100644 --- a/src/ui/column_layout.cpp +++ b/src/ui/column_layout.cpp @@ -9,6 +9,19 @@ void ColumnLayout::update(float dt) { layout(); } +float ColumnLayout::width() const { + if (m_parent) { + return m_parent->width(); + } + return m_window_width; +} +float ColumnLayout::height() const { + if (m_parent) { + return m_parent->height(); + } + return m_window_height; +} + void ColumnLayout::set_spacing(int spacing) { m_spacing = spacing; } void ColumnLayout::layout() { diff --git a/src/ui/main_menu_ui_manager.cpp b/src/ui/main_menu_ui_manager.cpp index a361c94..edda1f9 100644 --- a/src/ui/main_menu_ui_manager.cpp +++ b/src/ui/main_menu_ui_manager.cpp @@ -12,13 +12,21 @@ MainMenuUIManager::MainMenuUIManager(MainMenuScene& scene) : m_scene(scene) {} MainMenuUIManager::~MainMenuUIManager() {} void MainMenuUIManager::init() { + + auto rect = std::make_unique(nullptr); + + rect->set_fill(true); + rect->set_anchor(Anchor::TOP_LEFT); + rect->set_color(Color::WHITE); auto& renderer = m_scene.scene_manager().app().renderer(); - auto layout = std::make_unique(nullptr); - layout->set_spacing(20); - layout->set_anchor(Anchor::CENTER); - layout->set_window_size(renderer.window_width(), renderer.window_height()); + rect->set_window_size(renderer.window_width(), renderer.window_height()); + + auto& layout = rect->add_child(); + layout.set_spacing(20); + layout.set_anchor(Anchor::CENTER); + layout.set_window_size(renderer.window_width(), renderer.window_height()); { - auto& start_game_button = layout->add_child