使用sampler2D时OpenGL显示条纹

rfbsl7qr  于 2022-09-26  发布在  其他
关注(0)|答案(2)|浏览(178)

在尝试用C++编写OpenGL应用程序时,我遇到了一个奇怪的问题。在减少代码后,我发现问题出在纹理采样上。纹理顶部有奇怪的条纹:

应该绘制的是一个具有以下纹理的矩形:

奇怪的是,当我调整窗口大小时,条纹的粗细也发生了变化:

我不认为着色器有任何问题,但以下是它们:

//-----------------Vertex-----------------

# version 330 core

layout (location = 0) in vec3 pos_;
layout (location = 1) in vec3 color_;
layout (location = 2) in vec2 uv_;

out vec2 uv;

void main()
{
    uv = uv_;
    gl_Position = vec4(pos_, 1.0);
}
//-----------------Fragment---------------

# version 330 core

out vec4 frag_color;

in vec2 uv;

uniform sampler2D diffuse_;

void main()
{
    frag_color = texture(diffuse_, uv);
}

我也认为这可能不是纹理加载问题的原因,但无论如何,它是:

GLuint load_texture(const std::string& source)
{
    GLuint texture = 0;

    int width, height, nrChannels;
    unsigned char* data = stbi_load(source.c_str(), &width, &height, &nrChannels, 0);
    if (data != nullptr)
    {
        glGenTextures(1, &texture);
        glBindTexture(GL_TEXTURE_2D, texture);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    else
    {
        std::cerr << "Failed to load texture" << std::endl;
    }
    stbi_image_free(data);

    return texture;
}

此外,如果它可以提供帮助,下面我提供了分配顶点属性的代码:

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(0 * sizeof(GLfloat)));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);

并将纹理设置为均匀:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, diffuse);

glUseProgram(shader);
glUniform1i(glGetUniformLocation(shader, "diffuse_"), 0);

抱歉,如果代码太多,但我不知道问题出在哪里。你们当中有没有人以前见过这样的东西,知道如何修复它?

vxf3dgd4

vxf3dgd41#

多亏了@Botje,问题才得以解决。提供给具有glTexImage2D的OpenGL的通道数不等于nrChannels。我能够通过在load_texture中使用一个简单的switch来解决这个问题。以下是更新版:

GLuint load_texture(const std::string& source)
{
    GLuint texture = 0;

    int width, height, nrChannels;
    unsigned char* data = stbi_load(source.c_str(), &width, &height, &nrChannels, 0);
    if (data != nullptr)
    {
        glGenTextures(1, &texture);
        glBindTexture(GL_TEXTURE_2D, texture);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        GLenum format;
        switch (nrChannels)
        {
        case 1:
            format = GL_LUMINANCE;
            break;
        case 2:
            format = GL_LUMINANCE_ALPHA;
            break;
        case 3:
            format = GL_RGB;
            break;
        case 4:
            format = GL_RGBA;
            break;
        }

        glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    else
    {
        std::cerr << "Failed to load texture" << std::endl;
    }
    stbi_image_free(data);

    return texture;
}
ego6inou

ego6inou2#

我在加载jpg图像时遇到了同样的问题。设置GL_UNPACK_ALIGNLY修复了这个问题。https://github.com/nothings/stb/issues/695

if (channels == 3) {
        //HERE WAS THE MISTAKE
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

    }

相关问题