Alpha Blended Textures

Hello,

Is there a way to change the alpha value of a texture as it is being rendered, instead of actually using an image editor to change the alpha value of the texture? I need to be able to change the transparency on the fly for various textures based on the height read from a height map…

Yes, just get a handle to the RGBA bytes for the texture and change the alpha component to be less than 0xFF.

Ah, yes that would work if I just wanted to statically change the alpha component of each texture, but what I need to do is render each texture with a certain level of transparency based on the current height of the terrain so that dirt slowly fades into grass fades into rock fades into snow as the terrain gets higher.

What you want is the texture combiner. You can set an alpha scale for each texture unit, like this:

glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, floatScaleValue);

See page 437 of the Red Book (Texture Combiner Functions, Chapter 9)

Or, alternatively, you can use the GL_INTERPOLATE combiner mode. See Example 9-16 in the Red Book. This example is for interpolating an incoming texture with the existing screen fragment. By changing the source operands around (instead of GL_PREVIOUS, use GL_TEXTUREn for the texture unit you want to blend with), you can use the code to interpolate between 2 textures.

Hope this helps, sorry it’s not JOGL-ified!

Hello,

Well I must be doing something wrong. I am setting up the texture object with:

gl.glBindTexture(GL.GL_TEXTURE_2D, textureObjects[GRASS_TEXTURE_ID]);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, textures[GRASS_TEXTURE_ID].getWidth(), textures[GRASS_TEXTURE_ID].getHeight(), 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, textures[GRASS_TEXTURE_ID].getData());
gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_LINEAR);

then I set up the texture unit 1 with:

gl.glClientActiveTexture(GL.GL_TEXTURE1);
gl.glActiveTexture(GL.GL_TEXTURE1);
gl.glEnable(GL.GL_TEXTURE_2D);
gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, texCoordBuffer);
gl.glBindTexture(GL.GL_TEXTURE_2D, textureObjects[GRASS_TEXTURE_ID]);
gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_COMBINE);
gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_ALPHA_SCALE, 0.5f);

Then I render with:

gl.glClientActiveTexture(GL.GL_TEXTURE1);
gl.glActiveTexture(GL.GL_TEXTURE1);
gl.glBindTexture(GL.GL_TEXTURE_2D, textureObjects[WATER_TEXTURE_ID]);
gl.glDrawArrays(GL.GL_TRIANGLES, 0, vertexList.length/3);

But I still get no level of transparency. Anyone know what is going on?

Hrm, looking around it seems like the specification of this feature is a little, uh, broken.

I found this online:

Which makes these things pretty useless.

I think you’re going to have to use GL_INTERPOLATE.

Assuming I’m actually on the right bandwidth with you, i’ve not had to do anything special in the past when it comes to effecting the alpha/translucency of a textured area.

Just glColor(red, green, blue, ALPHA); then draw your textured area, and the area is as translucent as the alpha I use.

That won’t work in this particular situation, as I need different textures to be rendered with different levels of transparency depending on the height of the current vertex AND the actual texture being rendered. If I were to use glColor4f() to specify the alpha channel every texture rendered on a given vertex would be rendered with the same level of transparency and this will not do.

I’m positive GL_INTERPOLATE is the combine mode you want. It’s a bit lame that GL_ALPHA_SCALE doesn’t work in a manner that is very useful.

You are indeed correct, many thanks anarchotron. I am now trying to assemble all of the triangles into different arrays based on their heights and render them in “height groups” if you will.

Hi
Maybe this is what you want to do: http://www.delphi3d.net/articles/viewarticle.php?article=terraintex.htm
Check out the source to the demo, its in delphi, but the opengl parts are not hard to translate.

// Gregof

That is a good link gregof, thanks.