目前,如果我不乘以采样,我设法渲染看起来像对应字符的四边形,但每当我这样做时,四边形就会完全透明并消失
FreeType 和 FontConfig 的设置
c.glEnable(c.GL_BLEND);
c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA);
var ft: c.FT_Library = undefined;
_ = c.FT_Init_FreeType(&ft);
var face: c.FT_Face = undefined;
const font_path = getFontPath(alloc, font.family) catch unreachable; // Returned path matches font
_ = c.FT_New_Face(ft, font_path.ptr, 0, &face);
_ = c.FT_Set_Pixel_Sizes(face, 0, 16);
c.glPixelStorei(c.GL_UNPACK_ALIGNMENT, 1);
for (keys_s.search) |key| {
keys_s.char_info.put(key, Character.new(face, key)) catch unreachable;
}
保存有关角色信息的结构
pub const Character = struct {
texture_id: u32,
size: [2]i32,
bearing: [2]i32,
advance: [2]u32,
fn new(face: c.FT_Face, key: u8) Character {
var texture: u32 = undefined;
c.glGenTextures(1, &texture);
c.glBindTexture(c.GL_TEXTURE_2D, texture);
c.glTexImage2D(
c.GL_TEXTURE_2D,
0,
c.GL_RED,
@intCast(face.*.glyph.*.bitmap.width),
@intCast(face.*.glyph.*.bitmap.rows),
0,
c.GL_RED,
c.GL_UNSIGNED_BYTE,
face.*.glyph.*.bitmap.buffer,
);
c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_WRAP_S, c.GL_CLAMP_TO_EDGE);
c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_WRAP_T, c.GL_CLAMP_TO_EDGE);
c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MIN_FILTER, c.GL_LINEAR);
c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MAG_FILTER, c.GL_LINEAR);
return .{
.texture_id = texture,
.size = .{
@intCast(face.*.glyph.*.bitmap.width),
@intCast(face.*.glyph.*.bitmap.rows),
},
.bearing = .{
@intCast(face.*.glyph.*.bitmap_left),
@intCast(face.*.glyph.*.bitmap_top),
},
.advance = .{
@intCast(face.*.glyph.*.advance.x >> 6),
@intCast(face.*.glyph.*.advance.y >> 6),
},
};
}
};
渲染文本的实际函数(setColor 只是将制服设置为所选颜色)
pub fn renderText(self: *const Self, text: []const u8, x: i32, y: i32) void {
setColor(self.config.font.color, self.egl.text_shader_program.*);
c.glActiveTexture(c.GL_TEXTURE0);
for (text, 0..) |char, i| {
const ch = self.config.keys.char_info.get(char).?;
const move: i32 = @intCast(ch.advance[0] * i);
const x_pos = x + ch.size[0] + move;
const y_pos = y - ch.bearing[1];
const vertices = [_]i32{
x_pos, y_pos, 0, 1,
x_pos + ch.size[0], y_pos, 1, 1,
x_pos, y_pos + ch.size[1], 0, 0,
x_pos + ch.size[0], y_pos + ch.size[1], 1, 0,
};
c.glBindTexture(c.GL_TEXTURE_2D, ch.texture_id);
c.glBindBuffer(c.GL_ARRAY_BUFFER, self.egl.VBO);
c.glBufferSubData(c.GL_ARRAY_BUFFER, 0, @sizeOf(i32) * vertices.len, &vertices);
c.glVertexAttribPointer(0, 4, c.GL_INT, c.GL_FALSE, 0, null);
c.glDrawElements(c.GL_TRIANGLES, 6, c.GL_UNSIGNED_INT, null);
}
}
我也使用这个 EBO 来渲染四边形
const indices = [_]i32{
0, 1, 3,
0, 2, 3,
};
c.glBindBuffer(c.GL_ELEMENT_ARRAY_BUFFER, EBO[0]);
c.glBufferData(c.GL_ELEMENT_ARRAY_BUFFER, @sizeOf(i32) * indices.len, &indices, c.GL_STATIC_DRAW);
片段着色器
#version 460 core
layout(location = 0) out vec4 FragColor;
uniform vec4 u_color;
uniform sampler2D text;
in vec2 v_texcoords;
void main() {
vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, v_texcoords).r);
FragColor = u_color * sampled;
}
顶点着色器
#version 460 core
layout(location = 0) in vec4 vertex;
uniform mat4 projection;
out vec2 v_pos;
out vec2 v_texcoords;
void main() {
gl_Position = projection * vec4(in_pos.xy, 0.0, 1.0);
v_texcoords = vertex.zw;
}
看起来您没有告诉 FreeType 库加载/渲染任何字形。尝试在循环中的此行之前调用
FT_Load_Char
函数:
keys_s.char_info.put(key, Character.new(face, key)) catch unreachable;
另外,避免使用
catch unreachable
;它仅适用于您可以保证代码永远不会失败的情况。只需使用try
。