iPhone opengl es alpha-blending. I have black colo

2020-07-10 08:12发布

问题:

I am developing iPhone game. I have the below Source image to draw it to the background. The Source image has alpha 0x00 and gradation around edge and the background's alpha is 0xff. When I draw the source image to the background, I have black color like you could see the Result image. I am using OpenGL ES glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) method. I have changed every possible arguments, but every time it is not moved.

Why do I have the black color in the edge of the source image? What is the problem? Does not every games in iphone use gradation?

Do I need to make the source image with out gradation?

Does anyone know the solution?

Source image :

Result image :

回答1:

Does your image have pre-multiplied alpha? Then you should be using

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

Here is some explanations of what it is.

Note: I rewrote the answer after doing some research. The article rotoglup mentioned has some insight on what's going on and it makes more sense then my original formula. I also tried to see what other people are using in their code and it looks like this formula is the most used one. It's amazing how such a basic thing in 3D graphics as alpha blending can be so controversial and everyone seems to reinvent the wheel and come up with their own solutions.



回答2:

Just check the view on which you are drawing is opaque or not. set opaque property to false



回答3:

One way this can occur is if you haven't correctly set your glTexParameteri for minification and magnification filters correctly, along with your clamp method. See Adam Redwood's comment here. Note issues of power-of-two textures, texture boundaries etc. may also come into play.

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );