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

Rust OpenGL纹理编程代码显示黑三角无报错如何解决

Rust + OpenGL 纹理渲染黑三角形问题修复

代码存在5处直接导致纹理不生效、渲染结果异常的问题,按影响优先级排序:

  • 顶点索引越界:定义的VERTICES数组仅包含3个顶点(有效索引范围0~2),但INDICES数组中引用了不存在的索引3,且总共有6个索引值试图绘制两个三角形,OpenGL读取越界内存拿到的垃圾纹理坐标、顶点位置会直接导致渲染结果异常。
  • 未校验纹理加载结果:调用stbi_load后没有判断返回指针是否为空,只要图片路径错误、文件损坏导致加载失败,就会把空指针传给glTexImage2D,上传的纹理数据为空,自然渲染全黑。
  • 渲染前未绑定纹理:纹理加载完成后调用glBindTexture(GL_TEXTURE_2D, 0)解绑了纹理,后续渲染循环中从来没有重新把纹理绑定到活动纹理单元,片元着色器的sampler2D采样不到有效纹理数据。
  • 纹理格式硬编码:调用glTexImage2D时写死了像素格式为GL_RGB,如果加载的png是带透明通道的4通道RGBA格式,格式不匹配会导致像素解析错误,输出异常颜色。
  • 纹理坐标范围异常:定义的纹理坐标存在负值,且未对齐OpenGL纹理坐标原点在左下角的规则,即使纹理正常加载也会出现采样错位。

关键修复代码

1. 修正顶点定义

如果绘制单个带纹理的三角形,可直接去掉EBO使用glDrawArrays避免索引越界,同时把纹理坐标归一化到[0,1]范围:

type Vertex = [f32; 5]; //x, y, z, tx, ty
const VERTICES: [Vertex; 3] = [
    [0.5, 0.5, 0.0, 1.0, 1.0],   // 右上顶点 对应纹理右上角
    [0.5, -0.5, 0.0, 1.0, 0.0],  // 右下顶点 对应纹理右下角
    [-0.5, -0.5, 0.0, 0.0, 0.0], // 左下顶点 对应纹理左下角
];

注意:stb_image默认加载的图片y轴原点在左上角,和OpenGL纹理坐标原点相反,需要在加载纹理前调用stbi_set_flip_vertically_on_load(1)开启垂直翻转,否则纹理会上下颠倒。

2. 增加纹理加载校验、适配通道数

// 加载纹理前开启y轴翻转
stbi_set_flip_vertically_on_load(1);
let _data = stbi_load(path, &mut width, &mut height, &mut nrChannels, 0);
if _data.is_null() {
    panic!("纹理加载失败,请检查文件路径与文件完整性");
}
// 根据图片实际通道数自动选择像素格式
let format = match nrChannels {
    3 => GL_RGB,
    4 => GL_RGBA,
    _ => panic!("不支持的纹理通道数")
};

glTexImage2D(
    GL_TEXTURE_2D,
    0,
    format as i32,
    width,
    height,
    0,
    format,
    GL_UNSIGNED_BYTE,
    _data as *const c_void
);

3. 渲染前绑定纹理

着色器初始化完成后,先给采样器设置关联的纹理单元,渲染循环中激活对应单元并绑定纹理:

// 着色器链接完成后设置一次即可
let tex_loc = glGetUniformLocation(
    shader_program.id, 
    CString::new("tex").unwrap().as_ptr()
);
glUniform1i(tex_loc, 0); // 把采样器tex关联到0号纹理单元

// 渲染循环内绘制逻辑
unsafe {
    glClearColor(0.2, 0.3, 0.3, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    shader_program.use_program();
    // 激活0号纹理单元,绑定创建好的纹理
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, tex);
    vao.bind();
    // 绘制三角形,不需要EBO
    glDrawArrays(GL_TRIANGLES, 0, 3);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 10:45:39