softparticles.cpp
来自「声音和图片的加载功能,不过运行起来有点卡」· C++ 代码 · 共 990 行 · 第 1/3 页
CPP
990 行
//--------------------------------------------------------------------------------------
// File: SoftParticles.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include "DXUT.h"
#include "DXUTgui.h"
#include "DXUTsettingsdlg.h"
#include "DXUTcamera.h"
#include "SDKmisc.h"
#include "SDKmesh.h"
#include "resource.h"
#define MAX_PARTICLES 500
struct PARTICLE_VERTEX
{
D3DXVECTOR3 Pos;
D3DXVECTOR3 Vel;
float Life;
float Size;
};
//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
CModelViewerCamera g_Camera; // A model viewing camera
CDXUTDialogResourceManager g_DialogResourceManager; // manager for shared resources of dialogs
CD3DSettingsDlg g_D3DSettingsDlg; // Device settings dialog
CDXUTDialog g_HUD; // manages the 3D UI
CDXUTDialog g_SampleUI; // dialog for sample specific controls
PARTICLE_VERTEX* g_pCPUParticles = NULL;
DWORD* g_pCPUParticleIndices = NULL;
float* g_pParticleDepthArray = NULL;
CDXUTSDKMesh g_ObjectMesh;
CDXUTSDKMesh g_SkyMesh;
ID3DX10Font* g_pFont10 = NULL;
ID3DX10Sprite* g_pSprite10 = NULL;
CDXUTTextHelper* g_pTxtHelper = NULL;
ID3D10Effect* g_pEffect10 = NULL;
ID3D10InputLayout* g_pSceneVertexLayout = NULL;
ID3D10InputLayout* g_pParticleVertexLayout = NULL;
ID3D10Texture2D* g_pDepthStencilTexture = NULL;
ID3D10DepthStencilView* g_pDepthStencilDSV = NULL;
ID3D10ShaderResourceView* g_pDepthStencilSRV = NULL;
ID3D10Buffer* g_pParticleVB = NULL;
ID3D10Buffer* g_pParticleIB = NULL;
ID3D10ShaderResourceView* g_pParticleTexRV = NULL;
ID3D10Texture3D* g_pNoiseVolume = NULL;
ID3D10ShaderResourceView* g_pNoiseVolumeRV = NULL;
ID3D10Texture2D* g_pColorGradTexture = NULL;
ID3D10ShaderResourceView* g_pColorGradTexRV = NULL;
ID3D10EffectTechnique* g_pRenderScene = NULL;
ID3D10EffectTechnique* g_pRenderSky = NULL;
ID3D10EffectTechnique* g_pRenderBillboardParticlesHard = NULL;
ID3D10EffectTechnique* g_pRenderBillboardParticlesODepth = NULL;
ID3D10EffectTechnique* g_pRenderBillboardParticlesSoft = NULL;
ID3D10EffectTechnique* g_pRenderBillboardParticlesODepthSoft = NULL;
ID3D10EffectTechnique* g_pRenderVolumeParticlesHard = NULL;
ID3D10EffectTechnique* g_pRenderVolumeParticlesSoft = NULL;
ID3D10EffectMatrixVariable* g_pmWorldViewProj = NULL;
ID3D10EffectMatrixVariable* g_pmWorldView = NULL;
ID3D10EffectMatrixVariable* g_pmWorld = NULL;
ID3D10EffectMatrixVariable* g_pmInvView = NULL;
ID3D10EffectMatrixVariable* g_pmInvProj = NULL;
ID3D10EffectScalarVariable* g_pfFadeDistance = NULL;
ID3D10EffectScalarVariable* g_pfSizeZScale = NULL;
ID3D10EffectVectorVariable* g_pvViewLightDir1 = NULL;
ID3D10EffectVectorVariable* g_pvViewLightDir2 = NULL;
ID3D10EffectVectorVariable* g_pvWorldLightDir1 = NULL;
ID3D10EffectVectorVariable* g_pvWorldLightDir2 = NULL;
ID3D10EffectVectorVariable* g_pvEyePt = NULL;
ID3D10EffectVectorVariable* g_pvViewDir = NULL;
ID3D10EffectVectorVariable* g_pvOctaveOffsets = NULL;
ID3D10EffectShaderResourceVariable* g_pDiffuseTex = NULL;
ID3D10EffectShaderResourceVariable* g_pNormalTex = NULL;
ID3D10EffectShaderResourceVariable* g_pColorGradient = NULL;
ID3D10EffectShaderResourceVariable* g_pVolumeDiffTex = NULL;
ID3D10EffectShaderResourceVariable* g_pVolumeNormTex = NULL;
ID3D10EffectShaderResourceVariable* g_pDepthTex = NULL;
enum PARTICLE_TECHNIQUE
{
PT_VOLUME_SOFT = 0x0,
PT_VOLUME_HARD,
PT_BILLBOARD_ODEPTHSOFT,
PT_BILLBOARD_ODEPTH,
PT_BILLBOARD_SOFT,
PT_BILLBOARD_HARD
};
float g_fFadeDistance = 1.0f;
float g_fParticleLifeSpan = 5.0f;
float g_fEmitRate = 0.015f;
float g_ParticleVel = 3.0f;
float g_fParticleMaxSize = 1.25f;
float g_fParticleMinSize = 1.0f;
bool g_bAnimateParticles = true;
PARTICLE_TECHNIQUE g_ParticleTechnique = PT_VOLUME_SOFT;
D3DXVECTOR3 g_vLightDir1 = D3DXVECTOR3(1.705f,5.557f,-9.380f);
D3DXVECTOR3 g_vLightDir2 = D3DXVECTOR3(-5.947f,-5.342f,-5.733f);
//--------------------------------------------------------------------------------------
// UI control IDs
//--------------------------------------------------------------------------------------
#define IDC_STATIC -1
#define IDC_TOGGLEFULLSCREEN 1
#define IDC_TOGGLEREF 3
#define IDC_CHANGEDEVICE 4
#define IDC_TECHNIQUE 5
//--------------------------------------------------------------------------------------
// Forward declarations
//--------------------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext );
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext );
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext );
void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext );
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext );
bool CALLBACK IsD3D10DeviceAcceptable( UINT Adapter, UINT Output, D3D10_DRIVER_TYPE DeviceType, DXGI_FORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
HRESULT CALLBACK OnD3D10CreateDevice( ID3D10Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
HRESULT CALLBACK OnD3D10SwapChainResized( ID3D10Device* pd3dDevice, IDXGISwapChain *pSwapChain, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
void CALLBACK OnD3D10SwapChainReleasing( void* pUserContext );
void CALLBACK OnD3D10DestroyDevice( void* pUserContext );
void CALLBACK OnD3D10FrameRender( ID3D10Device* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
void InitApp();
void RenderText();
HRESULT CreateParticleBuffers(ID3D10Device* pd3dDevice);
HRESULT CreateNoiseVolume( ID3D10Device* pd3dDevice, UINT VolumeSize );
void SortParticleBuffer( D3DXVECTOR3 vEye, D3DXVECTOR3 vDir );
void AdvanceParticles( ID3D10Device* pd3dDevice, double fTime, float fTimeDelta );
void UpdateParticleBuffers( ID3D10Device* pd3dDevice );
//--------------------------------------------------------------------------------------
// Entry point to the program. Initializes everything and goes into a message processing
// loop. Idle time is used to render the scene.
//--------------------------------------------------------------------------------------
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
{
// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
// DXUT will create and use the best device (either D3D9 or D3D10)
// that is available on the system depending on which D3D callbacks are set below
// Set DXUT callbacks
DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
DXUTSetCallbackMsgProc( MsgProc );
DXUTSetCallbackKeyboard( KeyboardProc );
DXUTSetCallbackFrameMove( OnFrameMove );
DXUTSetCallbackD3D10DeviceAcceptable( IsD3D10DeviceAcceptable );
DXUTSetCallbackD3D10DeviceCreated( OnD3D10CreateDevice );
DXUTSetCallbackD3D10SwapChainResized( OnD3D10SwapChainResized );
DXUTSetCallbackD3D10SwapChainReleasing( OnD3D10SwapChainReleasing );
DXUTSetCallbackD3D10DeviceDestroyed( OnD3D10DestroyDevice );
DXUTSetCallbackD3D10FrameRender( OnD3D10FrameRender );
InitApp();
DXUTInit( true, true, NULL ); // Parse the command line, show msgboxes on error, no extra command line params
DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
DXUTCreateWindow( L"SoftParticles" );
DXUTCreateDevice( true, 640, 480 );
DXUTMainLoop(); // Enter into the DXUT render loop
}
//--------------------------------------------------------------------------------------
// Initialize the app
//--------------------------------------------------------------------------------------
void InitApp()
{
g_D3DSettingsDlg.Init( &g_DialogResourceManager );
g_HUD.Init( &g_DialogResourceManager );
g_SampleUI.Init( &g_DialogResourceManager );
g_HUD.SetCallback( OnGUIEvent ); int iY = 10;
g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Toggle full screen", 35, iY, 125, 22 );
g_HUD.AddButton( IDC_TOGGLEREF, L"Toggle REF (F3)", 35, iY += 24, 125, 22, VK_F3 );
g_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", 35, iY += 24, 125, 22, VK_F2 );
g_SampleUI.SetCallback( OnGUIEvent ); iY = 10;
CDXUTComboBox* pComboBox = NULL;
g_SampleUI.AddStatic( IDC_STATIC, L"(T)echnique", 0, 0, 105, 25 );
g_SampleUI.AddComboBox( IDC_TECHNIQUE, 0, 25, 140, 24, 'T', false, &pComboBox );
if( pComboBox )
pComboBox->SetDropHeight( 80 );
pComboBox->AddItem( L"Volume Soft", (void*)PT_VOLUME_SOFT );
pComboBox->AddItem( L"Volume Hard", (void*)PT_VOLUME_HARD );
pComboBox->AddItem( L"Depth Sprites Soft", (void*)PT_BILLBOARD_ODEPTHSOFT );
pComboBox->AddItem( L"Depth Sprites Hard", (void*)PT_BILLBOARD_ODEPTH );
pComboBox->AddItem( L"Billboard Soft", (void*)PT_BILLBOARD_SOFT );
pComboBox->AddItem( L"Billboard Hard", (void*)PT_BILLBOARD_HARD );
}
//--------------------------------------------------------------------------------------
// Called right before creating a D3D9 or D3D10 device, allowing the app to modify the device settings as needed
//--------------------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext )
{
// For the first device created if its a REF device, optionally display a warning dialog box
static bool s_bFirstTime = true;
if( s_bFirstTime )
{
s_bFirstTime = false;
if( (DXUT_D3D9_DEVICE == pDeviceSettings->ver && pDeviceSettings->d3d9.DeviceType == D3DDEVTYPE_REF) ||
(DXUT_D3D10_DEVICE == pDeviceSettings->ver && pDeviceSettings->d3d10.DriverType == D3D10_DRIVER_TYPE_REFERENCE) )
DXUTDisplaySwitchingToREFWarning( pDeviceSettings->ver );
}
// Disable MSAA settings from the settings dialog
g_D3DSettingsDlg.GetDialogControl()->GetComboBox( DXUTSETTINGSDLG_D3D10_MULTISAMPLE_COUNT )->SetEnabled(false);
g_D3DSettingsDlg.GetDialogControl()->GetComboBox( DXUTSETTINGSDLG_D3D10_MULTISAMPLE_QUALITY )->SetEnabled(false);
g_D3DSettingsDlg.GetDialogControl()->GetStatic( DXUTSETTINGSDLG_D3D10_MULTISAMPLE_COUNT_LABEL )->SetEnabled(false);
g_D3DSettingsDlg.GetDialogControl()->GetStatic( DXUTSETTINGSDLG_D3D10_MULTISAMPLE_QUALITY_LABEL )->SetEnabled(false);
return true;
}
static int iFrame = 0;
//--------------------------------------------------------------------------------------
// Handle updates to the scene. This is called regardless of which D3D API is used
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext )
{
// Update the camera's position based on user input
g_Camera.FrameMove( fElapsedTime );
D3DXVECTOR3 vEye = *g_Camera.GetEyePt();
D3DXVECTOR3 vDir = *g_Camera.GetLookAtPt() - vEye;
D3DXVec3Normalize( &vDir, &vDir );
ID3D10Device* pd3dDevice = DXUTGetD3D10Device();
AdvanceParticles( pd3dDevice, fTime, fElapsedTime );
SortParticleBuffer( vEye, vDir );
UpdateParticleBuffers( pd3dDevice );
// Update the movement of the noise octaves
D3DXVECTOR4 OctaveOffsets[4];
for( int i=0; i<4; i++ )
{
OctaveOffsets[i].x = -(float)(fTime*0.05);
OctaveOffsets[i].y = 0;
OctaveOffsets[i].z = 0;
OctaveOffsets[i].w = 0;
}
g_pvOctaveOffsets->SetFloatVectorArray( (float*)OctaveOffsets, 0, 4 );
}
//--------------------------------------------------------------------------------------
// Handle messages to the application
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext )
{
// Pass messages to dialog resource manager calls so GUI state is updated correctly
*pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
if( *pbNoFurtherProcessing )
return 0;
// Pass messages to settings dialog if its active
if( g_D3DSettingsDlg.IsActive() )
{
g_D3DSettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam );
return 0;
}
// Give the dialogs a chance to handle the message first
*pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
if( *pbNoFurtherProcessing )
return 0;
*pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
if( *pbNoFurtherProcessing )
return 0;
// Pass all remaining windows messages to camera so it can respond to user input
g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
return 0;
}
//--------------------------------------------------------------------------------------
// Handle key presses
//--------------------------------------------------------------------------------------
void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext )
{
}
//--------------------------------------------------------------------------------------
// Handles the GUI events
//--------------------------------------------------------------------------------------
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext )
{
switch( nControlID )
{
case IDC_TOGGLEFULLSCREEN: DXUTToggleFullScreen(); break;
case IDC_TOGGLEREF: DXUTToggleREF(); break;
case IDC_CHANGEDEVICE: g_D3DSettingsDlg.SetActive( !g_D3DSettingsDlg.IsActive() ); break;
case IDC_TECHNIQUE:
{
CDXUTComboBox* pComboBox = (CDXUTComboBox*)pControl;
g_ParticleTechnique = (PARTICLE_TECHNIQUE)(int)PtrToInt(pComboBox->GetSelectedData());
}
break;
}
}
//--------------------------------------------------------------------------------------
// Reject any D3D10 devices that aren't acceptable by returning false
//--------------------------------------------------------------------------------------
bool CALLBACK IsD3D10DeviceAcceptable( UINT Adapter, UINT Output, D3D10_DRIVER_TYPE DeviceType, DXGI_FORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?