How do I render a GL_ALPHA texture? - opengl

I'm trying to work with the FTGL font library, to create a texture-mapped font and render it to the screen. The library creates a texture in the GL_ALPHA format to hold the font glyphs, and then when you tell it to render a string, it goes through and glBegin(GL_QUADS) and renders each glyph, exactly how you'd expect.
Only problem is, I'm not getting any text. In one scenario, I get solid black boxes instead of text, in another I get nothing. I've run the code under gDEBugger to ensure that the texture is getting uploaded and set up properly, and everything looks right, but I'm still not seeing any output.
I've tried the obvious stuff. Calling glColor beforehand to try to set a text color does nothing. Neither does attempting to ensure that alpha-blending will work properly, like so:
glEnable(GL_ALPHA_TEST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Does anyone have any idea what I'm missing, in order to make rendering from a GL_ALPHA texture to the screen show up properly?

It's clear after an examination of FTGL's code that the API is designed to do the text rendering itself. You're expected to call its rendering functions, which will make the OpenGL calls internally.
To put it another way, FTGL is not designed to load a font into a texture, then give you that texture object and have you draw the glyphs yourself. That doesn't mean you can't, only that the API is not going to help you do it.
The reason you get black is because GL_ALPHA textures return zeros for the RGB component when accessed. Since you use GL_MODULATE in your texture environment, that's going to multiply zero by the RGB part of the color.
To do what you intend, you need to set the GL_TEXTURE_ENV_MODE to GL_COMBINE instead of GL_MODULATE. Which means you need to use the combine environment mode, which isn't simple. Having abandoned fixed-function for shaders pretty much as soon as they existed, I haven't touched combiners in a long time. So take what follows with a grain of salt. Here's a guess at what the environment code should look like:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
What you want to do is generate a color where the RGB part comes from glColor and the Alpha part comes from the texture. This is how you do that.
In English, the first line says that the texture environment mode is "combine", which activates a more complicated operation mode. The next three lines specify how the RGB part of the color is generated. The GL_COMBINE_RGB set to GL_REPLACE means that the source RGB value 0 will be what the output RGB is. Setting GL_SRC0_RGB to GL_PRIMARY_COLOR means that source RGB value 0 is the primary color, which is the color generated by vertex processing (ie: unless you're using lighting, this is just what you passed with glColor). Setting GL_OPERAND0_RGB to GL_SRC_COLOR means to take the color as it is (there are special operations you can do, like take 1 - the color or whatever).
The next 3 lines set up where the alpha part of the output color comes from. The GL_COMBINE_ALPHA set to GL_REPLACE means that the source alpha value 0 (different from the source RGB value 0) will be what the output alpha is. Setting GL_SRC0_ALPHA to GL_TEXTURE means that the source alpha value 0 comes from the texture of the current texture unit. Setting GL_OPERAND0_ALPHA to GL_SRC_ALPHA means to take the alpha as it is (as before, you could apply some transform to the alpha here).
Alternatively, if your OpenGL implementation has ARB_texture_swizzle available, you can set up a swizzle mask to effectively transform the GL_ALPHA format into GL_INTENSITY. Then you can use GL_MODULATE as your GL_TEXTURE_ENV_MODE. However, you have to make sure that your blend mode is glBlendMode(GL_ONE, GL_ONE_MINUS_SRC_ALPHA). This is necessary because GL_MODULATE will multiply the color by the alpha. If you used GL_SRC_ALPHA instead of GL_ONE, you would be doing the multiply by alpha twice (once in the texture env stage, once in the blend stage).

Related

OpenGL Blend Function To Copy RBG/Disregard Alpha?

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

How do I make my object transparent but still show the texture?

I'm trying to render a model in OpenGL. I'm on Day 4 of C++ and OpenGL (Yes, I have learned this quickly) and I'm at a bit of a stop with textures.
I'm having a bit of trouble making my texture alpha work. In this image, I have this character from Spiral Knights. As you can see on the top of his head, there's those white portions.
I've got Blending enabled and my blend function set to glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
What I'm assuming here, and this is why I ask this question, is that the texture transparency is working, but the triangles behind the texture are still showing.
How do I make those triangles invisible but still show my texture?
Thanks.
There are two important things to be done when using blending:
You must sort primitives back to front and render in that order (order independent transparency in depth buffer based renderers is still an ongoing research topic).
When using textures to control the alpha channel you must either write a shader that somehow gets the texture's alpha values passed down to the resulting fragment color, or – if you're using the fixed function pipeline – you have to use GL_MODULATE texture env mode, or GL_DECAL with the primitive color alpha value set to 0, or use GL_REPLACE.

How to override texture color in opengl?

I am working on engine (http://b2dengine.com/) to implement my game idea, which is already in progress. Now for quite a while I am stuck with this problem with text rendering.
I have texture atlas that contains all supported/needed characters in a single png image. Character mapping is defined by Font class.
Everything works fine, characters are rendered correctly and accurately. Thing is that I also need ability to change color of the text.
This sounds and I bet it is simple but I cant make it work.
I am using this gl blend function to get desired effect.
GL.instance.glBlendFunc(GL.instance.GL_SRC_ALPHA, GL.instance.GL_ONE_MINUS_SRC_ALPHA);
In most cases it works, well as long as the color is somewhat dark. But when its set to white, I can see artifacts. I can provider screenshot if needed.
Also for this to work, "text" in texture must be white.
I am using opengl 1.1 ( yes I know its old, but I am just not ready for shaders ).
So in short, my question is: how to render a texture and completely replace the color? Keeping only alpha channel.
E.g. if its black and 80% transparent in png, when I render I want it green at 80% transparency on screen.
I think this will work, though these are some anciently deprecated functions and I don't remember too much about them anymore.
With your texture unit active which has the text texture, try setting these options:
glTexEnv(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
glTexEnv(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnv(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR);
glTexEnv(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
I believe this will replace the RGB of your fragment with the incoming fragment color (glColor), and completely ignore the RGB channel of the texture. Having said this, it would be a lot better if you just uploaded an alpha channel texture to begin with.
Make sure to check for errors, and if it doesn't work, you can see if I've grabbed something incorrectly from here: http://www.opengl.org/sdk/docs/man/xhtml/glTexEnv.xml

How to render a texture with alpha?

How to render a texture with alpha?
I have a texture, and need to render it with different alpha values at different locations. Any way to do so? (My texture is GL_RGBA)
If not possible to change alpha value on the fly, I have to create different textures for different alpha levels?
First, make sure that your texture has an alpha channel. You mention you are loading an RGBA format, but it's always good to check the original file in an image editing program. Then make sure your texture is ready for rendering in openGL. A common mistake is to forget to set up the texture's filtering mode through glTexParameter*. It starts on a setting requiring mipmaps, so I find that it's easiest to start with:
glTexParameteri(GL_TEXTURE_2D, GL_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_MAG_FILTER, GL_LINEAR);
Secondly, you will need to set up openGL to be ready for blending. This involves a glEnable call with GL_BLEND and a glBlendFunc call. Most of the time, you will want the function call to be glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA), as most other combinations of tokens will give you effects you are not after (see the glBlendFunc spec page for more info).
Finally, ensure you are sampling your texture at different points. If you are using immediate mode (you are using glVertex* to draw your scene), you will need to either use glTexGen* or manually specify texture points using glTexCoord* before calls to glVertex*. If using array data to draw your scene, make sure you have enabled the texture pointer using glEnableClientState(GL_TEXTURE_COORD_ARRAY) and glTexCoordPointer.
Your texture is GL_RGBA so it has a different alpha value for each texel.
If you want to change the alpha value used for render, I can think of the following methods:
Change the texture alpha values (not sure if you say that you don't want to do that).
Use glColor4f to change the alpha value of the vertices. It will multiply the texture values. You may need to use glEnable(GL_COLOR_MATERIAL) and/or glColorMaterial().
Use a vertex shader to change the vertex alpha values. It will multiply the texture values.
Use a fragment shader to change the sampled texture values on the fly.
Use two texture stages and multiply them. The second one will have the modified alpha values (see glActiveTexture() and friends).
Use a fragment shader and two (or more) texture stages. This is the coolest!

OpenGL - Textures - Replacing black (white) with color

I am generating a bitmap for a text display with OpenGL using Cairo/Pango. I generate the bitmap as RGBA with a transparent background and with the text in either black or white. (Let's assume black.)
If I load this bitmap as an OpenGL texture and display it, it appears as black text or white text, as expected.
I'd like to be able to color the text using only the original texture, but with OpenGL taking care of the coloring.
Preferably, I'd like to use glColor to set the color, but I'm willing to use glBlendColor or GL_TEXTURE_ENV_COLOR.
However, I can't get any of those options to work.
I've try what seem like innumerable combinations of
- white text or black text
- enabling blending or using GL_TEXTURE_ENV_MODE's GL_BLEND
- trying GL_MODULATE, GL_REPLACE, and GL_COMBINE
- trying various differnt glBlendFunc combinations
I've been searching online and reading the spec for a few hours and I'm really at the end of my rope.
Can anyone point me to the right place to get the answer to this?
The simplest way to go is to have your text bitmap with white text and transparent background.
Then, to color it, you have to make sure that TEXTURE_ENV_MODE is set to MODULATE :
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
With this, the draw color will be glColor * textureColor == glColor (as textureColor is white)
Then you have to enable blending to handle your transparent background :
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
or, if your bitmaps are in premultiplied alpha form :
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
Instead of supplying a full RGBA set, let the text just determinine the non-/transparency, i.e. just supply an alpha channel. Then use the normal glColor to set the text color.
It sounds like you can create the bitmap as you see fit. If that's the case, instead of black on white, I'd draw the text into the alpha channel. Then to color the text, you draw a rectangle (or whatever) of the color you want. Then draw your texture over it. Where the texture is opaque, you'll get the texture color. Where the texture is transparent, the background color will show through.
To do that, you will have to set up glBlendFunc. The usual should be fine:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
You also have to turn on blending for texturing:
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);