• Advertisement

Archived

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

Damn SetTextureStageState() (DX9)

This topic is 5267 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ok, I don't even know if this is possible to do efficiently (but to be honest it doesn't really matter). I have these three tiles: (If the image is broken, #1 is a mask (magenta & black), and #2 & #3 are normal textures [grass & sand]). I'd really like to be able to blend the second and third textures using the first as a mask of some sort, but i really don't know how to go about it. At the moment is have this:
m_pDevice->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_MODULATE);
m_pDevice->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
m_pDevice->SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_CURRENT);

m_pDevice->SetTextureStageState(1,D3DTSS_ALPHAOP,D3DTOP_MODULATE);
m_pDevice->SetTextureStageState(1,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
m_pDevice->SetTextureStageState(1,D3DTSS_ALPHAARG2,D3DTA_CURRENT);

m_pDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_ADD);
m_pDevice->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_TEXTURE);
m_pDevice->SetTextureStageState(1,D3DTSS_COLORARG2,D3DTA_CURRENT);
Which produces an image like this: (Ignore the window title - its a work in progress ) But i don't know what to do next... Someone suggested something to do with the stencil buffer that sounds over-complicated to me. Is this the only way to do it? How do terrain engines do this? Terrain engines blend 2 textures into one another (e.g. grass & rock), which is what i'm doing - except with only 1 bit of alpha (effectively 0.0 or 1.0) Any suggestions? Cheers, Steve [edited by - Evil Steve on August 12, 2003 8:07:55 AM]

Share this post


Link to post
Share on other sites
Advertisement
If your card supports fancy features like >2 texture stages, temp registers and lerp commands, try something like this:

m_pDevice->SetTexture( 0, m_mask );
m_pDevice->SetTexture( 1, m_sand );
m_pDevice->SetTexture( 2, m_grass );

m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE | D3DTA_ALPHAREPLICATE );
m_pDevice->SetTextureStageState( 0, D3DTSS_RESULTARG1, D3DTA_TEMP );

m_pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pDevice->SetTextureStageState( 1, D3DTSS_RESULTARG1, D3DTA_CURRENT );

m_pDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_LERP );
m_pDevice->SetTextureStageState( 2, D3DTSS_COLORARG0, D3DTA_TEMP );
m_pDevice->SetTextureStageState( 2, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pDevice->SetTextureStageState( 2, D3DTSS_COLORARG2, D3DTA_CURRENT );
m_pDevice->SetTextureStageState( 2, D3DTSS_RESULTARG1, D3DTA_CURRENT );


otherwise go multi-pass:

m_pDevice->SetTexture( 0, m_sand );

m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );

m_pDevice->SetTexture( 0, m_grass );
m_pDevice->SetTexture( 1, m_mask );

m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );

m_pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
m_pDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_CURRENT );
m_pDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE );

Share this post


Link to post
Share on other sites
Ok, one more question.
I''ve tried to implement both methods in my game, so that i can use single-pass if its supported. When i did this, i got 950 fps, an increase of 100fps, so i reckon its worthwhile.
Anyway, to determine if the graphics card supports it, i do this:

if((m_theCaps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP) &&
(m_theCaps.TextureOpCaps & D3DTEXOPCAPS_LERP))
m_bRenderWithLerp = true;
else
m_bRenderWithLerp = false;

However, i seem to be missing something because although this works on my server (with only onboard graphics), it doesn''t work on my sisters GeForce2. All i get is a black screen. If i skip that step and set m_bRenderWithLerp to false, it works fine. So i guess there must be another cap that i need to test against.
Anyone know what it is?

Cheers,
Steve

Share this post


Link to post
Share on other sites
Although the GeForce2 accepts lerp, it may not support 3 textures. You''ll need to check the maximum number of textures a card supports.

If someone has a link describing all cards feature sets, I''d love to have it, as I''m sure many others would too. If anyone has such a beast, post a new thread (more likely to be seen by interested parties).

Share this post


Link to post
Share on other sites
D''oh that was it. The GeForce 2 can only handle 2 textures at once.

Thanks for the help

Share this post


Link to post
Share on other sites
The GeForce 2 can only handle 2 textures at once.

How to check this value? Is it under (Caps Viewer)

D3D Device Types\HAL\Caps\

"MaxTextureBlendStages" or
"MaxSimultaneousTextures" ?





Share this post


Link to post
Share on other sites
Sorry again, in that "multi-pass" option, isn't the
second "SetTexutre(0, m_grass)" over-writin' the first "SetTexture(0, m_sand)"? Some kind of DrawPrimitive() is
needed in between them, am I right?

m_pDevice->SetTexture( 0, m_sand );
m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );

// Some kind of DrawPrimitive() here...

m_pDevice->SetTexture( 0, m_grass );
m_pDevice->SetTexture( 1, m_mask );

etc...







[edited by - HaywireGuy on August 17, 2003 9:50:59 PM]

Share this post


Link to post
Share on other sites
Q1) I check MaxSimultaneousTextures
Q2) Yes:

m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);
m_pDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
m_pDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
// For each tile:

m_theScene.SetTexture(0,m_vTiles[pTile->wTile].pTexture);
m_pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,(y*m_sizeView.cx+x)*4,2);

m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
m_pDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
m_pDevice->SetTextureStageState(1,D3DTSS_ALPHAOP,D3DTOP_SELECTARG2);
m_pDevice->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_CURRENT);
m_pDevice->SetTextureStageState(1,D3DTSS_ALPHAARG2,D3DTA_TEXTURE);
// For each tile:

m_theScene.SetTexture(0,m_vTiles[pTile->wOverlayTile].pTexture);
m_theScene.SetTexture(1,m_vMasks[pTile->wMask].pTexture);
m_pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,(y*m_sizeView.cx+x)*4,2);


[edited by - Evil Steve on August 19, 2003 10:33:25 AM]

Share this post


Link to post
Share on other sites

  • Advertisement