使用sampler2D时OpenGL显示条纹

时间:2019-07-15 13:51:15

标签: c++ opengl

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

应该绘制的是具有此纹理的矩形: enter image description here

奇怪的是,当我调整窗口大小时,条纹的厚度也会改变: enter image description here

我认为着色器没有任何问题,但是在这里:

//-----------------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);

抱歉,如果有很多代码,但是我不知道问题出在哪里。你们中的任何人以前见过这样的东西,并且知道如何解决吗?

1 个答案:

答案 0 :(得分:1)

感谢@Botje,问题已解决。使用glTexImage2D给OpenGL的通道数量不等于nrChannels。我能够在switch内部使用简单的load_texture来解决这个问题。这是更新的版本:

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