使用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
相关产品推荐
相关产品推荐

