下载链接:
?新建文件夹,把下载好的文件放入对应路径:
?SRC下的premake5.lua文件:添加ImGui
workspace "YOTOEngine" -- sln文件名
architecture "x64"
configurations{
"Debug",
"Release",
"Dist"
}
-- https://github.com/premake/premake-core/wiki/Tokens#value-tokens
-- 组成输出目录:Debug-windows-x86_64
outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}"
-- 包含相对解决方案的目录
IncludeDir={}
IncludeDir["GLFW"]="YOTOEngine/vendor/GLFW/include"
IncludeDir["Glad"]="YOTOEngine/vendor/Glad/include"
IncludeDir["ImGui"] ="YOTOEngine/vendor/imgui"
--项目中包含某包
include "YOTOEngine/vendor/GLFW"
include "YOTOEngine/vendor/Glad"
include "YOTOEngine/vendor/imgui"
project "YOTOEngine" --YOTOEngine项目
location "YOTOEngine"--在sln所属文件夹下的YOTOEngine文件夹
kind "SharedLib"--dll动态库
language "C++"
targetdir ("bin/" .. outputdir .. "/%{prj.name}") -- 输出目录
objdir ("bin-int/" .. outputdir .. "/%{prj.name}")-- 中间目录
pchheader "ytpch.h"
pchsource "YOTOEngine/src/ytpch.cpp"
-- 包含的所有h和cpp文件
files{
"%{prj.name}/src/**.h",
"%{prj.name}/src/**.cpp"
}
-- 包含目录
includedirs{
"%{prj.name}/src",
"%{prj.name}/vendor/spdlog-1.x/include",
"%{IncludeDir.GLFW}",
"%{IncludeDir.Glad}",
"%{IncludeDir.ImGui}"
}
links{
"GLFW",-- GLFW.lib库链接到YOTOEngine项目中
"Glad",-- Glad.lib库链接到YOTOEngine项目中
"ImGui",-- ImGui.lib库链接到YOTOEngine项目中
"opengl32.lib"
}
-- 如果是window系统
filter "system:windows"
cppdialect "C++17"
-- On:代码生成的运行库选项是MTD,静态链接MSVCRT.lib库;
-- Off:代码生成的运行库选项是MDD,动态链接MSVCRT.dll库;打包后的exe放到另一台电脑上若无这个dll会报错
staticruntime "On"
systemversion "latest" -- windowSDK版本
-- 预处理器定义
defines{
"YT_PLATFORM_WINDOWS",
"YT_BUILD_DLL",
"YT_ENABLE_ASSERTS",
"GLFW_INCLUDE_NONE"-- 让GLFW不包含OpenGL
}
-- 编译好后移动Hazel.dll文件到Sandbox文件夹下
postbuildcommands{
("{COPY} %{cfg.buildtarget.relpath} ../bin/" .. outputdir .. "/Sandbox")
}
-- 不同配置下的预定义不同
filter "configurations:Debug"
defines "YT_DEBUG"
buildoptions"/MDd"
symbols "On"
filter "configurations:Release"
defines "YT_RELEASE"
buildoptions"/MD"
optimize "On"
filter "configurations:Dist"
defines "YT_DIST"
buildoptions"/MD"
optimize "On"
project "Sandbox"
location "Sandbox"
kind "ConsoleApp"
language "C++"
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
objdir ("bin-int/" .. outputdir .. "/%{prj.name}")
files{
"%{prj.name}/src/**.h",
"%{prj.name}/src/**.cpp"
}
-- 同样包含spdlog头文件
includedirs{
"YOTOEngine/vendor/spdlog-1.x/include",
"YOTOEngine/src"
}
-- 引用YOTOEngine
links{
"YOTOEngine",
"GLFW",
"opengl32.lib"
}
filter "system:windows"
cppdialect "C++17"
staticruntime "On"
systemversion "latest"
defines{
"YT_PLATFORM_WINDOWS"
}
filter "configurations:Debug"
defines "YT_DEBUG"
buildoptions"/MDd"
symbols "On"
filter "configurations:Release"
defines "YT_RELEASE"
buildoptions"/MD"
optimize "On"
filter "configurations:Dist"
defines "YT_DIST"
buildoptions"/MD"
optimize "On"
在Platform下创建OpenGl,将imgui_impl_opengl3.cpp和.h加入到该文件夹。
并且更名:
150行改为:#include "backends/imgui_impl_opengl3_loader.h"
96行添加:#include"ytpch.h"?至此错误消除,导入成功。
在YOTO下创建ImGui文件夹创建ImGuiLayer.cpp和.h:
ImGuiLayer.h:UI层的.h文件
#pragma once
#include"YOTO/Layer.h"
namespace YOTO {
class YOTO_API ImGuiLayer:public Layer
{
public:
ImGuiLayer();
~ImGuiLayer();
void OnAttach();
void OnDetach();
void OnUpdate();
void OnEvent(Event& event);
private:
float m_Time = 0.0f;
};
}
ImGuiLayer.cpp:在层初始化的时候和刷新的时候对io的参数进行修改,达到修改UI的目的
#include"ytpch.h"
#include"ImGuiLayer.h"
#include"Platform/OpenGL/ImGuiOpenGLRenderer.h"
#include"GLFW/glfw3.h"
#include"YOTO/Application.h"
namespace YOTO {
ImGuiLayer::ImGuiLayer()
:Layer("ImGuiLayer") {
}
ImGuiLayer::~ImGuiLayer() {
}
void ImGuiLayer::OnAttach()
{
//创建上下文
ImGui::CreateContext();
//设置颜色
ImGui::StyleColorsDark();
//配置类:ImGuiIO
ImGuiIO& io = ImGui::GetIO();
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;// 光标
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos;
// imgui输入key对应glfw的key,临时的:最终会对应引擎自身的key
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() {
//每帧刷新UI配置
ImGuiIO& io = ImGui::GetIO();
Application& app = Application::Get();
//显示的size大小
io.DisplaySize = ImVec2(app.GetWindow().GetWidth(), app.GetWindow().GetHeight());
float time = (float)glfwGetTime();
//时间
io.DeltaTime = m_Time > 0.0f ? (time - m_Time) : (1.0f / 60.0f);
m_Time = time;
ImGui_ImplOpenGL3_NewFrame();
ImGui::NewFrame();
static bool show = true;
// 显示ImGui Demo
ImGui::ShowDemoWindow(&show);
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
void ImGuiLayer::OnEvent(Event& event) {
}
}
?Application.h:将Application变为单例,添加Get方法和GetWindow方法
#pragma once
#include"Core.h"
#include"Event/Event.h"
#include"Event/ApplicationEvent.h"
#include "YOTO/Window.h"
#include"YOTO/LayerStack.h"
namespace YOTO {
class YOTO_API Application
{
public:
Application();
virtual ~Application();
void Run();
void OnEvent(Event &e);
void PushLayer(Layer* layer);
void PushOverlay(Layer* layer);
inline static Application& Get() {return * s_Instance;}
inline Window& GetWindow() { return *m_Window; }
private:
bool OnWindowClosed(WindowCloseEvent& e);
std::unique_ptr<Window> m_Window;
bool m_Running = true;
LayerStack m_LayerStack;
static Application* s_Instance;
};
//在客户端定义
Application* CreateApplication();
}
??Application.cpp:构造时候令s_Instance = this
#include"ytpch.h"
#include "Application.h"
#include"Log.h"
#include<glad/glad.h>
namespace YOTO {
#define BIND_EVENT_FN(x) std::bind(&x, this, std::placeholders::_1)
Application* Application::s_Instance = nullptr;
Application::Application() {
YT_CORE_ASSERT(!s_Instance, "Application需要为空!")
s_Instance = this;
//智能指针
m_Window = std::unique_ptr<Window>(Window::Creat());
//设置回调函数
m_Window->SetEventCallback(BIND_EVENT_FN(Application::OnEvent));
unsigned int id;
glGenBuffers(1, &id);
}
Application::~Application() {
}
/// <summary>
/// 所有的Window事件都会在这触发,作为参数e
/// </summary>
/// <param name="e"></param>
void Application::OnEvent(Event& e) {
//根据事件类型绑定对应事件
EventDispatcher dispatcher(e);
dispatcher.Dispatch<WindowCloseEvent>(BIND_EVENT_FN(Application::OnWindowClosed));
//输出事件信息
YT_CORE_INFO("{0}",e);
for (auto it = m_LayerStack.end(); it != m_LayerStack.begin();) {
(*--it)->OnEvent(e);
if (e.m_Handled)
break;
}
}
bool Application::OnWindowClosed(WindowCloseEvent& e) {
m_Running = false;
return true;
}
void Application::Run() {
WindowResizeEvent e(1280, 720);
if (e.IsInCategory(EventCategoryApplication)) {
YT_CORE_TRACE(e);
}
if (e.IsInCategory(EventCategoryInput)) {
YT_CORE_ERROR(e);
}
while (m_Running)
{
glClearColor(1,0,1,1);
glClear(GL_COLOR_BUFFER_BIT);
for (Layer* layer : m_LayerStack) {
layer->OnUpdate();
}
m_Window->OnUpdate();
}
}
void Application::PushLayer(Layer* layer) {
m_LayerStack.PushLayer(layer);
layer->OnAttach();
}
void Application::PushOverlay(Layer* layer) {
m_LayerStack.PushOverlay(layer);
layer->OnDetach();
}
}
YOTO.h:添加ImGuiLayer.h
#pragma once
#include "YOTO/Application.h"
#include"YOTO/Layer.h"
#include "YOTO/Log.h"
#include"YOTO/ImGui/ImGuiLayer.h"
//入口点
#include"YOTO/EntryPoint.h"
?SandboxApp.cpp:new且push这个层
#include<YOTO.h>
#include<stdio.h>
class ExampleLayer:public YOTO::Layer
{
public:
ExampleLayer()
:Layer("Example") {
}
void OnUpdate()override {
//YT_CLIENT_INFO("测试update");
}
void OnEvent(YOTO::Event& e)override {
YT_CLIENT_TRACE("测试event{0}",e);
}
private:
};
class Sandbox:public YOTO::Application
{
public:
Sandbox() {
PushLayer(new ExampleLayer());
PushLayer(new YOTO::ImGuiLayer());
}
~Sandbox() {
}
private:
};
YOTO::Application* YOTO::CreateApplication() {
printf("helloworld");
return new Sandbox();
}
Bug:这里莫名爆红
注释掉:
?暂时解决(不知道这个bug会不会未来给我一脚)
运行成功但是什么都不能点,因为没添加事件。
?谢谢大家的支持,我会把每次可成改动的整个代码、类都粘上来,虽然有点儿多,但是防止迷路然后出现一些蜜汁bug。有问题欢迎评论区讨论(博主也是菜鸡,希望大佬指点)