LIGHTMAP_M2 AND TRANSPARENT ALPHA CHANNEL Material

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
qez111
Posts: 54
Joined: Mon Apr 28, 2008 9:44 pm

LIGHTMAP_M2 AND TRANSPARENT ALPHA CHANNEL Material

Post by qez111 »

This is my new material by which you can use lightmap as well as alpha channel. Basically this lets you use EMT_LIGHTMAP_M2 AND EMT_TRANSPARENT_ALPHA_REF at the same time.

Code: Select all

class MaterialRenderer_LightMap_M2_Alpha_Ref: virtual public IMaterialRenderer {
public:
	IDirect3DDevice9   *mID3DDevice;
	IVideoDriver      *mDriver;

	MaterialRenderer_LightMap_M2_Alpha_Ref(IDirect3DDevice9 *dev, IVideoDriver *driver): mID3DDevice(dev),
		mDriver(driver) {}

	//Wrapped functions
	virtual void   OnSetMaterial(const SMaterial &material, const SMaterial &lastMaterial, bool resetAllRenderstates,
		IMaterialRendererServices *services) {
			if (material.MaterialType != lastMaterial.MaterialType ||
				material.MaterialTypeParam != lastMaterial.MaterialTypeParam ||
				resetAllRenderstates) {


					//for alpha channel
					mID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE  );
					mID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
					mID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
					mID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1 );
					mID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );

					s32 refValue = core::floor32(material.MaterialTypeParam * 255);
					if ( !refValue )
					refValue = 127; // default value

					mID3DDevice->SetRenderState(D3DRS_ALPHAREF,refValue);
					mID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
					mID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
					


					// lIGHTMAPM2
					mID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
					mID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); 
					mID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
					mID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
					mID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
					mID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);

					//mID3DDevice->SetTextureStageState (1, D3DTSS_ALPHAOP,  D3DTOP_DISABLE);

					mID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
			}

			services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
	}
	virtual void   OnUnsetMaterial() {
		mID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
	}
	virtual bool   isTransparent() const {
		return false;
		
	}
}; 
Edit: I have fixed a bug in the previous code by adding few extra lines, Now this material behaves exactly like EMT_LIGHTMAP_M2, but with alpha channel transparency.

Thanks to Nyxojaele for starting this thread:http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=27768, as I was able to build this material only after seeing his thread.
Last edited by qez111 on Wed May 28, 2008 8:28 pm, edited 2 times in total.
qez111
Posts: 54
Joined: Mon Apr 28, 2008 9:44 pm

ADDING THE NEW LIGHTMAP MATERIALS AS BUILT-IN MATERIAL

Post by qez111 »

In case anybody's interested in adding this material as a built-in material in Irrlicht engine, here's the patch:

STEP 1. Open E_MATERIAL_TYPES.H and add the following two definitions to the enum E_MATERIAL_TYPE (preferably at the end of the list, just before the 0):

Code: Select all

EMT_LIGHTMAP_M2_ALPHA_REF,
EMT_LIGHTMAP_ALPHA_REF,
Step 2: In the same file, add the following code to the end of the const char* const sBuiltInMaterialTypeNames[] array,just before the '0':

Code: Select all

"lightmap_m2_alpha_ref",
"lightmap_alpha_ref",

Step 3: Replace the lightmap class with the following modified class:

Code: Select all


//! material renderer for all kinds of linghtmaps
class CD3D9MaterialRenderer_LIGHTMAP : public CD3D9MaterialRenderer
{
public:

	CD3D9MaterialRenderer_LIGHTMAP(IDirect3DDevice9* p, video::IVideoDriver* d)
		: CD3D9MaterialRenderer(p, d) {}

	virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
		bool resetAllRenderstates, IMaterialRendererServices* services)
	{
		if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
		{
			if(material.MaterialType==EMT_LIGHTMAP_M2_ALPHA_REF||material.MaterialType==EMT_LIGHTMAP_ALPHA_REF)
			{

				//for alpha channel
				pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE  );
				pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
				pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
				pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1 );
				pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );

				s32 refValue = core::floor32(material.MaterialTypeParam * 255);
				if ( !refValue )
					refValue = 127; // default value

				//For Lightmap
				pID3DDevice->SetRenderState(D3DRS_ALPHAREF,refValue);
				pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
				pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);

				pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
				pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); 
				pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);

				if(material.MaterialType==(EMT_LIGHTMAP_M2_ALPHA_REF))
						pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE2X);
					
				else
						pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);

				pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
				pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);

				pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
			}

			else
			
			{

					if (material.MaterialType >= EMT_LIGHTMAP_LIGHTING)
					{
						// with lighting
						pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
						pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
						pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
					}
					else
					{
						pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
						pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
					}

					pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP,  D3DTOP_DISABLE);
					pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);

					if (material.MaterialType == EMT_LIGHTMAP_ADD)
						pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD);
					else
					if (material.MaterialType == EMT_LIGHTMAP_M4)
						pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE4X);
					else
					if (material.MaterialType == EMT_LIGHTMAP_M2)
						pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE2X);
					else
						pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);

					pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
					pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
					pID3DDevice->SetTextureStageState (1, D3DTSS_ALPHAOP,  D3DTOP_DISABLE);

					pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
				}

			} //close outer else for LightMap_m2_alpha comparison set

		services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
	}
};
Note: The new materials, EMT_LIGHTMAP_M2_ALPHA AND EMT_LIGHTMAP_ALPHA will only work with DIRECT3D9. If you are able to write an OPENGL Material equivalent to the above direct3d9 material, please post it here.
Post Reply