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

2024-01-13 04:52

本文主要是介绍跟着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"把它删掉就好了。

结果:

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

这篇关于跟着cherno手搓游戏引擎【4】窗口抽象、GLFW配置的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/600306

相关文章

VScode连接远程Linux服务器环境配置图文教程

《VScode连接远程Linux服务器环境配置图文教程》:本文主要介绍如何安装和配置VSCode,包括安装步骤、环境配置(如汉化包、远程SSH连接)、语言包安装(如C/C++插件)等,文中给出了详... 目录一、安装vscode二、环境配置1.中文汉化包2.安装remote-ssh,用于远程连接2.1安装2

Redis多种内存淘汰策略及配置技巧分享

《Redis多种内存淘汰策略及配置技巧分享》本文介绍了Redis内存满时的淘汰机制,包括内存淘汰机制的概念,Redis提供的8种淘汰策略(如noeviction、volatile-lru等)及其适用场... 目录前言一、什么是 Redis 的内存淘汰机制?二、Redis 内存淘汰策略1. pythonnoe

windos server2022的配置故障转移服务的图文教程

《windosserver2022的配置故障转移服务的图文教程》本文主要介绍了windosserver2022的配置故障转移服务的图文教程,以确保服务和应用程序的连续性和可用性,文中通过图文介绍的非... 目录准备环境:步骤故障转移群集是 Windows Server 2022 中提供的一种功能,用于在多个

windos server2022里的DFS配置的实现

《windosserver2022里的DFS配置的实现》DFS是WindowsServer操作系统提供的一种功能,用于在多台服务器上集中管理共享文件夹和文件的分布式存储解决方案,本文就来介绍一下wi... 目录什么是DFS?优势:应用场景:DFS配置步骤什么是DFS?DFS指的是分布式文件系统(Distr

关于Maven中pom.xml文件配置详解

《关于Maven中pom.xml文件配置详解》pom.xml是Maven项目的核心配置文件,它描述了项目的结构、依赖关系、构建配置等信息,通过合理配置pom.xml,可以提高项目的可维护性和构建效率... 目录1. POM文件的基本结构1.1 项目基本信息2. 项目属性2.1 引用属性3. 项目依赖4. 构

龙蜥操作系统Anolis OS-23.x安装配置图解教程(保姆级)

《龙蜥操作系统AnolisOS-23.x安装配置图解教程(保姆级)》:本文主要介绍了安装和配置AnolisOS23.2系统,包括分区、软件选择、设置root密码、网络配置、主机名设置和禁用SELinux的步骤,详细内容请阅读本文,希望能对你有所帮助... ‌AnolisOS‌是由阿里云推出的开源操作系统,旨

mysql-8.0.30压缩包版安装和配置MySQL环境过程

《mysql-8.0.30压缩包版安装和配置MySQL环境过程》该文章介绍了如何在Windows系统中下载、安装和配置MySQL数据库,包括下载地址、解压文件、创建和配置my.ini文件、设置环境变量... 目录压缩包安装配置下载配置环境变量下载和初始化总结压缩包安装配置下载下载地址:https://d

gradle安装和环境配置全过程

《gradle安装和环境配置全过程》本文介绍了如何安装和配置Gradle环境,包括下载Gradle、配置环境变量、测试Gradle以及在IntelliJIDEA中配置Gradle... 目录gradle安装和环境配置1 下载GRADLE2 环境变量配置3 测试gradle4 设置gradle初始化文件5 i

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

MySQL中my.ini文件的基础配置和优化配置方式

《MySQL中my.ini文件的基础配置和优化配置方式》文章讨论了数据库异步同步的优化思路,包括三个主要方面:幂等性、时序和延迟,作者还分享了MySQL配置文件的优化经验,并鼓励读者提供支持... 目录mysql my.ini文件的配置和优化配置优化思路MySQL配置文件优化总结MySQL my.ini文件