我如何在这个基本的OpenGL演示中修复这个纹理渲染问题?

btqmn9zl  于 2022-09-26  发布在  其他
关注(0)|答案(1)|浏览(192)

我试着用Rust OpenGL制作了一个基本的正方形+纹理演示,我渲染的纹理如下所示:

...虽然它应该是这样的:

下面是我的纹理创建和上传代码,这是learnopengl.com创建、绑定和上传基本纹理的版本的 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))
                }
            }
        }

以下是我的着色器:

const VERT_SHADER: &str = r#"#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;
         }"#;

const FRAG_SHADER: &str = r#"#version 330 core
        out vec4 final_color;

        in vec2 texCoords;

        uniform sampler2D Texture;

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

这是我从learnopengl.com上买的VAOS、VBO和EBO

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

a14dhokn1#

问题是VAO中第二个参数的偏移量不正确。它当前的偏移量是2,而实际上它的偏移量应该是3。这会导致纹理坐标被解释为[0.0, 1.0][0.0, 1.0][0.0, 0.0][0.0, 0.0]。这实际上会导致忽略采样的y轴,因为纹理仅沿其对角线进行采样。

以下是通话的更正版本:

glVertexAttribPointer(
    1,
    2,
    GL_FLOAT,
    GL_FALSE,
    (5 * size_of::<f32>()) as GLsizei,
    (3 * size_of::<f32>()) as *const _,  // <- This was the line with the issue
);

相关问题