   Damn SetTextureStageState() (DX9)
  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]
  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 );;  Excellent, multi-pass works perfectly.Thanks! ;  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 ;  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).;  D''oh that was it. The GeForce 2 can only handle 2 textures at once.Thanks for the help ;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" ? ;  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];  Q1) I check MaxSimultaneousTexturesQ2) 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];  Cool, that makes better sense. Thanks!