Hazel游戏引擎
文章平均质量分 88
2023年2月14日开始做此专栏,可能会耗时两三个月。
此专栏是我学习TheCherno的Hazel游戏引擎教程的笔记,包括一些重要的步骤和代码及思考,建议看原视频教程。
刘建杰
像我这么优秀的人,
本该当个公务员。
怎么二十多年到头来,
还在招聘会沉沦。
像我这样迷茫的人,
像我这样牛马的人,
像我这样打工度年的人,
你还见过多少人。
展开
-
Hazel游戏引擎(123)C#脚本属性在编辑器面板可见、Mono热更新dll
此节目的为完成在编辑器面板上可以显示C#脚本类的属性,对属性的值修改,C#脚本会热更新(mono4.5api支持)如何实现使用mono的api,根据类名获取和设置属性的值实现细节由于C#类类型名称有点不太一眼看出什么意思,所以要自定义类类型,并用map来进行C#类型名称标识转换。比如:C#的float空间名+类名是->,需转换我们自定义的类名称**“Float”。**自定义的类名称需接近C++类名,容易标识。原创 2023-08-15 00:09:17 · 681 阅读 · 0 评论 -
Hazel游戏引擎(122)C#分离游戏和核心库代码
此节目的将C#游戏代码作为新工作空间的项目,并引用C#核心库的项目1个C#核心库项目1个C#脚本项目里面脚本调用C#核心库的函数,从而实现脚本功能像Unity开发时,Unity有一套自己的dll,我们写脚本需要using UnityEngine;,调用Unity库dll才能实现相应效果如何实现使用premake5快速制作实现细节当分离了C#游戏代码和核心库代码,那C++加载dll从一个变成两个得到C# dll的Mono类应该区分是获取C#核心库程序集的 Mono类。原创 2023-08-15 00:08:09 · 560 阅读 · 0 评论 -
Hazel游戏引擎(121)C#获取实体的组件
此节目的由上节根据UUID获取实体的translation在根据wsad调整实体的位置此节优化上节所做,实体的translation应属于实体的TransformComponent,所以此节需要在C#创建组件类用UUID,C#组件类对应cpp的组件类。为完成像Unity的C#脚本API能在C#获取当前实体在cpp的Rigidbody2DComponent组件并C#可以通过组件实例对象操作实体比如给实体添加物理冲力。原创 2023-08-15 00:07:32 · 497 阅读 · 0 评论 -
Hazel游戏引擎(120)将C#脚本融入ECS
此节目的为实现C#脚本WSAD能控制实体的位置变化如何实现使用118节C++内部调用C#的函数功能,实现C++调用C#脚本的OnCreate、OnUpdate函数的调用。使用119节C#内部调用C++的函数功能,实现C#的WSAD能调用C++函数修改实体的位置。有利于理解本节重点的代码初始化Mono准备,需得到MonoDomain、MonoAssembly、MonoImage// 0.1设置程序集装配路径(复制的4.5版本的路径)// 0.2声明根域// 存储root domain指针。原创 2023-08-15 00:07:03 · 341 阅读 · 0 评论 -
Hazel游戏引擎(119)在C#调用C++内部函数
此节目的上一节实现了cpp调用c#函数这一节要实现C#调用cpp内部函数,这样才可以算得上脚本封装类封装加载构建mono环境、Mono类ScriptEngine类封装 加载构建Mono环境类ScriptClass类封装 加载C#类成Mono类 的类封装,C#调用cpp内部函数,需向C#提供的接口,成为类如何实现(带有例子)原创 2023-08-15 00:06:47 · 326 阅读 · 0 评论 -
Hazel游戏引擎(118)Mono实现C#脚本、Github加速
此节目的hazel实现能cpp能调用C#的函数(C#语言嵌入cpp中),需要安装mono.Net库,并克隆git上的mono项目自己构建导出mono库。需要.Net库和构建的mono库Cherno所做用visual studio构建mono项目导出mono静态库,静态链接,而不是像peter一样使用mono安装路径下文件夹下已有的mono库。(为什么要静态库,因为当前引擎就是用静态链接)相关链接Peter的讲解mono。原创 2023-08-15 00:05:21 · 721 阅读 · 0 评论 -
Hazel游戏引擎(117)维护项目
此节目的维护项目要完善和修理的地方。原创 2023-08-14 23:50:38 · 267 阅读 · 0 评论 -
Hazel游戏引擎(116)处理GitHub上的ISSUE
此节目的如标题,处理GitHub上的pull请求,以防项目有什么问题。原创 2023-08-14 23:50:07 · 208 阅读 · 0 评论 -
Hazel游戏引擎(115)维护项目和合并,模板、模板参数包、函数参数包、参数包转发、扩展参数包、折叠表达式、lambda函数
此节目的为了进入下一个新功能,需要先维护好项目要维护或者完善的地方复制一个实体的所有组件代码、复制一个场景的所有实体的所有组件代码优化有一个组件就要调用一次函数,很麻烦取消链接当前目录下的vulkan的lib直接链接vulkan安装路径下的lib删除按键重复因为按键重复总是返回false,可以删除KeyEvent的按键事件检测不到重复事件。原创 2023-08-14 23:49:43 · 375 阅读 · 0 评论 -
Hazel游戏引擎(113-114)物理模拟模式
此节目的增加一个物理模拟运行模式来运行给物体添加的物理效果,摄像机使用编辑模式下的摄像机。区分Play运行模式的物理效果这个模式的摄像机会变成场景里的主摄像机,而不是当前的编辑相机。关于物理模拟模式渲染的场景部分物理模拟模式下:渲染的场景和编辑模式下一样物理模拟部分物理模拟模式下:物理模拟和Play模式下的部分一样所以物理模拟模式编辑模式和Play模式下的交集,物理模拟模式也要复制当前编辑场景。如何实现添加一个图标、一个状态来控制实现细节物理模拟模式运行时再点击Play模式应无bug。原创 2023-08-14 23:48:58 · 330 阅读 · 0 评论 -
Hazel游戏引擎(112)可视化包围盒
此节目的实现一个复选框点击后,场景可以渲染出图形相应的包围盒如何实现使用上两节加的渲染Line和Rect来渲染盒状包围盒。至于圆的包围盒,一样绘制圆,只不过控制厚度,从而实现圆环形状=圆包围盒实现细节渲染包围盒的代码应放在哪?应放在编辑层,而不是场景层。场景层是渲染场景内的物体的,而至于包围盒不属于场景,若放在场景里,需要向编辑层获取是否显示包围盒的控制, 这样会导致紊乱。放在编辑层,等渲染物体后再渲染包围盒,这使得物体与调试相关的渲染分开,更好扩展。重点。原创 2023-08-14 23:48:45 · 451 阅读 · 0 评论 -
Hazel游戏引擎(111)添加圆形包围盒
此节目的为了承上启下,在编辑场景显示实体物理组件的包围盒,更好调整包围盒的参数实现想要的结果。此节只完成了在面板上显示调整包围盒参数,下一节才渲染了包围盒如何实现使用box2D的API,先得到圆形对象,设置半径,再被赋给fixture当参数实现细节需添加圆形组件需设置圆形组件的属性面板圆形组件需被序列化yaml和解析yaml以后要做的由于有20左右个组件,若每次添加一个组件都得设置新组件的属性面板有点麻烦,需要考虑建立一个表用for循环,简化代码。原创 2023-08-14 23:48:16 · 258 阅读 · 0 评论 -
Hazel游戏引擎(110)渲染Line和Rect
此节目的要给当前引擎添加能渲染线条方框功能。渲染方框是在渲染线条的基础上实现的为什么当前的物体包围盒需用线条、方框显示,提供友好的视觉功能以后使用引擎的人员可能会需要射线检测,在编辑场景时就要看到射线的效果,相当于gizmos。线条、Rect如何画先说quad怎么画OpenGL的API画Quad需要提供索引缓冲区,会有重复的索引被使用线条使用OpenGL的API画不需要提供索引缓冲区,只需要提供顶点数组就行。同quad一样,顶点位置可以重复利用,两个顶点位置确定一条线Rect是用。原创 2023-08-14 23:47:36 · 249 阅读 · 0 评论 -
Hazel游戏引擎(109)渲染2D圆Circle
此节目的给引擎添加渲染Circle图形如何实现对项目来说:用批处理,同quad的顶点坐标与布局,但是shader的fragment阶段,控制在一个圆圈输出颜色。抛开项目说:用Quad顶点包围一个范围作为画布(Canvas)用glsl控制画出一个圆alpha为1,圆外的范围的alpha为0。实现细节运行时需要拷贝circle组件,序列化和解析yaml-cpp时都得加上circle组件的代码。circle的shader具有顶点属性。如何画圆请点这。原创 2023-08-14 23:47:23 · 384 阅读 · 0 评论 -
Hazel游戏引擎(108)开始、结束、复制场景
此节目的为实现点击运行,复制当前场景成为运行场景,点击结束销毁当前场景。在当前场景复制实体最重要的如何复制场景,复制场景需要复制当前场景的所有实体及其包含的组件,但是当前的entt库不包含复制组件的API,所以我们需要手动写复制实体。如何实现复制场景entt的注册表起关键作用entt::registry创建新场景,为新场景创建和旧场景同名和uuid的实体,并用map存入(旧实体的uuid对应新实体)的关系遍历旧场景所有uuid组件的旧实体,用旧实体的uuid-map-对应新实体获取旧实体的。原创 2023-08-14 23:46:53 · 340 阅读 · 0 评论 -
Hazel游戏引擎(107)UUID唯一标识
什么是UUID可以理解为全球唯一标识为什么要使用UUID标识实体 = 此节目的为了点击运行场景,实体发生位置等变化复原而要实现的标识功能为什么不简单的使用increment递增假设从0开始,游戏分发到两个电脑,他们创建实体标识id,需要知道从多少开始递增,需要服务器提供权威多少开始递增,这样的设计不太好,不想多一个服务器功能,所以只需使用uuid。uuid发生的冲突很小,所以不用担心两个电脑创建实体的id一样如何实现定义UUID类,使用cpp的随机函数,随机ID实现细节。原创 2023-08-14 23:46:20 · 286 阅读 · 0 评论 -
Hazel游戏引擎(106)Box2D
网址Box2D库此节目的实现2D物理效果如何实现使用Box2D库引入项目之中实现细节实现物体效果需要rigidbody和box2dcollider两个组件添加了rigidbody和box2dcollider两个组件,需要修改面板以及序列化代码以后要实现:每次运行结束后可以重置物体的位置。原创 2023-08-13 21:41:50 · 401 阅读 · 0 评论 -
Hazel游戏引擎(105)PlayStop按钮
此节目的为了物理效果能可以运行,这节需要完成工具栏的UI,点击播放运行和停止物理效果(后几节做)。如何实现使用ImGui的API,渲染OpenGL的加载纹理实现细节按钮应该在中间按钮适应窗口大小、放大时应使用线性插值保证不那么模糊按钮图片透明背景按钮针对hover、click有不同效果。原创 2023-08-13 21:40:32 · 297 阅读 · 0 评论 -
Hazel游戏引擎(104)目前不做3D+2D要做的
2D游戏引擎规划原创 2023-08-13 21:39:27 · 704 阅读 · 0 评论 -
Hazel游戏引擎(103)实体的材质
前前言由于开发引擎,渲染是一部分,所以前期跳过了给实体附加材质功能,从而开发其它比较重要的部分,其它基础功能写好后,再回到渲染部分写好渲染代码是正确的选择。由于2D和3D的纹理不一样,所以要设计一个好的纹理系统目的为完成101节所说的拖动内容面板上的材质给实体,实体表面会显示这个材质如何实现同102节实现拖动场景文件到viewport视口一样只需要在实体的属性面板上设置数据源目标接受拖过来的文件路径然后加载这个材质,再drawcall绘画出来。原创 2023-08-13 21:37:03 · 389 阅读 · 0 评论 -
Hazel游戏引擎(102)内容面板和ImGui拖放+Icon
此节目的为完成101所说的,拖动材质赋予实体,需先完成拖动这个功能,因为项目已经有打开场景函数,所以此节完成拖动场景是否能打开场景。如何实现使用ImGui的Api实现细节看后面的Bug合集最主要的是:PushID区分不同按钮在ImGui_Demo.cpp中可以看到拖动代码如何实现的。原创 2023-08-13 21:36:07 · 615 阅读 · 0 评论 -
Hazel游戏引擎(101)内容面板显示资源文件和文件夹
前前言Cherno改变视频方式,就是用直播方式来做接下来的视频,而不是先在直播前想好写好,再录制另一个视频用来Copy和解释直播写的代码。此节目的为了实现quad有纹理,要实现像Unity那样拖动纹理的文件 到 实体的组件下就能生成纹理组件。此节为完成此目的,需先完成显示本地assets文件夹下的文件夹和文件。如何实现用ImGUI渲染由C++的fstream检索处理的文件和文件夹。参考C++的fstreamAPI网站。原创 2023-08-13 21:34:08 · 216 阅读 · 0 评论 -
Hazel游戏引擎(100)Vulkan、SPIR-V和新Shader系统
前前言Cherno未来想做的当前项目以后Cherno打算支持vulkan,由于vulkan着色器代码也支持glsl语言,但是和Opengl的glsl标准不一。因为Vulkan中存在OpenGL的不存在的东西(反之亦然),所以着色器代码肯定不同。vulkan和opengl的glsl对比-以Uniform为例主要不同在于,opengl支持uniform,vulkan不支持uniform,而是支持uniform缓冲区(push_constant、存储缓冲区)这比OpenGL的glsl更好。原创 2023-08-13 21:33:10 · 849 阅读 · 0 评论 -
Hazel游戏引擎(099)点击选择实体
前情提要由上节已经可以读取当前鼠标位置所在实体围成的像素在缓冲区的实体ID值此节目的鼠标点击实体,会出现gizmos,并且可以拖动什么的如何实现使用点击事件(事件系统)设置hierarchy面板哪个实体被选中实现过程中出现的Bug拖动gizmo移动一个实体与另一个实体重叠时停下,且另一个实体在当前实体上面,再点击gizmo想移动原先实体,那么会获取在上面另一个实体的实体ID,即另一个实体会被选中,会切换gizmo。显示了gizmo,但是若按下leftalt拖动旋转摄像机,则gizmo会消失。原创 2023-08-13 21:30:23 · 144 阅读 · 0 评论 -
Hazel游戏引擎(098)获取当前鼠标所在的实体的ID
前情提要由097节已经可以读取鼠标位置的颜色缓冲区的值,但是quad的范围读取的值是一个固定的50数字此节目的读取quad实体内的像素在第二个缓冲区的值,会返回当前实体的ID如何实现见095的思路二中讨论的,在顶点缓冲布局中添加实体ID,这样每个顶点都有一个自己的EntityID值,再将这个ID值作为第二个缓冲区像素的颜色值,这样就可以成功在当前实体里的每个像素都有这个ID值实现细节重载DrawQuad的API以及相关代码考虑性能。原创 2023-08-13 21:29:11 · 153 阅读 · 0 评论 -
Hazel游戏引擎(097)用固定值填充帧缓冲的附加缓冲区
前情提要由上节已经可以读取鼠标位置的颜色缓冲区的值但是当读取不是quad的范围的值是一个奇怪的数字是因为cpp代码中使用了glClearColor(color.r, color.g, color.b, color.a);将缓冲区默认填上了颜色这个颜色本来是float值,转换为int读取出来则是奇怪的数字此节目的读取不是quad的范围的值返回特定的**-1**值如何实现使用新的OpenGL函数,用特定值填充缓冲区实现细节。原创 2023-08-13 21:28:16 · 125 阅读 · 0 评论 -
Hazel游戏引擎(096)为鼠标拾取帧缓冲的数据做准备
此节目的上一节已经显示了帧缓冲第二个颜色纹理缓冲的颜色这节需要把帧缓冲第二个缓冲区改变类型,为有符号整形对应实体ID。并且需要增加获取当前鼠标在viewport视口的相对位置,然后读取鼠标位置像素的**帧缓冲中第二个缓冲区(渲染目标)**的数据。如何实现修改帧缓冲第二个缓冲区类型利用上一节已经封装好了的OpenGlframebuffer,只需简单的设置为鼠标在viewport视口的相对位置鼠标的绝对位置是:当前位置距离整个屏幕**左上角(0,0)**的位置鼠标的相对。原创 2023-08-11 23:19:50 · 220 阅读 · 0 评论 -
Hazel游戏引擎(095)多个渲染目标和帧缓冲类修改
要实现什么完善093节的Gizmos,点击场景的物体,即会显示gizmos,而不用点击hierarchy的实体才会显示。实现思路光栅化输出到界面有每一个像素对应的实体ID(这节要实现的)实现要求 (下几节要实现的)设计鼠标点击屏幕将鼠标坐标转换实现能采样当前像素的值,从而得到对应hierarchy中对应实体的ID。此节要完成由下面的思路三得出:修改和优化帧缓冲类,能附加多个不同类别缓冲区。使得帧缓冲区可以附加两个颜色纹理,实现一个渲染通道有两个渲染目标,并且imgui可以显示出第二个。原创 2023-08-11 23:17:01 · 249 阅读 · 0 评论 -
Hazel游戏引擎(094)编辑时的摄像机
目的实现像Unity编辑时有一个编辑摄像机呈现画面给开发人员,运行时有一个主摄像机呈现游戏画面给玩家。如何实现使用Cherno写好的EditorCamera类实现细节编辑时摄像机是透视投影摄像机编辑时摄像机缩小不会透过实体,这样更简单实现编辑时摄像机越接近实体,它的放大范围越小。原创 2023-08-11 23:15:46 · 239 阅读 · 0 评论 -
Hazel游戏引擎(093)变化Gizmos
目的为实现像大多3D软件那种,点击物体,会有那种拖动、缩放、旋转的辅助小程序。如何实现利用开源的imguizmo库,网址介绍imguizmoImGizmo是一个建立在Dear ImGui之上的小型(.h和.cpp)库,允许你操作(目前是旋转和平移)4x4浮点矩阵,没有其他依赖性。编写时考虑到了即时模式(IM)的理念。gizmos实现小点平移、缩放、旋转可以用快捷键切换可以像Unity一样设置每次移动或者旋转的量,snap。原创 2023-08-11 23:11:01 · 363 阅读 · 0 评论 -
Hazel游戏引擎(092)保存和打开场景对话框
前一节的bug多次加载场景,不会清空当前场景,会将新场景的实体和当前场景的实体一起呈现此节目的可以有询问对话框保存、解析场景新场景:不绘制的实体,创建一个空白的场景保存场景:有对话框,问保存到本地哪个位置加载场景:有对话框,从本地哪个位置加载场景,重新创建新场景即可解决上一节的bug实现细节Cherno说对话框不应该依赖ImGUI库。原创 2023-08-11 23:09:34 · 163 阅读 · 0 评论 -
Hazel游戏引擎(091)保存和加载场景、序列化场景、Yaml使用
目的如此节标题,为了实现像unity那样保存场景到本地和从本地加载场景的功能原理这功能其实就是将场景的实体和组件用文本信息保存起来,加载场景的话就是读取文本信息,根据文本存储的信息,创建实体并且设置组件和组件数据。用什么存储和解析技术实现用yaml存储和解析yaml。使用第三方库yaml,将为其写premake文件融入到项目中,使用这个库的存储和解析功能。地址为什么不用其它格式存储二进制虽然有保护性,但是阅读困难对引擎开发人员来说JsonCherno说它的格式{},会漏掉{}括号,原创 2023-08-11 23:07:36 · 286 阅读 · 2 评论 -
Hazel游戏引擎(090)让界面变得好看,C++模板类型如何推断
此节目的更换字体按钮字体加粗调整布局控制最小宽度界面颜色用模板函数去除重复代码如何实现ImGui的Api。原创 2023-08-11 23:05:42 · 265 阅读 · 0 评论 -
Hazel游戏引擎(089)添加删除实体和组件
目的此节需要完成像Unity那样右键实体可以弹出菜单可以删除实体,右键空白地方可以弹出菜单添加实体在属性面板显示实体的组件,有添加组件按钮,点击弹出菜单项可以添加相应组件。在属性面板显示实体的组件,每个组件的下拉有按钮,点击弹出菜单项可以删除这个组件有点需要注意给实体添加摄像机组件后,并不会立即显示画面,因为投影矩阵的aspect ratio宽高比是0,投影矩阵无,所以应在添加摄像机实体的时候就设置当前视口的宽高比,从而计算投影矩阵。原创 2023-08-11 23:03:40 · 204 阅读 · 0 评论 -
Hazel游戏引擎(088)Tranform组件UI
此节目的点击实体,在属性面板显示实体的Transform组件的位置、缩放、旋转属性。对UI有要求文字需在左边,属性按钮在右边x不是label,而是按钮且带有颜色,且点击按钮可以复原值。如何实现照样087那样,点击实体,检测是否有Transform组件,再将值传入ImGUi上绘制。原创 2023-08-11 23:01:14 · 220 阅读 · 0 评论 -
Hazel游戏引擎(087)Drawing组件UI
此节目的点击实体,在属性面板里显示这个实体的组件的属性,应包括颜色、texture、shader什么的(纹理),但目前先只显示颜色如何实现同86 85节,只需判定是否有这个组件,然后传入ImGui的Api中。原创 2023-08-11 22:59:09 · 211 阅读 · 0 评论 -
Hazel游戏引擎(086)Camera组件UI
此节目的在属性面板上实现点击摄像机实体,属性面板显示摄像机实体的摄像机组件参数。修改摄像机的参数,摄像机会做出相应的显示。给摄像机添加透视投影类型。如何实现使用ImGui的API使用glm::perspctive()来计算透视投影矩阵。原创 2023-08-06 23:21:54 · 267 阅读 · 0 评论 -
Hazel游戏引擎(085)属性面板
此节目的写出像Unity点击Cube,会显示一个Inspector面板,上面显示Cube的所有组件:transform、Mesh等。实现思路在上一节SceneHierarchyPanel类的基础上,根据保存当前点击的哪个实体,传入这个实体的组件值进ImGUI的UI上。原创 2023-08-06 23:20:35 · 310 阅读 · 0 评论 -
Hazel游戏引擎(084)场景Hierarchy面板
此节目的给引擎添加hierarchy界面面板,显示当前场景存活的实体如何实现用ECS遍历当前场景的实体,用imgui显示小提示用ImGui::ShowDemoWindow();可以看想要的UI代码。原创 2023-08-06 23:19:28 · 277 阅读 · 0 评论 -
Hazel游戏引擎(083)优化原生C++脚本(虚函数和函数指针)
提示此节和082节内容差不多这节目的将上一节在NativeScriptComponent写的function执行的功能替换为虚函数(OnCreate、OnUpdate、OnDestroy)和函数指针为什么之前的视频有讲过,有人在GitHub给cherno提意见说虚函数降低性能,所以上一节他刻意避免了使用虚函数,但是这节他说虚函数并不会降低太多性能,而且在引擎很多类都写了虚函数。使用函数指针是因为不用function使得代码更简洁。原创 2023-08-06 23:18:04 · 348 阅读 · 0 评论