I'm trying to make texture splatting. The setMaterialType() function with EMT_TRANSPARENT_ALPHA_CHANNEL parameter only affect for the self-texture alpha channel, and in this case the alpha channel will be scaled if the texture scaled.
Code: Select all
terrain->setMaterialTexture(1, m_driver->getTexture("alphamap.tga"));
terrain->setMaterialTexture(0, m_driver->getTexture("grass.jpg"));
terrain->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL );
To do this in DX9 first, I replaced function CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL::OnSetMaterial() on CD3D9MaterialRender.h by:
Code: Select all
virtual void OnSetMaterial(SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
// trg takes code from texture splating - Nate Glasser
// Allow multiple passes to blend together correctly, like Irrlicht did
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
pID3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
pID3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
pID3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
// Prevent some ugliness with the alphamaps
pID3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
pID3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
pID3DDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
pID3DDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
pID3DDevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
// Alphamap: take the alpha from the alphamap, we don't care about the color
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
// Texture: take the color from the texture, take the alpha from the previous stage
pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
}
//material.ZWriteEnable = false;
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
}
To use, using modified code from the terrain tutorial example:
Code: Select all
terrain->setMaterialTexture(0, m_driver->getTexture("alphamap.tga"));
terrain->setMaterialTexture(1, m_driver->getTexture("grass.jpg"));
terrain->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL );
terrain->scaleTexture(1.0f, 1.0f);
The result sounds good ! The terrain will be transparent by the transparency defined in the 1st alphamap, and the texture painted by the 2nd texture map.
But I have only one problem: when set scaleTexture() other than 1.0f, such as 2.0f for example, the terrain is tiled OK with 2x2 tiled texture and alpha, but only one cell is painted by the "grass" texture. The rest 3 cells are not painted and seem solid.
I uploaded my binary here if you want to test:
http://vine.phpwebhosting.com/~bjohnsto ... rlicht.zip
Can anyone help me to paint all 2x2 tiled texture and so on?
Thanks!