www.pudn.com > fluid.rar > demo.cpp, change:2006-10-29,size:31470b
#include "stableHeader.h"
#include "resource.h"
#include "Scene.h"
#include "DTKStringConverter.h"
#include "DTKUtil.h"
#include "FluidAnimator2D.h"
#include "DTKVectorTrigger.h"
#include "DTKParamSettingDialog.h"
#include "Substance2D.h"
#include "DTKColorValue.h"
//#define DEBUG_VS // Uncomment this line to debug vertex shaders
//#define DEBUG_PS // Uncomment this line to debug pixel shaders
//------------------------------------------------------------------------------
//external variables
//------------------------------------------------------------------------------
extern DTK::FluidAnimator2D g_animator;
extern DTK::Substance2D g_substance;
extern float g_fTimeScale;
extern DTK::uint g_uCurDisplayMode;
extern bool g_bShowQuiverVelocityField;
extern float g_forceRadius;
extern float g_forceStrength;
extern float g_sourceRadius;
extern DTK::ColorValue g_sourceStrength;
//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
ID3DXFont* g_pFont = NULL; // Font for drawing text
ID3DXSprite* g_pTextSprite = NULL; // Sprite for batching draw text calls
CModelViewerCamera g_Camera; // A model viewing camera
bool g_bShowHelp = true; // If true, it renders the UI control text
CDXUTDialogResourceManager g_DialogResourceManager; // manager for shared resources of dialogs
CD3DSettingsDlg g_SettingsDlg; // Device settings dialog
CDXUTDialog g_HUD; // dialog for standard controls
CDXUTDialog g_SampleUI; // dialog for sample specific controls
DTK::VectorTrigger g_vecTrigger;
DTK::ParamSettingDialog g_paramDialog;
const DTK::uint NUM_DISPLAY_MODE =5;
const WCHAR* DISPLAY_MODE[]=
{
{L"source"},
{L"velocity"},
{L"pressure"},
{L"vorticity"},
{L"vorticity confinement force"},
};
const DTK::uint NUM_FLUID_TYPE = 1;
const WCHAR* FLUID_TYPE[]=
{
{L"Smoke"}
};
DTK::uint g_uFluidType = Scene::FT_SMOKE;
bool gs_bDiffuse=true;
bool gs_bAdvection=true;
bool gs_bProject=true;
bool gs_bVelocityBoundary=true;
bool gs_bPressureBoundary=true;
bool gs_bVorticityConfinement = true;
//--------------------------------------------------------------------------------------
// UI control IDs
//--------------------------------------------------------------------------------------
#define IDC_TOGGLEFULLSCREEN 1
#define IDC_TOGGLEREF 2
#define IDC_CHANGEDEVICE 3
const int IDP_D = 0;
const int IDP_TIME_SCALE = 1;
const int IDP_FORCE_RADIUS = 2;
const int IDP_FORCE_STRENGTH = 3;
const int IDP_VISCOUS = 4;
const int IDP_VORTICITY_CONFINEMENT_COEFFICIENT = 5;
const int IDP_JACOBI_ITERATE_NUM = 6;
const int IDP_DISSIPATION = 7;
const int IDP_UNIT = 8;
const int IDP_SUBSTANCE_DISSIPATION = 9;
const int IDP_SOURCE_RADIUS = 10;
const int IDP_SOURCE_STRENGTH = 11;
//--------------------------------------------------------------------------------------
// Forward declarations
//--------------------------------------------------------------------------------------
bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext );
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, 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 );
void CALLBACK OnLostDevice( void* pUserContext );
void CALLBACK OnDestroyDevice( void* pUserContext );
void InitApp();
void RenderText();
void impulse(DTK::Vector2 pos,DTK::Vector2 vec);
void toggleQuiverVelocityField();
void toggleDisplayMode();
void toggleDiffuse();
void toggleAdvection();
void toggleProject();
void toggleVelocityBoundary();
void togglePressureBoundary();
void toggleVorticityConfinement();
void toggleDefaultParam();
void updateParam(int iID,const float value[4]);
//--------------------------------------------------------------------------------------
// Entry point to the program. Initializes everything and goes into a message processing
// loop. Idle time is used to render the scene.
//--------------------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
// Set the callback functions. These functions allow DXUT to notify
// the application about device changes, user input, and windows messages. The
// callbacks are optional so you need only set callbacks for events you're interested
// in. However, if you don't handle the device reset/lost callbacks then the sample
// framework won't be able to reset your device since the application must first
// release all device resources before resetting. Likewise, if you don't handle the
// device created/destroyed callbacks then DXUT won't be able to
// recreate your device resources.
DXUTSetCallbackDeviceCreated( OnCreateDevice );
DXUTSetCallbackDeviceReset( OnResetDevice );
DXUTSetCallbackDeviceLost( OnLostDevice );
DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
DXUTSetCallbackMsgProc( MsgProc );
DXUTSetCallbackKeyboard( KeyboardProc );
DXUTSetCallbackFrameRender( OnFrameRender );
DXUTSetCallbackFrameMove( OnFrameMove );
// Show the cursor and clip it when in full screen
DXUTSetCursorSettings( true, true );
DTK::init();
InitApp();
Scene::init();
// Initialize DXUT and create the desired Win32 window and Direct3D
// device for the application. Calling each of these functions is optional, but they
// allow you to set several options which control the behavior of the framework.
DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
DXUTCreateWindow( L"GPU Fluid Simulation:by Kaijie Xu. 2006.10.28" );
DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 500, 500, IsDeviceAcceptable, ModifyDeviceSettings );
// Pass control to DXUT for handling the message pump and
// dispatching render calls. DXUT will call your FrameMove
// and FrameRender callback when there is idle time between handling window messages.
DXUTMainLoop();
// Perform any application-level cleanup here. Direct3D device resources are released within the
// appropriate callback functions and therefore don't require any cleanup code here.
DTK::shutdown();
return DXUTGetExitCode();
}
//--------------------------------------------------------------------------------------
// Initialize the app
//--------------------------------------------------------------------------------------
void InitApp()
{
g_vecTrigger.setImpulseCallback(impulse);
g_vecTrigger.setImpulseUnit(1.0f/64.0f);
g_vecTrigger.setWindowSize(640.0f,480.0f);
// Initialize dialogs
g_SettingsDlg.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 );
g_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", 35, iY += 24, 125, 22, VK_F2 );
g_SampleUI.SetCallback( OnGUIEvent ); iY = 10;
g_paramDialog.init(g_DialogResourceManager);
g_paramDialog.setUpdateParamCallback(updateParam);
g_paramDialog.addFloatParam(IDP_FORCE_RADIUS,L"Force Radius",1,0.0f,0.1f);
g_paramDialog.addFloatParam(IDP_FORCE_STRENGTH,L"Force Strength",1,0.0f,10000.0f);
g_paramDialog.addFloatParam(IDP_DISSIPATION,L"dissipation",1,0.98f,1.0f);
g_paramDialog.addFloatParam(IDP_D,L"Particle Distance",1,0.0f,1.0f);
g_paramDialog.addFloatParam(IDP_JACOBI_ITERATE_NUM,L"Jacobi Iterate Number",1,1.0f,64.0f);
g_paramDialog.addFloatParam(IDP_VISCOUS,L"Kinematic Viscosity",1.0f,0.0f,10.0f);
g_paramDialog.addFloatParam(IDP_VORTICITY_CONFINEMENT_COEFFICIENT,
L"Vorticity Confinement Coefficient",1.0f,0.0f,20.0f);
g_paramDialog.addFloatParam(IDP_UNIT,L"Substance Advect Speed",1,0.0f,0.5f);
g_paramDialog.addFloatParam(IDP_SOURCE_RADIUS,L"Source Radius",1,0.0f,0.5f);
g_paramDialog.addColorParam(IDP_SOURCE_STRENGTH,L"Source Color");
g_paramDialog.addFloatParam(IDP_SUBSTANCE_DISSIPATION,L"Substance Dissipationt",1,0.98f,1.0f);
g_paramDialog.addFloatParam(IDP_TIME_SCALE,L"Time Scale",1,0.0f,2.0f);
DTK::registerDeviceListener(&g_paramDialog);
/*
TODO: add UI controls as needed
g_SampleUI.AddComboBox( 19, 35, iY += 24, 125, 22 );
g_SampleUI.GetComboBox( 19 )->AddItem( L"Text1", NULL );
g_SampleUI.GetComboBox( 19 )->AddItem( L"Text2", NULL );
g_SampleUI.GetComboBox( 19 )->AddItem( L"Text3", NULL );
g_SampleUI.GetComboBox( 19 )->AddItem( L"Text4", NULL );
g_SampleUI.AddCheckBox( 21, L"Checkbox1", 35, iY += 24, 125, 22 );
g_SampleUI.AddCheckBox( 11, L"Checkbox2", 35, iY += 24, 125, 22 );
g_SampleUI.AddRadioButton( 12, 1, L"Radio1G1", 35, iY += 24, 125, 22 );
g_SampleUI.AddRadioButton( 13, 1, L"Radio2G1", 35, iY += 24, 125, 22 );
g_SampleUI.AddRadioButton( 14, 1, L"Radio3G1", 35, iY += 24, 125, 22 );
g_SampleUI.GetRadioButton( 14 )->SetChecked( true );
g_SampleUI.AddButton( 17, L"Button1", 35, iY += 24, 125, 22 );
g_SampleUI.AddButton( 18, L"Button2", 35, iY += 24, 125, 22 );
g_SampleUI.AddRadioButton( 15, 2, L"Radio1G2", 35, iY += 24, 125, 22 );
g_SampleUI.AddRadioButton( 16, 2, L"Radio2G3", 35, iY += 24, 125, 22 );
g_SampleUI.GetRadioButton( 16 )->SetChecked( true );
g_SampleUI.AddSlider( 20, 50, iY += 24, 100, 22 );
g_SampleUI.GetSlider( 20 )->SetRange( 0, 100 );
g_SampleUI.GetSlider( 20 )->SetValue( 50 );
g_SampleUI.AddEditBox( 20, L"Test", 35, iY += 24, 125, 32 );
*/
}
//--------------------------------------------------------------------------------------
// Called during device initialization, this code checks the device for some
// minimum set of capabilities, and rejects those that don't pass by returning false.
//--------------------------------------------------------------------------------------
bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat,
D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
{
// Skip backbuffer formats that don't support alpha blending
IDirect3D9* pD3D = DXUTGetD3DObject();
if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
return false;
return true;
}
//--------------------------------------------------------------------------------------
// This callback function is called immediately before a device is created to allow the
// application to modify the device settings. The supplied pDeviceSettings parameter
// contains the settings that the framework has selected for the new device, and the
// application can make any desired changes directly to this structure. Note however that
// DXUT will not correct invalid device settings so care must be taken
// to return valid device settings, otherwise IDirect3D9::CreateDevice() will fail.
//--------------------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )
{
//check if device support vertex shader 3.0
if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
pCaps->VertexShaderVersion D3DVS_VERSION(3,0) ||
pCaps->PixelShaderVersion D3DPS_VERSION(3,0))
{
MessageBox(NULL,
L"Sorry this demo require SM3 which is not supported by your GPU, we suggest Geforce6 Serial GPU or above.",
L"Your video card is not capable with this demo",MB_OK);
exit(0);
}
pDeviceSettings->pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE ;
// Debugging vertex shaders requires either REF or software vertex processing
// and debugging pixel shaders requires REF.
#ifdef DEBUG_VS
if( pDeviceSettings->DeviceType != D3DDEVTYPE_REF )
{
pDeviceSettings->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;
pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}
#endif
#ifdef DEBUG_PS
pDeviceSettings->DeviceType = D3DDEVTYPE_REF;
#endif
// 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( pDeviceSettings->DeviceType == D3DDEVTYPE_REF )
DXUTDisplaySwitchingToREFWarning();
}
return true;
}
//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D device has been
// created, which will happen during application initialization and windowed/full screen
// toggles. This is the best location to create D3DPOOL_MANAGED resources since these
// resources need to be reloaded whenever the device is destroyed. Resources created
// here should be released in the OnDestroyDevice callback.
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
HRESULT hr;
V_RETURN( g_DialogResourceManager.OnCreateDevice( pd3dDevice ) );
V_RETURN( g_SettingsDlg.OnCreateDevice( pd3dDevice ) );
// Initialize the font
V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
L"Arial", &g_pFont ) );
// Setup the camera's view parameters
D3DXVECTOR3 vecEye(0.0f, 0.0f, -5.0f);
D3DXVECTOR3 vecAt (0.0f, 0.0f, -0.0f);
g_Camera.SetViewParams( &vecEye, &vecAt );
DTK::onCreateDevice(pd3dDevice,pBackBufferSurfaceDesc,pUserContext);
Scene::onCreateDevice(pd3dDevice,pBackBufferSurfaceDesc,pUserContext);
return S_OK;
}
//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D device has been
// reset, which will happen after a lost device scenario. This is the best location to
// create D3DPOOL_DEFAULT resources since these resources need to be reloaded whenever
// the device is lost. Resources created here should be released in the OnLostDevice
// callback.
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice,
const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
HRESULT hr;
V_RETURN( g_DialogResourceManager.OnResetDevice() );
V_RETURN( g_SettingsDlg.OnResetDevice() );
if( g_pFont )
V_RETURN( g_pFont->OnResetDevice() );
// Create a sprite to help batch calls when drawing many lines of text
V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pTextSprite ) );
// Setup the camera's projection parameters
float fAspectRatio = pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height;
g_Camera.SetProjParams( D3DX_PI/4, fAspectRatio, 0.1f, 1000.0f );
g_Camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );
g_HUD.SetLocation( pBackBufferSurfaceDesc->Width-170, 0 );
g_HUD.SetSize( 170, 170 );
g_SampleUI.SetLocation( pBackBufferSurfaceDesc->Width-170, pBackBufferSurfaceDesc->Height-350 );
g_SampleUI.SetSize( 170, 300 );
DTK::onResetDevice(pd3dDevice,pBackBufferSurfaceDesc,pUserContext);
Scene::onResetDevice(pd3dDevice,pBackBufferSurfaceDesc,pUserContext);
return S_OK;
}
//--------------------------------------------------------------------------------------
// This callback function will be called once at the beginning of every frame. This is the
// best location for your application to handle updates to the scene, but is not
// intended to contain actual rendering calls, which should instead be placed in the
// OnFrameRender callback.
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
// Update the camera's position based on user input
g_Camera.FrameMove( fElapsedTime );
g_vecTrigger.timeStep(fElapsedTime);
}
//--------------------------------------------------------------------------------------
// This callback function will be called at the end of every frame to perform all the
// rendering calls for the scene, and it will also be called if the window needs to be
// repainted. After this function has returned, DXUT will call
// IDirect3DDevice9::Present to display the contents of the next buffer in the swap chain
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
HRESULT hr;
D3DXMATRIXA16 mWorld;
D3DXMATRIXA16 mView;
D3DXMATRIXA16 mProj;
D3DXMATRIXA16 mWorldViewProjection;
// If the settings dialog is being shown, then
// render it instead of rendering the app's scene
if( g_SettingsDlg.IsActive() )
{
g_SettingsDlg.OnRender( fElapsedTime );
return;
}
// Clear the render target and the zbuffer
V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(255, 0, 0, 0), 1.0f, 0) );
// Render the scene
if( SUCCEEDED( pd3dDevice->BeginScene() ) )
{
// Get the projection & view matrix from the camera class
mWorld = *g_Camera.GetWorldMatrix();
mProj = *g_Camera.GetProjMatrix();
mView = *g_Camera.GetViewMatrix();
mWorldViewProjection = mWorld * mView * mProj;
Scene::render(fTime,fElapsedTime);
if (g_bShowHelp)
{
DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" ); // These events are to help PIX identify what the code is doing
RenderText();
V( g_HUD.OnRender( fElapsedTime ) );
V( g_SampleUI.OnRender( fElapsedTime ) );
V( g_paramDialog.onRender(fElapsedTime));
DXUT_EndPerfEvent();
}
V( pd3dDevice->EndScene() );
}
}
//--------------------------------------------------------------------------------------
// Render the help and statistics text. This function uses the ID3DXFont interface for
// efficient text rendering.
//--------------------------------------------------------------------------------------
void RenderText()
{
// The helper object simply helps keep track of text position, and color
// and then it calls pFont->DrawText( m_pSprite, strMsg, -1, &rc, DT_NOCLIP, m_clr );
// If NULL is passed in as the sprite object, then it will work however the
// pFont->DrawText() will not be batched together. Batching calls will improves performance.
CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 15 );
// Output statistics
txtHelper.Begin();
txtHelper.SetInsertionPos( 5, 5 );
txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) );
txtHelper.DrawTextLine( DXUTGetFrameStats() );
txtHelper.DrawTextLine( DXUTGetDeviceStats() );
DTK::String buf;
buf = DTK::String(L"FPS :")+DTK::StringConverter::toString(DXUTGetFPS());
txtHelper.DrawTextLine(buf.c_str());
buf = DTK::String(L"[R] : clear scene");
txtHelper.DrawTextLine(buf.c_str());
buf = DTK::String(L"[1] : toggle display mode : ")+DISPLAY_MODE[g_uCurDisplayMode];
txtHelper.DrawTextLine(buf.c_str());
buf = DTK::String(L"[2] : toggle quiver velocity field : ")+
DTK::StringConverter::toString(g_bShowQuiverVelocityField);
txtHelper.DrawTextLine(buf.c_str());
buf = DTK::String(L"[0] : toggle default fluid param : ")+FLUID_TYPE[g_uFluidType];
txtHelper.DrawTextLine(buf.c_str());
buf = DTK::String(L"[Z] : toggle diffuse : ")+DTK::StringConverter::toString(gs_bDiffuse);
txtHelper.DrawTextLine(buf.c_str());
buf = DTK::String(L"[X] : toggle advection : ")+DTK::StringConverter::toString(gs_bAdvection);
txtHelper.DrawTextLine(buf.c_str());
buf = DTK::String(L"[C] : toggle project : ")+DTK::StringConverter::toString(gs_bProject);
txtHelper.DrawTextLine(buf.c_str());
buf = DTK::String(L"[V] : toggle velocity boundary : ")+DTK::StringConverter::toString(gs_bVelocityBoundary);
txtHelper.DrawTextLine(buf.c_str());
buf = DTK::String(L"[B] : toggle pressure boundary : ")+DTK::StringConverter::toString(gs_bPressureBoundary);
txtHelper.DrawTextLine(buf.c_str());
buf = DTK::String(L"[N] : toggle vorticity confinement : ")+
DTK::StringConverter::toString(gs_bVorticityConfinement);
txtHelper.DrawTextLine(buf.c_str());
buf = DTK::String(L"[F1]: toggle UI");
txtHelper.DrawTextLine(buf.c_str());
/*
TODO: add UI text as needed
txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
txtHelper.DrawTextLine( L"Put whatever misc status here" );
// Draw help
const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetBackBufferSurfaceDesc();
if( g_bShowHelp )
{
txtHelper.SetInsertionPos( 10, pd3dsdBackBuffer->Height-15*6 );
txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 0.75f, 0.0f, 1.0f ) );
txtHelper.DrawTextLine( L"Controls (F1 to hide):" );
txtHelper.SetInsertionPos( 40, pd3dsdBackBuffer->Height-15*5 );
txtHelper.DrawTextLine( L"Quit: ESC" );
}
else
{
txtHelper.SetInsertionPos( 10, pd3dsdBackBuffer->Height-15*2 );
txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
txtHelper.DrawTextLine( L"Press F1 for help" );
}
*/
txtHelper.End();
}
//--------------------------------------------------------------------------------------
// Before handling window messages, DXUT passes incoming windows
// messages to the application through this callback function. If the application sets
// *pbNoFurtherProcessing to TRUE, then DXUT will not process this message.
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext )
{
// Always allow dialog resource manager calls to handle global messages
// so GUI state is updated correctly
*pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
if( *pbNoFurtherProcessing )
return 0;
if( g_SettingsDlg.IsActive() )
{
g_SettingsDlg.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;
g_paramDialog.onMessage(hWnd,uMsg,wParam,lParam,pbNoFurtherProcessing);
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 );
g_vecTrigger.onMessage(hWnd,uMsg,wParam,lParam);
if (hWnd = DXUTGetHWND())
{
//switch(uMsg)
//{
//default:
// break;
//}
}
return 0;
}
//--------------------------------------------------------------------------------------
// As a convenience, DXUT inspects the incoming windows messages for
// keystroke messages and decodes the message parameters to pass relevant keyboard
// messages to the application. The framework does not remove the underlying keystroke
// messages, which are still passed to the application's MsgProc callback.
//--------------------------------------------------------------------------------------
void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext )
{
if( bKeyDown )
{
switch( nChar )
{
case VK_F1: g_bShowHelp = !g_bShowHelp; break;
case 'R':Scene::clearScene(); break;
case '1':toggleDisplayMode(); break;
case '2':toggleQuiverVelocityField(); break;
case '0':toggleDefaultParam();break;
case 'Z':toggleDiffuse(); break;
case 'X':toggleAdvection();break;
case 'C':toggleProject();break;
case 'V':toggleVelocityBoundary();break;
case 'B':togglePressureBoundary();break;
case 'N':toggleVorticityConfinement();break;
default:
break;
}
}
}
//--------------------------------------------------------------------------------------
// 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_SettingsDlg.SetActive( !g_SettingsDlg.IsActive() ); break;
}
}
//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D device has
// entered a lost state and before IDirect3DDevice9::Reset is called. Resources created
// in the OnResetDevice callback should be released here, which generally includes all
// D3DPOOL_DEFAULT resources. See the "Lost Devices" section of the documentation for
// information about lost devices.
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice( void* pUserContext )
{
g_DialogResourceManager.OnLostDevice();
g_SettingsDlg.OnLostDevice();
if( g_pFont )
g_pFont->OnLostDevice();
SAFE_RELEASE( g_pTextSprite );
Scene::onLostDevice(pUserContext);
DTK::onLostDevice(pUserContext);
}
//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D device has
// been destroyed, which generally happens as a result of application termination or
// windowed/full screen toggles. Resources created in the OnCreateDevice callback
// should be released here, which generally includes all D3DPOOL_MANAGED resources.
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice( void* pUserContext )
{
g_DialogResourceManager.OnDestroyDevice();
g_SettingsDlg.OnDestroyDevice();
SAFE_RELEASE( g_pFont );
Scene::onDestroyDevice(pUserContext);
DTK::onDestroyDevice(pUserContext);
}
void toggleQuiverVelocityField()
{
g_bShowQuiverVelocityField =!g_bShowQuiverVelocityField;
}
void toggleDisplayMode()
{
++g_uCurDisplayMode;
g_uCurDisplayMode %= NUM_DISPLAY_MODE;
}
void toggleDiffuse()
{
gs_bDiffuse = !gs_bDiffuse;
g_animator.enableDiffuse(gs_bDiffuse);
}
void toggleAdvection()
{
gs_bAdvection = !gs_bAdvection;
g_animator.enableAdvection(gs_bAdvection);
}
void toggleProject()
{
gs_bProject = !gs_bProject;
g_animator.enableProject(gs_bProject);
}
void toggleVelocityBoundary()
{
gs_bVelocityBoundary = ! gs_bVelocityBoundary;
g_animator.enableVelocityBoundary(gs_bVelocityBoundary);
}
void togglePressureBoundary()
{
gs_bPressureBoundary = ! gs_bPressureBoundary;
g_animator.enablePressureBoundary(gs_bPressureBoundary);
}
void toggleVorticityConfinement()
{
gs_bVorticityConfinement = !gs_bVorticityConfinement;
g_animator.enableVorticityConfinement(gs_bVorticityConfinement);
}
void toggleDefaultParam()
{
++g_uFluidType;
g_uFluidType %= NUM_FLUID_TYPE;
Scene::setFluidType(g_uFluidType);
}
void impulse(DTK::Vector2 pos,DTK::Vector2 vec)
{
DTK::FluidAnimator2D::ExternalForce force(g_forceRadius,pos,vec*g_forceStrength);
g_animator.addExternalForce(force);
DTK::Substance2D::PointSource src(g_sourceRadius,pos,g_sourceStrength);
g_substance.injectSource(src);
}
void updateParam(int iID,const float value[4])
{
switch(iID)
{
case IDP_SOURCE_STRENGTH:
g_sourceStrength = DTK::ColorValue(value[0],value[1],value[2],value[4]);
break;
case IDP_SUBSTANCE_DISSIPATION:
g_substance.setDissipation(value[0]);
break;
case IDP_UNIT:
{
DTK::Vector2 unit(value[0],value[0]);
g_substance.setUint(unit);
}
break;
case IDP_SOURCE_RADIUS:
g_sourceRadius = value[0];
break;
case IDP_D:
g_animator.setParticleDistance(value[0]);
break;
case IDP_DISSIPATION:
g_animator.setDissipation(value[0]);
break;
case IDP_TIME_SCALE:
g_fTimeScale = value[0];
break;
case IDP_FORCE_RADIUS:
g_forceRadius = value[0];
break;
case IDP_FORCE_STRENGTH:
g_forceStrength = value[0];
break;
case IDP_JACOBI_ITERATE_NUM:
g_animator.setIterateNumber(static_cast<DTK::uint>(value[0]));
break;
case IDP_VISCOUS:
g_animator.setViscous(value[0]);
break;
case IDP_VORTICITY_CONFINEMENT_COEFFICIENT:
g_animator.setVorticityConfinementCoefficient(value[0]);
break;
default:
break;
}
}