I try to render an object, but I don't want its edge blend with the background.
I use only 2 colors: red for the object, and white for the background.
When I get the pixels of the frame with glReadPixel() I see that there are other colors except for
red and white, a blending colors. These colors are located on the edges of the object.
Eventually, I need to get a picture of 2 colors only.
Someone can help me to solve this?
(note: I used glDisable(GL_BLEND) to make sure it didn't work)
Related
I am looking to reproduce the glow effect from this tutorial, if I understand well, we convert the first image to an "alpha texture" (black and white), and we blur the (rgb * a) texture.
How is it possible to create this alpha texture, so that some colors go to the white, and the other go to the black? I found this : How to render a texture with alpha? but I don't really know how to use these answers.
Thanks
It appears you are misunderstanding what that diagram is showing you. It is actually all one texture, but (a) shows the RGB color and (b) shows the alpha channel. (c) shows what happens when you multiply RGB by A.
Alpha is not actually "black and white", it is an abstract concept and amounts to a range of values between 0.0 and 1.0. For the human brain to make sense out of it, it interprets that as black (0.0) and white (1.0). In reality, alpha is whatever you want it to be and unrelated to color (though it can be used to do something to color).
Typically the alpha channel would be generated by a post-process image filter, that looks for areas of the texture with significantly above average luminance. In modern graphics engines HDR is used and any part of the scene with a color too bright to be displayed on a monitor is a candidate for glowing. The intensity of this glow is derived from just how much brighter the lighting at that point is than the monitor can display.
In this case, however, it appears to be human created. Think of the alpha channel like a mask, some artist looked at the UFO and decided that the areas that appear non-black in figure (b) were supposed to glow so a non-zero alpha value was assigned (with alpha = 1.0 glowing the brightest).
Incidentally, you should not be blurring the alpha mask. You want to blur the result of RGB * A. If you just blurred the alpha mask, then this would not resemble glowing at all. The idea is to blur the lit parts of the UFO that are supposed to glow and then add that on top of the base UFO color.
I'm rendering both a blue and a red line (in the context of an anaglyph). When the red line and blue line overlap I want a purple color to be rendered instead of the line in front.
I am using OpenGL. Some of the code I have tried so far is this:
glBlendFunc(GL_ONE, GL_DST_ALPHA);
This causes the overlap to render white, and the line appears as follows:
I thought maybe using an RGB scale factor on top of this blend would be the right thing to do.
So I tried using the glBlendFuncSeparate which takes parameters:
Source Factor RGB
Destination Factor RGB
Source Factor Alpha
Destination Factor Alpha
I could not find parameters which made this work for me.
I also attempted using glBlendEquation with an additive equation, but didn't notice any success in that method.
How do I produce a function which successfully blends the two lines into a purple color?
Edit:
I've noticed that glBlendFunc(GL_ONE, GL_DST_ALPHA) does perform some blending to produce intermediate colors (the actual lines are just nonsensical here, it was just to display some blending).
I'm rendering both a blue and a red line (in the context of an anaglyph)
Not the answer you expect, but the answer you need: The usual approach to render anaglyph images in OpenGL is not to use blending. Blending is hard enough to get right, you don't want to mess things up further with the anaglyph part.
There are two commonly used methods:
Rendering each view into a FBO attached texture and combining them in a postprocessing step.
using glColorMask to select the active color channels for each rendering step.
I think for now you're good with the color mask method: Do it as following:
display:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glViewport(…)
# prepare left view
setup_left_view_projection()
glColorMask(1,0,0, 1); # red is commonly used for the left eye
draw_scene()
glClear(GL_DEPTH_BUFFER_BIT) # clear the depth buffer (and just the depth buffer!)
# prepare right view
setup_right_view_projection()
glColorMask(0,1,1, 1); # cyan is commonly used for the right eye
draw_scene()
The typical blend function is glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);; note that the final color changes according to the draw order.
Blend functions are not so obvious, so a graphical representation sometimes is better; check out for example this site.
I'm trying to show only a part of a background image (game scenenario in the future). The basic way to work is for example, first I draw a background image, after that i need to "hide"/cover the image with some dark or darness (no light, don't know what option must be chosen) and use the mouse click to using a circle or a triangle (my options) show only the part of the image background over with the circle/triangle centered on mouse position. I called this "lantern effect".
First Option: Play with the alpha channel, creating a an square covering all the window size and after that trying to substract the circle area over the alpha square over the image.
Second Option: Play again with a black square covering all the image background and trying to substract a circle/triangle. Try with glLogicOp but this method only plays mixing colors. Don't know how to do operation with 2D polygons with OpenGL.
...
Any other idea or easy example to learn how to do something similar.
Image example:
That's quite easy to achieve actually:
Create black texture with your lantern light shape in Alpha channel. (Texture could be animated)
Render background.
Render Lantern texture centered at your in-game mouse cursor.
Render black padding around the lantern texture to hide everything around till screen edges.
There's no need to use any special blending modes, just an overlay.
I'm working on creating a transparent GUI in OpenGL, and am trying to get text rendered over some semi-transparent quads, but the results are odd.
If I render the text by itself, with nothing behind it, it looks fine:
However, if I render a semi-transparent quad behind it (rendering the quad before rendering the text), I get this:
I have blending set to (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA). The font texture is an all-white texture with the character shapes in the alpha channel.
Do I need to be doing something special when performing alpha-transparency over an existing layer of transparency? Or is there something else I need to check?
The alpha value of your font texture seems to be off. It should be 0 for texels that you want to be invisible and 1 (or 255 in bytes) for visible texels. You should check the texture and make sure alpha values are correct.
Instead of alpha blending, you can use alpha testing. This will completely get rid of fragments, that have a alpha value below a certain threshold and is often much faster than blending.
glDisbale(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.96f); // Or some fitting threshold for your texture
This might work even if your texture's alpha is off in some places, but doesn't look like it is the case here, as the 's' and 't' seem to have a low alpha in places where it should be 1.
Thanks for the responses. There was nothing wrong with my font texture, but your suggestions led me to try a few other things. Turns out the problem wasn't the transparency at all. There was a problem with rendering the background quad, which caused it to also render the text quads, but using the background texture. Bah...
Can anyone give some clues as to why when I try to render the color bar quad below
It appears like this:
Here is my rendering code:
gl.glEnable(GL.GL_BLEND);
gl.glBlendFunc(GL.GL_ONE, GL.GL_ZERO);
gl.glBlendEquation(GL.GL_FUNC_ADD);
gl.glEnable(GL.GL_ALPHA_TEST);
gl.glAlphaFunc(GL.GL_GREATER, 0.01f);
// do the drawing...
gl.glDisable(GL.GL_TEXTURE_2D);
gl.glDisable(GL.GL_ALPHA_TEST);
I'm sure the solution is simple and I'm just having a brainfart but it's just one of those days!
Thanks for the help!
What kind of blending are you trying to perform? To simply draw something without any color mixing or alpha channels you don't even have to play around with GL_BLEND or GL_ALPHA_TEST (leave both disabled). GL_BLEND is used to define how to add different "layers" of color (usually on how to apply alpha channels) while GL_ALPHA_TEST decides what alpha values to respect/ignore. Also check your vertex colors when rendering the quad (try to render a unicolor quad without texture, e.g. using magenta).
However looking at your images I'd guess you somehow disabled drawing to your red color channel (glColorMask()) - although there's yellow, which confuses me.
There was a problem with RGBA getting swapped around when I imported the PNG file.