I am attempting to put together a simple program that just displays two textured quads overlapping each other, and the textures have alpha channels.
I have successfully been able to get the quads themselves to display, and the textures look correct except for the transparency.
On this topic, the GL_BLEND flag does not seem to do anything at all, whether it is enabled or not. Is this particular flag inapplicable when shaders are being used?
I know for a fact that the alpha is being rendered in correctly, since if I set out_color = texture.aaaa, I get a nice pattern of blacks/whites/grays that match the original texture.
So, if GL_BLEND doesn't work, what are the usual methods for getting alpha blending working?
All that glEnable(GL_BLEND) does is turn blending on and off. It does not say what the blending will do; that is controlled by the various blending functions. If you want a typical alpha transparency blend, you do this:
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
If you use pre-multiplied alpha (and you probably should), you would do:
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
Related
There may be an easier way to do this, I can do it with a shader I'd imagine, but I feel like setting the blend function is simpler.
Shader would maybe be gl_FragColor = vec4(texture.rgb, 0);
For a reason, I need to have a freshly cleared FBO filled with a transparent (0) texture. That way the pixels in the FBO are visually transparent, but contain the RGB values of the texture.
It's tough to explain, but it's essentially a glClear() but with a texture rather than a solid color. Is there a combination blend src/dst function that would accomplish this?
Basically it shouldn't matter what the FBO looks like beforehand. I then want to render a texture to it, but since I'm rendering it with alpha 0, it's not overriding the existing FBO pixels.
If you really want to do this via blending, you can do this via the separate blend factors introduced originally in GL_EXT_blend_func_separate (promoted to OpenGL core functionalitiy in Version 2.0):
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ZERO, GL_ZERO);
glBlendEquation(GL_ADD); // is the default anyway
Is there a blending equation that can be made using the OpenGL glBlendFunc that would allow for a transparent color (RGBA) to be rendered behind an additive overlay.
Rendering Ontop:
This effect can be achieved using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Rendering Underneath:
Is there an equation for this blending effect?
There are no glBlendFunc options for directly drawing overlay. Info can be found here:
http://benmcdowell.com/implementing-photoshop-blend-modes-in-opengl/
However, your effect doesn't seem to be overlay, seems to be either screen
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
or additive
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
I'd suggest you try all combinations, there aren't that many possible. If you need crazier effects however, you'll need to code shaders.
P.S. I lied. You don't HAVE to code shaders to do crazy effects like overlay, but you have to draw so many times it becomes unusable in real time. I should have said it's better to use shaders.
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
and used this in the fragment shader.
I've used Alpha blend to get the transparency working however it only seems to work from one side.
Not sure what the problem is, am new to programming and shading.
http://imgur.com/WDK4qjc Link to see the picture
I think you see 2 distant faces blending where color is darker.
Maybe Culling is not activated.
Face culling is the ability to discard face drawing upon certain condition.
To achieve what you want, You have to discard faces not facing the camera which is call backface culling. You do this:
glEnableGL(GL_CULL_FACE); //(enable face culling)
glCullFace(GL_BACK); //(discard back faces)
Everything is fine. It's called Transparency Sorting.
Some more info:
http://www.opengl.org/archives/resources/faq/technical/transparency.htm
Rendering transparent objects in OpenGL
opengl z-sorting transparency
I am loading a PNG using:
theImage = [NSBitmapImageRep imageRepWithContentsOfFile:imagePath];
from which I can successfully create a gl texture and render correctly without any transparency. However, when I switch blending on using:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
The texture renders with the correct transparent background, but the image colours are incorrect.
I have tried several options in the blend function, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_DST_ALPHA, etc.
I was taught maybe I need to reorder the bits in the image data, maybe the channels have been mixed up, but I would not expect it to render correctly when blending is off in that case.
Alternatively, I could use libPNG I guess, but I would like to try using a NSBitmapImageRep if it is possible.
How about supplying a screenshot?
Anyway, your blending function is wrong either way for simple transparency channel blending. It should be either
normal alpha: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
or
premultiplied alpha: glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
I'm trying to render some transparent objects using:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
However, I don't get the result I want.
I draw a fully opaque square, and then i draw a semi-transparent square. The colors are just as a I would expect however, the alpha channel is NOT fully white as I want.
Basically I want the following equation:
r = old_r*(1.0-a)+r*a;
g = old_g*(1.0-a)+g*a;
b = old_b*(1.0-a)+b*a;
a = old_a + a;
Is this possible to achieve using glBlendFunc or do I have to resort to shaders and multiple FBOs for read-back?
You basically want separate blend functions for color and alpha, and this is achieved by using glBlendFuncSeparate:
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
Does the blend func you want.
Just draw your opaque square, then check the alpha channel. If it's not showing up as fully white when a known-opaque square is rendered, you may have a problem with some other setting.