2023-04-15《游戲引擎深入淺出》學(xué)習(xí)筆記

Font* Font::LoadFromFile(std::string font_file_path,unsigned short font_size){
Font* font=GetFont(font_file_path);
if(font!= nullptr){
return font;
}

//讀取 ttf 字體文件
//這段代碼創(chuàng)建了一個(gè)名為 input_file_stream 的 ifstream 對(duì)象瓤檐,并打開(kāi)了一個(gè)二進(jìn)制文件進(jìn)行讀取操作
//ios::in 是一個(gè)枚舉值牛隅,它表示打開(kāi)文件流時(shí)使用的文件訪問(wèn)模式汁尺。其中歉井,ios 是 C++ 標(biāo)準(zhǔn)庫(kù)中的一個(gè)命名空間汇陆,in 是 ios 命名空間中的一個(gè)常量氓奈,表示輸入模式(input mode)葡幸。
ifstream input_file_stream(Application::data_path()+ font_file_path,ios::in | ios::binary);
//ifstream 是 C++ 標(biāo)準(zhǔn)庫(kù)中的一個(gè)輸入流類氓仲,用于從文件中讀取數(shù)據(jù)坦仍。它是 fstream 類的派生類之一鳍烁,表示文件輸入流。 ifstream 對(duì)象可以打開(kāi)一個(gè)文件繁扎,讀取其中的數(shù)據(jù)幔荒,并將其存儲(chǔ)在內(nèi)存中以供后續(xù)操作使用。常見(jiàn)的操作包括從文件中讀取數(shù)據(jù)、檢查文件是否打開(kāi)成功铺峭、檢查文件是否結(jié)束等等墓怀。可以通過(guò)調(diào)用 open() 方法打開(kāi)一個(gè)文件卫键,close() 方法關(guān)閉文件傀履,eof() 方法檢查文件是否結(jié)束,以及 getline() 方法讀取文件中的一行數(shù)據(jù)等方法進(jìn)行文件的操作莉炉。
//ofstream 輸出文件流钓账,文件流(file stream)是指將文件視為輸入或輸出源的流。文件流是C++中標(biāo)準(zhǔn)庫(kù)的一部分絮宁,它允許將文件作為輸入或輸出對(duì)象梆暮,并支持與其他流對(duì)象一樣的操作,例如讀取和寫入數(shù)據(jù)绍昂、移動(dòng)文件指針等

//C++中啦粹,流(stream)是指數(shù)據(jù)在程序中的流動(dòng)方式,它是一種數(shù)據(jù)處理的抽象概念窘游。流的基本思想是將輸入和輸出數(shù)據(jù)都看作是一個(gè)數(shù)據(jù)流唠椭,程序通過(guò)讀寫流中的數(shù)據(jù)來(lái)完成輸入和輸出的操作。

// 獲取文件長(zhǎng)度 seekg 函數(shù)用于移動(dòng)輸入文件流的讀指針忍饰。
// input_file_stream 是一個(gè) ifstream 類型的文件輸入流對(duì)象贪嫂,seekg() 成員函數(shù)用于將文件讀取位置定位到文件末尾。
// 具體來(lái)說(shuō)艾蓝,第一個(gè)參數(shù) 0 表示從文件末尾的偏移量為 0(即指向文件末尾)力崇,
// 而第二個(gè)參數(shù) std::ios::end 表示定位的起始位置為文件流的末尾。
input_file_stream.seekg(0,std::ios::end);
//tellg() 成員函數(shù)用于獲取當(dāng)前文件讀取位置相對(duì)于文件起始位置的偏移量赢织,
// 也就是當(dāng)前讀取位置(文件流末尾)距離文件開(kāi)頭的字節(jié)數(shù)亮靴。
int len = input_file_stream.tellg();
//在讀取文件時(shí),通常會(huì)先將文件讀取位置定位到文件流的起始位置于置,然后讀取文件內(nèi)容台猴。
input_file_stream.seekg(0,std::ios::beg);

//new char[len] 表示在堆區(qū)中分配了一塊大小為 len 個(gè)字節(jié)的內(nèi)存空間,并將該內(nèi)存塊的首地址賦值給指針變量 font_file_buffer俱两。
char *font_file_buffer = new char[len];
//read() 成員函數(shù)用于從文件流中讀取 len 個(gè)字節(jié)的數(shù)據(jù)塊,并將其存儲(chǔ)到 font_file_buffer 指向的字符類型的內(nèi)存空間中曹步。
input_file_stream.read(font_file_buffer , len);

//將ttf 傳入FreeType解析

//ft_library 對(duì)象用于存儲(chǔ) FreeType 庫(kù)的全局狀態(tài)和內(nèi)部數(shù)據(jù)宪彩,包括字體文件的加載、字形的生成等操作讲婚。
FT_Library ft_library= nullptr;//struct object
//ft_face 對(duì)象用于存儲(chǔ)字體文件的字形數(shù)據(jù)尿孔,包括字形的輪廓、字形的寬度、字形的坐標(biāo)等信息
FT_Face ft_face= nullptr;//struct object
//FT_Init_FreeType(&ft_library) 函數(shù)用于初始化 FreeType 庫(kù)活合,返回一個(gè) FT_Library 類型的結(jié)構(gòu)體對(duì)象指針
FT_Init_FreeType(&ft_library);//FreeType初始化;
//通過(guò)調(diào)用 FT_New_Memory_Face() 函數(shù)來(lái)將字體文件數(shù)據(jù)讀入到 ft_face 結(jié)構(gòu)體對(duì)象中雏婶。
FT_Error error = FT_New_Memory_Face(ft_library, (const FT_Byte*)font_file_buffer, len, 0, &ft_face);
if (error != 0){
    DEBUG_LOG_ERROR("FT_New_Memory_Face return error {}!",error);
    return nullptr;
}
//FT_Select_Charmap 是 FreeType 庫(kù)中的一個(gè)函數(shù),用于選擇指定編碼的字符映射表(charmap)
//字符映射表則用于將字符編碼(Unicode白指、ASCII 等)和對(duì)應(yīng)的編號(hào)之間進(jìn)行轉(zhuǎn)換留晚。
FT_Select_Charmap(ft_face, FT_ENCODING_UNICODE);
//font_size 表示期望的字號(hào)大小(單位為點(diǎn))告嘲,將其乘以 $2^6$错维,然后將結(jié)果強(qiáng)制轉(zhuǎn)換為 FT_F26Dot6 類型,就得到了 FreeType 庫(kù)中使用的字號(hào)大小橄唬。
// 這個(gè)操作實(shí)際上是將點(diǎn)數(shù)轉(zhuǎn)換為 FreeType 庫(kù)中使用的固定點(diǎn)數(shù)格式赋焕,以便在生成字形時(shí)使用。
FT_F26Dot6 ft_size = (FT_F26Dot6)(font_size*(1 << 6));

//將 ft_face 指向的字體對(duì)象的字符大小設(shè)置為指定的大小仰楚。
FT_Set_Char_Size(ft_face, ft_size, 0, 72, 72);

if (ft_face == nullptr){
    DEBUG_LOG_ERROR("FT_Set_Char_Size error!");
    return nullptr;
}

//創(chuàng)建Font實(shí)例隆判,保存Freetype解析字體結(jié)果。
font=new Font();
//-> 是一個(gè)成員訪問(wèn)運(yùn)算符僧界,它用于通過(guò)指針訪問(wèn)一個(gè)對(duì)象的成員侨嘀。
// 例如,如果 obj_ptr 是一個(gè)指向?qū)ο蟮闹羔樕有海敲纯梢允褂?obj_ptr->member 來(lái)訪問(wèn)對(duì)象的成員 member飒炎。
// 這樣做相當(dāng)于先通過(guò)指針解引用得到對(duì)象,然后再訪問(wèn)對(duì)象的成員笆豁。
// 因此郎汪,obj_ptr->member 等價(jià)于 (*obj_ptr).member。
font->font_size_=font_size;
font->font_file_buffer_=font_file_buffer;
font->ft_library_=ft_library;
font->ft_face_=ft_face;
font_map_[font_file_path]=font;

//創(chuàng)建空白的闯狱、僅Alpha通道紋理煞赢,用于生成文字。
//font->font_texture_size_ * font->font_texture_size_ 字節(jié)大小的內(nèi)存哄孤,并將該內(nèi)存的起始地址賦給 pixels 指針
unsigned char * pixels = (unsigned char *)malloc(font->font_texture_size_ * font->font_texture_size_);
//這行代碼的作用是將 pixels 指針?biāo)赶虻膬?nèi)存空間全部初始化為 0
//fill a byte string with byte value
memset(pixels, 0,font->font_texture_size_*font->font_texture_size_);
font->font_texture_=Texture2D::Create(font->font_texture_size_,font->font_texture_size_,GL_RED,GL_RED,GL_UNSIGNED_BYTE,pixels);
//這其實(shí)就是一張圖集照筑,和普通的小圖打包成大圖唯一的不同之處就是,這里的小圖是freetype動(dòng)態(tài)生成的bitmap瘦陈。

delete pixels;

return font;

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末凝危,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子晨逝,更是在濱河造成了極大的恐慌蛾默,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捉貌,死亡現(xiàn)場(chǎng)離奇詭異支鸡,居然都是意外死亡冬念,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門牧挣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)急前,“玉大人,你說(shuō)我怎么就攤上這事瀑构●烧耄” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵检碗,是天一觀的道長(zhǎng)据块。 經(jīng)常有香客問(wèn)我,道長(zhǎng)折剃,這世上最難降的妖魔是什么另假? 我笑而不...
    開(kāi)封第一講書人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮怕犁,結(jié)果婚禮上边篮,老公的妹妹穿的比我還像新娘。我一直安慰自己奏甫,他們只是感情好戈轿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著阵子,像睡著了一般思杯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挠进,一...
    開(kāi)封第一講書人閱讀 49,985評(píng)論 1 291
  • 那天色乾,我揣著相機(jī)與錄音,去河邊找鬼领突。 笑死暖璧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的君旦。 我是一名探鬼主播澎办,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼金砍!你這毒婦竟也來(lái)了局蚀?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤恕稠,失蹤者是張志新(化名)和其女友劉穎琅绅,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體谱俭,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奉件,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了昆著。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片县貌。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖凑懂,靈堂內(nèi)的尸體忽然破棺而出煤痕,到底是詐尸還是另有隱情,我是刑警寧澤接谨,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布摆碉,位于F島的核電站,受9級(jí)特大地震影響脓豪,放射性物質(zhì)發(fā)生泄漏巷帝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一扫夜、第九天 我趴在偏房一處隱蔽的房頂上張望楞泼。 院中可真熱鬧,春花似錦笤闯、人聲如沸堕阔。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)超陆。三九已至,卻和暖如春浦马,著一層夾襖步出監(jiān)牢的瞬間时呀,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工捐韩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留退唠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓荤胁,卻偏偏與公主長(zhǎng)得像瞧预,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子仅政,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容