From 4621f86cb279f1f5757396de6ff6bbc433b1c7f2 Mon Sep 17 00:00:00 2001 From: Light3039 Date: Thu, 27 May 2021 10:41:32 +0430 Subject: [PATCH] ImGui & UserInterface class --- .gitmodules | 3 ++ BuildScripts/premake5.lua | 1 + Dependencies/GLAD/premake5.lua | 2 + Dependencies/imgui | 1 + Engine/premake5.lua | 3 ++ Engine/src/Engine/Core/Application.cpp | 4 ++ .../src/Engine/Graphics/GraphicsContext.cpp | 3 +- Engine/src/Engine/Graphics/GraphicsContext.h | 6 ++- Engine/src/Engine/Layer/Layer.h | 5 +++ Engine/src/Engine/Layer/LayerStack.cpp | 43 +++++++++++++----- Engine/src/Engine/Layer/LayerStack.h | 16 +++++-- .../Engine/UserInterface/UserInterface.cpp | 16 +++++-- .../src/Engine/UserInterface/UserInterface.h | 19 ++++++++ .../GraphicsAPI/OpenGL/glUserInterface.cpp | 45 +++++++++++++++++++ .../GraphicsAPI/OpenGL/glUserInterface.h | 19 ++++++++ Sandbox/imgui.ini | 10 +++++ Sandbox/premake5.lua | 10 ++++- Sandbox/src/SandboxApp.cpp | 4 ++ Sandbox/src/SandboxLayer.h | 10 ++--- 19 files changed, 192 insertions(+), 28 deletions(-) create mode 160000 Dependencies/imgui create mode 100644 Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.cpp create mode 100644 Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.h create mode 100644 Sandbox/imgui.ini diff --git a/.gitmodules b/.gitmodules index 1300e60..10007e6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "Dependencies/glm"] path = Dependencies/glm url = https://github.com/g-truc/glm +[submodule "Dependencies/imgui"] + path = Dependencies/imgui + url = https://github.com/Light3039/imgui diff --git a/BuildScripts/premake5.lua b/BuildScripts/premake5.lua index 26b7566..f3e9460 100644 --- a/BuildScripts/premake5.lua +++ b/BuildScripts/premake5.lua @@ -23,3 +23,4 @@ include "../Engine/" group "Dependencies" include "../Dependencies/GLFW/" include "../Dependencies/GLAD/" +include "../Dependencies/imgui/" diff --git a/Dependencies/GLAD/premake5.lua b/Dependencies/GLAD/premake5.lua index 8abd8e1..335a37e 100644 --- a/Dependencies/GLAD/premake5.lua +++ b/Dependencies/GLAD/premake5.lua @@ -15,6 +15,8 @@ project "GLAD" { "**.c", "**.h", + + "premake5.lua" } -- Dependencies -- diff --git a/Dependencies/imgui b/Dependencies/imgui new file mode 160000 index 0000000..04fd507 --- /dev/null +++ b/Dependencies/imgui @@ -0,0 +1 @@ +Subproject commit 04fd5072fbc635cc7a8814b8543d40836248d3a7 diff --git a/Engine/premake5.lua b/Engine/premake5.lua index efb146f..1c330e2 100644 --- a/Engine/premake5.lua +++ b/Engine/premake5.lua @@ -35,6 +35,8 @@ project "Engine" (dependenciesdir .. "spdlog/include/"), (dependenciesdir .. "glfw/include/"), (dependenciesdir .. "glad/include"), + (dependenciesdir .. "imgui/"), + (dependenciesdir .. "imgui/backends"), (dependenciesdir .. "glm/"), } @@ -42,6 +44,7 @@ project "Engine" { "GLFW", "GLAD", + "ImGui", } --- Filters --- diff --git a/Engine/src/Engine/Core/Application.cpp b/Engine/src/Engine/Core/Application.cpp index 689d1cb..cf761e0 100644 --- a/Engine/src/Engine/Core/Application.cpp +++ b/Engine/src/Engine/Core/Application.cpp @@ -32,6 +32,10 @@ namespace Light { m_Window->GetGfxContext()->GetRenderCommand()->SwapBuffers(); m_Window->GetGfxContext()->GetRenderCommand()->ClearBackBuffer(); + + m_Window->GetGfxContext()->GetUserInterface()->Begin(); + + m_Window->GetGfxContext()->GetUserInterface()->End(); } } diff --git a/Engine/src/Engine/Graphics/GraphicsContext.cpp b/Engine/src/Engine/Graphics/GraphicsContext.cpp index 9b3d2f6..2958639 100644 --- a/Engine/src/Engine/Graphics/GraphicsContext.cpp +++ b/Engine/src/Engine/Graphics/GraphicsContext.cpp @@ -5,7 +5,7 @@ namespace Light { - GraphicsContext* GraphicsContext::s_Context; + GraphicsContext* GraphicsContext::s_Context = nullptr; GraphicsContext* GraphicsContext::Create(GraphicsAPI api, GLFWwindow* windowHandle) { @@ -15,6 +15,7 @@ namespace Light { case Light::GraphicsAPI::OpenGL: s_Context = new glGraphicsContext(windowHandle); s_Context->m_RenderCommand = std::unique_ptr(RenderCommand::Create(windowHandle)); + s_Context->m_UserInterface = std::unique_ptr(UserInterface::Create(windowHandle)); // ...Renderer // ...UserInterface... diff --git a/Engine/src/Engine/Graphics/GraphicsContext.h b/Engine/src/Engine/Graphics/GraphicsContext.h index 3d4176d..552a705 100644 --- a/Engine/src/Engine/Graphics/GraphicsContext.h +++ b/Engine/src/Engine/Graphics/GraphicsContext.h @@ -4,6 +4,8 @@ #include "RenderCommand.h" +#include "UserInterface/UserInterface.h" + struct GLFWwindow {}; namespace Light { @@ -19,6 +21,7 @@ namespace Light { static GraphicsContext* s_Context; std::unique_ptr m_RenderCommand; + std::unique_ptr m_UserInterface; protected: GraphicsAPI m_GraphicsAPI; @@ -29,7 +32,8 @@ namespace Light { static inline GraphicsAPI GetGraphicsAPI() { return s_Context->m_GraphicsAPI; } - virtual RenderCommand* GetRenderCommand() { return m_RenderCommand.get(); } + inline RenderCommand* GetRenderCommand() { return m_RenderCommand.get(); } + inline UserInterface* GetUserInterface() { return m_UserInterface.get(); } }; } \ No newline at end of file diff --git a/Engine/src/Engine/Layer/Layer.h b/Engine/src/Engine/Layer/Layer.h index e1df981..2041994 100644 --- a/Engine/src/Engine/Layer/Layer.h +++ b/Engine/src/Engine/Layer/Layer.h @@ -14,12 +14,17 @@ namespace Light { { private: std::string m_Name; + public: Layer(const std::string& name): m_Name(name) {} virtual ~Layer() = default; inline const std::string& GetName() const { return m_Name; } + // Updates + virtual void OnUpdate(float deltaTime) {} + virtual void OnUserInterfaceUpdate() {} + // Mouse events virtual bool OnMouseMoved(const MouseMovedEvent& event) { return false; } virtual bool OnButtonPressed(const ButtonPressedEvent& event) { return false; } diff --git a/Engine/src/Engine/Layer/LayerStack.cpp b/Engine/src/Engine/Layer/LayerStack.cpp index cc6ec58..880db1d 100644 --- a/Engine/src/Engine/Layer/LayerStack.cpp +++ b/Engine/src/Engine/Layer/LayerStack.cpp @@ -2,30 +2,32 @@ #include "LayerStack.h" #include + namespace Light { + LayerStack* LayerStack::s_Context = nullptr; + + LayerStack::LayerStack() + { + s_Context = this; // TODO: ASSERT + } + LayerStack::~LayerStack() { for (Layer* layer : m_Layers) delete layer; } - void LayerStack::PushLayer(Layer* layer) + void LayerStack::OnUpdate(float deltaTime) { - m_Layers.push_back(layer); - m_Begin = m_Layers.begin(); - m_End = m_Layers.end(); - - LT_ENGINE_TRACE("LayerStack::PushLayer: Attached [{}]", layer->GetName()); + for (auto it = m_Begin; it != m_End; it++) + (*it)->OnUpdate(deltaTime); } - void LayerStack::PopLayer(Layer* layer) + void LayerStack::OnUserInterfaceUpdate() { - m_Layers.erase(std::find(m_Layers.begin(), m_Layers.end(), layer)); - m_Begin = m_Layers.begin(); - m_End = m_Layers.end(); - - LT_ENGINE_TRACE("LayerStack::PushLayer: Detatched[{}]", layer->GetName()); + for (auto it = m_Begin; it != m_End; it++) + (*it)->OnUserInterfaceUpdate(); } void LayerStack::OnEvent(const Event& event) @@ -84,5 +86,22 @@ namespace Light { } } + void LayerStack::AttachLayerImpl(Layer* layer) + { + m_Layers.push_back(layer); + m_Begin = m_Layers.begin(); + m_End = m_Layers.end(); + + LT_ENGINE_TRACE("LayerStack::PushLayer: Attached [{}]", layer->GetName()); + } + + void LayerStack::DetatchLayerImpl(Layer* layer) + { + m_Layers.erase(std::find(m_Layers.begin(), m_Layers.end(), layer)); + m_Begin = m_Layers.begin(); + m_End = m_Layers.end(); + + LT_ENGINE_TRACE("LayerStack::PushLayer: Detatched[{}]", layer->GetName()); + } } \ No newline at end of file diff --git a/Engine/src/Engine/Layer/LayerStack.h b/Engine/src/Engine/Layer/LayerStack.h index 1b9afce..d2db61e 100644 --- a/Engine/src/Engine/Layer/LayerStack.h +++ b/Engine/src/Engine/Layer/LayerStack.h @@ -13,22 +13,32 @@ namespace Light { class LayerStack { private: + static LayerStack* s_Context; + std::vector m_Layers; std::vector::iterator m_Begin; std::vector::iterator m_End; - public: + LayerStack(); ~LayerStack(); - void PushLayer(Layer* layer); - void PopLayer(Layer* layer); + static inline void AttachLayer(Layer* layer) { s_Context->AttachLayerImpl(layer); } + static inline void DetatchLayer(Layer* layer) { s_Context->DetatchLayerImpl(layer); } + + void OnUpdate(float deltaTime); + void OnUserInterfaceUpdate(); void OnEvent(const Event& event); std::vector::iterator begin() { return m_Layers.begin(); } std::vector::iterator end() { return m_Layers.end(); } + + private: + void AttachLayerImpl(Layer* layer); + void DetatchLayerImpl(Layer* layer); + }; } \ No newline at end of file diff --git a/Engine/src/Engine/UserInterface/UserInterface.cpp b/Engine/src/Engine/UserInterface/UserInterface.cpp index 5893a86..91abcf9 100644 --- a/Engine/src/Engine/UserInterface/UserInterface.cpp +++ b/Engine/src/Engine/UserInterface/UserInterface.cpp @@ -1,11 +1,19 @@ #include "ltpch.h" +#include "UserInterface.h" + +#include "Graphics/GraphicsContext.h" + +#include "OpenGL/glUserInterface.h" namespace Light { - class UserInterface + UserInterface* UserInterface::Create(GLFWwindow* windowHandle) { - private: - public: - }; + switch (GraphicsContext::GetGraphicsAPI()) + { + case GraphicsAPI::OpenGL: + return new glUserInterface(windowHandle); + } + } } \ No newline at end of file diff --git a/Engine/src/Engine/UserInterface/UserInterface.h b/Engine/src/Engine/UserInterface/UserInterface.h index e69de29..facd72e 100644 --- a/Engine/src/Engine/UserInterface/UserInterface.h +++ b/Engine/src/Engine/UserInterface/UserInterface.h @@ -0,0 +1,19 @@ +#pragma once + +#include "Base.h" + +struct GLFWwindow; + +namespace Light { + + class UserInterface + { + private: + public: + static UserInterface* Create(GLFWwindow* windowHandle); + + virtual void Begin() = 0; + virtual void End() = 0; + }; + +} \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.cpp b/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.cpp new file mode 100644 index 0000000..762c4ec --- /dev/null +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.cpp @@ -0,0 +1,45 @@ +#include "ltpch.h" +#include "glUserInterface.h" + +#include +#include +#include + +namespace Light { + + glUserInterface::glUserInterface(GLFWwindow* windowHandle) + { + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + + ImGui::StyleColorsDark(); + + ImGui_ImplGlfw_InitForOpenGL(windowHandle, true); + ImGui_ImplOpenGL3_Init(); + } + + glUserInterface::~glUserInterface() + { + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + } + + void glUserInterface::Begin() + { + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + ImGui::ShowDemoWindow(); + } + + void glUserInterface::End() + { + ImGui::Render(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + } + +} \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.h b/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.h new file mode 100644 index 0000000..a246dc7 --- /dev/null +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glUserInterface.h @@ -0,0 +1,19 @@ +#pragma once + +#include "Base.h" +#include "UserInterface/UserInterface.h" + +namespace Light { + + class glUserInterface : public UserInterface + { + private: + public: + glUserInterface(GLFWwindow* windowHandle); + ~glUserInterface(); + + void Begin() override; + void End() override; + }; + +} \ No newline at end of file diff --git a/Sandbox/imgui.ini b/Sandbox/imgui.ini new file mode 100644 index 0000000..b6eba40 --- /dev/null +++ b/Sandbox/imgui.ini @@ -0,0 +1,10 @@ +[Window][Debug##Default] +Pos=60,60 +Size=400,400 +Collapsed=0 + +[Window][Dear ImGui Demo] +Pos=219,40 +Size=550,536 +Collapsed=0 + diff --git a/Sandbox/premake5.lua b/Sandbox/premake5.lua index b8bbed4..d0a0a45 100644 --- a/Sandbox/premake5.lua +++ b/Sandbox/premake5.lua @@ -16,7 +16,8 @@ project "Sandbox" { "%{prj.location}/src/**.h", "%{prj.location}/src/**.cpp", - "%{prj.location}/**.lua", + + "%{prj.location}/premake5.lua", } -- Dependencies -- @@ -30,12 +31,17 @@ project "Sandbox" -- 3rd party (dependenciesdir .. "spdlog/include/"), + (dependenciesdir .. "imgui/"), + (dependenciesdir .. "imgui/backends"), (dependenciesdir .. "glm/"), } links { "Engine", + "GLFW", + "GLAD", + "ImGui", } --- Filters --- @@ -50,7 +56,7 @@ project "Sandbox" defines "LT_DEBUG" symbols "on" - -- release + -- release filter "configurations:Release" defines "LT_RELEASE" optimize "on" diff --git a/Sandbox/src/SandboxApp.cpp b/Sandbox/src/SandboxApp.cpp index c364c0c..80f8f7c 100644 --- a/Sandbox/src/SandboxApp.cpp +++ b/Sandbox/src/SandboxApp.cpp @@ -1,11 +1,15 @@ #include +#include "SandboxLayer.h" + class Sandbox : public Light::Application { public: Sandbox() { LT_CLIENT_TRACE("Sandbox::Sandbox"); + + Light::LayerStack::AttachLayer(new SandboxLayer("SandboxLayer")); } ~Sandbox() diff --git a/Sandbox/src/SandboxLayer.h b/Sandbox/src/SandboxLayer.h index 5a805a0..a41f7d2 100644 --- a/Sandbox/src/SandboxLayer.h +++ b/Sandbox/src/SandboxLayer.h @@ -1,9 +1,9 @@ #include -class TestLayer : public Light::Layer +class SandboxLayer : public Light::Layer { public: - TestLayer(const std::string& name) : Light::Layer(name) {} + SandboxLayer(const std::string& name): Light::Layer(name) {} // Mouse events virtual bool OnMouseMoved(const Light::MouseMovedEvent& event) override { LT_ENGINE_TRACE("{}", event.GetInfoLog()); return false; } @@ -12,10 +12,10 @@ public: virtual bool OnWheelScrolled(const Light::WheelScrolledEvent& event) override { LT_ENGINE_TRACE(event.GetInfoLog()); return false; } // Keyboard events - virtual bool OnKeyPressed(const Light::KeyPressedEvent& event) override - { + virtual bool OnKeyPressed(const Light::KeyPressedEvent& event) override + { LT_ENGINE_TRACE(event.GetInfoLog()); - return true; + return true; } virtual bool OnKeyReleased(const Light::KeyReleasedEvent& event) override { LT_ENGINE_TRACE(event.GetInfoLog()); return false; }