当前位置: 首页 > news >正文

跟着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配置

引入GLFW&#xff1a; 在vendor里创建GLFW文件夹&#xff1a; 在github上下载&#xff0c;把包下载到GLFW包下。 GitHub - TheCherno/glfw: A multi-platform library for OpenGL, OpenGL ES, Vulkan, window and input修改SRC/premake5.lua的配置&#xff1a;12、13、15、36…...

Tomcat基础升华学习

01 What is Tomcat 1.1 Tomcat官网 官网 &#xff1a;https://tomcat.apache.org 1.2 Understand 为什么说Tomcat是Servlet之类技术的实现&#xff1f; 在我们的理解中&#xff0c;Tomcat可以称为Web容器或者Servlet容器 不妨通过手写一个Tomcat来推导一下 1.2.1 创建Tomc…...

一种具有轨迹优化的无人驾驶车实时运动规划器 论文阅读

论文题目&#xff1a;A Real-Time Motion Planner with Trajectory Optimization for Autonomous Vehicles Abstract 本文的实时规划器首先将空间离散化&#xff0c;然后基于一组成本函数搜索出最佳轨迹。迭代优化所得到的轨迹的Path和Speed。post-optimization计算复杂度低&…...

GPDB - 高可用 - 流复制状态

GPDB - 高可用 - 流复制状态 GPDB的高可用基于流复制&#xff0c;通过FTS进行自动故障切换。自动故障切换需要根据primary-mirror流复制的各种状态进行判断。本节就聊聊primary-mirror流复制的各种状态。同样适用于PgSQL 1、WalSndState typedef enum WalSndState {WALSNDSTATE…...

最佳解决方案:如何在网络爬虫中解决验证码

Captcha&#xff08;全自动区分计算机和人类的公开图灵测试&#xff09;是广泛应用的安全措施&#xff0c;用于区分合法的人类用户和自动化机器人。它通过呈现复杂的挑战&#xff0c;包括视觉上扭曲的文本、复杂的图像或复杂的拼图等方式&#xff0c;要求用户成功解决这些挑战以…...

在线项目实习分享:股票价格形态聚类与收益分析

01前置课程 数据挖掘基础数据探索数据预处理数据挖掘算法基础Python数据挖掘编程基础Matplotlib可视化Pyecharts绘图 02师傅带练 行业联动与轮动分析 通过分析申银万国行业交易指数的联动与轮动现象&#xff0c;获得有意义的行业轮动关联规则&#xff0c;并在此基础上设计量…...

c# vb.net检测字符串是否匹配一组相似度数组input Like

VB.NET 检测字符串是否符合一个数组中的多个like条件&#xff0c;有没有最简单的函数&#xff1f; 在VB.NET中&#xff0c;可以使用Array.Exists方法结合String.Like方法来检测一个字符串是否符合一个数组中的多个LIKE条件。Array.Exists方法用于确定序列中的任何元素是否满足…...

DEJA_VU3D - Cesium功能集 之 113-获取圆节点(2)

前言 编写这个专栏主要目的是对工作之中基于Cesium实现过的功能进行整合,有自己琢磨实现的,也有参考其他大神后整理实现的,初步算了算现在有差不多实现小140个左右的功能,后续也会不断的追加,所以暂时打算一周2-3更的样子来更新本专栏(每篇博文都会奉上完整demo的源代码…...

spring-boot项目启动类错误: 找不到或无法加载主类 com.**Application

问题&#xff1a;Springboot项目启动报错&#xff1a;错误: 找不到或无法加载主类 com.**Application 解决步骤&#xff1a; 1.File–>Project Structure 2.Modules–>选中你的项目–点击“-”移除 3.重新导入&#xff1a;点击“”号&#xff0c;选择Import Module&…...

搭建大数据开发环境【AutoDL容器】

租用AutoDL容器 注意&#xff1a;结束实验时记得将数据库数据转移存储 使用Docker实现本地IDEA连接AutoDL 后为ssh服务器地址用户名为前的端口号ssh密码为用户密码 安装JDK 压缩包安装 Java下载地址&#xff1a;Oracle Java Download&#xff08;hadoop不指定特定版本java&…...

写一个简单的Java的Gui文本输入窗口,JFrame的简单使用

JFrame是指一个计算机语言-java的GUI程序的基本思路是以JFrame为基础,它是屏幕上window的对象,能够最大化、最小化、关闭。 Swing的三个基本构造块:标签、按钮和文本字段;但是需要个地方安放它们,并希望用户知道如何处理它们。JFrame 类就是解决这个问题的——它是一个容器…...

Unity中URP下抓屏的 开启 和 使用

文章目录 前言一、抓屏开启1、Unity下开启抓屏2、Shader中开启抓屏 二、抓屏使用1、设置为半透明渲染队列&#xff0c;关闭深度写入2、申明纹理和采样器3、在片元着色器使用请添加图片描述 三、测试代码 前言 我们在这篇文章中看一下&#xff0c;URP下怎么开启抓屏。 一、抓屏…...

业务题day01

1-1 请说一下你项目中是如何进行项目管理和发布的 我们项目使用的是Gogs进行代码托管&#xff0c;Jenkins进行项目自动运维发布。 在我们的项目中&#xff0c;我们使用Gogs进行代码托管和版本控制&#xff0c;以确保团队成员可以协同开发和管理代码。 Gogs是一个轻量级的、开…...

DEJA_VU3D - Cesium功能集 之 114-雷达效果(基础效果)

前言 编写这个专栏主要目的是对工作之中基于Cesium实现过的功能进行整合,有自己琢磨实现的,也有参考其他大神后整理实现的,初步算了算现在有差不多实现小140个左右的功能,后续也会不断的追加,所以暂时打算一周2-3更的样子来更新本专栏(每篇博文都会奉上完整demo的源代码…...

【Leetcode】2696. 删除子串后的字符串最小长度

文章目录 题目思路代码 题目 2696. 删除子串后的字符串最小长度 思路 计算通过删除字符串中的 “AB” 和 “CD” 子串后&#xff0c;可获得的最终字符串的最小长度。 主要思路是使用一个栈来模拟字符串的处理过程&#xff0c;每次遍历字符串时&#xff0c;如果当前字符和栈…...

利用gulp工具对常规web项目进行压缩打包

前言 对于一个常规的web项目&#xff0c;如下项目目录 |- imgs | - img1.png | - img2.png |- js | - user.js | - utils.js |- css | - index.css | - user.css |- html | - user.html |- index.html可以使用各种构建工具&#xff08;如webpack、gulp、grunt等&#xff09;来…...

面试经典题---68.文本左右对齐

68.文本左右对齐 我的解法&#xff1a; 两层while循环嵌套&#xff0c;外层循环用于处理不同行&#xff0c;内层while循环计算出每行应有的单词个数。 使用left和right记录一行中应有的单词下标&#xff0c;即当前行应包含从words[left]到words[right-1]这count个单词&#xf…...

完整的模型验证套路

读取图片 from PIL import Imageimg_path "../Yennefer_of_Vengerberg.jpg" image Image.open(img_path) print(image)转换成灰度图&#xff08;可选&#xff09; image image.convert(L) image.show()转换成RGB格式 image image.convert(RGB)因为png格式是四…...

内 存 取 证

1.用户密码 从内存中获取到用户admin的密码并且破解密码&#xff0c;以Flag{admin,password}形式提交(密码为6位)&#xff1b; 1&#xff09;查看帮助 -h ./volatility_2.6_lin64_standalone -h 2&#xff09;获取内存镜像文件的信息 imageinfo ./volatility_2.6_lin64_stand…...

【PHP】价格区间字段验证,如4万-5万

参数值示例&#xff1a; $str1 "4万-5万"; $str2 "4万-5万元"; $str3 "5万元以内"; 以下是一个PHP示例&#xff0c;用于检查字符串是否满足要求&#xff1a; function checkString($str) {// 检查字符串中是否包含"-"或"以内…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

windows系统MySQL安装文档

概览&#xff1a;本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容&#xff0c;为学习者提供全面的操作指导。关键要点包括&#xff1a; 解压 &#xff1a;下载完成后解压压缩包&#xff0c;得到MySQL 8.…...

鸿蒙HarmonyOS 5军旗小游戏实现指南

1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;采用DevEco Studio实现&#xff0c;包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...