You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用FreeType与OpenGL渲染文本问题:采样后四边形全透明消失

修复文本采样后透明消失的问题

以下是针对代码问题的具体修复步骤:

1. 修复顶点着色器的变量错误

顶点着色器中使用了未定义的in_pos变量,导致顶点位置计算错误,字符可能被渲染到屏幕外。修改后的顶点着色器:

#version 460 core

layout(location = 0) in vec4 vertex;

uniform mat4 projection;

out vec2 v_texcoords;

void main() {
  gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);
  v_texcoords = vertex.zw;
}
  • 移除未使用的v_pos变量
  • 将in_pos.xy替换为正确的输入变量vertex.xy

2. 修正字符位置计算逻辑

当前字符位置计算存在两处错误,导致字符偏移到不可见区域:

  • x_pos错误添加了字符宽度ch.size[0],应使用字符的水平偏移ch.bearing[0]
  • 字符偏移量计算方式错误,需累加每个字符的advance值,而非用当前字符advance乘以索引

修改后的renderText函数:

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);

    var x_offset: i32 = x;
    for (text) |char| {
        const ch = self.config.keys.char_info.get(char).?;

        const x_pos = x_offset + ch.bearing[0];
        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);

        x_offset += @intCast(ch.advance[0]);
    }
}

3. 确保纹理数据正确上传(可选)

部分GPU对GL_RED内部格式的支持存在差异,可尝试将glTexImage2D的内部格式改为GL_R8,明确指定8位单通道格式:

c.glTexImage2D(
    c.GL_TEXTURE_2D,
    0,
    c.GL_R8, // 替换原来的GL_RED
    @intCast(face.*.glyph.*.bitmap.width),
    @intCast(face.*.glyph.*.bitmap.rows),
    0,
    c.GL_RED,
    c.GL_UNSIGNED_BYTE,
    face.*.glyph.*.bitmap.buffer,
);

4. 验证VAO绑定(关键)

若代码未绑定VAO(顶点数组对象),glVertexAttribPointer的设置不会被持久化,导致绘制时无法正确读取顶点数据和纹理坐标。初始化时需绑定VAO并保存配置:

// 初始化阶段创建并绑定VAO
var VAO: u32 = undefined;
c.glGenVertexArrays(1, &VAO);
c.glBindVertexArray(VAO);

// 绑定VBO、EBO并设置顶点属性
c.glBindBuffer(c.GL_ARRAY_BUFFER, self.egl.VBO);
c.glBindBuffer(c.GL_ELEMENT_ARRAY_BUFFER, self.egl.EBO[0]);
c.glVertexAttribPointer(0, 4, c.GL_INT, c.GL_FALSE, 0, null);
c.glEnableVertexAttribArray(0);

// 渲染时绑定VAO
pub fn renderText(...) void {
    // ... 其他代码
    c.glBindVertexArray(VAO); // 添加该行
    c.glDrawElements(c.GL_TRIANGLES, 6, c.GL_UNSIGNED_INT, null);
}

以上步骤中,修正顶点着色器和字符位置计算是解决文本消失最关键的两点,VAO绑定问题也可能导致完全无渲染输出。

内容的提问来源于stack exchange,提问作者osk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 00:50:57