V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
codehz
V2EX  ›  分享创造

用 C++撸了一个 Minecraft 字体贴图生成器,发现 Minecraft 解决文字输出问题挺 6 的

  •  1
     
  •   codehz ·
    CodeHz · 2016-10-05 23:13:56 +08:00 · 4725 次点击
    这是一个创建于 2766 天前的主题,其中的信息可能已经有所发展或是发生改变。

    源码仓库地址

    (仅支持 Linux ,特别地,也支持 Bash On Windows )

    Minecraft 渲染 Unicode 文字的思路是把0x000000000xFFFFFFFF的每个文字都做成材质贴图,按照高 16 位进行分割,形成assets/minectaft/textures/font/unicode_page_ff.png这样的图片,每个文字都是方格的;

    为了解决文字宽度不同的问题,设置了一个文件(assets/minecraft/font/glyph_sizes.bin)来保存对应图像的水平坐标区间,采用一个字节来保存(高 4 位保存 xMin ,低 4 位保存 xMax ,当然精度方面也就只有 4 位了,但是考虑到 mc 的马赛克性质,确实足够用了),这些字节直接按照 Unicode 值作为文件中位置。

    这种方法的确不是完美方法,因为 Unicode 中的好多特性都不能实现(比如 RTL ,组合字符等等)——但是,对于一款游戏而言,这种处理可以说是比较好的了。

    研究完原理之后,我就直接手撸了一个字体材质生成器——当然不是直接生成.zip形式的字体包,不过也差不多了,只需要指定输出文件(glyph_sizes.bin)和材质输出目录就可以输出,如果需要打包成材质包的话,还需要补全目录结构和pack.mcmeta文件。

    • 生成配对的glyoh_sizes.bin文件,以支持非等宽字体。
    • 支持多进程同时生成(-t 参数指定的是产生的子进程,所以是总进程数-1 )。
    • 支持 2 种渲染模式( LIGHT 模式和标准模式,名字来源于 FreeType2 的渲染参数。

    注意:没有禁止超高分辨率图像的生成,所以可以生成超出 Minecraft 渲染极限的材质——显然大于等于16384x 的材质包是没有意义的(除了用于测试电脑性能)。

    效果预览:( Inziu Iosevka SC 字体, 1024x ) 效果预览


    PS:显然采用类似技术输出 Unicode 文字的游戏应该挺多的,但是想不通为啥都 2016 年了,还有好多游戏中文显示不了的(不说输入问题了,就说输出的),然后想到 ASCII 总共才 256 个字符,差不多就想通了。。。。。

    9 条回复    2016-10-09 18:56:52 +08:00
    bao3
        1
    bao3  
       2016-10-06 03:33:54 +08:00 via Android
    买了游戏,却一直没有入门的路过,打算申请退款去
    Arthur2e5
        2
    Arthur2e5  
       2016-10-06 09:27:16 +08:00
    东西不错,加个 1 。(要是把输出文件找个 releases 挂着做个懒人包就更棒了(x))

    > 因为 Unicode 中的好多特性都不能实现

    叫做 UCS 就好了(小声)

    > 还有好多游戏中文显示不了的

    嘛,字太多,没必要特地去设计放进去……
    语言设定里面有个 Force Unicode Font 的设定会把你全都搞进系统字体(以及你设置的这个字体?),大概也有点信任系统没眼瞎的意思吧。(笑
    话说这个字体材质的话有加粗这回事吗?我看别人 Linux 上跑的 Minecraft 截图,遇到加粗字体文泉驿会有描边……

    > 想到 ASCII 总共才 256 个字符

    不不不和编码完全没关系,真的就是懒的事。你看 minecraft 默认字体显示 naïve 是不是很正常啊。
    codehz
        3
    codehz  
    OP
       2016-10-06 12:45:11 +08:00
    @Arthur2e5 字体输出放 release 有版权问题。。。。
    加粗的问题可以通过微调 glyoh_sizes.bin 来解决。。。不过我这个自动生成的 glyoh_sizes.bin 已经覆盖大多数情况了(我不会说对于部分有问题字体,把字体大小调低,保持单元大小不变就可以解决一大半)

    有些蜜汁字体(特指拉丁字母那一坨),会出现超出方格的情况。。。。设置 16px 大小硬是给塞进 20px 的字体——所以我就把字体大小和单元格大小分离成两个参数了
    codehz
        4
    codehz  
    OP
       2016-10-06 12:49:42 +08:00
    @Arthur2e5 刚似乎理解错加粗的意思了。。。加粗完全由 minecraft 处理(而且没有选项自定义),所以如果要好一点的加粗效果,只能找适合的字体,没有专门的加粗字体贴图(也没有倾斜字体贴图,更不会有下划线字体贴图,别说删除线了。。。。)
    没下划线贴图这一点比较坑,由于某些字体基线的锅,经常出现下划线错位的情况
    codehz
        5
    codehz  
    OP
       2016-10-06 21:01:43 +08:00 via Android
    网页版也快出了 2333333 到时候新发一帖说好了
    Arthur2e5
        7
    Arthur2e5  
       2016-10-09 14:13:03 +08:00
    @codehz 自由字体放 release 不就好了( x
    codehz
        8
    codehz  
    OP
       2016-10-09 18:55:08 +08:00 via Android
    codehz
        9
    codehz  
    OP
       2016-10-09 18:56:52 +08:00 via Android
    @Arthur2e5 啊,不对,这个是网页版生成的。。。这个才是 c++版本的。。。。。体积差距明显。。。。
    http://www.mediafire.com/file/1kbbohojumdr1b7/Inziu_Iosevka_SC_x1024_only_unicode.zip
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1043 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 18:01 · PVG 02:01 · LAX 11:01 · JFK 14:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.