Search code examples
c++opengl-esglslfragment-shader

GLSL pass multiple arguments to shaders


I made a program that displays some textures like this it works just fine:

    void Texture::render(int w, int h, uint8_t *buffer)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
        glGenerateMipmap(GL_TEXTURE_2D);

        glActiveTexture(GL_TEXTURE0);

        shader.use();
        unsigned int transformLoc = glGetUniformLocation(shader.ID, "transform");
        glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));

        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    }

And this is the fragment shader:

#version 300 es
precision mediump float;
out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

uniform sampler2D texture1;

void main()
{
    vec4 nColor = texture(texture1, TexCoord);  
    FragColor = vec4(nColor.r, nColor.g, nColor.b, 1);
}

Normally this works fine, but I need to pass an argument to decide the transparency (currently it's 1 in the FragColor = vec4(...))

I've tried doing this to no avail:

void Texture::render(int w, int h, uint8_t *buffer)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
        glGenerateMipmap(GL_TEXTURE_2D);

        glActiveTexture(GL_TEXTURE0);

        shader.use();
        unsigned int transformLoc = glGetUniformLocation(shader.ID, "transform");
        glUniform1f(transformLoc, 0.5f);
        glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));

        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    }

And simply changed the fragment shader to this:

#version 300 es
precision mediump float;
out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

uniform sampler2D texture1;
uniform float transparency;

void main()
{
    vec4 nColor = texture(texture1, TexCoord);  
    FragColor = vec4(nColor.r, nColor.g, nColor.b, transparency);
}

How am I supposed to properly do this? I want to pass transparency as an additional argument.


Solution

  • Enable Blending (also see LearnOpenGL - Blending) and:

    unsigned int transparencyLoc = glGetUniformLocation(shader.ID, "transparency");
    
    float alpha = ...;
    glUniform1f(transparencyLoc, alpha);
    

    I suggest multiplying the alpha channel of the texture and the value of the uniform in the fragment shader:

    uniform sampler2D texture1;
    uniform float transparency;
    
    void main()
    {
        vec4 nColor = texture(texture1, TexCoord);  
        FragColor = vec4(nColor.rgb, nColor.a * transparency);
    }