开发者

glBlendFunc Disables Shader

开发者 https://www.devze.com 2023-04-03 11:53 出处:网络
I have a very simple shader (just sets a background square to green) and this works perfectly. I recently added in some quads that have a texture applied to them. This texture has 开发者_运维技巧some

I have a very simple shader (just sets a background square to green) and this works perfectly.

I recently added in some quads that have a texture applied to them. This texture has 开发者_运维技巧some alpha values so I use this to call it:

    glEnable (GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_TEXTURE_2D); 
    glBindTexture(GL_TEXTURE_2D, textureID);

    //draw quad

    glDisable(GL_TEXTURE_2D); 
    glBlendFunc (GL_ONE, GL_ZERO);
    glDisable (GL_BLEND);
    glBindTexture(GL_TEXTURE_2D, 0); //remove texture

The quad displays fine with the transparency - but the shader in the background is now gone. It's still being drawn but it is not displaying.

Now I removed both of the glBlendFunc(...) lines and the shader appears again (but I lose the alpha blending). However, whenever I call that function the shader seems to just stop working.

Any ideas on why this could be happening?

Image with glBlendFunc removed:

glBlendFunc Disables Shader

Image with glBlendFunc used:

glBlendFunc Disables Shader

Shader loading code:

    //create shaders
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

    //grab the char so we can send it to gfx card
    const char* vShadData = loadFile(vertexShaderFile);
    const char* fShadData = loadFile(fragShaderFile);

    //send data to gfx card
    glShaderSource(vertexShader, 1, (const GLchar **)&vShadData, NULL);
    glShaderSource(fragmentShader, 1, (const GLchar **)&fShadData, NULL);

    //check if compiled
    GLint compiled;

    glCompileShader(vertexShader);
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compiled);
    if(compiled==FALSE)
    {
        //doesn't get here
    }
    glCompileShader(fragmentShader);
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compiled);
    if(compiled==FALSE)
    {
        //doesn't get here
    }

    //finally, create shader program
    shaderProgram = glCreateProgram();

    //attach shaders to program
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);

    glLinkProgram(shaderProgram);

    GLint linkStatus;
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, (GLint *)&linkStatus);
    if(linkStatus==FALSE)
    {
        //doesn't get here
    }

Vert Shader (very simple):

void main(void)
{
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

Frag Shader:

void main(void)
{
    gl_FragColor = vec4(0.0, 0.3, 0.0, 0.0);
}


In your fragment shader you set the color (0, 0.3, 0, 0), which is a dark green color with an alpha of 0. With blending enabled and the standard glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) the alpha basically represents the opacity of the color and an opacity of 0 means, well, a perfectly transparent background.

So just change the background's alpha to 1 and you should see it again.

gl_FragColor = vec4(0.0, 0.3, 0.0, 1.0);

But keep in mind to render your background first, before the other shapes for them to correctly blend onto the background. You might also just disable blending when rendering the background and only enable it for the textured objects. But anyway using an alpha of 1 is the conceptually right way to say that your background is fully opaque.


The code for drawing a quad is like this:

glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D); 
glBindTexture(GL_TEXTURE_2D, textureID);

glBegin(GL_TRIANGLE_FAN);
    glTexCoord2f(0.0f, 0.0f);
    glVertex2f(-1.0f, 1.0f);    
    glTexCoord2f(1.0f, 0.0f);
    glVertex2f( 1.0f, 1.0f);
    glTexCoord2f(1.0f, 1.0f);
    glVertex2f( 1.0f,-1.0f);
    glTexCoord2f(0.0f, 1.0f);
    glVertex2f(-1.0f,-1.0f);
glEnd();
glDisable(GL_TEXTURE_2D); 
glBlendFunc (GL_ONE, GL_ZERO);
glDisable (GL_BLEND);
glBindTexture(GL_TEXTURE_2D, 0); //remove texture

Now for both the shader quad and the textured quad I use the same code. However, I never load a texture for the shader quad, so the textureID I send to opengl is -1.
After changing this code to NOT bind textureID if it is == to -1 the shader works the way it should, and I still get transparency on my textured quads.

However Christian Rau's answer found a bug in my code - which is probably the main reason why this failed.

0

精彩评论

暂无评论...
验证码 换一张
取 消