简体   繁体   English

STB 将 png 加载到 OpenGl 纹理导致黑色或白色背景

[英]STB Loading png to OpenGl Texture results in black or white backgroud

Hello I've got weird problem with my code, i've been looking for some time on stack and found no answer, there was few similar problems, but they didn't solve anything.您好,我的代码有一个奇怪的问题,我一直在堆栈上寻找一段时间,但没有找到答案,几乎没有类似的问题,但他们没有解决任何问题。

int createTexture(const char* path) {
    unsigned int texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    int width, height, nrChannels;
    unsigned char* data = stbi_load(path, &width, &height, &nrChannels, 0);
    int colorMode = nrChannels == 3 ? GL_RGB : GL_RGBA;
    if (data) {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, colorMode, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    } else {
        std::cout << "Failed to load texture" << std::endl;
    }
    stbi_image_free(data);
    return texture;
}

Here i have function loading texture, I choose GL_RGB or GL_RGBA depending on number of channels.这里我有 function 加载纹理,我根据通道数选择 GL_RGB 或 GL_RGBA。 I've good results of 3 and 4 channels depending on jpg/png image i use.根据我使用的 jpg/png 图像,我有 3 和 4 个通道的良好结果。 Anyways i have white background, ( it was black before i edited it in GIMP )无论如何我有白色背景,(在我在 GIMP 中编辑之前它是黑色的)

// set the texture wrapping/filtering options (on currently bound 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);


    

// load and create a texture 
    // -------------------------
    unsigned int texture1 = createTexture("brick.jpg");
    unsigned int texture2 = createTexture("grafiti.png");

    // Mode

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    // Shader Class

    Shader currentShader("vertexShader.glsl", "fragmentShader.glsl");

    currentShader.use();
    currentShader.setInt("texture1", 0);
    currentShader.setInt("texture2", 1);

    while (!glfwWindowShouldClose(window)) {
        processInput(window);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture1);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, texture2);
        currentShader.use();
        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, sizeof(indices) / sizeof(int), GL_UNSIGNED_INT, 0);
        glBindVertexArray(0);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

Then I use this textures together with this shaders然后我将此纹理与此着色器一起使用

Fragment分段

#version 330 core
out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

uniform sampler2D texture1;
uniform sampler2D texture2;

void main()
{
    FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 1);
}

Vertex顶点

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;

out vec3 ourColor;
out vec2 TexCoord;

void main()
{
    gl_Position = vec4(aPos, 1.0);
    ourColor = aColor;
    TexCoord = aTexCoord;
}

float vertices[] = {
        // positions // colors // texture coords
        0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
        0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
        -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left
        -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
    };

    unsigned int indices[] = {
        0, 1, 3,
        1, 2, 3,
    };

    unsigned int VBO;
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);


    unsigned int VAO;
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    unsigned int EBO;
    glGenBuffers(1, &EBO);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

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

I'm sorry if my english is hideous but it's middle of the night and i'm struggling with this for hours right now如果我的英语很糟糕,我很抱歉,但现在是半夜,我现在已经为此苦苦挣扎了好几个小时

I found solution, enabling blend was not satisfying so i wrote fragmentShader in different way我找到了解决方案,启用混合并不令人满意,所以我以不同的方式编写了 fragmentShader

#version 330 core
out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

uniform sampler2D texture1;
uniform sampler2D texture2;

void main()
{
    vec4 AlphaColor = texture(texture2, TexCoord);
    if(AlphaColor.a < 0.1) {
        FragColor = texture(texture1, TexCoord);
    } else {
        FragColor = mix(texture(texture1, TexCoord), AlphaColor, 0.9);
    }
}

Right now FragmentShader understands alpha channel and will mix only pixels without alpha现在 FragmentShader 理解 alpha 通道,并且只会混合没有 alpha 的像素

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM