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

news2024/11/16 9:58:13

引入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"
	}
	-- 引用hazel
	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"
		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);
		else
			glfwSwapInterval(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.coloradmin.cn/o/1377783.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

19_注解

文章目录 注解注解的作用注解的语法注解的使用 元注解注解处理器案例 注解VS配置文件注解的应用 注解 Annotation是代码里的特殊标记&#xff0c;这些标记可以在编译、类加载、运行时被读取&#xff0c;并执行相应的处理可以把Annotation理解为一个标签注解是不允许继承的 注…

C++内存管理机制(侯捷)笔记2

C内存管理机制&#xff08;侯捷&#xff09; 本文是学习笔记&#xff0c;仅供个人学习使用。如有侵权&#xff0c;请联系删除。 参考链接 Youtube: 侯捷-C内存管理机制 Github课程视频、PPT和源代码: https://github.com/ZachL1/Bilibili-plus 下面是第二讲allocator具体实…

记录汇川:H5U与Fctory IO测试10

主程序&#xff1a; 子程序&#xff1a; IO映射 子程序&#xff1a; 自动程序 Fctory IO配置&#xff1a; HMI配置&#xff1a; 实际动作如下&#xff1a; Fctory IO测试10

苹果电脑Markdown写作工具:ulysses mac软件介绍

ulysses for mac是一款Markdown写作工具&#xff0c;支持Markdown拼写检查、语音识别、iCloud同步、版本管理等功能&#xff0c;并且可以导出为 PDF、word、RTF、TXT、Markdown、HTML 和 ePub等文件格式。 ulysses for mac软件介绍 适用于Mac&#xff0c;iPad和iPhone的终极写…

Casper Labs 与 IBM Consulting 合作,AI透明度、审计能力的新方案

​ “全新解决方案&#xff0c;旨在帮助企业更有效地管理训练数据&#xff0c;这些数据由不同的组织通过生成式人工智能系统产生” 企业区块链软件和服务提供商 Casper Labs 与 IBM Consulting 共同宣布&#xff0c;它们将联手推出新的解决方案&#xff0c;以帮助客户在其人工…

P5736 【深基7.例2】质数筛题解

题目 输入n个不大于105的正整数。要求全部储存在数组中&#xff0c;去除掉不是质数的数字&#xff0c;依次输出剩余的质数。 输入输出格式 输入格式 第一行输入一个正整数n&#xff0c;表示整数个数。 第二行输入n个正整数&#xff0c;以空格隔开。 输出格式 输出一行&a…

Spring MVC 异常处理器

异常处理器 如果不加以异常处理&#xff0c;错误信息肯定会抛在浏览器页面上&#xff0c;这样很不友好&#xff0c;所以必须进行异常处理。 异常处理思路 系统的dao、service、controller出现都通过throws Exception向上抛出&#xff0c;最后由springmvc前端控制器交由异常处…

专业130+总400+哈尔滨工业大学803信号与系统和数字逻辑电路考研经验哈工大,电子信息,信息与通信工程,信通

今年专业课803信号与系统和数字逻辑130总分400如愿考上哈尔滨工业大学电子信息&#xff08;信息与通信工程-信通&#xff09;&#xff0c;总结了一些各门课程复习心得&#xff0c;希望对大家复习有帮助。 数学一 资料选择&#xff1a; ①高数&#xff1a;张宇强化班 ②线性…

spring Security源码讲解-Sevlet过滤器调用springSecurty过滤器的流程

承接上文 上一节 http://t.csdnimg.cn/ueSAl 最后讲到了过滤器收集完成注入容器&#xff0c;这节我们来讲Security的Filter是怎么被Spring调用的。 我们先看webSecurity的performBuild方法(), 也就是说&#xff0c;最终返回的过滤器对象实例有两种情况当我们配置debugEnabl…

UIUC CS241 讲义:众包系统编程书

原文&#xff1a;angrave/SystemProgramming 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 欢迎来到 Angrave 的众包系统编程维基书&#xff01;这个维基是由伊利诺伊大学的学生和教师共同建立的&#xff0c;是伊利诺伊大学 CS 的 Lawrence Angrave 的众包创作实验。…

SwiftUI 为任意视图加上徽章(Badge)而想到的(下)

概览 在 SwiftUI 为任意视图加上徽章(Badge)而想到的(上) 这篇文章中,我们讨论了如何使用 Preference 技术打造 SwiftUI 中任意视图上徽章的实现。 虽然,我们完成了一系列挑战最后基本得偿所愿,不过在上篇的实现中仍有些许不尽如人意之处。 在本篇博文中,您将学到如下…

安卓(雷电)模拟器清除屏幕密码[亲测可用]

1、设置磁盘可写 启动模拟器&#xff0c;然后在模拟器的设置界面&#xff0c;设置磁盘共享为可写入&#xff0c;重启模拟器&#xff0c;如下图&#xff1a; 2、找到模拟器目录 返回桌面&#xff0c;右键模拟器图标&#xff0c;打开文件所在目录&#xff0c;如下图&#xff1a…

实现稳定的联合显著性检测和联合目标分割

1 Title Toward Stable Co-Saliency Detection and Object Co-Segmentation(Bo Li; Lv Tang; Senyun Kuang; Mofei Song; Shouhong Ding)【IEEE Transactions on Image Processing 2022】 2 Conclusion This paper present a novel model for simultaneous stable co-saliency…

恼人的“龙天“(䶮)--谈谈从GBK转到GB18030的特殊情况

背景 最近在做一个去O迁移适配&#xff0c;刚好也有友商在一起做&#xff0c;两边测试方式不一样。友商先遇到了一个问题&#xff0c;就是在ORACLE中某个的2字节GBK字符到迁移到友商的库中变成了4字节&#xff0c;刚好那个字段在这个字是2字节的时候&#xff0c;已经存满了&am…

Vue.js设计与实现阅读-2

Vue.js设计与实现阅读-2 1、前言2、框架设计的核心要素2、1 提升用户体验2、2 控制代码体积2、3 Tree-Shaking2、4 特性开关2、5 错误处理 1、前言 上一篇我们了解到了 命令式和声明式的区别&#xff0c;前者关注过程&#xff0c;后者关注结果了解了虚拟dom存在的意义&#x…

Excel地址

解题思路&#xff1a; 根据题中歪歪和笨笨的话可以有两种解法。 1.输入的数为多大&#xff0c;则循环1多少次&#xff0c;当值为27时就要进行进位操作。这时要分情况讨论。 当集合中元素为一个时&#xff0c;如26&#xff0c;则需要变为1 1&#xff0c;集合元素个数加一。 当…

C语言指针(一)

目录 1.什么是指针 2.指针变量和地址 1.解引用操作符 2.指针变量类型的意义 3.void*指针 4.const修饰指针 1.const放在*左边 2.const放在*右边 3.指针的运算 1.指针加减整数 2.指针减指针 3.指针比较大小 4.野指针 1.没有给指针变量初始化 2.指针指向的空间释放 …

MES系统中的设备管理及设备数据采集

随时工厂数字化建设的大力推进&#xff0c;设备管理的效率得到了很大的提升&#xff0c;特别是作为机加工企业&#xff0c;设备是整个企业非常重要的核心资产。 一、设备进行数据采集面临痛点&#xff1a; 设备数据状况无法获取与掌握 设备老旧&#xff0c;信息化基础差&…

制造知识普及--MES系统中的调度排产管理

要想弄清楚MES系统调度排产的管理机制&#xff0c;则要首先搞清楚车间调度排产是一套怎样的工作流程&#xff0c;它的难点在什么地方&#xff1f; 生产调度指的是具体组织实现生产作业计划的工作&#xff0c;是对执行生产作业计划过程中发生的问题和可能出现的问题&#xff0c…

Springboot+vue学生考试系统

Springbootvue学生考试系统 演示视频 【Springbootvue学生考试系统】 https://www.bilibili.com/video/BV1gk4y1Q7em/?share_sourcecopy_web&vd_source11344bb73ef9b33550b8202d07ae139b 主要功能&#xff1a; 管理员可以添加题库分配课程教师&#xff0c;指定考试范围指定…