我试图使用子像素渲染渲染freetype中的一些文本。当我渲染大尺寸的文本时,结果看起来足够,只有一些颜色条纹,我认为这是预期的。然而,随着我减小尺寸,结果变得越来越模糊,并且变得略微伸展。这些是绘图的结果" Hello"作为像素大小13,18和100。
正如您所看到的,除了轻微的模糊和彩色条纹外,像素大小100相当清晰。像素大小18仍然可读,虽然丑陋。然而,像素大小13是如此扭曲,只有知道它的人应该是一个单词可以识别它。
这就是我从freetype获取位图的方法:
let bitmap_glyph = glyph.to_bitmap(freetype::render_mode::RenderMode::Lcd, None).unwrap();
let bitmap = bitmap_glyph.bitmap();
let texture = Texture::from_freetype_bitmap(bitmap);
这是我目前用于生成纹理的代码:
pub fn from_freetype_bitmap(bitmap: freetype::Bitmap) -> Texture {
let width = bitmap.width();
let height = bitmap.rows();
let mut texture = 0;
unsafe {
gl::GenTextures(1, &mut texture);
assert!(texture != 0);
gl::BindTexture(gl::TEXTURE_2D, texture);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as i32);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as i32);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as i32);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as i32);
gl::PixelStorei(gl::UNPACK_ALIGNMENT, 1);
let data = bitmap.buffer();
let pitch = bitmap.pitch();
let dataWidth = width / 3;
let mut finalData = Vec::<u8>::new();
for i in 0..height {
for j in 0..dataWidth {
finalData.push(data[(i * pitch + (j * 3) + 0) as usize]);
finalData.push(data[(i * pitch + (j * 3) + 1) as usize]);
finalData.push(data[(i * pitch + (j * 3) + 2) as usize]);
finalData.push(0xff);
}
}
gl::TexImage2D(
gl::TEXTURE_2D,
0,
gl::RGBA as GLint,
dataWidth, height,
0,
gl::RGBA,
gl::UNSIGNED_BYTE,
mem::transmute(finalData.as_ptr())
);
}
let mut mesh = Mesh::new();
mesh.add_vertex(0.0, 0.0); mesh.add_vertex(0.0, 0.0);
mesh.add_vertex(width as f32, 0.0); mesh.add_vertex(1.0, 0.0);
mesh.add_vertex(width as f32, height as f32); mesh.add_vertex(1.0, 1.0);
mesh.add_vertex(0.0, height as f32); mesh.add_vertex(0.0, 1.0);
return Texture {
mesh: mesh,
texture: texture
}
}
然后使用正交矩阵渲染这些纹理,其中原点位于左上角,并缩放到窗口的尺寸。因此,我相信在渲染时不应该进行上采样或下采样。这些是我目前使用的着色器:
// VS
#version 120
uniform vec3 tint;
uniform mat3 matrix;
attribute vec2 position;
attribute vec2 texCoords;
varying vec2 texFrag;
void main() {
texFrag = texCoords;
gl_Position = vec4(matrix * vec3(position, 1.0), 1.0);
}
// FS
#version 120
uniform vec3 tint;
uniform mat3 matrix;
uniform sampler2D texSample;
varying vec2 texFrag;
void main() {
vec4 color = texture(texSample, texFrag);
if(color.rgb == vec3(0.0, 0.0, 0.0)) {
color.a = 0.0;
}
gl_FragColor = color * vec4(tint, 1.0);
}
我相信我的问题可能与我将纹理转换为RGBA的方式有关。如果我使用位图而不进行此转换(也就是使用RGB而不使用finalData
缓冲区),结果是数据错误地对齐。更改解压缩对齐并不能解决该特定错误。这使得直接从freetype使用数据变得不可行。
如果相关,我使用的语言是生锈的,库是gl-rs和freetype-rs。我在Windows上,我使用的freetype是在启用子像素渲染的情况下编译的。我将如何解决这个问题,还有其他一些我应该注意的问题,因为我会继续努力让它发挥作用吗?