OpenGL Blending Color over Monochrome - opengl

I am wanting to set up a blend (without using shaders preferably) to produce the following.
I have a black/white textured quad, and a quad of a solid color(for example red). I'd like the blend to show the color (red) where all the white pixels are and black otherwise.
Is this possible and what does the code look like?

This typically not done by blending, but you could try glBlendFunc(GL_SRC_COLOR, GL_ZERO); drawing the red quad on top of the text.
However this will only work if there's no other content in the framebuffer.

Related

Rendering transparent texture onto glTexture

I've been working in opengl for a while relatively smoothly, but recently I've noticed that when I render a primitive with a transparent texture onto my fbo texture (custom frame buffer) it makes the fbo texture transparent at the pixels the primitive's texture is transparent. The problem is that there are things behind this primitive (with solid color) already rendered before the transparent one. So the fbo texture should not be transparent at those pixels - blending a solid & transparent color should result in a solid color, shouldn't it?
So basically, opengl is adding transparency to my fbo-texture just because the last primitive drawn has transparent pixels even though there are solid colors behind it already drawn into the fbo texture. Shouldn't opengl blend the transparent texture with the fbo's existing pixels, and result in a solid color if the fbo texture is already filled with solid colors before rendering the transparent primitive?
What happens when I render my fbo texture to the default frame buffer, is that the clear color bleeds through parts of it - where the last drawn texture is transparent. But when I render the same scene straight to the default opengl frame buffer, the scene looks fine and the clear color is not bleeding into the transparent texture.
What's even more interesting is that the glClearColor - color is only visible where the primitive's texture's alpha has a gradient - the clear color has no influence on where the texture alpha is 1.0 or 0.0... is this a bug? It seems to affect the primitive's texture the most at pixels with 0.5 alpha. Then going further above or below decreases the glClearColor influence.
I know it's a bit of a complex question/situation, I honestly tried my best to explain
I'm using:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
to draw both the partly transparent primitive into the fbo-texture, and then the fbo texture to the default framebuffer
This is what the fbo-texture drawn into the default opengl fbo looks like:
glClearColor is set to red.
blending a solid & transparent color should result in a solid color, shouldn't it?
Only if your blend mode tells it to. And it doesn't:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
This applies the same blending operation to all four components of the colors. This causes the final alpha to be the result of multiplying the source alpha by itself and adding that to the destination alpha times 1-src alpha.
Now, you could use separate blend functions for the color and the alpha:
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
The last two parameters specify the blending for just the alpha, while the first two specify the blending for the RGB colors. So this preserves the alpha. Separate blend functionality is available on GL 3.x and above, but is also available as an extension on older hardware.
But it seems to me that you probably don't want to change the alpha at all. So simply mask alpha writes when rendering to the texture:
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
Don't forget to undo the alpha mask when you want to write to it again.

OpenGL blending: texture on top overlaps its pixels which should be transparent (alpha = 0)

I am drawing a map texture and, on top of it, a colorbar texture. Both have alpha channel and I am using blending, set as
// Turn on blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
However, the following happens:
The texture on top (colorbar) with alpha channel imposes its black pixels, which I don't want to happen. The map texture should appear behind where the colorbar alpha = 0.
Is this related to the blending definitions? How should I change it?
Assuming the texture has an alpha channel and it's transparent in the right places, I suspect the issue is with the rendering order and depth testing.
Lets say you render the scale texture first. It blends correctly with a black background. Then you render the orange texture behind it, but the pixels from the scale texture have a higher depth value and cause the orange texture there to be discarded.
So, make sure you render all your transparent stuff in back to front order, or farthest to nearest.
Without getting into order independent transparency, a common approach to alpha transparency is as follows:
Enable the depth buffer
Render all your opaque geometry
Disable depth writes (glDepthMask)
Enable alpha blending (as in the OP's code)
Render your transparent geometry in farthest to nearest order
For particles you can sometimes get away without sorting and it'll still look OK. Another approach is using the alpha test or using alpha to coverage with a multisample framebuffer.

Inverted-colors text on top of an OpenGL scene

I have a font texture which I use in order to draw text on top of my OpenGL scene.
The problem is that the scene's colors vary so much that any solid color I use is hard to read. Is it possible to draw my font texture with inverted colors?
A call to glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); would just draw it with a solid color, A call to glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); would draw it inverted, but would disregard the alpha values of the texture so you'd just see an inverted rectangle instead of the letters.
What I need is something equivalent to
glBlendFunc(GL_SRC_ALPHA * GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
Can this be achieved somehow without using shaders ?
Following dave's comment:
Instead of using a GL_ALPHA texture I generate a GL_RGBA texture where each pixel is equal:
(alpha, alpha, alpha, 0xff) (this is a greyscale image instead of a luminance image).
Then I use this texture with:
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR);
The result is: (1 - dest_color) x "src_alpha" + dest_color x (1 - "src_alpha")
which is exactly what I needed.
Copy the subsection of the screen you want to overwrite, you can use the CPU to invert this copied portion. Draw your newly made inverted texture to the screen using the text as a mask.
Note that this is slow, there's no doubt that shaders would be much faster.

Opengl: use a texture only to give alpha channel to a colored object

I'm new at OpenGL and I can't find out how to do this:
I want to render a letter and be able to change it's color, so I have a texture with the letter on a transparent background. I managed to render it using this code:
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
But that renders the letter in black, as it's on the texture. How can I render it with the color setted with glColor4f?
Have you been messing with glTexEnv? If you did, call :
glTexEnv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
and that will restore the default behaviour, which is to multiply the texture color with the vertex color.
There are a couple of other possibilities. One would be to put the shape of the letter into the stencil buffer, and then draw a quad in your preferred color. Another would be to draw your text in light grey, and use lighting to have it displayed in the color you want.

Framebuffers, textures and glColor behavior in OpenGL/OpenGL ES

I apologize in advance if this question seems confused. The behaviour I am seeing makes no sense to me.
I have a Framebuffer rendering to a texture. I render solid rectangles of red, green, blue of varying opacity to this texture. I then render the texture to the screen (Framebuffer 0). The Framebuffer attached to the texture is persistent, and in each render loop I draw more rectangles to the texture -- eventually filling the screen.
I have found that if I do not set glColor() to white 100% opacity before rendering the texture to the screen, rectangles of particular colours will not be rendered. That is if glColor(1.f, 0.f, 0.f, 1.f) is set before rendering the texture, only the blue rectangles will be drawn.
I don't understand why the current colour would have an affect on the rendering of the texture (which I assume is like a blit). I have tried various texParameter(...) calls to no avail, but I am just guessing.
Thanks.
Amongst other things, glColor() sets the color used for a vertex. When the textured rectangle is drawn, each texel sample is multipled by the vertex color. Well, actually, a linear interpoloation of the vertices of the primitive which is simply the vertex color if all the verticies have the same color.
This tutorial explains the implications of all this pretty well:
http://www.falloutsoftware.com/tutorials/gl/gl4.htm
The only odd part here is your statement that glColor(1, 0, 0, 1) causes only blue rectangles to be drawn. I would expect that to be only red rectangles if the parameters to glColor are red, green, blue and alpha. Hopefully there's a typo or the parameter order is different such that red = 0, green = 0, blue = 1 and alpha = 1.