FTGL库初步剖析

来源:互联网 发布:哪个软件购票方便 编辑:程序博客网 时间:2024/05/29 13:02


ftgl库是一个跨操作系统平台的在opengl下用来渲染文字的开源库,其内部使用了freetype2库来处理字体相关,采用面向对象的编程风格,提供这种方式渲染文字,包括:bitmap方式、texture方式、polygon方式、ouline方式、extrude方式、pixmap方式、buffer方式,各种方式解释如下:

bitmap方式:先得到字形的位图数据,再使用glBitmap来绘制文字

pixmap方式:先得到字形的位图数据,使用glDrawPixels来绘制文字

buffer方式:先得到字形的位图数据,将文字绘制到buffer中,而不是显示到屏幕

texture方式:先得到字形的位图数据,且将该字体的所有字形位图数据生成一张纹理,存入纹理的alph通道,每个文字对应一个格子区域,该格子的坐标就是文字的纹理坐标,在绘制文字时,通过绘制一个四边形来渲染文字,将纹理贴到该四边形上,文字就显示出来。

polygon方式:针对矢量字体,使用freetype2得到轮廓信息,将轮廓转为mesh绘制。

outline方式:针对矢量字体,使用线框方式绘制轮廓,与polygon的区别是不填充内部。

extrude方式:针对矢量字体,将轮廓拉伸绘制为3D文字。


ftgl库中最主要是font系列类和glyph系列类,前者表示字体,后者表示一个字形,外部使用只需知道font类。对应上述各种不同的绘制方式,有不同的font类和不同的glyph类。由于作者使用了imp模式,font系列类的每一个子类又有一个对应的Imp类,字形系列类的每一个子类也同样有一个对应的imp类。不得不说一下这种模式,模式的使用使代码看起来非常费劲,这2族类的关系复杂,既有派生继承关系,又有接口实现关系,也就是说既有上下关系,又有平行关系,而且很多逻辑联系非常紧密的代码被分割到不同的类中,造成逻辑在类之间大距离的跳跃,实在是把问题复杂化了,很难认同这种过于看重模式的风格。

看一个FTBitmapFont的构造函数,其任务就是根据参数中的文件路径名,加载字体文件,实现过程:构造一个实现类FTBitmapFontImpl的对象,把该对象保存到父类的指针,在FTBitmapFontImpl的构造时,将字体路径传给父类FTFontImpl的构造函数,FTFontImpl再调用FTFace来真正加载字体文件,这个过程如下:

FTBitmapFont构造---->实现类FTBitmapFontImpl的构造----->实现类的父类FTFontImpl构造---->实现类父类子对象FTFace的构造---->利用FTFace加载字体文件

这一圈子绕的够大。


再看一个构造字形的过程, 函数入口:FTBitmapFont::MakeGlyph(FT_GlyphSlot ftGlyph),该函数根据一个freetype2的字形,返回一个ftgl的字形,调用过程如下:

FTBitmapFont::MakeGlyph---->FTBitmapGlyph构造--->FTBitmapGlyphImpl构造---->使用freetyp2取字形并转换


渲染过程,以纹理字FTTextureFont为例,Render方法在其父类FTFont中,所以从FTFont开始:

FTFont::Render--->纹理字实现类FTTextureFontImpl::Render---->子类的父类FTFontImpl::Render---->字形接口类FTTextureGlyph::Render---> 字形实现类FTTextureGlyphImpl::Render,才是最终的渲染。

一会是父类,一会是子类,一会是实现类,一会是接口类,一会是字体类,一会跳到字形类,这种炫技式的模式论,TMD, 坑爹!









0 0