Reputation: 2418
I'm working on an OpenLG ES 2.0 app for iOS, and I've come across some unexpected behaviour with the blending functions. I think this is probably just a lack of understanding and not specific to my app. My thought was that if you had a textured polygon and you call:
glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA)
before drawing, that you'd be able to see the clear colour behind the polygon where the texture is not transparent. However, when I try this, all I see is black where I would expect it to be transparent.
I've adapted some code from raywenderlich.com so show this happening in a very simple scenario and put it on GitHub here. I would like to be able to get the fish to show the clear colour (green), but instead it is black.
Any help would be greatly appreciated. Thanks!
Upvotes: 0
Views: 4546
Reputation: 172
as you know, when you use glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
first draw dest is glClearColor(0, 0, 0, 1.0); black color
src is you texture you fish image, because you use src zero, at last the color is black,
you can use
// src*(1)+dest*(1-src.alpha)
// glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
// src*(src.alpha)+dest*(1-src.alpha)
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Upvotes: 0
Reputation: 577
This is pretty specific to how I understood your problem.
You could:
glBlendFunc(GLES20.GL_ONE,GLES20.GL_ONE);
glBlendFunc(GLES20.GL_ONE_MINUS_DST_ALPHA,GLES20.GL_DST_ALPHA);
And you should be "seeing through" the second texture.
Upvotes: 0
Reputation: 54642
This looks like expected behavior. Based on your question, I think the main disconnect is about what exactly the clear color is, and what happens when you clear your color buffer.
The clear color is exactly what the name suggests. It is the color used to fill your color buffer when you call glClear(GL_COLOR_BUFFER_BIT | ...)
. It plays no role beyond that. In particular, it's not a background color that shows through parts of your rendering that are transparent at the end of the frame.
Based on this, let's walk through what happens in your example:
There are a number of different ways to achieve the result you are looking for.
(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
as the blend function. The downside of this is that the background color is baked into the texture.Similar to 1. Use the same blend function, but you feed the background color as a uniform into your fragment shader when you render the fish. Then in the shader, use the alpha value sampled from the texture for the alpha component of the fragment color, and use the uniform color for the RGB components of the fragment color. The key parts of the fragment shader would look like this:
uniform vec3 FishColor;
uniform sampler2D FishSampler;
...
vec4 texVal = texture2D(FishSampler, ...);
glFragColor = vec4(FishColor, texVal.a);
Render the grey square and the fish with a single draw call, with both textures bound. Enable blending with (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
during that draw call, and combine the square and the fish in the fragment shader:
uniform sampler2D SquareSampler;
uniform sampler2D FishSampler;
...
vec4 squareTexVal = texture2D(SquareSampler, ...);
vec4 fishTexVal = texture2D(FishSampler, ...);
glFragColor = vec4(squareTexVal.rgb, 1.0 - fishTexVal.a);
Note that the texture coordinates for the square and the fish textures will most likely have to be different to get both of them properly placed.
Upvotes: 2