Freetype 字形在加载到 openGL 时换行
Freetype glyphs wrap when loaded into openGL
我正在尝试通过 freetype 加载 TrueTypeFonts 并使用 openGL 显示它们,这就是我得到的结果:
如您所见,大部分都很好,但如果您仔细观察,每个字形的边界似乎都有一些小的不协调之处。我注意到这些奇怪的线条实际上是从另一边传递过来的像素。尤其是 'T' 和 'h',您可以在其中看到与纹理的另一侧相对应的小条。不同的字体也会发生这种情况。下面是负责将字形位图缓冲区复制到 openGL 中的代码:
void load(FT_GlyphSlot glyphSlot, double loadedHeight){
this->loadedHeight = loadedHeight;
int width = glyphSlot->bitmap.width;
int height = glyphSlot->bitmap.rows;
sizeRatios = Vector2D(width / loadedHeight, height / loadedHeight);
offsetRatios = Vector2D(glyphSlot->bitmap_left / loadedHeight, glyphSlot->metrics.horiBearingY / loadedHeight);
advanceRatios = Vector2D((glyphSlot->advance.x >> 6) / loadedHeight, (glyphSlot->advance.y >> 6) / loadedHeight);
std::cout << width << ", " << height << std::endl;
GLubyte * textureData = new GLubyte[width * height * 4];
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
for(int i = 0; i < 4; i++){
textureData[(x + y * width) * 4 + i] = glyphSlot->bitmap.buffer[x + width * y];
}
}
}
texture.bind();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
texture.load(GL_TEXTURE_2D, 0, GL_RGBA, glyphSlot->bitmap.width, glyphSlot->bitmap.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
// glGenerateMipmap(GL_TEXTURE_2D);
delete [] textureData;
}
字体的大小在别处设置并与我要加载的字形插槽一起传递给此方法。纹理对象只是一个 class 创建纹理句柄并跟踪它,加载只是将参数直接传递给 glTexImage2D()。
我试过使用模数旋转将像素移动一个,它在垂直方向上有效,但在水平方向上无效。我还尝试通过将格式更改为 GL_RED 将缓冲区直接传递到加载来加载纹理,如 here 所述,但问题并没有消失,所以我认为它甚至可能是freetype 的缺陷?
我想知道是否有一些我不理解的基本纹理加载元素。
如果您需要一些额外的源代码来了解问题所在,请询问。
GL_TEXTURE_WRAP_S
/GL_TEXTURE_WRAP_T
默认为GL_REPEAT
.
改用GL_CLAMP_TO_EDGE
。
我正在尝试通过 freetype 加载 TrueTypeFonts 并使用 openGL 显示它们,这就是我得到的结果:
如您所见,大部分都很好,但如果您仔细观察,每个字形的边界似乎都有一些小的不协调之处。我注意到这些奇怪的线条实际上是从另一边传递过来的像素。尤其是 'T' 和 'h',您可以在其中看到与纹理的另一侧相对应的小条。不同的字体也会发生这种情况。下面是负责将字形位图缓冲区复制到 openGL 中的代码:
void load(FT_GlyphSlot glyphSlot, double loadedHeight){
this->loadedHeight = loadedHeight;
int width = glyphSlot->bitmap.width;
int height = glyphSlot->bitmap.rows;
sizeRatios = Vector2D(width / loadedHeight, height / loadedHeight);
offsetRatios = Vector2D(glyphSlot->bitmap_left / loadedHeight, glyphSlot->metrics.horiBearingY / loadedHeight);
advanceRatios = Vector2D((glyphSlot->advance.x >> 6) / loadedHeight, (glyphSlot->advance.y >> 6) / loadedHeight);
std::cout << width << ", " << height << std::endl;
GLubyte * textureData = new GLubyte[width * height * 4];
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
for(int i = 0; i < 4; i++){
textureData[(x + y * width) * 4 + i] = glyphSlot->bitmap.buffer[x + width * y];
}
}
}
texture.bind();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
texture.load(GL_TEXTURE_2D, 0, GL_RGBA, glyphSlot->bitmap.width, glyphSlot->bitmap.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
// glGenerateMipmap(GL_TEXTURE_2D);
delete [] textureData;
}
字体的大小在别处设置并与我要加载的字形插槽一起传递给此方法。纹理对象只是一个 class 创建纹理句柄并跟踪它,加载只是将参数直接传递给 glTexImage2D()。
我试过使用模数旋转将像素移动一个,它在垂直方向上有效,但在水平方向上无效。我还尝试通过将格式更改为 GL_RED 将缓冲区直接传递到加载来加载纹理,如 here 所述,但问题并没有消失,所以我认为它甚至可能是freetype 的缺陷?
我想知道是否有一些我不理解的基本纹理加载元素。
如果您需要一些额外的源代码来了解问题所在,请询问。
GL_TEXTURE_WRAP_S
/GL_TEXTURE_WRAP_T
默认为GL_REPEAT
.
改用GL_CLAMP_TO_EDGE
。