没想到这个问题搞了快2个月时间;当然跟我只是断断续续地工作有关。

FTGL是freetype的opengl实现。我接触FTGL最初只是为了练习OpenGL,写几个简单的游戏app。开始试了试FTGL觉得挺简单好用,不需要太熟悉OpenGL底层的东西,于是决定在自己的一个app中正式加入用FTGL显示艺术True type字体的功能,预计应该很快能完成吧。

开始进展很顺利,似乎即将大工告成,结果最后突然发现一个问题:艺术字体(中文)显示若干段落以后,突然渲染不正常,总是显示一些混乱的字符;排除了应用逻辑错误以后,确定是FTGL库的问题,就此开始了漫长的调试过程。

我对OpenGL很不熟悉,前两个月由于另外一个项目中用到一点GL,看了点开发文档,弄完后其实也没打算要深入研究。没想到现在碰到这种问题,放弃又不甘心,为了调试FTGL库,不得已开始投入点精力开始研究GL。

尝试了一些跟踪后,出错的大致原因清楚了:我大概是运气太好,一开始就选用了FTTextureFont. FTGL显示Texture字体时,首先从ttf文件中创建face,根据用户要显示的字符串,读取face中的glyph,然后生成bitmap,这个bitmap没法保存在内存里,所以FTGL会把这些bitmap都一个个写到GPU的一张texture里面。问题是texture大小总是有限的,所以FTGL支持多个texture,即一旦一个texture被写满了以后,就创建一个新的texture,直到用完GPU内存。而我碰到的问题就在前一个texture被写满,创建一个新的texture之后,字符显示开始混乱;

但是我还是觉得这个问题很奇怪:FTGL库是个很老的库,并且据我查过开发版本这个支持多texture的功能在2010年的时侯就支持了,难道这么多年我是第一个碰到这个bug的人吗?FTGL库看代码作者水平还是比较高的,这个bug难道他没有测试发现吗?

没办法,搜了好几天除了有一个哥们在某个论坛提到过一句类似的情况,就再也没有任何线索;而且这个哥们居然很认命地就把这个问题当作FTGL固有的限制,毫无一点反抗的意图,居然建议改用PolygonFont或BufferFont:-(

仔细研究了几天FTGL的代码,横看竖看看不出问题;是iOS移植的问题?是iPhone硬件的限制?还是缓存的问题?猜测过各种错误原因最后都证明不靠谱;今天下午被另外一则坏消息狠狠打击了一下之后,脑袋灵光一闪,突然想到啊,莫非是这样?。。。

果然还是FTGL作者添加multiple texture支持时,考虑欠周到,测试估计也没做(其实是个挺明显的bug,但凡测试用例覆盖就会暴露);由于多个texture的存在,FTGL渲染时需要在多个texture之间切换时,没考虑到一个字符串里不同的字符的bitmap缓存可能位于不同的texture里,还是用了同一个texture做渲染,自然会出问题了。

考虑两种方法修改,一是采用multitexturing技术,这个听起来应该会比较酷,性能应该好点,但是要比较多时间;另外就是把原来一个字符串作为单位渲染改为逐个字符渲染,性能不一定好,不过就2行代码解决问题啦,自然就先这么干,以后有时间再做计较吧 :-)

iOS上用FTGL显示定制Truetype字体碰到的问题的更多相关文章

  1. 图像处理---《在图片上打印文字 windows+GDI+TrueType字体》

    图像处理---<在图片上打印文字  windows+GDI+TrueType字体> 刚开始使用的是putText()函数做,缺陷是只能显示非中文: 接着,看大多数推荐Freetype库来做 ...

  2. iOS在一个label中显示不同颜色的字体

    UILabel *Label = [[UILabel alloc] initWithFrame:CGRectMake(20, 300, 300, 30)]; NSMutableAttributedSt ...

  3. SpriteBuilder添加的TrueType字体未显示在log中的原因分析

    按照书上的说法,在SpriteBuilder中添加的TrueType字体名称会在枚举字体方法显示的log中出现.但是运行程序后没有在log中发现对应的字体名称. 因为该字体是例子中作者制作的,所以字体 ...

  4. NSMutableAttributedString iOS 在UILabel显示不同的字体和颜色(转)

    在项目开发中,我们经常会遇到在这样一种情形:在一个UILabel 使用不同的颜色或不同的字体来体现字符串,在iOS 以后我们可以很轻松的实现这一点,官方的API 为我们提供了UILabel类的attr ...

  5. vue中解决时间在ios上显示NAN的问题

    最近在用vue,遇到倒计时在ios上显示为NAN的问题. 因为做的是倒计时支付,思路是获取服务器时间和下单时间,再转成秒级时间戳做差值. 在网上找到说是ios 不支持例如2018-09-01 10:0 ...

  6. ios上 更改 状态栏(UIStatusBar)

    摘要 ios上 更改状态栏(UIStatusBar)的颜色 ios UIStatusBar statusBar 状态栏 更改状态栏颜色 目录[-] IOS上 关于状态栏的相关设置(UIStatusBa ...

  7. IOS上 关于状态栏的相关设置(UIStatusBar)

    知识普及 ios上状态栏 就是指的最上面的20像素高的部分 状态栏分前后两部分,要分清这两个概念,后面会用到: 前景部分:就是指的显示电池.时间等部分: 背景部分:就是显示黑色或者图片的背景部分: 如 ...

  8. [开源]在iOS上实现Android风格的控件Toast

    [开源]在iOS上实现Android风格的控件Toast iOS的风格和Apple其他产品一样,简单而粗暴.没有给人其他选择的余地,让你又爱又恨.同样的,Apple对待iOS平台的开发人员和对待大众消 ...

  9. ios上 更改 状态栏(UIStatusBar)的颜色,你值得一看、收藏

    IOS上 关于状态栏的相关设置(UIStatusBar) 知识普及 ios上状态栏 就是指的最上面的20像素高的部分 状态栏分前后两部分,要分清这两个概念,后面会用到: 前景部分:就是指的显示电池.时 ...

随机推荐

  1. AspxGridView 主子表设置

    AspxGridView主子表(master-detail)设置共分3步: 第1步: 设置主表允许其显示 DetailRow 放置主GridView到页面, 取名"grvList" ...

  2. 十二、Android UI开发专题(转)

    http://dev.10086.cn/cmdn/bbs/viewthread.php?tid=18736&page=1#pid89255Android UI开发专题(一) 之界面设计 近期很 ...

  3. part 2 Angular modules and controllers

    What is a module in AngularJS? A module is a container for different parts of your application i.e c ...

  4. JQuery、js判断复选框是否选中状态

    JQuery: var $isChecked = $("#id").is(":checked"); alert($isChecked); JS: var $id ...

  5. oracle 数据库导入导出

    要把公司的数据库导入到自己的电脑上(都需要再命令窗口下输入指令) 导出数据库的基本代码: exp zj_user_kf/oracle@tzsw_4 file=d:\test3.dmp full=y 导 ...

  6. Silverlight引用WebService时取消对ServiceReferences.ClientConfig文件的依赖

    做过Silverlight项目的朋友都知道一般来说我们在Silverlight项目中都需要引用WebService或是WCF,引用的方式是在Visual Studio窗口中通过“添加服务引用”来添加引 ...

  7. POJ 2499 Binary Tree

    题意:二叉树的根节点为(1,1),对每个结点(a,b)其左结点为 (a + b, b) ,其右结点为 (a, a + b),已知某结点坐标,求根节点到该节点向左和向右走的次数. 分析:往回一步一步走肯 ...

  8. SQL2008、SQL2013 执行Transact-SQL 语句或者批处理时发生了异常。错误5120

    附加数据库的时候遇到问题,问题描述如下: 附加数据库 对于 服务器"服务器名"失败.(Microsoft.SqlServer.Smo) 执行Transact-SQL 语句或者批处理 ...

  9. centos6.5安装flume

    这里安装flume是因为游戏业务日志搜集和分析用的 1.安装java 环境rpm -ivh jdk-8u51-linux-x64.rpm Preparing... ################## ...

  10. 1.servlet hello实例---HelloServlet

    1.用url调用servlet 建 web project “HelloServlet”,在src下建包com.amaker.servlet,在包下建HelloServlet.java. packag ...