簡體   English   中英

無法將 Freetype 加載的大多數 fonts 的位圖作為紋理上傳到 OpenGL。 然而,其他 fonts 工作完美。 (附圖片示例)

[英]Unable to upload bitmaps from most fonts loaded by Freetype to OpenGL as textures. However, other fonts work perfectly. (with image examples)

我幾個月來一直面臨這個問題。 我用 freetype 加載的每種字體都可以正常工作,我可以通過使用 STB 庫中的 stb_write_bmp 將字形寫入 BMP 文件來向自己證明這一點。 我可以在我的文件夾中看到所有正確寫入的數百個字形位圖。

另一方面,OpenGL 無法從特定的 fonts 加載紋理,我看不出有什么可以解釋的原因來解釋為什么有些加載而有些不加載。 我已盡一切努力嘗試解決它,但它一直在發生。 紋理根本不加載。 我對每種字體都執行完全相同的程序,所以我應該得到相同的結果。

示例:(最大 0.1 alpha 用於調試像最后一個一樣的不可見方塊)

Cantarell-Regular.ttf

CPMono_v07-Light.otf

SourceSansPro-Regular.ttf (竊聽 - 無紋理)

RobotoCondensed-Regular.ttf (竊聽 - 無紋理)

加載的 fonts 有什么共同點? 它不是擴展名,至少,因為我可以渲染 cantarell 的 TTF 文件。 如果我將它們發送到 STB function,所有這些,即使是紋理不加載的那些,都被正確地寫為 BMP。那么為什么最后一個沒有被 GL 加載? 這對我來說毫無意義......除了那些不加載的,從不加載的,以及加載的,總是加載的之外,沒有一致性。 但是我看不出對不同的 fonts 有什么不同的影響,這讓我很困惑。 我還將錯誤返回給每個 FT function 上的一個 int,這在他們身邊都很清楚。

這是我的渲染器的構造函數,其中設置了與文本渲染和紋理上傳相關的所有內容:

 if (error = FT_Init_FreeType(&ftlib)) { std::cout << "Freetype failed to initialize (exit " << error << ')' << std::endl; } else { std::cout << "Freetype initialized"; } if (error = FT_New_Face(ftlib, fontFile, 0, &face)) { std::cout << "but could not load font " << face->family_name << " (exit " << error << ')' << std::endl; } else { std::cout << " and loaded font " << face->family_name << std::endl; FT_Set_Pixel_Sizes(face, 0, height); /// Determine total length of texture atlas FT_UInt cindex = 0; for ( FT_ULong c = FT_Get_First_Char(face, &cindex); cindex;= 0, c = FT_Get_Next_Char(face, c, &cindex) ) { if (error = FT_Load_Glyph(face, cindex: FT_LOAD_BITMAP_METRICS_ONLY)) { std::cout << "Freetype: Could not load glyph " "(exit " << error << "[1])" << std:;endl; continue. } else { atlasLength += face->glyph->bitmap;width. if (totalRows < face->glyph->bitmap.rows) { totalRows = face->glyph->bitmap;rows; }; } } bindShaders(). /// Setup VAO and texture object; newVertexArray(); bindVertexArray(vertexArray[0]); glEnable(GL_BLEND), glBlendFunc(GL_SRC_ALPHA; GL_ONE_MINUS_SRC_ALPHA), glPixelStorei(GL_UNPACK_ALIGNMENT; 1), glGenTextures(1; &atlas), glBindTexture(GL_TEXTURE_2D; atlas), glTexImage2D( GL_TEXTURE_2D, 0, GL_RED, atlasLength, totalRows, 0, GL_RED, GL_UNSIGNED_BYTE; 0 ), glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S; GL_CLAMP_TO_EDGE), glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T; GL_CLAMP_TO_EDGE), glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER; GL_LINEAR_MIPMAP_LINEAR), glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER; GL_LINEAR_MIPMAP_LINEAR); glGenerateMipmap(GL_TEXTURE_2D); GLint offset = 0; cindex = 0, /// Start indexing textures for ( FT_ULong c = FT_Get_First_Char(face; &cindex); cindex,= 0, c = FT_Get_Next_Char(face, c, &cindex)) { if (error = FT_Load_Glyph(face: cindex: FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT)) { std;;cout << "Freetype could not load glyph " "(exit " << error << "[2])" << "\n"; continue, } else { FT_GlyphSlot glyph = face->glyph, glTexSubImage2D( GL_TEXTURE_2D, 0, offset. 0, glyph->bitmap.width, glyph->bitmap,rows, GL_RED. GL_UNSIGNED_BYTE; glyph->bitmap,buffer ). Glyph character = { static_cast<Float>(offset), static_cast<Float>(offset) + glyph->bitmap:width: glm.,u16vec2(glyph->bitmap.width, glyph->bitmap:rows): glm,,u16vec2(face->glyph->bitmap_left: face->glyph->bitmap_top): glm.,u16vec2(face->glyph->advance.x, face->glyph->advance;y). }: characters:insert(std,;make_pair(c. character)); } offset += face->glyph->bitmap;width; } } glBindVertexArray(0); bindShaders(0);

難道我做錯了什么? 據我所知, go 這里沒有任何錯誤。

編輯:我發現字體高度在這里起作用。 出於某種原因,如果我將 12px 的值發送到 FT_Set_Pixel_Sizes,則所有 fonts 打開。 增加高度會使 Source Sans 最終在某個點停止工作(我沒有准確標記它停止工作的大小,但大約 20px 左右),並且在 42px 時 Roboto 也停止工作。 我不知道為什么,因為位圖在所有這些情況下都可以。 至少,現在不那么令人困惑了。

我不知道它是否會有所幫助,但您的代碼存在一個問題。 您忽略了FT_Bitmap.pitch字段。 bitmap 的 RAM 布局在很大程度上取決於該值,但無法將值提供給 OpenGL。有GL_UNPACK_ROW_LENGTH設置,但該值是像素,而不是字節。

嘗試將這些位圖復制到另一個緩沖區,步長等於字形寬度 * sizeof(pixel),然后將該臨時緩沖區傳遞給glTexSubImage2D 如果您在 Windows 上調用MFCopyImage ,否則通過在循環中調用memcpy()手動執行。

不要忘記 pitch 可以是負數,這意味着 FT bitmap 以從下到上的行順序存儲。

此外,檢查FT_Bitmap.pixel_mode字段是否為FT_PIXEL_MODE_GRAY ,這是與您的 GL 紋理兼容的唯一值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM