2-Sided stencil for DirectX9

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
Viz_Fuerte
Posts: 91
Joined: Sun Oct 19, 2008 5:29 pm
Location: Valencia (Spain)
Contact:

2-Sided stencil for DirectX9

Post by Viz_Fuerte »

Hi all.

Testing codes and codes to achieve the result Depth-pass stencil shadow volume rendering, which certainly has not worked,
but worked the code to use the 2-Sided stencil.

It works well and fast that the system of Shadows zPass and zFail but is bug something to ¿infinity?.

Image

The code:

CD3D9Driver.cpp

Code: Select all

//! sets the needed renderstates
void CD3D9Driver::setRenderStatesStencilShadowMode(bool zfail)
{
	if ((CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS) ||
		Transformation3DChanged)
	{
		// switch back the matrices
		pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW]));
		pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD]));
		pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION]));

		Transformation3DChanged = false;

		setTexture(0,0);
		setTexture(1,0);
		setTexture(2,0);
		setTexture(3,0);

		pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
		pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
		pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
		pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
		pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
		pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
		pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE);
		pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

		pID3DDevice->SetFVF(D3DFVF_XYZ);
		LastVertexType = (video::E_VERTEX_TYPE)(-1);

		// Disable z-buffer writes and enable the stencil-buffer
		pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
		pID3DDevice->SetRenderState( D3DRS_STENCILENABLE, TRUE );

		// Dont bother with interpolating color
		pID3DDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT );

		// unset last 3d material
		if (CurrentRenderMode == ERM_3D &&
			Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size())
			MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial();
	}

	// Set up stencil compare fuction, reference value, and masks.
	pID3DDevice->SetRenderState( D3DRS_STENCILFUNC,  D3DCMP_ALWAYS );
	pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP );
	pID3DDevice->SetRenderState( D3DRS_STENCILFAIL,  D3DSTENCILOP_KEEP );

	// If z-test passes, inc/decrement stencil buffer value
	pID3DDevice->SetRenderState( D3DRS_STENCILREF,       0x1 );
	pID3DDevice->SetRenderState( D3DRS_STENCILMASK,      0xffffffff );
	pID3DDevice->SetRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff );
    pID3DDevice->SetRenderState( D3DRS_STENCILPASS,      D3DSTENCILOP_INCR );

	// Make sure that no pixels get drawn to the frame buffer
	pID3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE);
	pID3DDevice->SetRenderState( D3DRS_SRCBLEND,         D3DBLEND_ZERO );
	pID3DDevice->SetRenderState( D3DRS_DESTBLEND,        D3DBLEND_ONE );

    // With 2-sided stencil, we can avoid rendering twice:
    pID3DDevice->SetRenderState( D3DRS_TWOSIDEDSTENCILMODE, TRUE );
    pID3DDevice->SetRenderState( D3DRS_CCW_STENCILFUNC,     D3DCMP_ALWAYS );
    pID3DDevice->SetRenderState( D3DRS_CCW_STENCILZFAIL,    D3DSTENCILOP_KEEP );
    pID3DDevice->SetRenderState( D3DRS_CCW_STENCILFAIL,     D3DSTENCILOP_KEEP );
    pID3DDevice->SetRenderState( D3DRS_CCW_STENCILPASS,     D3DSTENCILOP_DECR );

    pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

	CurrentRenderMode = zfail ? ERM_SHADOW_VOLUME_ZFAIL : ERM_SHADOW_VOLUME_ZPASS;
}

Code: Select all

//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow.
void CD3D9Driver::drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail)
{
	setRenderStatesStencilShadowMode(zfail);

	pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df));

    pID3DDevice->SetRenderState( D3DRS_TWOSIDEDSTENCILMODE, FALSE );
}
If someone wants to try to see if he manages to make it work in Irrlicht,
I leave the address of the page.

Depth-pass stencil shadow volume rendering
http://www.gamedev.net/reference/articl ... le2019.asp
Post Reply