Imgui : https://github.com/TheCherno/imgui
Cherno视频:https://www.youtube.com/watch?v=st4lgNI6_F4&list=PLlrATfBNZ98dC-V-N3m0Go4deliWHPFwT&index=16&t=0s
目标:
1.把ImGUI加入到Hazel中
2.添加一个ImGUILayer
3.修改Application为单例
注意:ImGUI的文档在imgui.cpp,imgui.h里
接口调用方式查看:
和:
和:
修改 Hazel/premake5.lua
workspace "Hazel"
architecture "x64"
configurations{
"Debug",
"Release",
"Dist"
}
outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}" --Debug-Windows-x64
-- include directory relative to root folder (solution directory)
IncludeDir = {}
IncludeDir["GLFW"] = "Hazel/vendor/GLFW/include"
IncludeDir["Glad"] = "Hazel/vendor/Glad/include"
IncludeDir["ImGui"] = "Hazel/vendor/imgui"
include "Hazel/vendor/GLFW" --include Hazel/vendor/GLFW/premake5.lua
include "Hazel/vendor/Glad"
include "Hazel/vendor/imgui"
project "Hazel"
location "Hazel"
kind "SharedLib" --dll
language "C++"
targetdir("bin/" .. outputdir .. "/%{prj.name}")
objdir("bin-int/" .. outputdir .. "/%{prj.name}")
pchheader "hzpch.h"
pchsource "Hazel/src/hzpch.cpp"
files
{
"%{prj.name}/src/**.h",
"%{prj.name}/src/**.cpp",
}
includedirs
{
"%{prj.name}/vendor/spdlog/include",
"%{prj.name}/src",
"%{IncludeDir.GLFW}",
"%{IncludeDir.Glad}",
"%{IncludeDir.ImGui}",
}
links{
"GLFW",
"Glad",
"ImGui",
"opengl32.lib"
}
filter "system:windows"
cppdialect "C++17"
staticruntime "Off" --linking the runtime library
systemversion "latest"
defines
{
"HZ_BUILD_DLL",
"HZ_PLATFORM_WINDOWS",
"GLFW_INCLUDE_NONE",
}
--create a postbuild step to put the .dll where we want to be
postbuildcommands{
("{COPY} %{cfg.buildtarget.relpath} ../bin/" ..outputdir.. "/Sandbox")
}
filter "configurations:Debug" --only apply to Debug configurations
defines "HZ_DEGUG"
--buildoptions "/MDd"
symbols "On"
filter "configurations:Release" --only apply to Debug configurations
defines "HZ_RELEASE"
--buildoptions "/MD"
optimize "On"
filter "configurations:Dist" --only apply to Debug configurations
defines "HZ_DIST"
--buildoptions "/MD"
optimize "On"
project "Sandbox"
location "Sandbox"
kind "ConsoleApp" --.exe
language "C++"
targetdir("bin/" .. outputdir .. "/%{prj.name}")
objdir("bin-int/" .. outputdir .. "/%{prj.name}")
files
{
"%{prj.name}/src/**.h",
"%{prj.name}/src/**.cpp",
}
includedirs
{
"Hazel/vendor/spdlog/include",
"Hazel/src"
}
links{
"Hazel"
}
filter "system:windows"
cppdialect "C++17"
staticruntime "Off" --linking the runtime library
systemversion "latest"
defines
{
"HZ_PLATFORM_WINDOWS",
}
filter "configurations:Debug" --only apply to Debug configurations
defines "HZ_DEGUG"
--buildoptions "/MDd"
symbols "On"
filter "configurations:Release" --only apply to Debug configurations
defines "HZ_RELEASE"
--buildoptions "/MD"
optimize "On"
filter "configurations:Dist" --only apply to Debug configurations
defines "HZ_DIST"
--buildoptions "/MD"
optimize "On"
重新GenerateProject
添加 到Platform\OpenGL,并重命名为ImGuiOpenGLRenderer.cpp,ImGuiOpenGLRenderer.h
主要用到里面的这3个函数:
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = NULL);
IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
添加 ImGuiLayer :public Layer
ImGuiLayer .h
#pragma once
#include"Hazel/Layer.h"
namespace Hazel {
class HAZEL_API ImGuiLayer : public Layer
{
public:
ImGuiLayer();
~ImGuiLayer();
void OnAttach();
void OnDetach();
void OnUpdate();
void OnEvent(Event& e);
private:
float m_Time = 0.0f;
};
}
ImGuiLayer .cpp
#include "hzpch.h"
#include "ImGuiLayer.h"
#include "Platform/OpenGL/ImGuiOpenGLRenderer.h"
#include "GLFW/glfw3.h"
#include "Hazel/Application.h"
namespace Hazel {
ImGuiLayer::ImGuiLayer()
:Layer("ImGuiLayer")
{
}
ImGuiLayer::~ImGuiLayer()
{
}
void ImGuiLayer::OnAttach()
{
ImGui::CreateContext();
ImGui::StyleColorsDark();
ImGuiIO& io = ImGui::GetIO();
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos;
// TEMPORARY: should eventually use Hazel key codes
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB;
io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP;
io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN;
io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP;
io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN;
io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME;
io.KeyMap[ImGuiKey_End] = GLFW_KEY_END;
io.KeyMap[ImGuiKey_Insert] = GLFW_KEY_INSERT;
io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE;
io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE;
io.KeyMap[ImGuiKey_Space] = GLFW_KEY_SPACE;
io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER;
io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE;
io.KeyMap[ImGuiKey_A] = GLFW_KEY_A;
io.KeyMap[ImGuiKey_C] = GLFW_KEY_C;
io.KeyMap[ImGuiKey_V] = GLFW_KEY_V;
io.KeyMap[ImGuiKey_X] = GLFW_KEY_X;
io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y;
io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z;
ImGui_ImplOpenGL3_Init("#version 410");
}
void ImGuiLayer::OnDetach()
{
}
void ImGuiLayer::OnUpdate()
{
ImGuiIO& io = ImGui::GetIO();
Application &app = Application::Get();
io.DisplaySize = ImVec2(app.GetWindow().GetWidth(), app.GetWindow().GetHeight());
// Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame();
ImGui::NewFrame();
float time = (float)glfwGetTime();
io.DeltaTime = m_Time > 0.0f ? (time - m_Time) : (1.0f / 60.0f);
m_Time = time;
static bool show = true;
if (show)
ImGui::ShowDemoWindow(&show);
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
void ImGuiLayer::OnEvent(Event & e)
{
}
}
float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds.(两帧之间的时间间隔)
Application 整个Hazel只有一个,所以是一个单例:
Application .h
#pragma once
#include "Core.h"
#include "Event/Event.h"
#include "Hazel/Event/ApplicationEvent.h"
#include "Window.h"
#include "Layer.h"
#include "LayerStack.h"
namespace Hazel {
class HAZEL_API Application
{
public:
Application();
virtual ~Application();
void Run();
void OnEvent(Event& e);
void PushLayer(Layer* layer);
void PushOverlay(Layer* overlay);
inline static Application& Get() { return *s_Instance; }
inline Window& GetWindow() { return *m_Window; }
private:
bool OnWindowClose(WindowCloseEvent& e);
std::unique_ptr<Window> m_Window;
bool m_Running = true;
LayerStack m_LayerStack;
static Application* s_Instance;//Singleton
};
//To be define in a client
Application *CreateApplication();
}
#include "hzpch.h"
#include "Application.h"
#include "glad/glad.h"
namespace Hazel {
#define BIND_EVENT_FN(x) std::bind(&Application::x, this, std::placeholders::_1)
Application* Application::s_Instance = nullptr;
Application::Application()
{
HZ_CORE_ASSET(!s_Instance, "Application already exists!");
s_Instance = this;
m_Window = std::unique_ptr<Window>(Window::Create());
m_Window->SetEventCallback(BIND_EVENT_FN(OnEvent));
}
Application::~Application()
{
}
void Application::PushLayer(Layer* layer)
{
m_LayerStack.PushLayer(layer);
layer->OnAttach();
}
void Application::PushOverlay(Layer* overlay)
{
m_LayerStack.PushOverLayer(overlay);
overlay->OnAttach();
}
void Application::OnEvent(Event& e)
{
EventDispatcher dispatcher(e);
dispatcher.Dispatch<WindowCloseEvent>(BIND_EVENT_FN(OnWindowClose));
HZ_CORE_INFO("{0}", e);
for (auto it = m_LayerStack.end(); it!= m_LayerStack.begin();)
{
(*--it)->OnEvent(e);
if (e.Handled)
break;
}
}
bool Application::OnWindowClose(WindowCloseEvent& e)
{
m_Running = false;
return true;
}
void Application:: Run() {
while (m_Running) {
glClearColor(1, 0, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
for (Layer *layer:m_LayerStack)
{
layer->OnUpdate();
}
m_Window->OnUpdate();
}
}
}
注意这段代码:
Application* Application::s_Instance = nullptr;
Application::Application()
{
HZ_CORE_ASSET(!s_Instance, "Application already exists!");
s_Instance = this;
m_Window = std::unique_ptr<Window>(Window::Create());
m_Window->SetEventCallback(BIND_EVENT_FN(OnEvent));
}
回到客户端,SandBox里添加 ImGuiLayer
#include<Hazel.h>
class ExampleLayer : public Hazel::Layer{
public:
ExampleLayer()
:Layer("Example"){}
void OnUpdate() override {
// HZ_INFO("ExampleLayer::Update");
}
void OnEvent(Hazel::Event& e) override {
HZ_TRACE("{0}",e);
}
};
class SandBox:public Hazel::Application
{
public:
SandBox() {
PushLayer(new ExampleLayer());
PushLayer(new Hazel::ImGuiLayer());
}
~SandBox() {
}
};
Hazel::Application * Hazel::CreateApplication() {
return new SandBox();
}
F5运行: