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

📄 soft shadows.cpp

📁 这是一个用VC和DirectX编写的实时阴影程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	
	// View matrix
	D3DXVECTOR3 vLightPos = D3DXVECTOR3(  40.0f, 60.0f, -40.0f );
	D3DXVECTOR3 vLightAim = D3DXVECTOR3(   0.0f,  0.0f,   0.0f );

	D3DXMatrixLookAtLH( &matView, &vLightPos, &vLightAim, &g_vUp );

	// Compute the projection matrix
	D3DXMatrixOrthoLH( &matProj, 45.0f, 45.0f, 1.0f, 1024.0f );

	// Compute the light-view-projection matrix
	D3DXMATRIX matLightViewProj = matWorld * matView * matProj;
	
	// Compute the texture matrix
	float fTexOffs = 0.5 + (0.5 / (float)SHADOW_MAP_SIZE);
	D3DXMATRIX matTexAdj( 0.5f,		0.0f,	0.0f,	0.0f,
						  0.0f,    -0.5f,	0.0f,	0.0f,
						  0.0f,		0.0f,	1.0f,	0.0f,
						  fTexOffs, fTexOffs,  0.0f, 1.0f );

	D3DXMATRIX matTexture = matLightViewProj * matTexAdj;

	// Setup the effect variables
	g_pEffect->SetMatrix( "g_matWorldViewProj", &matWorldViewProj );
	g_pEffect->SetMatrix( "g_matLightViewProj", &matLightViewProj );
	g_pEffect->SetMatrix( "g_matWorld", &matWorld );
	g_pEffect->SetMatrix( "g_matWorldIT", &matWorldIT );
	g_pEffect->SetMatrix( "g_matTexture", &matTexture );

	g_pEffect->SetVector( "g_vLightPos", (D3DXVECTOR4*)&vLightPos );
	g_pEffect->SetVector( "g_vEyePos", (D3DXVECTOR4*)&g_vEyePos );
	g_pEffect->SetVector( "g_vLightColor", &D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 0.5f ) );

	g_pEffect->SetBool("g_bFiltered", g_bFiltered);
	
	return S_OK;
}

//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Render the frame
//-----------------------------------------------------------------------------
HRESULT Render()
{
    // Clear the viewport
	g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0 );

	// Begin rendering the scene
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
	{
		// Grab the old render target and depth buffer
		g_pd3dDevice->GetRenderTarget( 0, &g_pOldColorRT );
		g_pd3dDevice->GetDepthStencilSurface( &g_pOldDepthRT );
    
		// Render the scene depth to the shadow map
		g_pd3dDevice->SetRenderTarget( 0, g_pShadowSurf );
		g_pd3dDevice->SetDepthStencilSurface( g_pShadowDepth );
    
		// Clear the viewport
		g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xFFFFFFFF, 1.0f, 0 );

		// Set the technique
		g_pEffect->SetTechnique( "techShadow" );

		// Render the effect
		UINT uPasses = 0;
		g_pEffect->Begin( &uPasses, 0 );

		for( UINT uPass = 0; uPass < uPasses; uPass++ )
		{
			// Set the current pass
			g_pEffect->BeginPass( uPass );

			// Draw the floor
			g_pScene->DrawSubset(0);
			
			// Draw the statue
			g_pScene->DrawSubset(1);
			g_pScene->DrawSubset(2);

			// End the current pass
			g_pEffect->EndPass();
		}

		// End the effect
		g_pEffect->End();
		
		if( g_bSoftShadows )
		{
			// Render the shadowed scene into the screen map
			g_pd3dDevice->SetRenderTarget( 0, g_pScreenSurf );
			g_pd3dDevice->SetDepthStencilSurface( g_pNewDepthRT );
    
			// Clear the viewport
			g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0 );

			// Set the technique
			g_pEffect->SetTechnique( "techUnlit" );
			
			// Set the textures
			g_pEffect->SetTexture( "tShadowMap", g_pShadowMap );

			// Render the effect
			uPasses = 0;
			g_pEffect->Begin( &uPasses, 0 );

			for( uPass = 0; uPass < uPasses; uPass++ )
			{
				// Set the current pass
				g_pEffect->BeginPass( uPass );

				// Draw the floor
				g_pScene->DrawSubset(0);
				
				// Draw the statue
				g_pScene->DrawSubset(1);
				g_pScene->DrawSubset(2);

				// End the current pass
				g_pEffect->EndPass();
			}

			// End the effect
			g_pEffect->End();

			// Blur the screen map horizontally
			g_pd3dDevice->SetRenderTarget( 0, g_pBlurSurf[0] );
			g_pd3dDevice->SetDepthStencilSurface( g_pNewDepthRT );
    
			// Clear the viewport
			g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0 );

			// Set the technique
			g_pEffect->SetTechnique( "techBlurH" );
			
			// Compute the Gaussian offsets
			GetGaussianOffsets(TRUE, D3DXVECTOR2(1.0f / (FLOAT)SHADOW_MAP_SIZE, 1.0f / (FLOAT)SHADOW_MAP_SIZE),
							   g_vSampleOffsets, g_fSampleWeights);
			g_pEffect->SetValue("g_vSampleOffsets", g_vSampleOffsets, 15 * sizeof(D3DXVECTOR2));
			g_pEffect->SetValue("g_fSampleWeights", g_fSampleWeights, 15 * sizeof(FLOAT));

			// Set the textures
			g_pEffect->SetTexture( "tScreenMap", g_pScreenMap );

			// Render the effect
			uPasses = 0;
			g_pEffect->Begin( &uPasses, 0 );

			for( uPass = 0; uPass < uPasses; uPass++ )
			{
				// Set the current pass
				g_pEffect->BeginPass( uPass );

				// Draw the quad
				g_pd3dDevice->SetStreamSource( 0, g_pQuadVB, 0, sizeof(QuadVertex) );
				g_pd3dDevice->SetFVF( FVF_QUADVERTEX );
				g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
				
				// End the current pass
				g_pEffect->EndPass();
			}

			// End the effect
			g_pEffect->End();
			
			// Blur the screen map vertically
			g_pd3dDevice->SetRenderTarget( 0, g_pBlurSurf[1] );
			g_pd3dDevice->SetDepthStencilSurface( g_pNewDepthRT );
    
			// Clear the viewport
			g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0 );

			// Set the technique
			g_pEffect->SetTechnique( "techBlurV" );
			
			// Compute the Gaussian offsets
			GetGaussianOffsets(FALSE, D3DXVECTOR2(1.0f / (FLOAT)SHADOW_MAP_SIZE, 1.0f / (FLOAT)SHADOW_MAP_SIZE),
							   g_vSampleOffsets, g_fSampleWeights);
			g_pEffect->SetValue("g_vSampleOffsets", g_vSampleOffsets, 15 * sizeof(D3DXVECTOR2));
			g_pEffect->SetValue("g_fSampleWeights", g_fSampleWeights, 15 * sizeof(FLOAT));

			// Set the textures
			g_pEffect->SetTexture( "tBlurHMap", g_pBlurMap[0] );

			// Render the effect
			uPasses = 0;
			g_pEffect->Begin( &uPasses, 0 );

			for( uPass = 0; uPass < uPasses; uPass++ )
			{
				// Set the current pass
				g_pEffect->BeginPass( uPass );

				// Draw the quad
				g_pd3dDevice->SetStreamSource( 0, g_pQuadVB, 0, sizeof(QuadVertex) );
				g_pd3dDevice->SetFVF( FVF_QUADVERTEX );
				g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

				// End the current pass
				g_pEffect->EndPass();
			}

			// End the effect
			g_pEffect->End();

			// Restore the render target and depth buffer
			g_pd3dDevice->SetRenderTarget( 0, g_pOldColorRT );
			g_pd3dDevice->SetDepthStencilSurface( g_pOldDepthRT );
			SAFE_RELEASE( g_pOldColorRT );
			SAFE_RELEASE( g_pOldDepthRT );

			// Finally, render the shadowed scene
			g_pEffect->SetTechnique( "techScene" );
			
			// Set the textures
			g_pEffect->SetTexture( "tBlurVMap", g_pBlurMap[1] );
			g_pEffect->SetTexture( "tSpotMap", g_pSpotMap );

			// Render the effect
			uPasses = 0;
			g_pEffect->Begin( &uPasses, 0 );

			// Do we need to render the scene in wireframe mode
			if( g_bWireframe )
				g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );

			for( uPass = 0; uPass < uPasses; uPass++ )
			{
				// Set the current pass
				g_pEffect->BeginPass( uPass );

				// Draw the floor
				g_pEffect->SetTexture( "tColorMap", g_pColorMap_Floor );
				g_pEffect->CommitChanges();
				g_pScene->DrawSubset(0);
				
				// Draw the statue
				g_pEffect->SetTexture( "tColorMap", g_pColorMap_Statue );
				g_pEffect->CommitChanges();
				g_pScene->DrawSubset(1);
				g_pScene->DrawSubset(2);

				// End the current pass
				g_pEffect->EndPass();
			}

			// End the effect
			g_pEffect->End();
			
			// Restore the render state
			g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
		}

		else
		{
			// Restore the render target and depth buffer
			g_pd3dDevice->SetRenderTarget( 0, g_pOldColorRT );
			g_pd3dDevice->SetDepthStencilSurface( g_pOldDepthRT );
			SAFE_RELEASE( g_pOldColorRT );
			SAFE_RELEASE( g_pOldDepthRT );

			// Otherwise, render the scene with hard shadows
			g_pEffect->SetTechnique( "techSceneHard" );
			
			// Set the textures
			g_pEffect->SetTexture( "tShadowMap", g_pShadowMap );
			g_pEffect->SetTexture( "tSpotMap", g_pSpotMap );

			// Render the effect
			uPasses = 0;
			g_pEffect->Begin( &uPasses, 0 );

			// Do we need to render the scene in wireframe mode
			if( g_bWireframe )
				g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );

			for( uPass = 0; uPass < uPasses; uPass++ )
			{
				// Set the current pass
				g_pEffect->BeginPass( uPass );

				// Draw the floor
				g_pEffect->SetTexture( "tColorMap", g_pColorMap_Floor );
				g_pEffect->CommitChanges();
				g_pScene->DrawSubset(0);
				
				// Draw the statue
				g_pEffect->SetTexture( "tColorMap", g_pColorMap_Statue );
				g_pEffect->CommitChanges();
				g_pScene->DrawSubset(1);
				g_pScene->DrawSubset(2);

				// End the current pass
				g_pEffect->EndPass();
			}

			// End the effect
			g_pEffect->End();
			
			// Restore the render state
			g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
		}

		// Display the frame stats
		if( g_bDisplayStats )
		{
			TCHAR szStats[255];
			sprintf( szStats, "Framerate : %2.1f", g_fFramerate );
			
			RECT rc = { 5, 5, 0, 0 };
			g_pFont->DrawText( NULL, szStats, -1, &rc, DT_CALCRECT, 0xFFFFAA00 );
 			g_pFont->DrawText( NULL, szStats, -1, &rc, DT_NOCLIP,   0xFFFFAA00 );

			sprintf( szStats, "Use arrow and Z, X keys to move around the scene" );
			SetRect( &rc, 5, SCREEN_HEIGHT - 40, 0, 0 );
			g_pFont->DrawText( NULL, szStats, -1, &rc, DT_CALCRECT, 0xFFFFAA00 );
 			g_pFont->DrawText( NULL, szStats, -1, &rc, DT_NOCLIP,   0xFFFFAA00 );
			
			sprintf( szStats, "Press W to toggle wireframe display" );
			SetRect( &rc, 5, SCREEN_HEIGHT - 20, 0, 0 );
			g_pFont->DrawText( NULL, szStats, -1, &rc, DT_CALCRECT, 0xFFFFAA00 );
 			g_pFont->DrawText( NULL, szStats, -1, &rc, DT_NOCLIP,   0xFFFFAA00 );
			
			sprintf( szStats, "Press S to toggle soft shadows" );
			SetRect( &rc, 350, SCREEN_HEIGHT - 40, 0, 0 );
			g_pFont->DrawText( NULL, szStats, -1, &rc, DT_CALCRECT, 0xFFFFAA00 );
 			g_pFont->DrawText( NULL, szStats, -1, &rc, DT_NOCLIP,   0xFFFFAA00 );
				
			sprintf( szStats, "Press G to pump out a screenshot" );
			SetRect( &rc, 350, SCREEN_HEIGHT - 20, 0, 0 );
			g_pFont->DrawText( NULL, szStats, -1, &rc, DT_CALCRECT, 0xFFFFAA00 );
 			g_pFont->DrawText( NULL, szStats, -1, &rc, DT_NOCLIP,   0xFFFFAA00 );
		}

		// End rendering the scene and present it
		g_pd3dDevice->EndScene();
		g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
	}

	return S_OK;
}

//-----------------------------------------------------------------------------
// Name: ScreenGrab()
// Desc: Saves the backbuffer to a file
//-----------------------------------------------------------------------------
HRESULT ScreenGrab()
{
	//
	// Grab the back buffer and save it to a file
	//
	
	D3DDISPLAYMODE d3ddm;
	g_pd3dDevice->GetDisplayMode( 0, &d3ddm );

	g_pd3dDevice->CreateOffscreenPlainSurface( d3ddm.Width, d3ddm.Height, D3DFMT_A8R8G8B8,
											   D3DPOOL_DEFAULT, &g_pScreenshot, NULL );

	g_pd3dDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &g_pScreenshot );

	TCHAR szScreenshot[32];
	sprintf( szScreenshot, "ScreenShot%d.bmp", g_uNumScreenshots++ );
	D3DXSaveSurfaceToFile( szScreenshot, D3DXIFF_BMP, g_pScreenshot, NULL, NULL );

	SAFE_RELEASE( g_pScreenshot );

	return S_OK;
}

⌨️ 快捷键说明

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