LOG.ZS.0001.基於Freetype的遊戲字體渲染優化思路

 

Totalhtml

Utf8-ucs2ios

Html_parse算法

Layoutsql

Render_string瀏覽器

Init_texture緩存

Ft_load_glyphapp

原始函數

2293佈局

1性能

26

708

1556

2

1403

 

 

 

 

 

 

 

 

 

上表用於記錄優化各步驟的消耗時間。

生成的文本紋理,文本是加州賓館的全歌詞。

原始版本整個紋理的生成耗時2300毫秒左右,能夠看到實際是慢得髮指。

究其緣由,是因爲實現iron引擎的時候未進行任何性能方面的考慮。

上述時間表的構成:

total : 總消耗時間

utf8-ucs2: 將utf8字符串轉換爲ucs2的時間

html_parse : 引擎須要支持必定程度的富文本,因此須要支持簡單的html解析.

render_string: 將字符串轉換爲紋理所消耗的總時間

Ft_load_glygh : 在整個過程當中, 調用Ft_load_glygh 消耗的總時間。

 

由以上分析可知,最消耗時間的調用是Ft_load_glygh。

尚不知道爲何Ft_load_glygh消耗的時間這麼大,原覺得是由於每次Ft_load_glygh會到文件中去查詢加載具體字符數據,而將程序改形成從內存加載字庫數據,仍然耗時巨大。

若是freetype自己沒法優化,那麼就須要從其餘方向來考慮這個問題。

 

首先從新闡述一下字體渲染的需求:

(1) 常規的字體屬性須要支持,如font_size

(2) 可以爲字體指定邊框顏色,邊框尺寸,填充顏色。

(3) 可以按單行,或者多行進行佈局。

(4) 可以必定程度支持富文本, 例如爲精靈設置text = <font style="color:#FF0000; ">某X</font>施展了<font style=" color:#FF0000;outline:1;outline_color:#00FFFF">憤怒一擊</font>

(5) 性能不須要達到多高,但至少作到切換場景,不能由於字體紋理生成而產生明顯卡頓(特別是有動態字體的時候,好比聊天).

 

綜上所屬,一次紋理生成的過程至少包含以下邏輯

--> 將utf8轉換爲ucs2

--> 解析富文本

--> 計算佈局

--> 生成紋理

 

這裏須要說明的是: 按上表所述, Layout 消耗掉708ms的緣由是,Layout須要獲取各字符的尺寸. 因此調用了FT_Load_Glyph, 該函數起碼就佔用了700ms。

以後在生成紋理過程當中,對FT_Load_Glyph再次進行調用,因此不慢都不行。

 

問題大體清楚後,考慮解決方案.

目前初步考慮的優化方案是:避免每次生成字符紋理,都去調用Ft_load_glyph加載字模數據,改成採用緩存機制.僅在第一次加載字體時,纔會調用Ft_load_glyph。以後的調用,會從緩存中讀取。 至因而不是要對緩存設置閥值,控制內存增加,這裏先暫時不考慮。

那麼接下來就須要肯定我到底應該緩存什麼。

緩存什麼呢,緩存什麼呢。

先把參考用的freetype庫,生成帶邊框字體的example代碼貼上。

http://www.freetype.org/freetype2/docs/tutorial/example2.cpp

這個範例代碼寫得醜陋,可是邏輯仍是很簡單的。

大致上的過程實際就是加載字模後,

獲取字模fill 部分的Span表,

獲取字模outline 部分的Span表,

將兩部分數據打到一個Bitmap中.

這個Span結構須要特別說明一下,頗有意思。

struct Span

{

  Span() { }

  Span(int _x, int _y, int _width, int _coverage)

  : x(_x), y(_y), width(_width), coverage(_coverage) { }

 

  int x, y, width, coverage;

};

  

 

他實際描述的是一條橫向掃描線,起點在(x, y), 寬度爲with,  converage 存儲的是灰度數據(0-255)。你後面須要作的是拿到這個表之後,進行遍歷,將Span數據外加外部輸入的顏色值(邊框顏色 和 填充顏色) 轉換成最終的Bitmap。

 

因爲咱們的字體支持包邊,因此咱們可能會拿到兩個Span表,一個是用於渲染outline的,姑且叫他outlineSpans, 另外一個是用於渲染填充區的,姑且叫他fillSpans。

實際上,outlineSpan 和 fillSpan 所須要的Bitmap尺寸是不一樣的,一般是邊框須要的Bitmap略大於填充區所須要的Bitmap。

Freetype的設計,因爲是一次Ft_load_glyp得到outlineSpans 和 fillSpans, 因此能夠猜測,他們的座標系統是統一的,也就是說原點(0,0)點是重合的, 這也是爲何x, y 有時會出現負數的緣由。

這個span啥的有個好處,實際上有了這個span, 基本上就能夠脫離freetype的接口本身畫文字了。固然他應該還有更raw的東西,目前沒考慮要接觸。

 

爲了證明猜測,我首先作了一個測試。

打印出字符'g'的outlineSpans 和 fillSpans的數據.

其結果顯示以下:

[2.24 19:55:11]      [INFO]   there are 94 span in fill rect.

[2.24 19:55:11]      [INFO]   [0] x:2 y:-5 width:1 gray8:38

[2.24 19:55:11]      [INFO]   [1] x:3 y:-5 width:1 gray8:163

[2.24 19:55:11]      [INFO]   [2] x:4 y:-5 width:1 gray8:232

[2.24 19:55:11]      [INFO]   [3] x:5 y:-5 width:1 gray8:251

[2.24 19:55:11]      [INFO]   [4] x:6 y:-5 width:1 gray8:232

[2.24 19:55:11]      [INFO]   [5] x:7 y:-5 width:1 gray8:179

[2.24 19:55:11]      [INFO]   [6] x:8 y:-5 width:1 gray8:74

[2.24 19:55:11]      [INFO]   [7] x:2 y:-4 width:1 gray8:245

[2.24 19:55:11]      [INFO]   [8] x:3 y:-4 width:6 gray8:255

[2.24 19:55:11]      [INFO]   [9] x:9 y:-4 width:1 gray8:134

[2.24 19:55:11]      [INFO]   [10] x:2 y:-3 width:1 gray8:225

[2.24 19:55:11]      [INFO]   [11] x:3 y:-3 width:1 gray8:103

[2.24 19:55:11]      [INFO]   [12] x:4 y:-3 width:1 gray8:25

[2.24 19:55:11]      [INFO]   [13] x:5 y:-3 width:1 gray8:6

[2.24 19:55:11]      [INFO]   [14] x:6 y:-3 width:1 gray8:42

[2.24 19:55:11]      [INFO]   [15] x:7 y:-3 width:1 gray8:158

[2.24 19:55:11]      [INFO]   [16] x:8 y:-3 width:2 gray8:255

[2.24 19:55:11]      [INFO]   [17] x:10 y:-3 width:1 gray8:63

[2.24 19:55:11]      [INFO]   [18] x:2 y:-2 width:1 gray8:12

[2.24 19:55:11]      [INFO]   [19] x:8 y:-2 width:1 gray8:168

[2.24 19:55:11]      [INFO]   [20] x:9 y:-2 width:1 gray8:255

[2.24 19:55:11]      [INFO]   [21] x:10 y:-2 width:1 gray8:167

[2.24 19:55:11]      [INFO]   [22] x:8 y:-1 width:1 gray8:59

[2.24 19:55:11]      [INFO]   [23] x:9 y:-1 width:1 gray8:255

[2.24 19:55:11]      [INFO]   [24] x:10 y:-1 width:1 gray8:223

[2.24 19:55:11]      [INFO]   [25] x:2 y:0 width:1 gray8:16

[2.24 19:55:11]      [INFO]   [26] x:3 y:0 width:1 gray8:147

[2.24 19:55:11]      [INFO]   [27] x:4 y:0 width:1 gray8:230

[2.24 19:55:11]      [INFO]   [28] x:5 y:0 width:1 gray8:247

[2.24 19:55:11]      [INFO]   [29] x:6 y:0 width:1 gray8:206

[2.24 19:55:11]      [INFO]   [30] x:7 y:0 width:1 gray8:80

[2.24 19:55:11]      [INFO]   [31] x:8 y:0 width:1 gray8:13

[2.24 19:55:11]      [INFO]   [32] x:9 y:0 width:1 gray8:255

[2.24 19:55:11]      [INFO]   [33] x:10 y:0 width:1 gray8:247

[2.24 19:55:11]      [INFO]   [34] x:1 y:1 width:1 gray8:8

[2.24 19:55:11]      [INFO]   [35] x:2 y:1 width:1 gray8:207

[2.24 19:55:11]      [INFO]   [36] x:3 y:1 width:4 gray8:255

[2.24 19:55:11]      [INFO]   [37] x:7 y:1 width:1 gray8:254

[2.24 19:55:11]      [INFO]   [38] x:8 y:1 width:1 gray8:88

[2.24 19:55:11]      [INFO]   [39] x:9 y:1 width:2 gray8:255

[2.24 19:55:11]      [INFO]   [40] x:11 y:1 width:0 gray8:248

[2.24 19:55:11]      [INFO]   [41] x:1 y:2 width:1 gray8:119

[2.24 19:55:11]      [INFO]   [42] x:2 y:2 width:1 gray8:255

[2.24 19:55:11]      [INFO]   [43] x:3 y:2 width:1 gray8:247

[2.24 19:55:11]      [INFO]   [44] x:4 y:2 width:1 gray8:108

[2.24 19:55:11]      [INFO]   [45] x:5 y:2 width:1 gray8:21

[2.24 19:55:11]      [INFO]   [46] x:6 y:2 width:1 gray8:24

[2.24 19:55:11]      [INFO]   [47] x:7 y:2 width:1 gray8:113

[2.24 19:55:11]      [INFO]   [48] x:8 y:2 width:1 gray8:227

[2.24 19:55:11]      [INFO]   [49] x:9 y:2 width:2 gray8:255

[2.24 19:55:11]      [INFO]   [50] x:1 y:3 width:1 gray8:205

[2.24 19:55:11]      [INFO]   [51] x:2 y:3 width:1 gray8:255

[2.24 19:55:11]      [INFO]   [52] x:3 y:3 width:1 gray8:120

[2.24 19:55:11]      [INFO]   [53] x:8 y:3 width:1 gray8:114

[2.24 19:55:11]      [INFO]   [54] x:9 y:3 width:2 gray8:255

[2.24 19:55:11]      [INFO]   [55] x:1 y:4 width:1 gray8:244

[2.24 19:55:11]      [INFO]   [56] x:2 y:4 width:1 gray8:255

[2.24 19:55:11]      [INFO]   [57] x:3 y:4 width:1 gray8:31

[2.24 19:55:11]      [INFO]   [58] x:8 y:4 width:1 gray8:25

[2.24 19:55:11]      [INFO]   [59] x:9 y:4 width:2 gray8:255

[2.24 19:55:11]      [INFO]   [60] x:1 y:5 width:1 gray8:250

[2.24 19:55:11]      [INFO]   [61] x:2 y:5 width:1 gray8:255

[2.24 19:55:11]      [INFO]   [62] x:3 y:5 width:1 gray8:9

[2.24 19:55:11]      [INFO]   [63] x:9 y:5 width:2 gray8:255

[2.24 19:55:11]      [INFO]   [64] x:1 y:6 width:1 gray8:228

[2.24 19:55:11]      [INFO]   [65] x:2 y:6 width:1 gray8:255

[2.24 19:55:11]      [INFO]   [66] x:3 y:6 width:1 gray8:41

[2.24 19:55:11]      [INFO]   [67] x:8 y:6 width:1 gray8:10

[2.24 19:55:11]      [INFO]   [68] x:9 y:6 width:2 gray8:255

[2.24 19:55:11]      [INFO]   [69] x:1 y:7 width:1 gray8:172

[2.24 19:55:11]      [INFO]   [70] x:2 y:7 width:1 gray8:255

[2.24 19:55:11]      [INFO]   [71] x:3 y:7 width:1 gray8:141

[2.24 19:55:11]      [INFO]   [72] x:8 y:7 width:1 gray8:83

[2.24 19:55:11]      [INFO]   [73] x:9 y:7 width:2 gray8:255

[2.24 19:55:11]      [INFO]   [74] x:1 y:8 width:1 gray8:68

[2.24 19:55:11]      [INFO]   [75] x:2 y:8 width:1 gray8:255

[2.24 19:55:11]      [INFO]   [76] x:3 y:8 width:1 gray8:252

[2.24 19:55:11]      [INFO]   [77] x:4 y:8 width:1 gray8:128

[2.24 19:55:11]      [INFO]   [78] x:5 y:8 width:1 gray8:32

[2.24 19:55:11]      [INFO]   [79] x:6 y:8 width:1 gray8:16

[2.24 19:55:11]      [INFO]   [80] x:7 y:8 width:1 gray8:91

[2.24 19:55:11]      [INFO]   [81] x:8 y:8 width:1 gray8:235

[2.24 19:55:11]      [INFO]   [82] x:9 y:8 width:2 gray8:255

[2.24 19:55:11]      [INFO]   [83] x:2 y:9 width:1 gray8:147

[2.24 19:55:11]      [INFO]   [84] x:3 y:9 width:5 gray8:255

[2.24 19:55:11]      [INFO]   [85] x:8 y:9 width:1 gray8:142

[2.24 19:55:11]      [INFO]   [86] x:9 y:9 width:2 gray8:255

[2.24 19:55:11]      [INFO]   [87] x:3 y:10 width:1 gray8:100

[2.24 19:55:11]      [INFO]   [88] x:4 y:10 width:1 gray8:205

[2.24 19:55:11]      [INFO]   [89] x:5 y:10 width:1 gray8:246

[2.24 19:55:11]      [INFO]   [90] x:6 y:10 width:1 gray8:231

[2.24 19:55:11]      [INFO]   [91] x:7 y:10 width:1 gray8:132

[2.24 19:55:11]      [INFO]   [92] x:8 y:10 width:1 gray8:3

[2.24 19:55:11]      [INFO]   [93] x:9 y:10 width:2 gray8:255

[2.24 19:55:11]      [INFO]   fill rect :(0.000000,-5.000000) - (11.000000,10.000000), w:12.000000, h:16.000000

[2.24 19:55:11]      [INFO]   ---------------------------------------------------

[2.24 19:55:11]      [INFO]   there are 91 span in outline rect.

[2.24 19:55:11]      [INFO]   [0] x:2 y:-6 width:1 gray8:70

[2.24 19:55:11]      [INFO]   [1] x:3 y:-6 width:1 gray8:178

[2.24 19:55:11]      [INFO]   [2] x:4 y:-6 width:1 gray8:235

[2.24 19:55:11]      [INFO]   [3] x:5 y:-6 width:1 gray8:250

[2.24 19:55:11]      [INFO]   [4] x:6 y:-6 width:1 gray8:233

[2.24 19:55:11]      [INFO]   [5] x:7 y:-6 width:1 gray8:185

[2.24 19:55:11]      [INFO]   [6] x:8 y:-6 width:1 gray8:97

[2.24 19:55:11]      [INFO]   [7] x:9 y:-6 width:1 gray8:5

[2.24 19:55:11]      [INFO]   [8] x:1 y:-5 width:1 gray8:139

[2.24 19:55:11]      [INFO]   [9] x:2 y:-5 width:7 gray8:255

[2.24 19:55:11]      [INFO]   [10] x:9 y:-5 width:1 gray8:207

[2.24 19:55:11]      [INFO]   [11] x:10 y:-5 width:1 gray8:28

[2.24 19:55:11]      [INFO]   [12] x:1 y:-4 width:1 gray8:252

[2.24 19:55:11]      [INFO]   [13] x:2 y:-4 width:8 gray8:255

[2.24 19:55:11]      [INFO]   [14] x:10 y:-4 width:1 gray8:202

[2.24 19:55:11]      [INFO]   [15] x:11 y:-4 width:1 gray8:4

[2.24 19:55:11]      [INFO]   [16] x:1 y:-3 width:10 gray8:255

[2.24 19:55:11]      [INFO]   [17] x:11 y:-3 width:1 gray8:86

[2.24 19:55:11]      [INFO]   [18] x:1 y:-2 width:1 gray8:225

[2.24 19:55:11]      [INFO]   [19] x:2 y:-2 width:1 gray8:246

[2.24 19:55:11]      [INFO]   [20] x:3 y:-2 width:1 gray8:128

[2.24 19:55:11]      [INFO]   [21] x:4 y:-2 width:1 gray8:30

[2.24 19:55:11]      [INFO]   [22] x:5 y:-2 width:1 gray8:11

[2.24 19:55:11]      [INFO]   [23] x:6 y:-2 width:1 gray8:66

[2.24 19:55:11]      [INFO]   [24] x:7 y:-2 width:1 gray8:221

[2.24 19:55:11]      [INFO]   [25] x:8 y:-2 width:3 gray8:255

[2.24 19:55:11]      [INFO]   [26] x:11 y:-2 width:1 gray8:173

[2.24 19:55:11]      [INFO]   [27] x:1 y:-1 width:1 gray8:19

[2.24 19:55:11]      [INFO]   [28] x:2 y:-1 width:1 gray8:70

[2.24 19:55:11]      [INFO]   [29] x:3 y:-1 width:1 gray8:171

[2.24 19:55:11]      [INFO]   [30] x:4 y:-1 width:1 gray8:234

[2.24 19:55:11]      [INFO]   [31] x:5 y:-1 width:1 gray8:247

[2.24 19:55:11]      [INFO]   [32] x:6 y:-1 width:1 gray8:215

[2.24 19:55:11]      [INFO]   [33] x:7 y:-1 width:1 gray8:197

[2.24 19:55:11]      [INFO]   [34] x:8 y:-1 width:3 gray8:255

[2.24 19:55:11]      [INFO]   [35] x:11 y:-1 width:1 gray8:225

[2.24 19:55:11]      [INFO]   [36] x:1 y:0 width:1 gray8:81

[2.24 19:55:11]      [INFO]   [37] x:2 y:0 width:1 gray8:250

[2.24 19:55:11]      [INFO]   [38] x:3 y:0 width:8 gray8:255

[2.24 19:55:11]      [INFO]   [39] x:11 y:0 width:1 gray8:246

[2.24 19:55:11]      [INFO]   [40] x:0 y:1 width:1 gray8:29

[2.24 19:55:11]      [INFO]   [41] x:1 y:1 width:1 gray8:243

[2.24 19:55:11]      [INFO]   [42] x:2 y:1 width:10 gray8:255

[2.24 19:55:11]      [INFO]   [43] x:12 y:1 width:0 gray8:248

[2.24 19:55:11]      [INFO]   [44] x:0 y:2 width:1 gray8:139

[2.24 19:55:11]      [INFO]   [45] x:1 y:2 width:11 gray8:255

[2.24 19:55:11]      [INFO]   [46] x:0 y:3 width:1 gray8:211

[2.24 19:55:11]      [INFO]   [47] x:1 y:3 width:3 gray8:255

[2.24 19:55:11]      [INFO]   [48] x:4 y:3 width:1 gray8:177

[2.24 19:55:11]      [INFO]   [49] x:5 y:3 width:1 gray8:22

[2.24 19:55:11]      [INFO]   [50] x:6 y:3 width:1 gray8:25

[2.24 19:55:11]      [INFO]   [51] x:7 y:3 width:1 gray8:175

[2.24 19:55:11]      [INFO]   [52] x:8 y:3 width:4 gray8:255

[2.24 19:55:11]      [INFO]   [53] x:0 y:4 width:1 gray8:245

[2.24 19:55:11]      [INFO]   [54] x:1 y:4 width:3 gray8:255

[2.24 19:55:11]      [INFO]   [55] x:4 y:4 width:1 gray8:34

[2.24 19:55:11]      [INFO]   [56] x:7 y:4 width:1 gray8:29

[2.24 19:55:11]      [INFO]   [57] x:8 y:4 width:4 gray8:255

[2.24 19:55:11]      [INFO]   [58] x:0 y:5 width:1 gray8:250

[2.24 19:55:11]      [INFO]   [59] x:1 y:5 width:3 gray8:255

[2.24 19:55:11]      [INFO]   [60] x:4 y:5 width:1 gray8:9

[2.24 19:55:11]      [INFO]   [61] x:8 y:5 width:4 gray8:255

[2.24 19:55:11]      [INFO]   [62] x:0 y:6 width:1 gray8:230

[2.24 19:55:11]      [INFO]   [63] x:1 y:6 width:3 gray8:255

[2.24 19:55:11]      [INFO]   [64] x:4 y:6 width:1 gray8:48

[2.24 19:55:11]      [INFO]   [65] x:7 y:6 width:1 gray8:9

[2.24 19:55:11]      [INFO]   [66] x:8 y:6 width:4 gray8:255

[2.24 19:55:11]      [INFO]   [67] x:0 y:7 width:1 gray8:181

[2.24 19:55:11]      [INFO]   [68] x:1 y:7 width:3 gray8:255

[2.24 19:55:11]      [INFO]   [69] x:4 y:7 width:1 gray8:191

[2.24 19:55:11]      [INFO]   [70] x:5 y:7 width:1 gray8:34

[2.24 19:55:11]      [INFO]   [71] x:6 y:7 width:1 gray8:17

[2.24 19:55:11]      [INFO]   [72] x:7 y:7 width:1 gray8:149

[2.24 19:55:11]      [INFO]   [73] x:8 y:7 width:4 gray8:255

[2.24 19:55:11]      [INFO]   [74] x:0 y:8 width:1 gray8:93

[2.24 19:55:11]      [INFO]   [75] x:1 y:8 width:11 gray8:255

[2.24 19:55:11]      [INFO]   [76] x:0 y:9 width:1 gray8:5

[2.24 19:55:11]      [INFO]   [77] x:1 y:9 width:1 gray8:207

[2.24 19:55:11]      [INFO]   [78] x:2 y:9 width:10 gray8:255

[2.24 19:55:11]      [INFO]   [79] x:1 y:10 width:1 gray8:32

[2.24 19:55:11]      [INFO]   [80] x:2 y:10 width:1 gray8:222

[2.24 19:55:11]      [INFO]   [81] x:3 y:10 width:9 gray8:255

[2.24 19:55:11]      [INFO]   [82] x:2 y:11 width:1 gray8:13

[2.24 19:55:11]      [INFO]   [83] x:3 y:11 width:1 gray8:126

[2.24 19:55:11]      [INFO]   [84] x:4 y:11 width:1 gray8:212

[2.24 19:55:11]      [INFO]   [85] x:5 y:11 width:1 gray8:246

[2.24 19:55:11]      [INFO]   [86] x:6 y:11 width:1 gray8:230

[2.24 19:55:11]      [INFO]   [87] x:7 y:11 width:1 gray8:159

[2.24 19:55:11]      [INFO]   [88] x:8 y:11 width:1 gray8:212

[2.24 19:55:11]      [INFO]   [89] x:9 y:11 width:2 gray8:255

[2.24 19:55:11]      [INFO]   [90] x:11 y:11 width:1 gray8:180

[2.24 19:55:11]      [INFO]   outline rect :(0.000000,-6.000000) - (12.000000,11.000000), w:13.000000, h:18.000000

[2.24 19:55:11]      [INFO]   overlapped rect :(0.000000,-6.000000) - (12.000000,11.000000), w:13.000000, h:18.000000由此能夠獲得:

  

填充區一共有94個span, 分佈在座標左上(0,-5) 右下(11,10) , 其矩形區域尺寸爲(12,16)

溝邊區一共有91個span, 分別在(0, -6) (12,11) 其矩形區域尺寸爲(13,18)

填充與溝邊的合成位圖最終須要尺寸(13, 18)

媽呀,一個g 有94 + 91 = 185個span 只是一個g.

可是鑑於計算機處理的速度比我快,因此先忽略繼續往下走起。

 

範例中,設置顏色到bitmap的代碼是:

charBitmap[(int)((imgHeight - 1 - (s->y - rect.ymin)) * imgWidth + s->x - rect.xmin + w)] = outLineColor;

因此Bitmap 與 fillRect的座標映射關係是:

y = (imgHeight - 1 - (s->y - rect.ymin)) * imgWidth

x = s->x - rect.xmin

 

其實是完成形以下圖的座標變換:

 

那麼實際上,能夠較爲輕鬆的分別保存outlineBitmap 和 fillBitmap , 用於存儲灰度.並記錄offsetX, offsetY 做爲座標參考系對齊的依據。

可是,後來回過頭來考慮這個問題,我幹嗎要分別存儲2個bitmap, 難道是像複用fillBitmap麼? 沒有啊,因此我不用分別存儲outlineBitmap和fillBitmap,僅須要存儲一個總的bitmap, 其大小是outline rect 和 fill rect 的bound rect.而後將兩個灰度存入就好了。實際上,因爲不少設備不支持2通道紋理,這裏我選擇採用RGBA8888的格式存儲, R通道存儲填充灰度, G通道存儲邊框灰度。浪費了2個通道實在屬於無奈之舉,但shader能夠直接拿到這個texture作渲染,也是件好事。

 

除了bitmap須要關注,還須要取得相關的char metrics 並緩存下來, 由於Layout邏輯須要用到這些位置相關的數據。具體須要的值參考下圖:

 

另須要注意的是,因爲對邊框的支持, 因此可能會對一些位置數據進行修正。

須要修正的數據包括:

bearingX, bearingY, width, height, advance.

若是不調整會這樣?那麼在字符有邊框的時候,後面的字符極可能把前面的蓋住。

怎麼調整呢,嗯,嗯。直接寫代碼調整,對。

 

因此整理下載,緩存的結構體大概是這樣的:

CharChache

bitmap : 紋理位圖(r,g有用處, b,a 沒用, 也許未來能夠寫點啥在裏面)

charMetrics

       -bearingX

       -bearingY

       -advance

       -width

       -height

 

那麼緩存的Key怎麼考慮呢

Key包含一下部分:

char (uint16) 字符的unicode

font_size(uint8)

outline_size(unit8)

 

font_size 和 outline_size 採用uint8的緣由是, 這樣能夠用一個32位整形數來做爲緩存對象的鍵值,使用超過一個字節的狀況存儲font_size 和 outline_size 不作考慮,由於那種狀況太極端了。

 

剩下的工做就至關的輕鬆了.我能夠把大體須要的接口作個列表:

 

void renderString(string _str, TextStyle _defaultStyle, Texture2D _outTexture)

這個是整個文字渲染的進入點接口, 能夠按Factory模式處理,目前實現FreeTypeWithBitmapCache 實現, 未來還能夠搞個Device 實現,直接向操做系統要紋理,好比ios自己彷佛是支持包邊字體紋理生成的。

_defaultStyle 參數是文本的樣式參數,包含行間距,字符間距,是否換行,換行寬度,首行indent,字體顏色, 邊框顏色等信息.

總之,這個接口就是我把字符串給你,你按我要的效果給生成紋理。

 

void htmlParse(string _str, HtmlTagList _outHtmlTagList, string _outPureString)

該方法是解析富文本字符串(其實不是html,算是一種私有協議)。

輸出的HtmlTagList 是解析的結果,他不是一顆樹,實際只是一個鏈表而已(不想作那麼複雜, 由於我壓根就沒打算支持標籤的嵌套,簡單實現便可,沒必要搞成瀏覽器,若是策劃問爲啥不支持嵌套表格,文本輸入框, 嵌圖片,爲啥沒有播放音頻功能,直接耳屎扇飛)。

_outPureString 是純文本的內容,實際也能夠經過_outHtmlList 分析獲得,可是這個方法輸出來,做爲順便完成的工做.

 

ChatCacheEntry* queryCharCache(wchar _ch, uint8 _fontSize, _unit8 _outlineSize)

查詢緩存, 若是緩存中不存在, 則按以前分析的邏輯生成ChatCacheEntry。

這裏還有一個可優化的地方.就是能夠在ChatCacheEntry中存放一個命中次數,內部按該次數對ChatChacheEntry進行排序,在適當的時候刪除掉低命中次數的緩存條目,這樣能夠避免文字緩存把內存搞爆的狀況。

 

void layout(string _str, TextStyle _style, vector<CharMetrics> _metrics, vector<Point> _outPos)

該方法接受字符串,樣式,以及與字符串對應的每一個字符的metrcis信息,該方法對整個字符串進行佈局,並將位置輸出到_outPos中。

始終 _str.length = _metrics.size = _outPos.size

 

因此最核心的方法就是上述這些。

其中客戶端真正調用的就是 renderString, 其餘接口都是爲renderString服務,在renderString內部被調用的。

 

最後就是shader

shader很簡單,

傳入 fillColor, outlineColor

傳入 紋理 texture

 

那麼pixel顏色爲

outlineColor.rgb = outlineColor.rgb

outlineColor.a = texture.r

outColor.rgb = outlineColor.rgb  + (fillColor.rgb - outlineColor.rgb) * texture.g

outColor.a = outlineColor.a + texture.g

 

而後,就基本上沒有而後了。

雲風有篇博文提到了一種方案,提出直接用一張大texture 做爲文字的緩存。有興趣能夠去看下,不過我基於如下緣由暫時不打算採用。

其一:這一版本個人目標僅是性能足夠而非性能最優。

其二:大紋理而且隨着新字符的生成和老字符的移除,一樣會涉及主存和顯存的換入換出,若是更新頻繁,該方案是否整體上有益不能肯定。

其三:咱們的系統font_size 的尺寸很差估量12pt 和 24pt有可能都有,涉及到裝箱算法,若是單頁滿了,還可能會作multi paging , 總的來講可能會增長大量複雜度。

東西一複雜了我就拉不出屎了。先看看吧,先看看。

 

因此目前仍是先簡單實現一版,看看性能如何再說。

該文檔。。那啥,主要是整理本身的思路寫下的日誌和開發參考,大量細節都省略。因此估計很難閱讀。也可能有超多的錯漏。

 

嗯,嗯,明天開始編碼。

如今先去看行屍走肉

相關文章
相關標籤/搜索