Reputation: 4254
I'm using GLKit for an iPad app. With this code I setup blending:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
It works fine, but when I try to get a screenshot the blend mode seems wrong. It doesn't matter if I use GLKit's snapshot or glReadPixels.
This is what I get when working with the app:
And this is the screenshot:
Do I have to change the Blend Mode or something before I make the screenshot? And if so, to what?
Upvotes: 1
Views: 1112
Reputation: 16774
The problem you are having lies most likely in how the image is generated from the RGBA data. To solve this you will need to skip the alpha channel when creating CGImage
with kCGImageAlphaNoneSkipLast
or have the correct alpha values in the buffer in the first place.
To explain what is going. Your GL buffer consists of RGBA values but only RGB part is used to present it but when you create the image you use the alpha channel as well, thus the difference. How it comes to this is very simple, lets take a single pixel somewhere in the middle of the screen and go through its events:
(.4, .4, .4, .25)
. Your blend function says to multiply the source color with the source alpha and the destination with 1 - source alpha. That results in (.4, .4, .4, .25)*.25 + (.8, .8, .8, 1.0)*.75 = (.7, .7, .7, .76)
Now the result (.7, .7, .7, .76)
is displayed nicely because your buffer only presents the RGB part resulting in seeing (.7, .7, .7, 1.0)
but when you use all 4 components to create the image you also use the .76 alpha value which is further used to blend the image itself. Therefor you need to skip the alpha part at some point.
There is another way: As you can see in your case there is really no need to store the alpha value to the render buffer at all as you never use it, in your blend function you only use source alpha. Therefore you may just disable it using glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE)
, this also means you need to clear the alpha value to 1.0 (glClearColor(x,x,x,1.0)
)
Upvotes: 4