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

如何修复Rust OpenGL基础Demo中的纹理渲染异常问题?

OpenGL纹理渲染异常排查与修复

当前渲染效果:错误渲染效果
预期渲染效果:预期纹理效果

纹理创建与上传代码(Rust)

pub fn from_image(file: String) -> Result<Texture, String> {
    let mut texture: GLuint = 0;
    match image::open(file.clone()) {
        Err(err) => panic!("Could not load image {:?}: {}", file, err),
        Ok(img) => {
            let (width, height) = img.dimensions();
            let img = match img {
                DynamicImage::ImageRgb8(img) => img,
                img => img.to_rgb8(),
            };

            unsafe {
                glGenTextures(1, &mut texture);
                if texture == 0 {
                    return Err(String::from("Error creating texture"));
                }

                glBindTexture(GL_TEXTURE_2D, texture);

                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT as GLint);  // set texture wrapping to GL_REPEAT (default wrapping method)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT as GLint);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                                GL_LINEAR_MIPMAP_LINEAR as GLint);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
                                GL_LINEAR as GLint);

                glTexImage2D(GL_TEXTURE_2D,
                             0,
                             GL_RGB8 as GLint,
                             width as GLsizei,
                             height as GLsizei,
                             0,
                             GL_RGB,
                             GL_UNSIGNED_BYTE,
                             img.as_raw().as_ptr().cast());

                glGenerateMipmap(GL_TEXTURE_2D);
            }
            Ok(Texture(texture))
        }
    }
}

着色器代码

顶点着色器

#version 330 core
layout (location = 0) in vec3 pos;
layout (location = 1) in vec2 aTexCoords;

out vec2 texCoords;

void main() {
   gl_Position = vec4(pos.x, pos.y, pos.z, 1.0);
   texCoords = aTexCoords;
}

片段着色器

#version 330 core
out vec4 final_color;

in vec2 texCoords;

uniform sampler2D Texture;

void main() {
    final_color = texture(Texture, texCoords);
}

VAO/VBO/EBO相关代码(Rust)

const VAO: [Vertex; 4] =
    [[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], [-0.5, 0.5, 0.0, 0.0, 1.0]];

const EBO: [TriIndexes; 2] = [[0, 1, 3], [1, 2, 3]];

unsafe {
    glVertexAttribPointer(
        0,
        3,
        GL_FLOAT,
        GL_FALSE,
        (5 * size_of::<f32>()) as GLsizei,
        0 as *const _,
    );

    glEnableVertexAttribArray(0);

    glVertexAttribPointer(
        1,
        2,
        GL_FLOAT,
        GL_FALSE,
        (5 * size_of::<f32>()) as GLsizei,
        (2 * size_of::<f32>()) as *const _,
    );

    glEnableVertexAttribArray(1);
}

问题排查与修复

1. 核心错误:纹理坐标偏移计算错误

顶点数据结构为[3个位置分量, 2个纹理分量],但你设置纹理属性指针时,偏移量写为(2 * size_of::<f32>()),这会导致OpenGL从位置数据的第2个float开始读取纹理坐标,完全错位。

修改后的纹理属性指针代码:

glVertexAttribPointer(
    1,
    2,
    GL_FLOAT,
    GL_FALSE,
    (5 * size_of::<f32>()) as GLsizei,
    (3 * size_of::<f32>()) as *const _,
);

2. 可选补充优化

  • 图像对齐处理:如果图像宽高不是4的倍数,可能出现纹理错位,可在glTexImage2D前添加:
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    
  • 纹理单元绑定验证:渲染前确保激活并绑定纹理单元(单纹理场景默认可不显式设置,但多纹理场景必须):
    unsafe {
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture.0);
        let loc = glGetUniformLocation(shader_program, "Texture\0".as_ptr());
        glUniform1i(loc, 0);
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:39:21