Texture stage states can be set to control the texture blending and the manipulation of texture co-ordinates.
You can blend many textures onto geometry in one pass, the number depends on the graphic cards capabilities (MaxTextureBlendStages). 8 stages is the maximum and is quite common on modern hardware. The great part is that you can feed the output from one stage into the next stage and create a chain of effect. At the bottom of this page I give some examples of what you can do.
The device method:
HRESULT SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
The complete list of states is shown below: State Types
Note: there was a really useful sample application that came with the DirectX SDK called MFCTex. It allowed you to mess around with different sampler states and see the result. Unfortunately as everything moves into shaders this utility is no longer included with the SDK. I plan on creating one myself to replace it. This will appear here shortly.
These states provide a host of possibilities especially when you consider that they can be chained together across stages. So the result of one stage can be fed into the input of the next stage. For the first stage the defaults are:
device->SetTextureStageState(0, D3DTSS_COLOROP,D3DTOP_MODULATE);
device->SetTextureStageState(0, D3DTSS_COLORARG1,D3DTA_TEXTURE);
device->SetTextureStageState(0, D3DTSS_COLORARG2,D3DTA_CURRENT);
If we interpret this we can see that the operation is to multiply together the colour value in the texture with the diffuse colour (interpolated from vertex components during Gouraud shading). Current normally means the result of the previous stage but since this is the first stage it simply uses the diffuse colour.
Subsequent stages are disabled by default (their operation is set to D3DTOP_DISABLE).
These three states take the same values as those specified for the colour states but they act on the alpha channel only. The defaults for the first stage are:
device->SetTextureStageState(0, D3DTSS_ALPHAOP,D3DTOP_SELECTARG1);
device->SetTextureStageState(0, D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
device->SetTextureStageState(0, D3DTSS_ALPHAARG2,D3DTA_CURRENT);
This means that the alpha value is set to what is in the texture. Subsequent stages have the alpha operation disabled.
There are other states available e.g. ones that deal with bump mapping, that are beyond the scope of these notes. Please see the DirectX help or the MSDN page for more details: SetTextureStageState.
There is a lot of power in these states especially when you start feeding the output of one into the input of another. There are loads of possibilities.
You may wish to apply a light map to your geometry. You can do this in two stages:
First Stage
Set the first texture, perhaps a wall, then:
device->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
device->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
device->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
device->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
device->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
In this first stage we are saying modulate (multiply) the colour from the texture and from the existing diffuse colour value calculated on the triangle. The alpha channel is simply set to the diffuse colour.
Second Stage
Set the second texture, a light map, then:
device->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE );
device->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
device->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
device->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
device->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
Now we modulate the second texture colour with the result of the previous stage. This modulates our light map onto existing texture and hence on to the geometry. The alpha channel value is set to the alpha value in this texture.
Third Stage
device->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE );
device->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
We do nothing in this stage apart from disable all operations.
We can play around with these values as well. If we were to set the second stage operation to D3DTOP_MODULATE2 we would get a much brighter effect from the light map.
I hope to add more examples to this page soon.
Listed below is the complete list of possible state types that can be set per stage.