跟着cherno手搓游戏引擎【4】窗口抽象、GLFW配置

引入GLFW:

在vendor里创建GLFW文件夹:

在github上下载,把包下载到GLFW包下。

GitHub - TheCherno/glfw: A multi-platform library for OpenGL, OpenGL ES, Vulkan, window and input修改SRC/premake5.lua的配置:12、13、15、36、37、38、39、40行的代码是新加上去的:

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"include "YOTOEngine/vendor/GLFW"project "YOTOEngine"		--Hazel项目location "YOTOEngine"--在sln所属文件夹下的Hazel文件夹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}"}links{"GLFW","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",}-- 编译好后移动Hazel.dll文件到Sandbox文件夹下postbuildcommands{("{COPY} %{cfg.buildtarget.relpath} ../bin/" .. outputdir .. "/Sandbox")}-- 不同配置下的预定义不同filter "configurations:Debug"defines "YT_DEBUG"symbols "On"filter "configurations:Release"defines "YT_RELEASE"optimize "On"filter "configurations:Dist"defines "YT_DIST"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"}-- 引用hazellinks{"YOTOEngine","GLFW","opengl32.lib"}filter "system:windows"cppdialect "C++17"staticruntime "On"systemversion "latest"defines{"YT_PLATFORM_WINDOWS"}filter "configurations:Debug"defines "YT_DEBUG"symbols "On"filter "configurations:Release"defines "YT_RELEASE"optimize "On"filter "configurations:Dist"defines "YT_DIST"optimize "On"

GLFW中的premake5.lua: 

project "GLFW"kind "StaticLib"language "C"staticruntime "off"warnings "off"targetdir ("bin/" .. outputdir .. "/%{prj.name}")objdir ("bin-int/" .. outputdir .. "/%{prj.name}")files{"include/GLFW/glfw3.h","include/GLFW/glfw3native.h","src/glfw_config.h","src/context.c","src/init.c","src/input.c","src/monitor.c","src/null_init.c","src/null_joystick.c","src/null_monitor.c","src/null_window.c","src/platform.c","src/vulkan.c","src/window.c",}filter "system:linux"pic "On"systemversion "latest"files{"src/x11_init.c","src/x11_monitor.c","src/x11_window.c","src/xkb_unicode.c","src/posix_module.c","src/posix_time.c","src/posix_thread.c","src/posix_module.c","src/glx_context.c","src/egl_context.c","src/osmesa_context.c","src/linux_joystick.c"}defines{"_GLFW_X11"}filter "system:macosx"pic "On"files{"src/cocoa_init.m","src/cocoa_monitor.m","src/cocoa_window.m","src/cocoa_joystick.m","src/cocoa_time.c","src/nsgl_context.m","src/posix_thread.c","src/posix_module.c","src/osmesa_context.c","src/egl_context.c"}defines{"_GLFW_COCOA"}filter "system:windows"systemversion "latest"files{"src/win32_init.c","src/win32_joystick.c","src/win32_module.c","src/win32_monitor.c","src/win32_time.c","src/win32_thread.c","src/win32_window.c","src/wgl_context.c","src/egl_context.c","src/osmesa_context.c"}defines { "_GLFW_WIN32","_CRT_SECURE_NO_WARNINGS"}
--解决bug的部分:buildoptions "/MTD" 和"/MT"filter "configurations:Debug"defines "YT_DEBUG"buildoptions "/MTd"symbols "On"filter { "system:windows", "configurations:Debug-AS" }	runtime "Debug"symbols "on"sanitize { "Address" }flags { "NoRuntimeChecks", "NoIncrementalLink" }filter "configurations:Release"defines "YT_RELEASE"buildoptions "/MT"symbols "On"filter "configurations:Dist"defines "YT_DIST"buildoptions "/MT"symbols "On"

运行测试:

如出现此BUG:请找GLFW中的premake5文件,把上述的premake5.lua的bug解决部分改一下:

使GLFW项目的运行库,只能是MT或者MTD不能是MD或者MDD

执行GenerateProject.bat文件:

刷新解决方案得到GLFW的包: 

 

窗口抽象: 

创建window基类,用于不同平台window的实现。

YOTO/Window.h:

#pragma once#include"ytpch.h"
#include"YOTO/Core.h"
#include"YOTO/Event/Event.h"
namespace YOTO {struct WindowProps {std::string Title;unsigned int Width;unsigned int Height;WindowProps(const std::string &title="YOTO Engine",unsigned int width =1280, unsigned int height = 1280 ):Title(title),Width(width),Height(height){}};class YOTO_API Window {public://用EventCallbackFn代替std::function<void(Event&)>:输入为Event&返回值为void 的函数using EventCallbackFn = std::function<void(Event&)>;virtual ~Window(){}//=0为纯虚函数virtual void OnUpdate() = 0;virtual unsigned int GetWidth() const = 0;virtual unsigned int GetHeight() const = 0;virtual void SetEventCallback(const EventCallbackFn& callback) = 0;virtual void SetSync(bool enable)const = 0;virtual bool IsVSync() const = 0;static Window* Creat(const WindowProps& props = WindowProps());};
}

实现类:

创建文件夹src/Platform/Windows

WindowsWindow.h:

#pragma once
#include "YOTO/Window.h"
#include<GLFW/glfw3.h>
#include"YOTO/Log.h"
namespace YOTO {class WindowsWindow :public Window{public :WindowsWindow(const WindowProps& props);virtual ~WindowsWindow();void OnUpdate() override;inline unsigned int GetWidth() const override { return m_Data.Width; };inline unsigned int GetHeight() const override { return m_Data.Height; };inline void SetEventCallback(const EventCallbackFn& callback)override { m_Data.EventCallback = callback; };void SetVSync(bool enable) ;bool IsVSync()const;private: virtual void Init(const WindowProps& props);virtual void ShutDown();private:GLFWwindow* m_Window;struct WindowData {std::string Title;unsigned int Width, Height;bool VSync;EventCallbackFn EventCallback;};WindowData m_Data;};
}

 WindowsWindow.cpp:

#include "ytpch.h"
#include "WindowsWindow.h"namespace YOTO {static bool s_GLFWInitialized = false;Window* Window::Creat(const WindowProps& props) {return new WindowsWindow(props);}WindowsWindow::WindowsWindow(const WindowProps& props) {Init(props);}WindowsWindow::~WindowsWindow() {ShutDown();}void WindowsWindow::Init(const WindowProps& props) {m_Data.Title = props.Title;m_Data.Width = props.Width;m_Data.Height = props.Height;YT_CORE_INFO("创建了{0},{1},{2}", props.Title, props.Width, props.Height);if (!s_GLFWInitialized) {int success = glfwInit();YT_CLIENT_ASSERT("不能创建新的glfw,{0}", success);s_GLFWInitialized = true;}m_Window = glfwCreateWindow((int)props.Width, (int)props.Height, m_Data.Title.c_str(), nullptr, nullptr);glfwMakeContextCurrent(m_Window); glfwSetWindowUserPointer(m_Window, &m_Data);SetVSync(true);}void WindowsWindow::ShutDown() {glfwDestroyWindow(m_Window);}void WindowsWindow::OnUpdate(){//轮询事件glfwPollEvents();//交换缓冲区glfwSwapBuffers(m_Window);}void WindowsWindow::SetVSync(bool enable) {if (enable)glfwSwapInterval(1);elseglfwSwapInterval(0);m_Data.VSync = enable;}bool WindowsWindow::IsVSync() const {return m_Data.VSync;}
}

Core.h:添加新的Error

#pragma once
//用于dll的宏
#ifdef YT_PLATFORM_WINDOWS
#ifdef YT_BUILD_DLL
#define YOTO_API __declspec(dllexport) 
#else
#define YOTO_API __declspec(dllimport) #endif // DEBUG
#else
#error YOTO_ONLY_SUPPORT_WINDOWS
#endif // YOTO_PLATFORM_WINDOWS#ifdef YT_ENABLE_ASSERTS
#define YT_CLIENT_ASSERT(x,...) {if(!(x)){YT_CLIENT_ERROR("断言错误:{0}",__VA_ARGS__);__debugbreak();}}
#define YT_CORE_ASSERT(x,...) {if(!(x)){YT_CORE_ERROR("断言错误:{0}",__VA_ARGS__);__debugbreak();}}
#else
#define YT_ASSERT(x,...)
#define YT_CORE_ASSERT(x,...)#endif // YT_ENABLE_ASSERTS#define BIT(x)(1<<x)

Application.h:创建智能指针作为窗口的指针

#pragma once
#include"Core.h"
#include"Event/Event.h"
#include <YOTO/Window.h>namespace YOTO {class YOTO_API Application{public:Application();virtual ~Application();void Run();private:std::unique_ptr<Window>  m_Window;bool m_Running = true;};//在客户端定义Application* CreateApplication();
}

最终测试:

Application.cpp:在构造函数中创建窗口,在run的while循环中调用Update,写一段opengl测试代码窗口改变颜色

#include"ytpch.h"
#include "Application.h"
#include"Event/ApplicationEvent.h"
#include"Log.h"
#include<GLFW/glfw3.h>
namespace YOTO {Application::Application() {//智能指针m_Window = std::unique_ptr<Window>(Window::Creat());}Application::~Application() {}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);m_Window->OnUpdate();}}
}

 BUG:只需要重新生成一下YOTOEngine就好了

BUG:可抽象的一个bug。原因是WindowsWindow.cpp错误的添加了#include"YOTO.h"把它删掉就好了。

结果:

 至此,基本的环境已经搭建完毕。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/344964.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

概率大揭秘:深度复习概率论,事半功倍的学霸秘籍!

第一章 概率论的基本概念 一、事件及其关系与运算 1、样本空间、样本点、随机事件、必然事件、不可 能事件、基本事件和复合事件的概念&#xff1b; 2、事件的包含与相等&#xff1a;若事件A包含事件B&#xff0c;则B的发生必然导致A的发生。进而有P(AB)P(B)&#xff0c;P…

【服务器数据恢复】服务器硬盘磁头损坏的数据恢复案例

服务器硬盘故障&#xff1a; 一台服务器上raid阵列上有两块硬盘出现故障&#xff0c;用户方已经将故障硬盘送到其他机构检测过&#xff0c;其中一块硬盘已经开盘&#xff0c;检测结果是盘片损伤严重&#xff1b;另一块硬盘尚未开盘&#xff0c;初步判断也存在硬件故障&#xff…

学习Vue封装的过渡与动画总结

今天学习了Vue封装的过渡与动画&#xff0c;接下来说一下Vue是如何实现的&#xff0c;首先原生的方法是在style元素中给指定元素添加过渡的过渡或动画&#xff0c;但Vue就不需要直接获取到需要过渡或动画的元素&#xff0c;而是使用一个<transition>的标签来包裹住想要过…

提供一些防扫描被封禁、防溯源工具

1► 介绍 SecScanC2可以创建P2P网络进行安全扫描和C2。该工具可以帮助安全研究人员更有效地进行渗透测试&#xff0c;防止扫描被封禁&#xff0c;保护自己免受溯源。 2► 工具特性 P2P&#xff1a;将大量互联网节点构建成P2P网络 防止扫描被封禁&#xff1a;随机或指定节点…

STM32CubeMX配置STM32G071UART+DMA收发数据(HAL库开发)

时钟配置HSI主频配置64M 配置好串口&#xff0c;选择异步模式 配置DMA TX,RX,选择循环模式。 NVIC中勾选使能中断 勾选生成独立的.c和h文件 配置好需要的开发环境并获取代码 串口重定向勾选Use Micro LIB main.c文件修改 增加头文件和串口重定向 #include <string.h&g…

linux安装MySQL5.7(安装、开机自启、定时备份)

一、安装步骤 我喜欢安装在/usr/local/mysql目录下 #切换目录 cd /usr/local/ #下载文件 wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.38-linux-glibc2.12-x86_64.tar.gz #解压文件 tar -zxvf mysql-5.7.38-linux-glibc2.12-x86_64.tar.gz -C /usr/local …

MacOS环境下Kali Linux安装及使用指导

Kali Linux是一个开源的、基于Debian的Linux发行版&#xff0c;面向各种信息安全任务&#xff0c;如渗透测试、安全研究、计算机取证和逆向工程&#xff0c;是最先进的渗透测试发行版&#xff0c;它的前身是BackTrack。 1. 我们为什么要用Kali Linux 由于Kali Linux具有以下特…

redis夯实之路-键过期与发布订阅详解

设置键的生存时间或过期时间 Setex&#xff08;单位s&#xff09;&#xff0c;expire&#xff08;s&#xff09;&#xff0c;pexpire&#xff08;ms&#xff09;可以设置键的生存时间&#xff0c; Expirate&#xff0c;pexpirate设置键的过期时间&#xff08;timestamp的时间…

SqlAlchemy使用教程(一) 原理与环境搭建

一、SqlAlchemy 原理及环境搭建 SqlAlchemy是1个支持连接各种不同数据库的Python库&#xff0c;提供DBAPI与ORM&#xff08;object relation mapper&#xff09;两种方式使用数据库。 DBAPI方式&#xff0c;即使用SQL方式访问数据库 ORM, 对象关系模型&#xff0c;是用 Python…

c++学习笔记-STL案例-机房预约系统2-创建身份类

前言 衔接上一篇“c学习笔记-STL案例-机房预约系统1-准备工作”&#xff0c;本文主要包括&#xff1a;创建身份类&#xff0c;建立了整个系统的框架&#xff0c;Identity基类&#xff0c;派生类&#xff1a;Sudent、Teacher、Manager&#xff0c;基类无实现源文件&#xff0c;…

【Python】编程练习的解密与实战(四)

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《Python | 编程解码》⏰诗赋清音&#xff1a;云生高巅梦远游&#xff0c; 星光点缀碧海愁。 山川深邃情难晤&#xff0c; 剑气凌云志自修。 目录 &#x1fa90;1. 初识Python &a…

HTML5 article标签,<time>...</time>标签和pubdate属性的运用

1、<article>...</article>标签的运用 article标签代表文档、页面或应用程序中独立的、完整的、可以独自被外部引用的内容。它可以是一篇博客或报竟杂志中的文章、一篇论坛帖子、一段用户评论或一个独立的插件&#xff0c;或者其他任何独立的内容。把文章正文放在h…