⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shader_shadows.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:

	m_Models.clear();

	SAFE_RELEASE( m_pTigerTexture );
	SAFE_RELEASE(m_pShowShadowMapVB);

	SAFE_DELETE(m_pFloorMesh);

	SAFE_DELETE(m_pObjectMesh);
    SAFE_RELEASE(m_pShadowMap);
    SAFE_RELEASE(m_pShadowGen);
    SAFE_RELEASE(m_pShadowZBuffer);

	SAFE_DELETE(m_pNVDevice);

	if (m_pD3DDev)
	{
		m_pD3DDev->DeleteVertexShader(m_dwShadowGenShader);
		m_pD3DDev->DeleteVertexShader(m_dwShadowShowShader);
		m_pD3DDev->DeleteVertexShader( m_dwDrawObjectShader );
		SAFE_RELEASE(m_pD3DDev);
	}

	return S_OK;
}

HRESULT CShaderShadows::Start()
{
	return S_OK;
}

HRESULT CShaderShadows::SetTransform()
{
	D3DXMATRIX matWorld, matView, matProj;
	D3DXMATRIX matWorldView, matWorldViewIT;
	float      unused;

	matWorld = m_pNVDevice->GetWorldTransform();
	matView  = m_pNVDevice->GetViewTransform();
	matProj  = m_pNVDevice->GetProjectionTransform();

	m_pD3DDev->SetTransform( D3DTS_VIEW, (D3DMATRIX*)(&matView) );
	m_pD3DDev->SetTransform( D3DTS_WORLD, (D3DMATRIX*)(&matWorld));
	m_pD3DDev->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)(&matProj));

	D3DXMatrixMultiply(&matWorldView,   &matWorld, &matView);
    D3DXMatrixInverse( &matWorldViewIT, &unused, &matWorldView);
	
	 //Projection to clip space
	//D3DXMatrixTranspose(&matProj, &matProj);
	//m_pD3DDev->SetVertexShaderConstant(CV_PROJ_TXF_0, &matProj(0, 0), 4);

    // Projection to view-space
//	D3DXMatrixTranspose(&matWorldView, &matWorldView);
//    m_pD3DDev->SetVertexShaderConstant(CV_CURR_WORLDVIEW_TXF_0, &matWorldView(0, 0), 3);

    return S_OK;
}

D3DXMATRIX CShaderShadows::CreateLightMatrix( const unsigned int& i )
{
	D3DXMATRIX matView; 

	D3DXMatrixIdentity( &matView );

	assert( i < LIGHT_COUNT );
	if ( i < LIGHT_COUNT )
	{
		// Light Camera setup
		D3DXVECTOR3 vEyePt    = m_Lights[ i ].Position;
		D3DXVECTOR3 vLookatPt = m_Lights[ i ].Position;
					vLookatPt += m_Lights[ i ].Direction;

		D3DXVECTOR3 vUp       = D3DXVECTOR3( 0.0f,  0.0f, 1.0f );

		D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUp);
	}
	return matView;
}

HRESULT CShaderShadows::CreateShadowMap()
{
	// Set up Render to Texture

	D3DXMATRIX matView = CreateLightMatrix( 0 );

	m_pNVDevice->SetViewTransform(&matView);

	LPDIRECT3DSURFACE8 pSurface = 0;
	LPDIRECT3DSURFACE8 pBackBuffer = 0;
	LPDIRECT3DSURFACE8 pZBuffer = 0;

	HRESULT hr = D3D_OK;

	{ // save back buffer & Z buffer
		hr = m_pD3DDev->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );

		hr = m_pD3DDev->GetDepthStencilSurface( &pZBuffer );
	}

	hr = m_pShadowMap->GetSurfaceLevel(0, &pSurface );

	// Dx8 will automatically set up the Viewport for us when we call SetRenderTarget()
	hr = m_pD3DDev->SetRenderTarget( pSurface, m_pShadowZBuffer );

	// Clear to objectID # 00, at closest distance

	hr = m_pD3DDev->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0x00000000, 1.0, 0xffffffff );

	m_pD3DDev->SetStreamSource(0, m_pObjectMesh->m_pVB, sizeof(ShadowsVertex));

	m_pD3DDev->SetVertexShaderConstant( CV_CURR_WORLD2LIGHT_TXF_0, &matView,  4 );

	m_pD3DDev->SetVertexShader(m_dwShadowGenShader);
	m_pD3DDev->SetTexture(0, m_pShadowGen);

	m_pObjectMesh->SetVertexShader( m_dwShadowGenShader );
	m_pObjectMesh->SetTexture( m_pShadowGen);

	m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
	m_pD3DDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
	m_pD3DDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );

	m_pD3DDev->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );

	// Setup render states
	m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
	m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
	m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );

	m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
	m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1);
	m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

	m_pD3DDev->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_DISABLE );
	m_pD3DDev->SetTextureStageState( 1, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );

	//   Set up projection matrix for rendering
	D3DXMATRIX matProj;
	D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(90.0f), 1.0f, 1.0f, 1000.0f);
	m_pNVDevice->SetProjectionTransform(&matProj);

	// For each object

	// Set up Squish matrix that will take the Z depth from the light and map into the depth texture
	//  such that 0..1 maps to center - radius .. center + radius

	// Go through each model and draw to the shadow map

	for ( unsigned int i = 0; i < m_Models.size(); ++i )
	{
		// TODO: Handle case where sphere overlaps that light plane, just clamp the range...?
		D3DXMATRIX tempMatrix, modelToLightMatrix;

		D3DXMATRIX matModel = m_Models[ i ].mModelMatrix;

		D3DXMatrixMultiply( &modelToLightMatrix, &matModel, &matView);

		D3DXMatrixMultiply( &tempMatrix, &modelToLightMatrix, &matProj );

		D3DXMatrixTranspose( &tempMatrix, &tempMatrix );
		m_pD3DDev->SetVertexShaderConstant( CV_MVP_TXF_0, &tempMatrix,  4 );

		matView = CreateLightMatrix( 0 );

		D3DXMatrixMultiply( &modelToLightMatrix, &matModel, &matView);

		//D3DXMatrixMultiply( &tempMatrix, &modelToLightMatrix, &matProj );

		// set its objectID in the vertex program constants
		unsigned int theObjectID = 1 + i;
		D3DXVECTOR4 vColorCurrent( (float)( theObjectID ) / 255.0f, 0.0f, 0.0f, 0.0f );
		m_pD3DDev->SetVertexShaderConstant( CV_CURR_OBJECTID_IN_TEXELS, &vColorCurrent,  1 );

		// Compute Squish Matrix - Maps object from Model Space to Light View Space and scales the Z range
		//  to be 0..1 within the object's bounding sphere
		{
//			aBounds.Transform( &modelToLightMatrix );

			NVBounds aBounds = *(m_pObjectMesh->GetBounds());

			aBounds.Transform( &modelToLightMatrix );

			// Only really need radius with respect to light space Z

			// We are overestimating a bit to eliminate clamping
			float theRadius = max( 1.0f, ( aBounds.m_vecMaxExtents.z - aBounds.m_vecMinExtents.z ) / 1.95f );

			D3DXVECTOR4 center( aBounds.m_vecCenter.x, 
								aBounds.m_vecCenter.y,
								aBounds.m_vecCenter.z,
								1.0f );
			// Use center.z - radius to map to a Z of 0

			D3DXMATRIX SquishMatrix( 1.0f, 0.0f, 0.0f, 0.0f,
									 0.0f, 1.0f, 0.0f, 0.0f,
									 0.0f, 0.0f, 1.0f, 0.0f,
									 0.0f, 0.0f, -( center.z - theRadius  ), 1.0f );

			D3DXMatrixMultiply( &tempMatrix, &modelToLightMatrix, &SquishMatrix  );

			D3DXMATRIX SquishMatrix2( 1.0f, 0.0f, 0.0f, 0.0f,
									  0.0f, 1.0f, 0.0f, 0.0f,
									  0.0f, 0.0f, 0.5f / theRadius, 0.0f, 
									  0.0f, 0.0f, 0.0f , 1.0f );

			D3DXMatrixMultiply( &SquishMatrix, &tempMatrix, &SquishMatrix2 );

			// Set the SquishMatrix
			D3DXMatrixTranspose( &SquishMatrix, &SquishMatrix );
			m_pD3DDev->SetVertexShaderConstant( CV_CURR_SQUISH_TXF_0, &SquishMatrix,  4 );

		}

		// Set up Texture States & Render
		{
			// Don't mip map or filter the ShadowGen Texture

			m_pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT );
			m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT );
			m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT );

			// Clamp outside of range 0..1
			m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
			m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );

			m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
			m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );

			m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

			m_pD3DDev->SetRenderState( D3DRS_TEXTUREFACTOR, 0x80808080 );

			m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0 );
			m_pD3DDev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1 );

			// Setup render states
			m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
			m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
			m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );

			m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
			m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1);
			m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

			m_pD3DDev->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_DISABLE );
			m_pD3DDev->SetTextureStageState( 1, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );

			hr = m_pObjectMesh->Render( m_pNVDevice );
		}

	}


	{ // Restore Back & Z buffers

		if ( pSurface )
		{
			pSurface->Release(), pSurface = 0;
		}

		if ( m_pShadowZBuffer )
		{
			//m_pShadowZBuffer->Release();
		}

		// Dx8 will automatically set up the Viewport for us when we call SetRenderTarget()
		hr = m_pD3DDev->SetRenderTarget( pBackBuffer, pZBuffer );

		// Give back refcounts on our local copies
		pBackBuffer->Release();
		pZBuffer->Release();
	}

	return hr;

}


HRESULT	CShaderShadows::DrawObjects()
{
	D3DXMATRIX matView, matTemp, matProj;

    // Projection set up
	D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(90.0f), 1.0f, 1.0f, 1000.0f);
	m_pNVDevice->SetProjectionTransform(&matProj);

	D3DXMatrixMultiply( &matView, &m_pMouseUI->GetRotationMatrix(), &m_pMouseUI->GetTranslationMatrix() );

	for ( unsigned int i = 0; i < m_Models.size(); ++i )
	{
		m_Models[ i ].m_pNVMesh->SetVertexShader( m_dwDrawObjectShader );
		m_Models[ i ].m_pNVMesh->SetTexture(m_Models[ i ].m_pOldTexture);

		D3DXMatrixMultiply( &matView, &m_pMouseUI->GetRotationMatrix(), &m_pMouseUI->GetTranslationMatrix() );
		D3DXMatrixMultiply( &matTemp, &m_Models[ i ].mModelMatrix, &matView );
		D3DXMatrixMultiply( &matTemp, &matTemp, &matProj);

		D3DXMatrixTranspose( &matTemp, &matTemp);
		m_pD3DDev->SetVertexShaderConstant( CV_MVP_TXF_0, &matTemp,  4 );

		m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP );
		m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP );

		m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP );
		m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP );

		m_pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
		m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
		m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );

		m_pD3DDev->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
		m_pD3DDev->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
		m_pD3DDev->SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );

		m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
		m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
		m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT );

		m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT );
		m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE );

		m_pD3DDev->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
		m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

		m_pNVDevice->SetWorldTransform( & m_Models[ i ].mModelMatrix );

		SetTransform();

		m_Models[ i ].m_pNVMesh->Render(m_pNVDevice);
	}

	return S_OK;
}

HRESULT	CShaderShadows::DrawSeaFloor()
{
	D3DXMATRIX matWorld,matView;
    // Sea floor
	D3DXMatrixScaling( &matWorld, 1.0f, 1.0f, 1.0f);
	m_pNVDevice->SetWorldTransform(&matWorld);

	m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP );

	m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP );
	m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP );

	D3DXMatrixMultiply( &matView, &m_pMouseUI->GetRotationMatrix(), &m_pMouseUI->GetTranslationMatrix() );

	m_pNVDevice->SetViewTransform( &matView );

	m_pFloorMesh->SetVertexShader( 0 );

	m_pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
    m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );

	m_pD3DDev->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
    m_pD3DDev->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
	m_pD3DDev->SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );

	SetTransform();

	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT );

	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT );
	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE );

	m_pD3DDev->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
	m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

	m_pFloorMesh->Render( m_pNVDevice );

	return S_OK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -