简体   繁体   中英

glBlendFunc transparency in OpenGL with GLKit

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?

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:

  1. You clear the pixel to any color you want
  2. You overwrite the pixel (all 4 channels RGBA) with a solid color received from the texture for instance (.8, .8, .8, 1.0)
  3. You draw a color over that pixel with some smaller alpha value and try to blend it, for instance (.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) )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM