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

📄 soft shadows.cpp

📁 这是一个用VC和DirectX编写的实时阴影程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				{
					break;
				}
			}
			break;
		}

		default:
		{
			return DefWindowProc( hWnd, msg, wParam, lParam );
		}
		break;
	}

	return 0;
}

//-----------------------------------------------------------------------------
// Name: Initialize()
// Desc: Initialize Direct3D
//-----------------------------------------------------------------------------
HRESULT Initialize()
{
    // Create the Direct3D object
	g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );

	if( g_pD3D == NULL )
	{
		MessageBox( g_hWnd, "Unable to create the Direct3D object!", ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}

    // Display mode
	D3DDISPLAYMODE d3ddm;

    // Get the suitable display mode
	UINT uNumModes = g_pD3D->GetAdapterModeCount( D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8 );
    
	// Select the best mode (offering the highest frequency at the specified resolution)
	D3DDISPLAYMODE* pModes = new D3DDISPLAYMODE[uNumModes];
	for( UINT uMode = 0; uMode < uNumModes; uMode++ )
	{
		// Enumerate the adapter modes
		if( FAILED( g_pD3D->EnumAdapterModes( D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, uMode, &pModes[uMode] ) ) )
		{
			MessageBox( g_hWnd, "Unable to enumerate adapter display mode!", ERROR, MB_OK | MB_ICONERROR );
			return E_FAIL;
		}	
	}
	
	for( uMode = 0; uMode < uNumModes; uMode++ )
	{
		if( pModes[uMode].Width == SCREEN_WIDTH && pModes[uMode].Height == SCREEN_HEIGHT )
		{
			if( pModes[uMode + 1].Width == SCREEN_WIDTH && pModes[uMode + 1].Height == SCREEN_HEIGHT )
			{
				if( pModes[uMode].RefreshRate > pModes[uMode + 1].RefreshRate )
				{
					d3ddm = pModes[uMode];
				}
				else
				{
					d3ddm = pModes[uMode + 1];
				}
			}
			else
			{
				d3ddm = pModes[uMode];
			}
		}

		else if( pModes[uMode].Width > SCREEN_WIDTH || pModes[uMode].Height > SCREEN_HEIGHT ) {
			break;
		}
	}

	// Delete the list
	delete [] pModes;

	if( FAILED( g_pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 
										   d3ddm.Format, D3DUSAGE_DEPTHSTENCIL,
										   D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )
	{
		MessageBox( g_hWnd, "Unable to find suitable display mode!", ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}

	// If we are using windowed mode
	if( g_bWindowed )
		g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm );

	if( FAILED( g_pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 
										   d3ddm.Format, D3DUSAGE_DEPTHSTENCIL,
										   D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )
	{
		MessageBox( g_hWnd, "Unable to get adapter display mode!", ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}

	// Get the hardware caps
	D3DCAPS9 d3dCaps;

	if( FAILED( g_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, 
		                               D3DDEVTYPE_HAL, &d3dCaps ) ) )
	{
		MessageBox( g_hWnd, "Unable to get hardware caps!", ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}

	// Check for vertex/pixel shaders 2.0 support
	if( d3dCaps.VertexShaderVersion < D3DVS_VERSION( 2, 0 ) || d3dCaps.PixelShaderVersion < D3DPS_VERSION( 2, 0 ) )
	{
		MessageBox( g_hWnd, "Vertex/Pixel shaders 2.0 not supported!", ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}

	// Check for R32F surface format support
	if( FAILED( g_pD3D->CheckDepthStencilMatch( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format,
												D3DFMT_R32F, D3DFMT_D16 ) ) )
	{
		MessageBox( g_hWnd, "R32F format not supported!", ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}

	DWORD dwBehaviorFlags = 0;

	if( d3dCaps.VertexProcessingCaps != 0 )
		dwBehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE;
	else
		dwBehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

	D3DPRESENT_PARAMETERS d3dpp;
	memset(&d3dpp, 0, sizeof(d3dpp));

	d3dpp.BackBufferWidth			= d3ddm.Width;
	d3dpp.BackBufferHeight			= d3ddm.Height;
	d3dpp.BackBufferFormat			= d3ddm.Format;
	d3dpp.BackBufferCount			= 1;
	
	d3dpp.MultiSampleType			= D3DMULTISAMPLE_NONE;
	d3dpp.SwapEffect				= D3DSWAPEFFECT_DISCARD;

	d3dpp.hDeviceWindow				= g_hWnd;
	d3dpp.Windowed					= g_bWindowed;

	d3dpp.EnableAutoDepthStencil	= TRUE;
	d3dpp.AutoDepthStencilFormat	= D3DFMT_D16;
	d3dpp.Flags						= D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;

	if( g_bWindowed )
	{
		d3dpp.FullScreen_RefreshRateInHz = 0;
		d3dpp.PresentationInterval		 = D3DPRESENT_INTERVAL_IMMEDIATE;
	}

	else
	{
		d3dpp.FullScreen_RefreshRateInHz = d3ddm.RefreshRate;
		d3dpp.PresentationInterval		= D3DPRESENT_INTERVAL_ONE;
	}

    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
                                      dwBehaviorFlags, &d3dpp, &g_pd3dDevice ) ) )
	{
		MessageBox( g_hWnd, "Unable to create the Direct3D device!", ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}

	// Create the font object
    if( FAILED( D3DXCreateFont( g_pd3dDevice, 16, 0, FW_BOLD, 1, false, DEFAULT_CHARSET, 
								OUT_TT_ONLY_PRECIS, 0, 0, "Veranda", &g_pFont ) ) )
	{
		MessageBox( g_hWnd, "Unable to create the font object!", ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}

	// Load the scene
	LPD3DXMESH pTempScene = NULL;
	if( FAILED( D3DXLoadMeshFromX( "Media/Soft Shadows.x", D3DXMESH_32BIT, g_pd3dDevice,
									NULL, NULL, NULL, NULL, &pTempScene ) ) )
	{
		MessageBox( g_hWnd, "Unable to load Soft Shadows.x", "Error", MB_OK | MB_ICONERROR );
		return E_FAIL;
	}
	pTempScene->CloneMesh( D3DXMESH_32BIT, dwElement, g_pd3dDevice, &g_pScene );

	SAFE_RELEASE( pTempScene );

	// Compute the normals and tangents for the scene
	D3DXComputeNormals( g_pScene, NULL );

	// Create the effect
	LPD3DXBUFFER pBufferErrors = NULL;
	if( FAILED( D3DXCreateEffectFromFile( g_pd3dDevice, "Media/Soft Shadows.fx", NULL, NULL, 0, 
										  NULL, &g_pEffect, &pBufferErrors ) ) )
	{
		LPVOID pErrors = pBufferErrors->GetBufferPointer();
		MessageBox(NULL, (const char*)pErrors, ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}

	SAFE_RELEASE( pBufferErrors );
	
	// Create the quad vertex buffer
	if( FAILED( g_pd3dDevice->CreateVertexBuffer( 4 * sizeof(QuadVertex), D3DUSAGE_WRITEONLY, FVF_QUADVERTEX,
												  D3DPOOL_DEFAULT, &g_pQuadVB, NULL ) ) )
	{
		MessageBox( g_hWnd, "Unable to create vertex buffer!", ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}

	// Copy the vertices
	QuadVertex* pVertices;
	g_pQuadVB->Lock( 0, 0, (void**)&pVertices, 0 );
	pVertices[0].p = D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f );
	pVertices[1].p = D3DXVECTOR4( 0.0f, SCREEN_HEIGHT / 2, 0.0f, 1.0f );
	pVertices[2].p = D3DXVECTOR4( SCREEN_WIDTH / 2, 0.0f, 0.0f, 1.0f );
	pVertices[3].p = D3DXVECTOR4( SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 0.0f, 1.0f );
	
	pVertices[0].t = D3DXVECTOR2( 0.0f, 0.0f );
	pVertices[1].t = D3DXVECTOR2( 0.0f, 1.0f );
	pVertices[2].t = D3DXVECTOR2( 1.0f, 0.0f );
	pVertices[3].t = D3DXVECTOR2( 1.0f, 1.0f );
	g_pQuadVB->Unlock();

	// Load the color and spot maps
	if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "Media/Color_Floor.dds", &g_pColorMap_Floor ) ) )
	{
		MessageBox( g_hWnd, "Unable to load Color_Floor.dds", ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}
	
	if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "Media/Color_Statue.dds", &g_pColorMap_Statue ) ) )
	{
		MessageBox( g_hWnd, "Unable to load Color_Statue.dds", ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}
		
	if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "Media/SpotMap.dds", &g_pSpotMap ) ) )
	{
		MessageBox( g_hWnd, "Unable to load SpotMap.dds", ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}

	// Create the shadow map
	if( FAILED( g_pd3dDevice->CreateTexture( SHADOW_MAP_SIZE, SHADOW_MAP_SIZE, 1, D3DUSAGE_RENDERTARGET,
											 D3DFMT_R32F, D3DPOOL_DEFAULT, &g_pShadowMap, NULL ) ) )
	{
		MessageBox( g_hWnd, "Unable to create shadow map!", ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}

	// Grab the texture's surface
	g_pShadowMap->GetSurfaceLevel( 0, &g_pShadowSurf );

	// Create the screen-sized buffer map
	if( FAILED( g_pd3dDevice->CreateTexture( SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 1, D3DUSAGE_RENDERTARGET,
											 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pScreenMap, NULL ) ) )
	{
		MessageBox( g_hWnd, "Unable to create screen map!", ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}

	// Grab the texture's surface
	g_pScreenMap->GetSurfaceLevel( 0, & g_pScreenSurf );

	// Create the blur maps
	for( int i = 0; i < 2; i++ )
	{
		if( FAILED( g_pd3dDevice->CreateTexture( SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 1, D3DUSAGE_RENDERTARGET,
												 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pBlurMap[i], NULL ) ) )
		{
			MessageBox( g_hWnd, "Unable to create blur map!", ERROR, MB_OK | MB_ICONERROR );
			return E_FAIL;
		}

		// Grab the texture's surface
		g_pBlurMap[i]->GetSurfaceLevel( 0, & g_pBlurSurf[i] );
	}
	
	// Create the shadow depth surface
	if( FAILED( g_pd3dDevice->CreateDepthStencilSurface( SHADOW_MAP_SIZE, SHADOW_MAP_SIZE, D3DFMT_D16,
														 D3DMULTISAMPLE_NONE, 0, TRUE, &g_pShadowDepth, NULL ) ) )
	{
		MessageBox( g_hWnd, "Unable to create shadow depth surface!", ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}

	// Create the general depth surface
	if( FAILED( g_pd3dDevice->CreateDepthStencilSurface( SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, D3DFMT_D16,
														 D3DMULTISAMPLE_NONE, 0, TRUE, &g_pNewDepthRT, NULL ) ) )
	{
		MessageBox( g_hWnd, "Unable to create general depth surface!", ERROR, MB_OK | MB_ICONERROR );
		return E_FAIL;
	}

	return S_OK;
}

//-----------------------------------------------------------------------------
// Name: ShutDown()
// Desc: ShutDown Direct3D
//-----------------------------------------------------------------------------
HRESULT ShutDown()
{
	// Clean up
	SAFE_RELEASE( g_pFont );

	SAFE_RELEASE( g_pScene );
	SAFE_RELEASE( g_pEffect );

	SAFE_RELEASE( g_pColorMap_Floor );
	SAFE_RELEASE( g_pColorMap_Statue );
	SAFE_RELEASE( g_pSpotMap );
	
	SAFE_RELEASE( g_pShadowMap );
	SAFE_RELEASE( g_pShadowSurf );
	SAFE_RELEASE( g_pShadowDepth );

	SAFE_RELEASE( g_pScreenMap );
	SAFE_RELEASE( g_pScreenSurf );

	SAFE_RELEASE( g_pBlurMap[0] );
	SAFE_RELEASE( g_pBlurSurf[0] );
	SAFE_RELEASE( g_pBlurMap[1] );
	SAFE_RELEASE( g_pBlurSurf[1] );

	SAFE_RELEASE( g_pNewDepthRT );
	SAFE_RELEASE( g_pOldColorRT );
	SAFE_RELEASE( g_pOldDepthRT );

	SAFE_RELEASE( g_pd3dDevice );
	SAFE_RELEASE( g_pD3D );
	
	return S_OK;
}

//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: Setup effect variables and update stuff
//-----------------------------------------------------------------------------
HRESULT FrameMove()
{
	//
	// Camera space matrices
	//
	
	// Computee the world matrix
	D3DXMATRIX matWorld;
	D3DXMatrixIdentity( &matWorld );

	// Compute the view matrix
	D3DXMATRIX matView;
	D3DXMatrixLookAtLH( &matView, &g_vEyePos, &g_vEyeAim, &g_vUp );

	// Compute the projection matrix
	D3DXMATRIX matProj;
	D3DXMatrixPerspectiveFovLH( &matProj, D3DXToRadian(60.0f), (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, 1.0f, 1024.0f );

	// Compute the world-view-projection matrix
	D3DXMATRIX matWorldViewProj = matWorld * matView * matProj;

	// World inverse matrix
	D3DXMATRIX matWorldIT;
	D3DXMatrixInverse( &matWorldIT, NULL, &matWorld );
	D3DXMatrixTranspose( &matWorldIT, &matWorldIT );

	//
	// Light space matrices
	//

⌨️ 快捷键说明

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