Archived

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

Golroc

Alpha Blending Textures

Recommended Posts

I have a newbie DX question that I hope someone can help me with. I have been working on a 3D engine for a month or so, and I have got basic mesh rendering and brute force landscape rendering up and running. I thought it was time to spice up my terrain somewhat, so I decided to use blending to get a more varied look. The idea is to have three textures: two terrain textures (grass, rock, mud, etc.) and one blending texture. I want to use the third texture as a 'mask' for blending the other two. In essence I want FINAL_COLOR = TEX0 * (TEX2) + TEX1 * (1-TEX2) I am assuming for simplicity that TEX2 has values from 0 to 1, which is of course not the case. But the point should be obvious. I played around with various texture stages, and finally decided that this should do the trick: Textures 0 and 2 are the terrain textures, texture 1 is the blend mask (which has only alpha values).
    
		m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
		m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
		m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
		m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
		m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

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

		m_pDevice->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_TEXTURE);
		m_pDevice->SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_CURRENT);
		m_pDevice->SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
		m_pDevice->SetTextureStageState(2, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
		m_pDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_BLENDCURRENTALPHA);
		m_pDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
    
This however does not work. It produces really odd results. I have set the following render states:
  
      
	m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
	m_pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
	m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
	m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
    
To make it even more odd, I tried to render a heightmap with just a single texture with an alpha channel (to make it semi-transparent) - but it looks absolutely opaque. Can anyone point to something I may have overlooked/done wrong. I have had alpha blending working in some earlier code I wrote, but now it seems I can't get alpha blending to work at all. I am running in windowed mode with 16bit color. Could that be a problem? Thanks in advance. Edited by - Golroc on January 13, 2002 2:10:09 PM

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Use the MFC texture sample to get the render states you want and then have it generate the code for you

Share this post


Link to post
Share on other sites
Thanks for the advice, but I solved my problem

I discovered a couple of errors. The following was wrong:
  
m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);

The correct version was:
  
m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);


I also discovered that my vertex format was wrong. I had one u,v coordinate set, but three textures. I thought that since the same u,v was used for all, I didn''t need any more. That was wrong. I needed 3 u,v coordinate sets, one for each texture.

I ended up using the following render states (tex0 is blending texture, tex1 and 2 are terrain textures):
  
m_pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
m_pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

m_pDevice->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
m_pDevice->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
m_pDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
m_pDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE);
m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);

m_pDevice->SetTextureStageState(2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
m_pDevice->SetTextureStageState(2, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
m_pDevice->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_CURRENT);
m_pDevice->SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_TEXTURE);
m_pDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_BLENDCURRENTALPHA);

Share this post


Link to post
Share on other sites