glBlendFunc Disables Shader
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:
Image with glBlendFunc used: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.
精彩评论