近期在 bgfx 上做的一些工作
这段时间玩 bgfx ,除了前段公布的 lua binding 外,还颇做了一些别的工作。
首先是帮 bgfx 的 directx 12 driver 打了补丁,使之可以用 mingw build 出来正确运行。也就是之前 blog 上提到的 Direct3D12 的接口设计 bug 。这个 pr 已经被官方接纳。
然后是我给 bgfx 的 debug text 做了中文的支持。 bgfx 专门做了一个层,模拟 VGA 的 text mode 。一开始我学着过去 dos 模式下做中文系统的方式增加了双字节支持,采用在模拟出来的 video memory 的 attribute byte 上设置几个特殊标记来表示接下来的两个 slot 是连起来的一个 unicode 字符。
这种让一个汉子占据两个 video memory slot 的方式在过去非常常见,不过弊端也很明显:容易产生半个汉字乱码问题,解决方案看起来比较 trick 。而且把汉字作为一种特殊字符来处理,而不是彻底解决 unicode 大字符集的解决方案感觉也很不美观。
接下来我花了一点气力实现一个更加通用的 unicode 方案:
至少要支持多个 code page , 并把原本就支持的 dos 字符集当作 cp437 ,而可以由使用者执行添加新的 codepage ,比如汉字所用的 cp936 。再将不同的 codepage 统一转换为 unicode 。我为多 codepage 编写了一个简单的查找 cache ,字形贴图管理的新模块。cp936 里用到 15 点阵汉字字形是从文泉驿黑体中导出的。另外为了更好的支持 unicode ,把 virtual video memory 里保存 codepoint 的单字节扩展为 3 字节,可以把单个汉字放在一个 slot 里。不过,为了排版正确,还是需要在 debug print 的 api 中检测到汉字就在每个汉字后保留一个空格,让单个汉子占两个英文字符的位置。
这个 patch 现在可以在 bgfx 里使用 ,不过尚未合并到主干。看起来作者也没有拒掉,目前还留在 open 的 pr 列表中。
bgfx 的跨平台 shader 采用了一种奇特的方案。它基本保留了 opengl shader 的语法,仅用 C 风格的预处理语言做了跨平台处理。换句话说,就是用程序加上一堆宏替换和 #ifdef 。这种方法仅仅是利用 cpp 这样的工具就可以了。
不过 bgfx 引入的一个第三方 cpp 工具只能从文件系统处理文本,不能从内存加载文本。所以 shader 的编译流程是一个独立的用 C++ 编写的工具,而没有一个运行时的库。这对于本身基于 C/C++ 开发时不太所谓,反正都有构建流程,无非是让 shader 也进入构建工具链而已。
但如果是用动态语言开发,就麻烦了很多。所以我花了两天时间用 lua 重写了这个 shader 编译工具,采用了一个纯 lua 版本的 cpp 库来做预处理。github 仓库在这里。
目前后端编译部分只接了 opengl 尚没有支持 directx ,暂且够用吧。
用 lua 重写的好处是,lua 的文本处理比 C/C++ 强了太多,重写的代码虽然只改了部分,但也清晰了许多,便于维护。现在 shader 也可以直接 runtime 加载了,可以更方便的做 demo 。
bgfx 的作者似乎不太喜欢用动态语言做 runtime 库,但他有计划用 C++ 重构这部分代码,争取把 shader 编译过程做成库可以运行时加载。有这样的预期,我也就没太多兴趣跟进我这个项目了。
btw, 我这里用到的 lua 版 cpp 挺多 bug 的,我边用边改。它似乎是个死项目,提 pr 也没人搭理,只好 copy 过来用,而没有做引用。
Comments
Posted by: abc | (2) November 6, 2017 01:07 AM
Posted by: Ian | (1) November 5, 2017 10:52 PM