中美冲突一直加剧,再来挖个坑玩备胎。
很多年没有从c++层面开始折腾了,打算重新捡起来,搞一个跨平台的游戏引擎,对了,没错,就是对标那个UnityEngine。
万一哪天美国把U3D也给ban了呢,这可能性不大,权当个笑话,主要是折腾一下细节,自己动手,其乐无穷。
U3D有些很有意思的特性,我想自己去实践一下,自己动手其乐无穷。
比如,跨平台的渲染能力。
跨平台不是什么的神秘的特性,无外乎两个关键词,一是抽象,二是抽象。
只要抽象出共性的接口,分别实现各个平台就可以实现跨平台。
Unity的跨平台体现在两个方面,用户逻辑(c#脚本)和渲染
用户逻辑Unity是通过mono和IL2CPP去实现的跨平台,il2cpp总感觉怪怪的,我尝试使用dotnet5 去实现逻辑的跨平台(dotnetcore+xamarin)
渲染的跨平台,unity应该是自己实现的吧,我们可以简单的把他分成
1.渲染api的跨平台
2.shader的跨平台
3.高级渲染功能的跨平台
三个部分来考虑
其中3是业务,只需要跨平台编译就完了。
1.渲染api的跨平台unity应该是自家代码,有一个现成的开源项目bgfx就专注在这件事情上。所以他是可替代的。
2.shader的跨平台Unity也应该是自家代码,写cg,交叉编译去兼容各种平台,微软也有一个相似的开源项目ShaderConductor专注在这件事情上,他也是可替代的。
另外还有一点,Unity有一个对扩展很友好的Editor,当然Editor也是跨平台的,并且它使用IMGUI这种状态和逻辑混合的UI系统,确实在编写UI上简化很多。
UnityEditor跨平台主要是基于Mono,我们可以用net5替代他
UnityEditor还有一个很重要的特点是改脚本无需重启,或者说脚本的热加载,这也是效率的重大来源之一,UnityEditor用Embmono 来实现,这个东西在NET5 里面也有ALC可以实现。
分析下来Unity重要的这些特点,都有开源项目在,缺乏的是一个整合,那就不会太复杂,让我们开始学习BGFX
一、BGFX的编译
他有一个专门build的页面
https://bkaradzic.github.io/bgfx/build.html
但是内容有点多,我来总结一下吧。
我现阶段,只想要windows下折腾折腾
1.代码获取,bgfx 是由三个仓库构成的,
git clone git://github.com/bkaradzic/bx.git git clone git://github.com/bkaradzic/bimg.git git clone git://github.com/bkaradzic/bgfx.git
我在图中这个时间点,抓了这三个仓库
注意要把他们的目录并排放置,他们之间的文件引用就这么暴力
2.vc 项目生成
他有一个genie工具,exe就在仓库里,你直接调用就能生成项目文件
cd bgfx
..x oolsinwindowsgenie --with-examples vs2019
但是生成的项目文件很扯淡,默认sdk版本是8,你如果像我装最新的vs2019肯定是没有的,自己改一下就行。
编译比较顺利
编译完你可以自己跑跑demo,接下去你需要这些文件
二、第一个bgfx例子
c++很讨厌的一点是没有像样的库的概念
先要组织头文件和库文件
头文件分散在 bgfx bx bimg 三个项目的include目录里,你自己配置路径也行,copy到一起也行,毕竟c++的include就是个字符串替换而已。
vc++编程,这个运行库要注意一下,最好从头到尾全一样。
链接库全套
好了,基本环境折腾完,我们可以来谈代码了。
第一个真正真正的helloworld,我们不谈shader,不谈顶点,我就要个clear。看看bgfx怎么初始化,怎么开始画出颜色。
此时你最好拥有某一种图形api的基础,毕竟跨平台的核心是抽象和抽象。虽然抽象出接口,大体的思路还是一样的。
这是这个程序的样子
trace就是简单的实现了一个log,你可愿意忽略他
winmain是一个标准的消息循环,插入了 oninit onupdate onexit 三个事件,改成了peekmessage机制
消息处理函数,只处理了窗口关闭和改变大小,改变大小处理了onresize事件。
所有的图形系统的基本接口,都可以归为这四个
onInit 初始化
onUpdate帧处理
onExit 结束
onResize屏幕分辨率改变
OnInit包括了BGFX初始化所需的四个必要操作
1是SetPlatformData,在windows来说是绑定到一个窗口,当然你服务器用,也可以不绑。
2.是Init,这里打开了垂直同步和自动选择渲染器,在windows上可以用 dx9 dx11 dx12 opengl vulkan等,自动选择 他有个打分系统,在我的电脑上自动选择的是dx11
3.是设置ClearColor 我选择了错误专用粉红色 ff00ff
4.是设置viewport,这里用窗口大小
OnResize 在窗口尺寸变化时发生,reset 的功能是改变Backbuffer尺寸,他是最终输出的buffer,没有特殊情况,一般都是和窗口分辨率相等。如果backbuffer和最终window不一样大,会被硬件拉伸,这个拉伸就是个线性插值。
然后也更新下viewport。
onUpdate 每帧发生
这里touch就是个空提交,保证会干点啥,要不然bgfx在啥也没画的情况下,连clear都不会做。
frame()就会执行提交,真的画出东西来。
onExit退出时执行。
然后这一切都搞对了,你的跨平台渲染第一步就跨出来了。