Archived

This topic is now archived and is closed to further replies.

Tonhom

Help me please! i'm so confuse about glTexEnv()

Recommended Posts

Tonhom    122
i try to read specs for the ARB_texture_env_combine and ARB_texture_env_dot3 extension, but don''t understand. i have an basic example code here : glActiveTextureARB(GL_TEXTURE0_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); glActiveTextureARB(GL_TEXTURE1_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGB_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); it has 2 dot3 textures. but i want to know if i have 3 how can i do it? could anybody give me some example or URL for tutorial for combine 3 textures such as : texture0 dot3 texture1 result in texture1, then texture0 dot3 texture2 result in texture2 , then texture1 dot3 texture2 result in texture1. Thank you very much.

Share this post


Link to post
Share on other sites
JTippetts    12950
In a multi-texturing setup, you have what amounts to a series of texture stages (GL_TEXTURE0_ARB, GL_TEXTURE1_ARB, etc...) which each have an associated texture. These textures can, of course, have a variety of different formats: GL_RGB, GL_RGBA, GL_ALPHA, GL_LUMINOSITY, and so forth.

Now, before ARB_texture_env_combine came around, the ways in which you could use multi-texturing were pretty much limited to modulation, decaling, blending or replacing; the options provided by glTexEnv().

For instance, with GL_MODULATE, an RGB texture in stage 1 would be multiplied by an RGB texture in stage 0. This was useful for lightmapping, using a texture of varying white intensity in stage 1 to add the appearance of lighting to a texture. You can do a lot with the options as provided by default, but people wanted/needed more.

With ARB_texture_env_combine, the programmer can specify exactly how the various texture stages are to be combined to get the final pixel/fragment color and alpha.

Combination is done by means of an equation that is specified for each texture stage. This equation deals with sources, combination methods and operands. The sources and source operands determine where the pixel or color data comes from, and the combination methods determine how the sources are combined together to get the final output pixel data of the texture stage. The various sources for pixel/color data for any given texture are:

TEXTURE -- A source pixel/fragment for the equation is taken from this texture stage's texture data
CONSTANT_ARB-- A source fragment is determined by a supplied constant color
PRIMARY_COLOR_ARB-- A source fragment is determined by a color supplied by such means as materials or glColor()
PREVIOUS_ARB-- A source fragment is taken from the output of a previous texture stage

Sources for a current texture stage are set using calls such as glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE). This example call sets the source0 of the equation for the current stage to take color data from the current stage's texture. glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE) instructs the stage to take alpha data from the texture. glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS) instructs the stage equation to take the source1 parameter from the previous texture stage's color output.

Now, once you have specified your sources for RGB and Alpha data, you specify the operands of the equation, which determine how the sources are combined. Operands can be specified for either alpha or color, to control each aspect of the output fragment. You specify an equation for color manipulation using GL_COMBINE_RGB_ARB, and an equation for alpha manipulation using GL_COMBINE_ALPHA_RGB. These equations determine how the color and alpha sources specified are mixed together to output the final color or alpha value for a fragment/pixel. Successive texture stages can possibly use this output color/alpha using GL_PREVIOUS for a source, thus continuing the chain.

The valid equation specifiers provided by ARB_texture_env_combine are:

REPLACE -- Replace the outgoing color or alpha with the incoming color/alpha supplied by source0
MODULATE -- Multiply source0 by source1 to get the output
ADD -- Add source0 and source1 to get the output
ADD_SIGNED_ARB -- Add source0 and source1, then subtract 0.5
INTERPOLATE_ARB -- Interpolate (blend) between source0 and source1 using source2 as a t factor
SUBTRACT_ARB -- Subtract source1 from source0

The ARB_texture_env_dot3 is a tiny extension which adds the following equation options to the list:

DOT3_RGB_ARB -- Take the dot product (3 components) of source0 and source1
DOT3_RGBA_ARB -- Take the dot product (4 components) of source0 and source1



As well, it is possible to change how the source data is taken using operands. The possible operands are:

For OPERAND< N>_RGB_ARB, where N corresponds to a SOURCE:

SRC_COLOR
ONE_MINUS_SRC_COLOR
SRC_ALPHA
ONE_MINUS_SRC_ALPHA

For OPERAND< N>_ALPHA_ARB:

SRC_ALPHA
ONE_MINUS_SRC_ALPHA

So, if a color source is specified as GL_TEXTURE and the associated operand is specified as GL_ONE_MINUS_SRC_COLOR, then instead of using the actual color extracted from the texture for a pixel, instead it subtracts that color from 1 and uses the result, in effect "inverting" the color. This could be used, for example, to turn a lightmap into a shadow map of some sort.


Now, with this base set of sources, combiners and operands it is possible to create more complicated effects than are possible with standard TexEnv() settings.

To use ARB_texture_env_combine, you need to first figure out how you are going to need to combine a set of textures. I will provide an example that could easily be done using standard TexEnv() settings, but still might help to clarify things.

In a game I am working on, I have a terrain that is tiled with various types of terrain (dirt, grass, stone, etc...) that must blend together smoothly on the edges where terrain types meet. Rather than create sets of special tiles for each transition, I elected to go instead with an approach that uses a terrain texture and a special alpha mask texture to dynamically generate a terrain transition tile to overlay on top of the terrain. So, on the first pass of drawing the terrain, I iterate through all of the tiles in the view and draw the base terrain texture. If I were to stop there, I would get a patch of rigidly rectangular tiles with sharp transitional edges that would look bad. So I make another pass, calculating for each tile a blending pattern I need to use to blend a tile in with neighbors.

I select an alpha texture from a set of all possibly terrain transitions, and use multi-texturing to combine this alpha texture with a neighboring base terrain RGB texture, to create a custom blend pattern.

This effect can easily be achieved using standard TexEnv() settings. For stage0, I would set the terrain RGB texture as the texture, and use default settings. For stage1, I would set the ALPHA mask texture, and use GL_REPLACE as the combiner. The effect of this is to take color data from stage0, and alpha data from stage1, resulting in a smoothly blended, masked texture to overlay the base terrain and create a nice transition.

To emulate this behavior using ARB_texture_env_combine, this is what I would do:

First, I need to set settings for stage0. Basically these are "default" texturing settings, but for clarity I will lay them out explicitly:

1) Select stage0
glActiveTextureARB(GL_TEXTURE0_ARB);

2) Setup to use the ARB_texture_env_combine settings
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);

3) Setup the sources. Since this is just "default" settings, sources are simply the current texture
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);

4) Setup how the incoming (source) RGB data affects the output. Since it is the base texture, a simple replace should do.
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);

This, then, basically sets up the texture stage 0 to output it's RGB texture data. Alone, this would draw the specified polygon as a simple textured polygon. The "default" behavior, in other words, and hardly necessary to do it with ARB_texture_env_combine parameters...


Now, for the second stage for the alpha masking:

1) Select the stage
glActiveTextureARB(GL_TEXTURE1_ARB);

2) Setup the sources for color data. The sole source is the incoming color from stage0
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);

3) Setup the sources for alpha data. This is drawn from the current alpha-map texture.
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);

4) Setup the equation to combine the source color to generate output color data. This is simple replace, since we want the color data as output by stage0 to be used as-is.
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);

5) Setup the equation to combine the source alphas. This is, again, a simple replace, to replace source0 (texture) alpha.
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);

So, the sum of all this (redundant) work is that we take an RGB texture in stage0, combine it with an alpha channel from stage1 and draw it to the screen. The alpha channel masks off and blends the texture, creating our smooth transition. This is the bogo-sort means of accomplishing this, but it serves to illustrate the purpose of the ARB_texture_env_combine extension.

It is admittedly a little complicated, and may be tough to come around to the ARB_texture_env_combine way of thinking at first. But it is a very handy extension to have around.

I hope that helps you, and I hope I didn't mislead your or feed you false information on anything. The combine extension is still fairly new to me, so I am far from an expert on its use. Good luck.


Golem
Blender--The Gimp--Python--Lua--SDL
Nethack--Crawl--ADOM--Angband--Dungeondweller


[edited by - VertexNormal on March 21, 2004 4:02:45 PM]

Share this post


Link to post
Share on other sites
Tonhom    122
Thank you very much for your explanation. i feel better, but i'm confuse where the ouput keep in.
from your example you means when you draw after step 5 of masking step it's done, right?

but when i try my example:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGB_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);

if i delete the last row why it doesn't work. so, what is the last row doing?

another question, what is the difference for glClientActiveTextureARB and glActiveTextureARB? and what happen if i set :
glActiveTextureARB(GL_TEXTURE0_ARB); but
glClientActiveTextureARB(GL_TEXTURE1_ARB);

[edited by - Tonhom on March 22, 2004 4:33:06 AM]

Share this post


Link to post
Share on other sites
JTippetts    12950
quote:
Original post by Tonhom
Thank you very much for your explanation. i feel better, but i''m confuse where the ouput keep in.
from your example you means when you draw after step 5 of masking step it''s done, right?



These steps don''t actively do or draw anything. They just define what happens when you draw your primitives. After calling those glTexEnv() calls, you need to bind an RGB texture to stage 0, an alpha texture to stage 1, and then call all of your glColor(), glVertex() type calls to draw primitives. If texture coords are specified for stages 0 and 1, then the combination math specified by the glTexEnv() calls will take place when the primitives are drawn, outputing the results to the screen.

quote:

but when i try my example:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGB_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);

if i delete the last row why it doesn''t work. so, what is the last row doing?



The GL_DOT3_RGB_ARB option requires 2 sources, which you set in the calls glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE) and glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB). The result of this DOT3 operation is to take the dotproduct of SOURCE0 (from the current stage''s texture) and SOURCE1 (from the "output" of the previous stage). If you don''t set SOURCE1, then it uses whatever default or left-over setting was in it before, possibly nothing meaningful. The output of this operation is: (TexturePixelColor) dotproduct (PreviousStagePixelColor). So removing that last row removes one of the sources that GL_DOT3_RGB_ARB needs to function correctly.

quote:


another question, what is the difference for glClientActiveTextureARB and glActiveTextureARB? and what happen if i set :
glActiveTextureARB(GL_TEXTURE0_ARB); but
glClientActiveTextureARB(GL_TEXTURE1_ARB);



If you are using glDrawArrays() or glDrawElements() to draw primitives, I believe you need to use the glClientActiveTexture() call to ensure that texture coordinates are output for all enabled texture stages. glTexCoordPointer() sets the texture coordinate array for the texture currently enabled by glClientActiveTexture().


Golem
Blender--The Gimp--Python--Lua--SDL
Nethack--Crawl--ADOM--Angband--Dungeondweller

Share this post


Link to post
Share on other sites