summaryrefslogtreecommitdiff
path: root/test/d3d11/ocean_cufft_app.cpp
diff options
context:
space:
mode:
authorJason Maskell <[email protected]>2016-05-09 10:39:54 +0200
committerJason Maskell <[email protected]>2016-05-09 10:39:54 +0200
commit79b3462799c28af8ba586349bd671b1b56e72353 (patch)
tree3b06e36c390254c0dc7f3733a0d32af213d87293 /test/d3d11/ocean_cufft_app.cpp
downloadarchived-waveworks-archive-79b3462799c28af8ba586349bd671b1b56e72353.tar.xz
archived-waveworks-archive-79b3462799c28af8ba586349bd671b1b56e72353.zip
Initial commit with PS4 and XBone stuff trimmed.
Diffstat (limited to 'test/d3d11/ocean_cufft_app.cpp')
-rw-r--r--test/d3d11/ocean_cufft_app.cpp1488
1 files changed, 1488 insertions, 0 deletions
diff --git a/test/d3d11/ocean_cufft_app.cpp b/test/d3d11/ocean_cufft_app.cpp
new file mode 100644
index 0000000..f056cbd
--- /dev/null
+++ b/test/d3d11/ocean_cufft_app.cpp
@@ -0,0 +1,1488 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright � 2008- 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+#include "DXUT.h"
+#include "resource.h"
+
+#include "DXUTcamera.h"
+#include "DXUTgui.h"
+#include "DXUTsettingsdlg.h"
+#include "SDKmisc.h"
+
+#include "../testing_src/testing.h"
+
+#include "ocean_surface.h"
+#include "GFSDK_WaveWorks.h"
+#include "GFSDK_WaveWorks_D3D_Util.h"
+
+#include "client.h"
+#include "message_types.h"
+#include <shlwapi.h>
+#include <tchar.h>
+
+
+//#define DEBUG_VS // Uncomment this line to debug vertex shaders
+//#define DEBUG_PS // Uncomment this line to debug pixel shaders
+
+// Disable warning "conditional expression is constant"
+#pragma warning(disable:4127)
+
+extern HRESULT LoadFile(LPCTSTR FileName, ID3DXBuffer** ppBuffer);
+
+
+//--------------------------------------------------------------------------------------
+// Global variables
+//--------------------------------------------------------------------------------------
+bool g_bShowHelp = false; // If true, it renders the UI control text
+CFirstPersonCamera g_Camera; //
+CDXUTDialogResourceManager g_DialogResourceManager; // manager for shared resources of dialogs
+CD3DSettingsDlg g_SettingsDlg; // Device settings dialog
+CDXUTTextHelper* g_pTxtHelper = NULL; // Text helper
+CDXUTDialog g_HUD; // manages the 3D UI
+CDXUTDialog g_SampleUI; // dialog for sample specific controls
+
+Client* g_pNetworkClient = NULL; // For testing client/server use-cases
+
+TestParams* g_pTestParams = NULL;
+
+GFSDK_WaveWorks_SavestateHandle g_hOceanSavestate = NULL;
+GFSDK_WaveWorks_SimulationHandle g_hOceanSimulation = NULL;
+gfsdk_U64 g_LastKickID = 0;
+gfsdk_U64 g_LastArchivedKickID = GFSDK_WaveWorks_InvalidKickID;
+gfsdk_U64 g_LastReadbackKickID = GFSDK_WaveWorks_InvalidKickID;
+gfsdk_U32 g_RenderLatency = 0;
+gfsdk_S32 g_ReadbackLatency = 0;
+enum { ReadbackArchiveSize = 32 };
+enum { ReadbackArchiveInterval = 30 };
+float g_ReadbackCoord = 0.f;
+OceanSurface* g_pOceanSurf = NULL;
+GFSDK_WaveWorks_Simulation_Params g_ocean_simulation_param;
+GFSDK_WaveWorks_Simulation_Settings g_ocean_simulation_settings;
+
+OceanSurfaceParameters g_ocean_surface_param;
+GFSDK_WaveWorks_Quadtree_Params g_ocean_param_quadtree;
+GFSDK_WaveWorks_Quadtree_Stats g_ocean_stats_quadtree;
+GFSDK_WaveWorks_Simulation_Stats g_ocean_stats_simulation;
+GFSDK_WaveWorks_Simulation_Stats g_ocean_stats_simulation_filtered;
+int g_max_detail_level;
+
+bool g_RenderWireframe = false;
+bool g_RenderWater = true;
+bool g_SimulateWater = true;
+bool g_ForceKick = false;
+bool g_DebugCam = false;
+bool g_bShowRemoteMarkers = false;
+
+enum SynchronizationMode
+{
+ SynchronizationMode_None = 0,
+ SynchronizationMode_RenderOnly,
+ SynchronizationMode_Readback,
+ Num_SynchronizationModes
+};
+SynchronizationMode g_bSyncMode = SynchronizationMode_None;
+
+float g_TessellationLOD = 8.0f;
+
+ID3D11ShaderResourceView* g_pSkyCubeMap = NULL;
+ID3D11ShaderResourceView* g_pLogoTex = NULL;
+ID3DX11Effect* g_pSkyboxFX = NULL;
+ID3DX11EffectTechnique* g_pSkyBoxTechnique = NULL;
+ID3DX11EffectShaderResourceVariable* g_pSkyBoxSkyCubeMapVariable = NULL;
+ID3DX11EffectVectorVariable* g_pSkyBoxEyePosVariable = NULL;
+ID3DX11EffectMatrixVariable* g_pSkyBoxMatViewProjVariable = NULL;
+ID3D11Buffer* g_pSkyBoxVB = NULL;
+ID3D11Buffer* g_pLogoVB = NULL;
+
+// These are borrowed from the effect in g_pOceanSurf
+ID3DX11EffectTechnique* g_pLogoTechnique = NULL;
+ID3DX11EffectShaderResourceVariable* g_pLogoTextureVariable = NULL;
+
+ID3D11InputLayout* g_pSkyboxLayout = NULL;
+
+ID3D11InputLayout* g_pMarkerLayout = NULL;
+ID3DX11Effect* g_pMarkerFX = NULL;
+ID3DX11EffectTechnique* g_pMarkerTechnique = NULL;
+ID3DX11EffectMatrixVariable* g_pMarkerMatViewProjVariable = NULL;
+ID3DX11EffectVectorVariable* g_pMarkerColor = NULL;
+ID3D11Buffer* g_pMarkerVB = NULL;
+ID3D11Buffer* g_pMarkerIB = NULL;
+
+float g_NearPlane = 200.0f;
+float g_FarPlane = 300000.0f;
+double g_SimulationTime = 0.0;
+
+//--------------------------------------------------------------------------------------
+// UI control IDs
+//--------------------------------------------------------------------------------------
+#define IDC_TOGGLEFULLSCREEN 1
+#define IDC_TOGGLEREF 3
+#define IDC_CHANGEDEVICE 4
+#define IDC_ENABLE_PRESHADER 5
+#define IDC_TOGGLEWIREFRAME 6
+#define IDC_BUFFERTYPE_STATIC 7
+#define IDC_AMPLITUDE_SLIDER 9
+#define IDC_CHOPPY_SCALE_SLIDER 10
+#define IDC_WIND_SPEED_SLIDER 11
+#define IDC_WIND_DEPENDENCY_SLIDER 12
+#define IDC_TIME_SCALE_SLIDER 13
+#define IDC_SKY_BLENDING_SLIDER 14
+#define IDC_PATCH_LENGTH_SLIDER 17
+#define IDC_FURTHEST_COVER_SLIDER 18
+#define IDC_UPPER_GRID_COVER_SLIDER 19
+#define IDC_TOGGLERENDER 20
+#define IDC_TOGGLESIMULATE 21
+#define IDC_ANISO_SLIDER 22
+#define IDC_TOGGLEREADBACK 23
+#define IDC_FOAM_THRESHOLD_SLIDER 24
+#define IDC_FOAM_AMOUNT_SLIDER 25
+#define IDC_FOAM_DISSIPATION_SLIDER 26
+#define IDC_FOAM_FADEOUT_SLIDER 27
+#define IDC_TESSELLATION_LOD_SLIDER 28
+
+const FLOAT kAmplitudeSliderScaleFactor = 3.0f;
+const FLOAT kChoppyScaleSliderScaleFactor = 100.0f;
+const FLOAT kWindDependencySliderScaleFactor = 100.f;
+const FLOAT kTimeScaleSliderScaleFactor = 100.f;
+const FLOAT kSkyBlendingSliderScaleFactor = 10.f;
+const FLOAT kWindSpeedSliderScaleFactor = 2.5f;
+const FLOAT kGeomorphingDegreeSlideScaleFactor = 100.f;
+const FLOAT kFoamGenerationThresholdFactor = 100.0f;
+const FLOAT kFoamGenerationAmountFactor = 1000.0f;
+const FLOAT kFoamDissipationSpeedFactor = 100.0f;
+const FLOAT kFoamFadeoutSpeedFactor = 1000.0f;
+
+const FLOAT kWaterScale = 50.f;
+
+//--------------------------------------------------------------------------------------
+// Forward declarations
+//--------------------------------------------------------------------------------------
+bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
+bool CALLBACK IsD3D11DeviceAcceptable( const CD3D11EnumAdapterInfo *AdapterInfo, UINT Output, const CD3D11EnumDeviceInfo *DeviceInfo, DXGI_FORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
+bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext );
+HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
+HRESULT CALLBACK OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
+void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext );
+void CALLBACK OnD3D11FrameRender( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, 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 OnD3D11ReleasingSwapChain( void* pUserContext );
+void CALLBACK OnD3D11DestroyDevice( void* pUserContext );
+
+void InitApp();
+void RenderText( double fTime );
+void AddGUISet();
+void RenderSkybox(ID3D11DeviceContext* pDC);
+void RenderLogo(ID3D11DeviceContext* pDC);
+void RenderMarkers(ID3D11DeviceContext* pDC);
+void UpdateServerControlledUI();
+void RenderLocalMarkers(ID3D11DeviceContext* pDC);
+void RenderRemoteMarkers(ID3D11DeviceContext* pDC);
+void UpdateMarkers();
+void UpdateRemoteMarkerCoords();
+
+// custom memory management
+void* myMalloc(size_t size);
+void myFree(void* p);
+size_t AllocatedMemory = 0;
+size_t NumAllocations = 0;
+size_t AllocatedAlignedMemory = 0;
+size_t NumAlignedAllocations = 0;
+
+void* myMalloc(size_t size)
+{
+ AllocatedMemory += size;
+ NumAllocations ++;
+ return malloc(size);
+}
+
+void myFree(void* p)
+{
+ NumAllocations --;
+ free(p);
+}
+
+void* myAlignedMalloc(size_t size, size_t alignment)
+{
+ AllocatedAlignedMemory += size;
+ NumAlignedAllocations ++;
+ return _aligned_malloc(size, alignment);
+}
+
+void myAlignedFree(void* p)
+{
+ NumAlignedAllocations --;
+ _aligned_free(p);
+}
+//--------------------------------------------------------------------------------------
+// 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 cmdline, int )
+{
+ // Enable run-time memory check for debug builds.
+#if defined(DEBUG) | defined(_DEBUG)
+ _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
+#endif
+
+ g_pTestParams = new TestParams(cmdline);
+
+ // 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.
+ DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
+ DXUTSetCallbackMsgProc( MsgProc );
+ DXUTSetCallbackKeyboard( KeyboardProc );
+ DXUTSetCallbackFrameMove( OnFrameMove );
+
+ DXUTSetCallbackD3D9DeviceAcceptable( IsD3D9DeviceAcceptable );
+ DXUTSetCallbackD3D11DeviceAcceptable( IsD3D11DeviceAcceptable );
+ DXUTSetCallbackD3D11DeviceCreated( OnD3D11CreateDevice );
+ DXUTSetCallbackD3D11SwapChainResized( OnD3D11ResizedSwapChain );
+ DXUTSetCallbackD3D11FrameRender( OnD3D11FrameRender );
+ DXUTSetCallbackD3D11SwapChainReleasing( OnD3D11ReleasingSwapChain );
+ DXUTSetCallbackD3D11DeviceDestroyed( OnD3D11DestroyDevice );
+
+ // TBD: Switch to gamma-correct
+ DXUTSetIsInGammaCorrectMode(false);
+
+ // Show the cursor and clip it when in full screen
+ DXUTSetCursorSettings( true, true );
+
+ InitApp();
+
+ // 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, NULL ); // Parse the command line, and show msgboxes
+ DXUTSetCursorSettings( true, true );
+ DXUTCreateWindow( L"FFT Ocean" );
+ DXUTCreateDevice( D3D_FEATURE_LEVEL_10_0, true, 1280, 720 );
+
+ // 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.
+ if(g_pNetworkClient) {
+ Client::Destroy(g_pNetworkClient);
+ g_pNetworkClient = NULL;
+ }
+
+ return DXUTGetExitCode();
+}
+
+//--------------------------------------------------------------------------------------
+// Initialize the app
+//--------------------------------------------------------------------------------------
+void InitApp()
+{
+ g_ocean_param_quadtree.min_patch_length = 40.0f;
+ g_ocean_param_quadtree.upper_grid_coverage = 64.0f;
+ g_ocean_param_quadtree.mesh_dim = 128;
+ g_ocean_param_quadtree.sea_level = 0.0f;
+ g_ocean_param_quadtree.auto_root_lod = 10;
+ g_ocean_param_quadtree.tessellation_lod = 40.0f;
+ g_ocean_param_quadtree.geomorphing_degree = 1.f;
+ g_ocean_param_quadtree.use_tessellation = true;
+ g_ocean_param_quadtree.enable_CPU_timers = true;
+
+ g_ocean_simulation_param.time_scale = 0.5f;
+ g_ocean_simulation_param.wave_amplitude = 1.0f;
+ g_ocean_simulation_param.wind_dir = NvFromDX(D3DXVECTOR2(0.8f, 0.6f));
+ g_ocean_simulation_param.wind_speed = 9.0f;
+ g_ocean_simulation_param.wind_dependency = 0.98f;
+ g_ocean_simulation_param.choppy_scale = 1.f;
+ g_ocean_simulation_param.small_wave_fraction = 0.f;
+ g_ocean_simulation_param.foam_dissipation_speed = 0.6f;
+ g_ocean_simulation_param.foam_falloff_speed = 0.985f;
+ g_ocean_simulation_param.foam_generation_amount = 0.12f;
+ g_ocean_simulation_param.foam_generation_threshold = 0.37f;
+
+ g_ocean_simulation_settings.fft_period = 1000.0f;
+ g_ocean_simulation_settings.detail_level = GFSDK_WaveWorks_Simulation_DetailLevel_Normal;
+ g_ocean_simulation_settings.readback_displacements = false;
+ g_ocean_simulation_settings.num_readback_FIFO_entries = ReadbackArchiveSize;
+ g_ocean_simulation_settings.aniso_level = 4;
+ g_ocean_simulation_settings.CPU_simulation_threading_model = GFSDK_WaveWorks_Simulation_CPU_Threading_Model_Automatic;
+ g_ocean_simulation_settings.use_Beaufort_scale = false;
+ g_ocean_simulation_settings.num_GPUs = 1;
+ g_ocean_simulation_settings.enable_CUDA_timers = true;
+ g_ocean_simulation_settings.enable_gfx_timers = true;
+ g_ocean_simulation_settings.enable_CPU_timers = true;
+
+ g_ocean_surface_param.sky_color = D3DXVECTOR4(0.38f, 0.45f, 0.56f, 0);
+ g_ocean_surface_param.waterbody_color = D3DXVECTOR4(0.07f, 0.15f, 0.2f, 0);
+ g_ocean_surface_param.sky_blending = 100.0f;
+
+ memset(&g_ocean_stats_simulation_filtered, 0, sizeof(g_ocean_stats_simulation_filtered));
+
+ // Initialize dialogs
+ g_SettingsDlg.Init( &g_DialogResourceManager );
+ g_HUD.Init( &g_DialogResourceManager );
+ g_SampleUI.Init( &g_DialogResourceManager );
+
+ g_Camera.SetRotateButtons( true, false, false );
+ g_Camera.SetScalers(0.003f, 4000.0f);
+
+ g_HUD.SetCallback( OnGUIEvent );
+ g_SampleUI.SetCallback( OnGUIEvent );
+
+ g_pNetworkClient = Client::Create();
+ if(g_pNetworkClient) {
+ UpdateWaveWorksParams(g_ocean_simulation_param,g_pNetworkClient->GetSimulationConfig());
+ }
+
+ AddGUISet();
+ UpdateServerControlledUI();
+
+
+}
+
+void UpdateServerControlledUI()
+{
+ bool enable = true;
+ if(g_pNetworkClient) {
+ enable = false;
+
+ // Server is in control, sync the UI values
+ g_HUD.GetSlider(IDC_WIND_SPEED_SLIDER)->SetValue(int(g_ocean_simulation_param.wind_speed * kWindSpeedSliderScaleFactor));
+ g_HUD.GetSlider(IDC_WIND_DEPENDENCY_SLIDER)->SetValue(int(kWindDependencySliderScaleFactor * (1.0f - g_ocean_simulation_param.wind_dependency)));
+ g_HUD.GetSlider(IDC_TIME_SCALE_SLIDER)->SetValue(int(kTimeScaleSliderScaleFactor * g_ocean_simulation_param.time_scale));
+ }
+
+ g_HUD.GetControl(IDC_WIND_SPEED_SLIDER)->SetEnabled(enable);
+ g_HUD.GetControl(IDC_WIND_DEPENDENCY_SLIDER)->SetEnabled(enable);
+ g_HUD.GetControl(IDC_TIME_SCALE_SLIDER)->SetEnabled(enable);
+}
+
+void AddGUISet()
+{
+ int iY = 20;
+ g_HUD.AddButton(IDC_TOGGLEFULLSCREEN, L"Toggle Full Screen", 10, iY, 130, 24);
+ g_HUD.AddButton(IDC_CHANGEDEVICE, L"Change Device", 10, iY += 30, 130, 24, VK_F2);
+ g_HUD.AddCheckBox(IDC_TOGGLEWIREFRAME, L"Wireframe", 10, iY += 30, 130, 24, g_RenderWireframe);
+ g_HUD.AddCheckBox(IDC_TOGGLERENDER, L"Render Water", 10, iY += 30, 130, 24, g_RenderWater);
+ g_HUD.AddCheckBox(IDC_TOGGLESIMULATE, L"Simulate Water", 10, iY += 30, 130, 24, g_SimulateWater);
+
+ g_HUD.AddStatic(0, L"Wave amplitude", 10, iY += 25, 130, 24);
+ g_HUD.AddSlider(IDC_AMPLITUDE_SLIDER, 10, iY += 20, 130, 24, 0, 100, int(kAmplitudeSliderScaleFactor * g_ocean_simulation_param.wave_amplitude));
+
+ g_HUD.AddStatic(0, L"Chop scale", 10, iY += 25, 130, 24);
+ g_HUD.AddSlider(IDC_CHOPPY_SCALE_SLIDER, 10, iY += 20, 130, 24, 0, 150, int(kChoppyScaleSliderScaleFactor * g_ocean_simulation_param.choppy_scale));
+
+ g_HUD.AddStatic(0, L"Wind speed", 10, iY += 25, 130, 24);
+ g_HUD.AddSlider(IDC_WIND_SPEED_SLIDER, 10, iY += 20, 130, 24, 0, 200, int(g_ocean_simulation_param.wind_speed * kWindSpeedSliderScaleFactor));
+
+ g_HUD.AddStatic(0, L"Wind dependency", 10, iY += 25, 130, 24);
+ g_HUD.AddSlider(IDC_WIND_DEPENDENCY_SLIDER, 10, iY += 20, 130, 24, 0, 100, int(kWindDependencySliderScaleFactor * (1.0f - g_ocean_simulation_param.wind_dependency)));
+
+ g_HUD.AddStatic(0, L"Time scale", 10, iY += 25, 130, 24);
+ g_HUD.AddSlider(IDC_TIME_SCALE_SLIDER, 10, iY += 20, 130, 24, 0, 200, int(kTimeScaleSliderScaleFactor * g_ocean_simulation_param.time_scale));
+
+ g_HUD.AddStatic(0, L"Sky blending", 10, iY += 25, 130, 24);
+ g_HUD.AddSlider(IDC_SKY_BLENDING_SLIDER, 10, iY += 20, 130, 24, 0, 1000, int(kSkyBlendingSliderScaleFactor * g_ocean_surface_param.sky_blending));
+
+ g_HUD.AddStatic(0, L"Foam generation threshold", 10, iY += 25, 130, 24);
+ g_HUD.AddSlider(IDC_FOAM_THRESHOLD_SLIDER, 10, iY += 20, 130, 24, 0, 100, int(g_ocean_simulation_param.foam_generation_threshold*kFoamGenerationThresholdFactor));
+
+ g_HUD.AddStatic(0, L"Foam generation amount", 10, iY += 25, 130, 24);
+ g_HUD.AddSlider(IDC_FOAM_AMOUNT_SLIDER, 10, iY += 20, 130, 24, 0, 100, int(g_ocean_simulation_param.foam_generation_amount*kFoamGenerationAmountFactor));
+
+ g_HUD.AddStatic(0, L"Foam dissipation speed", 10, iY += 25, 130, 24);
+ g_HUD.AddSlider(IDC_FOAM_DISSIPATION_SLIDER, 10, iY += 20, 130, 24, 0, 100, int(g_ocean_simulation_param.foam_dissipation_speed*kFoamDissipationSpeedFactor));
+
+ g_HUD.AddStatic(0, L"Foam fadeout speed", 10, iY += 25, 130, 24);
+ g_HUD.AddSlider(IDC_FOAM_FADEOUT_SLIDER, 10, iY += 20, 130, 24, 0, 100, int((g_ocean_simulation_param.foam_falloff_speed-0.9f)*kFoamFadeoutSpeedFactor));
+
+ g_HUD.AddStatic(0, L"Aniso level", 10, iY += 25, 130, 24);
+ g_HUD.AddSlider(IDC_ANISO_SLIDER, 10, iY += 20, 130, 24, 1, 16, (int)g_ocean_simulation_settings.aniso_level);
+
+ g_HUD.AddCheckBox(IDC_TOGGLEREADBACK, L"Readback", 10, iY += 40, 130, 24, g_ocean_simulation_settings.readback_displacements);
+
+ g_HUD.AddStatic(0, L"Tessellation LOD", 10, iY += 40, 130, 24);
+ g_HUD.AddSlider(IDC_TESSELLATION_LOD_SLIDER, 10, iY += 20, 130, 24, 0, 200, int(g_TessellationLOD));
+}
+
+//--------------------------------------------------------------------------------------
+// Called during device initialization, this code checks the device for some
+// minimum set of capabilities, and rejects those that don't pass by returning E_FAIL.
+//--------------------------------------------------------------------------------------
+bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat,
+ D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
+{
+ return false;
+}
+
+bool CALLBACK IsD3D11DeviceAcceptable(const CD3D11EnumAdapterInfo *AdapterInfo, UINT Output, const CD3D11EnumDeviceInfo *DeviceInfo,
+ DXGI_FORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
+{
+ // It seems that AdapterInfo->m_pAdapter cannot be trusted (DXUT bug?), so enumerate our own
+ IDXGIFactory1* pFactory = DXUTGetDXGIFactory();
+ IDXGIAdapter* pAdapter = NULL;
+ HRESULT hr = pFactory->EnumAdapters(AdapterInfo->AdapterOrdinal,&pAdapter);
+ if(FAILED(hr) || NULL == pAdapter)
+ return false;
+
+ // Check ocean capability
+ bool result = GFSDK_WaveWorks_Simulation_DetailLevelIsSupported_D3D11(pAdapter, g_ocean_simulation_settings.detail_level);
+ SAFE_RELEASE(pAdapter);
+ return result;
+}
+
+
+//--------------------------------------------------------------------------------------
+// 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, void* pUserContext )
+{
+ IDXGIAdapter* adapter = NULL;
+ DXGI_ADAPTER_DESC ad;
+ DXUTGetDXGIFactory()->EnumAdapters(pDeviceSettings->d3d11.AdapterOrdinal,&adapter);
+ adapter->GetDesc(&ad);
+
+ static bool s_bFirstTime = true;
+ if( s_bFirstTime && ad.VendorId == 0x10DE )
+ {
+ s_bFirstTime = false;
+
+ if(g_pTestParams->AllowAA())
+ {
+ // 16x CSAA
+ pDeviceSettings->d3d11.sd.SampleDesc.Count = 4;
+ pDeviceSettings->d3d11.sd.SampleDesc.Quality = 16;
+ }
+
+ // Turn off vsync
+ pDeviceSettings->d3d11.SyncInterval = 0;
+ }
+
+ // Check detail level support
+ int detail_level = 0;
+ for(; detail_level != Num_GFSDK_WaveWorks_Simulation_DetailLevels; ++detail_level) {
+ if(!GFSDK_WaveWorks_Simulation_DetailLevelIsSupported_D3D11(adapter, (GFSDK_WaveWorks_Simulation_DetailLevel)detail_level))
+ break;
+ }
+ if(0 == detail_level)
+ return false;
+
+ g_max_detail_level = (GFSDK_WaveWorks_Simulation_DetailLevel)(detail_level - 1);
+ g_ocean_simulation_settings.detail_level = (GFSDK_WaveWorks_Simulation_DetailLevel)g_max_detail_level;
+
+ SAFE_RELEASE(adapter);
+
+ return true;
+}
+
+//--------------------------------------------------------------------------------------
+// Create any D3D11 resources that aren't dependant on the back buffer
+//--------------------------------------------------------------------------------------
+HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc,
+ void* pUserContext )
+{
+ HRESULT hr;
+
+ ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext();
+ V_RETURN( g_DialogResourceManager.OnD3D11CreateDevice( pd3dDevice, pd3dImmediateContext ) );
+ V_RETURN( g_SettingsDlg.OnD3D11CreateDevice( pd3dDevice ) );
+ g_pTxtHelper = new CDXUTTextHelper( pd3dDevice, pd3dImmediateContext, &g_DialogResourceManager, 15 );
+
+ // Setup the camera's view parameters
+ //D3DXVECTOR3 vecEye(1358.16f, 441.017f, -1558.43f);
+ //D3DXVECTOR3 vecAt (881.419f, 340.248f, -1670.25f);
+
+ D3DXVECTOR3 vecEye(0.f, 1210.534f, 0.f);
+ D3DXVECTOR3 vecAt (4490.944f, 0.f, -3000.f);
+
+ //D3DXVECTOR3 vecEye(1511.21f, 559.553f, -1164.19f);//(1691.43f, 503.88f, -1382.71f);
+ //D3DXVECTOR3 vecAt (1821.63f, 429.548f, -1533.82f);
+ //D3DXVECTOR3 vecEye(0, 1000, 0);
+ //D3DXVECTOR3 vecAt (1000, 0, 0);
+ //D3DXVECTOR3 vecEye(1691.43f, 503.88f, -1382.71f);
+ //D3DXVECTOR3 vecAt (1732.75f, 429.646f, -1875.57f);
+ //D3DXVECTOR3 vecEye(-1700, 1200, 1700);
+ //D3DXVECTOR3 vecAt (-200, 0, 200);
+ g_Camera.SetViewParams(&vecEye, &vecAt);
+
+ GFSDK_WaveWorks_Malloc_Hooks malloHooks;
+ malloHooks.pMalloc = myMalloc;
+ malloHooks.pFree = myFree;
+ malloHooks.pAlignedMalloc = myAlignedMalloc;
+ malloHooks.pAlignedFree = myAlignedFree;
+ GFSDK_WaveWorks_InitD3D11(pd3dDevice,&malloHooks,GFSDK_WAVEWORKS_API_GUID);
+
+ // Do an unnecessary release-init cycle, to test that specific use-case
+ GFSDK_WaveWorks_InitD3D11(pd3dDevice,&malloHooks,GFSDK_WAVEWORKS_API_GUID);
+ GFSDK_WaveWorks_ReleaseD3D11(pd3dDevice);
+ GFSDK_WaveWorks_ReleaseD3D11(pd3dDevice);
+ GFSDK_WaveWorks_InitD3D11(pd3dDevice,&malloHooks,GFSDK_WAVEWORKS_API_GUID);
+
+ // Ocean sim
+ GFSDK_WaveWorks_Simulation_CreateD3D11(g_ocean_simulation_settings, g_ocean_simulation_param, pd3dDevice, &g_hOceanSimulation);
+ GFSDK_WaveWorks_Savestate_CreateD3D11(GFSDK_WaveWorks_StatePreserve_All, pd3dDevice, &g_hOceanSavestate);
+ g_ForceKick = true;
+ g_pTestParams->HookSimulation(g_hOceanSimulation);
+
+ // Ocean object
+ g_pOceanSurf = new OceanSurface();
+ g_pOceanSurf->init(g_ocean_surface_param);
+ g_pOceanSurf->initQuadTree(g_ocean_param_quadtree);
+ GFSDK_WaveWorks_Quadtree_SetFrustumCullMargin(g_pOceanSurf->m_hOceanQuadTree, GFSDK_WaveWorks_Simulation_GetConservativeMaxDisplacementEstimate(g_hOceanSimulation));
+
+ // Effect hooks borrowed from ocean object
+ g_pLogoTechnique = g_pOceanSurf->m_pOceanFX->GetTechniqueByName("DisplayBufferTech");
+ g_pLogoTextureVariable = g_pOceanSurf->m_pOceanFX->GetVariableByName("g_texBufferMap")->AsShaderResource();
+
+ // Skybox
+ {
+ TCHAR path[MAX_PATH];
+ V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("..\\Media\\skybox_d3d11.fxo")));
+ ID3DXBuffer* pEffectBuffer = NULL;
+ V_RETURN(LoadFile(path, &pEffectBuffer));
+ V_RETURN(D3DX11CreateEffectFromMemory(pEffectBuffer->GetBufferPointer(), pEffectBuffer->GetBufferSize(), 0, pd3dDevice, &g_pSkyboxFX));
+ pEffectBuffer->Release();
+ }
+
+ g_pSkyBoxTechnique = g_pSkyboxFX->GetTechniqueByName("SkyboxTech");
+ g_pSkyBoxMatViewProjVariable = g_pSkyboxFX->GetVariableByName("g_matViewProj")->AsMatrix();
+ g_pSkyBoxEyePosVariable = g_pSkyboxFX->GetVariableByName("g_EyePos")->AsVector();
+ g_pSkyBoxSkyCubeMapVariable = g_pSkyboxFX->GetVariableByName("g_texSkyCube")->AsShaderResource();
+
+ const D3D11_INPUT_ELEMENT_DESC sky_layout[] = {
+ { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ };
+ const UINT num_layout_elements = sizeof(sky_layout)/sizeof(sky_layout[0]);
+
+ D3DX11_PASS_DESC PassDesc;
+ V_RETURN(g_pSkyBoxTechnique->GetPassByIndex(0)->GetDesc(&PassDesc));
+
+ V_RETURN(pd3dDevice->CreateInputLayout( sky_layout, num_layout_elements,
+ PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize,
+ &g_pSkyboxLayout
+ ));
+
+ TCHAR path[MAX_PATH];
+ V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("..\\Media\\sky_cube.dds")));
+ ID3D11Resource* pD3D11Resource = NULL;
+ V_RETURN(D3DX11CreateTextureFromFile(pd3dDevice, path, NULL, NULL, &pD3D11Resource, NULL));
+ V_RETURN(pd3dDevice->CreateShaderResourceView(pD3D11Resource, NULL, &g_pSkyCubeMap));
+ V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("..\\Media\\nvidia_logo.dds")));
+ SAFE_RELEASE(pD3D11Resource);
+ V_RETURN(D3DX11CreateTextureFromFile(pd3dDevice, path, NULL, NULL, &pD3D11Resource, NULL));
+ V_RETURN(pd3dDevice->CreateShaderResourceView(pD3D11Resource, NULL, &g_pLogoTex));
+ SAFE_RELEASE(pD3D11Resource);
+
+ {
+ D3D11_BUFFER_DESC vBufferDesc;
+ vBufferDesc.ByteWidth = 4 * sizeof(D3DXVECTOR4);
+ vBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+ vBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ vBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ vBufferDesc.MiscFlags = 0;
+ V_RETURN(pd3dDevice->CreateBuffer(&vBufferDesc, NULL, &g_pSkyBoxVB));
+ }
+
+ // Readback marker
+ {
+ TCHAR path[MAX_PATH];
+ V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("..\\Media\\ocean_marker_d3d11.fxo")))
+ ID3DXBuffer* pEffectBuffer = NULL;
+ V_RETURN(LoadFile(path, &pEffectBuffer));
+ V_RETURN(D3DX11CreateEffectFromMemory(pEffectBuffer->GetBufferPointer(), pEffectBuffer->GetBufferSize(), 0, pd3dDevice, &g_pMarkerFX));
+ pEffectBuffer->Release();
+ }
+
+ g_pMarkerTechnique = g_pMarkerFX->GetTechniqueByName("RenderMarkerTech");
+ g_pMarkerMatViewProjVariable = g_pMarkerFX->GetVariableByName("g_matViewProj")->AsMatrix();
+ g_pMarkerColor = g_pMarkerFX->GetVariableByName("gMarkerColor")->AsVector();
+
+ const D3D11_INPUT_ELEMENT_DESC marker_layout[] = {
+ { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ };
+ const UINT num_marker_layout_elements = sizeof(marker_layout)/sizeof(marker_layout[0]);
+
+ V_RETURN(g_pMarkerTechnique->GetPassByIndex(0)->GetDesc(&PassDesc));
+
+ V_RETURN(pd3dDevice->CreateInputLayout( marker_layout, num_marker_layout_elements,
+ PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize,
+ &g_pMarkerLayout
+ ));
+
+ {
+ D3D11_BUFFER_DESC vBufferDesc;
+ vBufferDesc.ByteWidth = 5 * sizeof(D3DXVECTOR4);
+ vBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+ vBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ vBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ vBufferDesc.MiscFlags = 0;
+ V_RETURN(pd3dDevice->CreateBuffer(&vBufferDesc, NULL, &g_pMarkerVB));
+ }
+
+ {
+ static const WORD indices[] = {0,1,2, 0,2,3, 0,3,4, 0,4,1};
+
+ D3D11_BUFFER_DESC iBufferDesc;
+ iBufferDesc.ByteWidth = sizeof(indices);
+ iBufferDesc.Usage = D3D11_USAGE_IMMUTABLE ;
+ iBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+ iBufferDesc.CPUAccessFlags = 0;
+ iBufferDesc.MiscFlags = 0;
+
+ D3D11_SUBRESOURCE_DATA iBufferData;
+ iBufferData.pSysMem = indices;
+ iBufferData.SysMemPitch = 0;
+ iBufferData.SysMemSlicePitch = 0;
+
+ V_RETURN(pd3dDevice->CreateBuffer(&iBufferDesc, &iBufferData, &g_pMarkerIB));
+ }
+
+ return S_OK;
+}
+
+//--------------------------------------------------------------------------------------
+// Create any D3D11 resources that depend on the back buffer
+//--------------------------------------------------------------------------------------
+HRESULT CALLBACK OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain,
+ const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
+{
+ HRESULT hr;
+
+ V_RETURN( g_DialogResourceManager.OnD3D11ResizedSwapChain(pd3dDevice,pBackBufferSurfaceDesc) );
+ V_RETURN( g_SettingsDlg.OnD3D11ResizedSwapChain(pd3dDevice,pBackBufferSurfaceDesc) );
+
+ // Setup the camera's projection parameters
+ float fAspectRatio = pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height;
+ g_Camera.SetProjParams(D3DX_PI/4, fAspectRatio, g_NearPlane, g_FarPlane);
+ //g_Camera.SetWindow(pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height);
+
+ // UI
+ g_HUD.SetLocation(pBackBufferSurfaceDesc->Width-200, 0);
+ g_HUD.SetSize(170, 170);
+
+ // Create Vb for logo
+ float width = (float)200/pBackBufferSurfaceDesc->Width;
+ float height = (float)160/pBackBufferSurfaceDesc->Height;
+ float half_tex = 0;
+ float vertices0[] = {0.98f - width, -0.96f + height, 0, half_tex, half_tex,
+ 0.98f - width, -0.96f, 0, half_tex, half_tex+1.0f,
+ 0.98f, -0.96f + height, 0, half_tex+1.0f, half_tex,
+ 0.98f, -0.96f, 0, half_tex+1.0f, half_tex+1.0f};
+
+ D3D11_BUFFER_DESC vBufferDesc;
+ vBufferDesc.ByteWidth = sizeof(vertices0);
+ vBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
+ vBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ vBufferDesc.CPUAccessFlags = 0;
+ vBufferDesc.MiscFlags = 0;
+ vBufferDesc.StructureByteStride = 0;
+
+ D3D11_SUBRESOURCE_DATA vSrd;
+ vSrd.pSysMem = vertices0;
+ vSrd.SysMemPitch = 0;
+ vSrd.SysMemSlicePitch = 0;
+
+ V_RETURN(pd3dDevice->CreateBuffer(&vBufferDesc, &vSrd, &g_pLogoVB));
+
+ return S_OK;
+}
+
+void UpdateSimulationTime(float fDXUTElapsedTime)
+{
+ if(g_pNetworkClient) {
+ // Use server-sync'd time when running networked
+ g_SimulationTime = g_pNetworkClient->GetSimulationTime();
+ } else {
+ g_SimulationTime += fDXUTElapsedTime;
+ }
+}
+
+//--------------------------------------------------------------------------------------
+// Handle updates to the scene. This is called regardless of which D3D API is used
+//--------------------------------------------------------------------------------------
+void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext )
+{
+ if(g_pNetworkClient)
+ {
+ if(g_pNetworkClient->IsUsable())
+ {
+ g_pNetworkClient->Tick();
+ }
+
+ while(g_pNetworkClient->HasPendingMessage() && g_pNetworkClient->IsUsable())
+ {
+ switch(g_pNetworkClient->ConsumePendingMessage())
+ {
+ case MessageTypeID_ServerSendConfigToClient:
+ UpdateWaveWorksParams(g_ocean_simulation_param,g_pNetworkClient->GetSimulationConfig());
+ GFSDK_WaveWorks_Simulation_UpdateProperties(g_hOceanSimulation, g_ocean_simulation_settings, g_ocean_simulation_param);
+ GFSDK_WaveWorks_Quadtree_SetFrustumCullMargin(g_pOceanSurf->m_hOceanQuadTree, GFSDK_WaveWorks_Simulation_GetConservativeMaxDisplacementEstimate(g_hOceanSimulation));
+ UpdateServerControlledUI();
+ break;
+ }
+ }
+
+ // Abandon networking if the socket went bad for some reason
+ if(!g_pNetworkClient->IsUsable())
+ {
+ Client::Destroy(g_pNetworkClient);
+ g_pNetworkClient = NULL;
+ UpdateServerControlledUI();
+ }
+ }
+
+ UpdateSimulationTime(g_pTestParams->ShouldTakeScreenshot() ? 20.0f : fElapsedTime);
+
+ // Update the camera's position based on user input
+ if(!g_pTestParams->ShouldTakeScreenshot())
+ {
+ g_Camera.FrameMove( fElapsedTime );
+ }
+ ////DEBUG
+ //D3DXVECTOR3 vEye = *g_Camera.GetEyePt();
+ //D3DXVECTOR3 vLookAt = (*g_Camera.GetLookAtPt() - vEye) * 500 + vEye;
+}
+
+//--------------------------------------------------------------------------------------
+// Render the scene using the D3D11 device
+//--------------------------------------------------------------------------------------
+void CALLBACK OnD3D11FrameRender( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pDC, double fTime,
+ float fElapsedTime, void* pUserContext )
+{
+ if(g_SimulateWater || g_ForceKick || (gfsdk_waveworks_result_NONE==GFSDK_WaveWorks_Simulation_GetStagingCursor(g_hOceanSimulation,NULL)))
+ {
+ GFSDK_WaveWorks_Simulation_SetTime(g_hOceanSimulation, g_SimulationTime);
+ GFSDK_WaveWorks_Simulation_KickD3D11(g_hOceanSimulation, &g_LastKickID, pDC, g_hOceanSavestate);
+
+ if(g_bSyncMode >= SynchronizationMode_RenderOnly)
+ {
+ // Block until the just-submitted kick is ready to render
+ gfsdk_U64 stagingCursorKickID = g_LastKickID - 1; // Just ensure that the initial value is different from last kick,
+ // so that we continue waiting if the staging cursor is empty
+ GFSDK_WaveWorks_Simulation_GetStagingCursor(g_hOceanSimulation, &stagingCursorKickID);
+ while(stagingCursorKickID != g_LastKickID)
+ {
+ const bool doBlock = true;
+ GFSDK_WaveWorks_Simulation_AdvanceStagingCursorD3D11(g_hOceanSimulation, doBlock, pDC, g_hOceanSavestate);
+ GFSDK_WaveWorks_Simulation_GetStagingCursor(g_hOceanSimulation, &stagingCursorKickID);
+ }
+
+ if(g_bSyncMode >= SynchronizationMode_Readback && g_ocean_simulation_settings.readback_displacements)
+ {
+ gfsdk_U64 readbackCursorKickID = g_LastKickID - 1; // Just ensure that the initial value is different from last kick,
+ // so that we continue waiting if the staging cursor is empty
+ while(readbackCursorKickID != g_LastKickID)
+ {
+ const bool doBlock = true;
+ GFSDK_WaveWorks_Simulation_AdvanceReadbackCursor(g_hOceanSimulation, doBlock);
+ GFSDK_WaveWorks_Simulation_GetReadbackCursor(g_hOceanSimulation, &readbackCursorKickID);
+ }
+ }
+ }
+ else
+ {
+ // Keep feeding the simulation pipeline until it is full - this loop should skip in all
+ // cases except the first iteration, when the simulation pipeline is first 'primed'
+ while(gfsdk_waveworks_result_NONE==GFSDK_WaveWorks_Simulation_GetStagingCursor(g_hOceanSimulation,NULL))
+ {
+ GFSDK_WaveWorks_Simulation_SetTime(g_hOceanSimulation, g_SimulationTime);
+ GFSDK_WaveWorks_Simulation_KickD3D11(g_hOceanSimulation, &g_LastKickID, pDC, g_hOceanSavestate);
+ }
+ }
+
+ GFSDK_WaveWorks_Savestate_RestoreD3D11(g_hOceanSavestate, pDC);
+ g_ForceKick = false;
+
+ // Exercise the readback archiving API
+ if(gfsdk_waveworks_result_OK == GFSDK_WaveWorks_Simulation_GetReadbackCursor(g_hOceanSimulation, &g_LastReadbackKickID))
+ {
+ if((g_LastReadbackKickID-g_LastArchivedKickID) > ReadbackArchiveInterval)
+ {
+ GFSDK_WaveWorks_Simulation_ArchiveDisplacements(g_hOceanSimulation);
+ g_LastArchivedKickID = g_LastReadbackKickID;
+ }
+ }
+ }
+
+ // deduce the rendering latency of the WaveWorks pipeline
+ {
+ gfsdk_U64 staging_cursor_kickID = 0;
+ GFSDK_WaveWorks_Simulation_GetStagingCursor(g_hOceanSimulation,&staging_cursor_kickID);
+ g_RenderLatency = (gfsdk_U32)(g_LastKickID - staging_cursor_kickID);
+ }
+
+ // likewise with the readback latency
+ if(g_ocean_simulation_settings.readback_displacements)
+ {
+ gfsdk_U64 readback_cursor_kickID = 0;
+ if(gfsdk_waveworks_result_OK == GFSDK_WaveWorks_Simulation_GetReadbackCursor(g_hOceanSimulation,&readback_cursor_kickID))
+ {
+ g_ReadbackLatency = (gfsdk_S32)(g_LastKickID - readback_cursor_kickID);
+ }
+ else
+ {
+ g_ReadbackLatency = -1;
+ }
+ }
+ else
+ {
+ g_ReadbackLatency = -1;
+ }
+
+ // getting simulation timings
+ GFSDK_WaveWorks_Simulation_GetStats(g_hOceanSimulation,g_ocean_stats_simulation);
+
+ // exponential filtering for stats
+ g_ocean_stats_simulation_filtered.CPU_main_thread_wait_time = g_ocean_stats_simulation_filtered.CPU_main_thread_wait_time*0.98f + 0.02f*g_ocean_stats_simulation.CPU_main_thread_wait_time;
+ g_ocean_stats_simulation_filtered.CPU_threads_start_to_finish_time = g_ocean_stats_simulation_filtered.CPU_threads_start_to_finish_time*0.98f + 0.02f*g_ocean_stats_simulation.CPU_threads_start_to_finish_time;
+ g_ocean_stats_simulation_filtered.CPU_threads_total_time = g_ocean_stats_simulation_filtered.CPU_threads_total_time*0.98f + 0.02f*g_ocean_stats_simulation.CPU_threads_total_time;
+ g_ocean_stats_simulation_filtered.GPU_simulation_time = g_ocean_stats_simulation_filtered.GPU_simulation_time*0.98f + 0.02f*g_ocean_stats_simulation.GPU_simulation_time;
+ g_ocean_stats_simulation_filtered.GPU_FFT_simulation_time = g_ocean_stats_simulation_filtered.GPU_FFT_simulation_time*0.98f + 0.02f*g_ocean_stats_simulation.GPU_FFT_simulation_time;
+ g_ocean_stats_simulation_filtered.GPU_gfx_time = g_ocean_stats_simulation_filtered.GPU_gfx_time*0.98f + 0.02f*g_ocean_stats_simulation.GPU_gfx_time;
+ g_ocean_stats_simulation_filtered.GPU_update_time = g_ocean_stats_simulation_filtered.GPU_update_time*0.98f + 0.02f*g_ocean_stats_simulation.GPU_update_time;
+
+ // 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 depth stencil
+ float ClearColor[4] = { 0.0f, 0.5f, 0.6f, 0.8f };
+ ID3D11RenderTargetView* pRTV = DXUTGetD3D11RenderTargetView();
+ pDC->ClearRenderTargetView( pRTV, ClearColor );
+ ID3D11DepthStencilView* pDSV = DXUTGetD3D11DepthStencilView();
+ pDC->ClearDepthStencilView( pDSV, D3D11_CLEAR_DEPTH, 1.0, 0 );
+
+ UpdateMarkers();
+ if(g_ocean_simulation_settings.readback_displacements)
+ RenderLocalMarkers(pDC);
+ if(g_bShowRemoteMarkers)
+ RenderRemoteMarkers(pDC);
+
+ if(g_RenderWater)
+ {
+ const D3DXMATRIX matView = D3DXMATRIX(kWaterScale,0,0,0,0,0,kWaterScale,0,0,kWaterScale,0,0,0,0,0,1) * *g_Camera.GetViewMatrix();
+ const D3DXMATRIX matProj = *g_Camera.GetProjMatrix();
+
+ if (g_RenderWireframe)
+ g_pOceanSurf->renderWireframe(pDC, matView,matProj,g_hOceanSimulation, g_hOceanSavestate, g_DebugCam);
+ else
+ g_pOceanSurf->renderShaded(pDC, matView,matProj,g_hOceanSimulation, g_hOceanSavestate, g_DebugCam);
+
+ g_pOceanSurf->getQuadTreeStats(g_ocean_stats_quadtree);
+ }
+
+ //if(g_RenderWater)
+ {
+ RenderSkybox(pDC);
+ }
+
+ RenderLogo(pDC);
+
+ if(!g_pTestParams->ShouldTakeScreenshot())
+ {
+ g_HUD.OnRender( fElapsedTime );
+ g_SampleUI.OnRender( fElapsedTime );
+ RenderText( fTime );
+ }
+
+ pDC->GSSetShader(NULL,NULL,0);
+
+ if(g_pTestParams != NULL )
+ {
+ g_pTestParams->Tick();
+
+ if(g_pTestParams->IsTestingComplete() && g_pTestParams->ShouldTakeScreenshot())
+ {
+ int slength = (int)g_pTestParams->ScreenshotDirectory.length() + 1;
+ int len = MultiByteToWideChar(CP_ACP, 0, g_pTestParams->ScreenshotDirectory.c_str(), slength, 0, 0);
+ wchar_t* buf = new wchar_t[len];
+ MultiByteToWideChar(CP_ACP, 0, g_pTestParams->ScreenshotDirectory.c_str(), slength, buf, len);
+
+ DXUTSnapD3D11Screenshot( buf, D3DX11_IFF_BMP );
+ delete[] buf;
+
+ DXUTShutdown();
+ }
+ }
+}
+
+//--------------------------------------------------------------------------------------
+// Render the help and statistics text. This function uses the ID3DXFont interface for
+// efficient text rendering.
+//--------------------------------------------------------------------------------------
+void RenderText( double fTime )
+{
+ // Output statistics
+ g_pTxtHelper->Begin();
+ g_pTxtHelper->SetInsertionPos( 2, 0 );
+ g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 0.9f, 0.9f, 0.9f, 1.0f ) );
+ g_pTxtHelper->DrawTextLine( DXUTGetFrameStats(true) );
+ g_pTxtHelper->DrawTextLine( DXUTGetDeviceStats() );
+
+ const UINT buffer_len = 256;
+ WCHAR buffer[buffer_len];
+ swprintf_s(buffer, buffer_len, L"Quad patches drawn: %d\n", g_ocean_stats_quadtree.num_patches_drawn);
+ g_pTxtHelper->DrawTextLine(buffer);
+
+ g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
+
+ // Draw help
+ if( g_bShowHelp )
+ {
+ const DXGI_SURFACE_DESC* pd3dsdBackBuffer = DXUTGetDXGIBackBufferSurfaceDesc();
+ g_pTxtHelper->SetInsertionPos( 2, pd3dsdBackBuffer->Height-15*6 );
+ g_pTxtHelper->SetForegroundColor( D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f ) );
+ g_pTxtHelper->DrawTextLine( L"Controls:" );
+
+ g_pTxtHelper->SetInsertionPos( 20, pd3dsdBackBuffer->Height-15*5 );
+ g_pTxtHelper->DrawTextLine( L"Camera control: left mouse\n");
+ g_pTxtHelper->DrawTextLine( L"W/S/A/D/Q/E to move camera" );
+
+ g_pTxtHelper->SetInsertionPos( 250, pd3dsdBackBuffer->Height-15*5 );
+ g_pTxtHelper->DrawTextLine( L"Hide help: F1\n"
+ L"Quit: ESC\n" );
+ }
+ else
+ {
+ g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
+ g_pTxtHelper->DrawTextLine( L"Press F1 for help" );
+ swprintf_s(buffer,buffer_len,L" GPU_gfx_time : %3.3f msec",g_ocean_stats_simulation_filtered.GPU_gfx_time);
+ g_pTxtHelper->DrawTextLine(buffer);
+ swprintf_s(buffer,buffer_len,L" GPU_update_time : %3.3f msec",g_ocean_stats_simulation_filtered.GPU_update_time);
+ g_pTxtHelper->DrawTextLine(buffer);
+ swprintf_s(buffer,buffer_len,L" CPU_main_thread_wait_time : %3.3f msec",g_ocean_stats_simulation_filtered.CPU_main_thread_wait_time);
+ g_pTxtHelper->DrawTextLine(buffer);
+ swprintf_s(buffer,buffer_len,L"CPU_threads_start_to_finish_time : %3.3f msec",g_ocean_stats_simulation_filtered.CPU_threads_start_to_finish_time);
+ g_pTxtHelper->DrawTextLine(buffer);
+ swprintf_s(buffer,buffer_len,L" CPU_threads_total_time : %3.3f msec",g_ocean_stats_simulation_filtered.CPU_threads_total_time);
+ g_pTxtHelper->DrawTextLine(buffer);
+ swprintf_s(buffer,buffer_len,L" GPU_simulation_time : %3.3f msec",g_ocean_stats_simulation_filtered.GPU_simulation_time);
+ g_pTxtHelper->DrawTextLine(buffer);
+ swprintf_s(buffer,buffer_len,L" GPU_FFT_simulation_time : %3.3f msec",g_ocean_stats_simulation_filtered.GPU_FFT_simulation_time);
+ g_pTxtHelper->DrawTextLine(buffer);
+ swprintf_s(buffer,buffer_len,L" CPU_quadtree_update_time : %3.3f msec",g_ocean_stats_quadtree.CPU_quadtree_update_time);
+ g_pTxtHelper->DrawTextLine(buffer);
+
+ swprintf_s(buffer,buffer_len,L" NumAllocations : %i",NumAllocations);
+ g_pTxtHelper->DrawTextLine(buffer);
+ swprintf_s(buffer,buffer_len,L" NumAlignedAllocations : %i",NumAlignedAllocations);
+ g_pTxtHelper->DrawTextLine(buffer);
+
+ swprintf_s(buffer,buffer_len,L" RenderLatency : %i",g_RenderLatency);
+ g_pTxtHelper->DrawTextLine(buffer);
+ if(g_ReadbackLatency >= 0)
+ {
+ swprintf_s(buffer,buffer_len,L" ReadbackLatency : %i",g_ReadbackLatency);
+ g_pTxtHelper->DrawTextLine(buffer);
+ }
+ else
+ {
+ swprintf_s(buffer,buffer_len,L" ReadbackLatency : <NONE-AVAILABLE>");
+ g_pTxtHelper->DrawTextLine(buffer);
+ }
+ }
+ g_pTxtHelper->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;
+
+ // Pass all remaining windows messages to camera so it can respond to user input
+ g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
+
+ 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 VK_F2: g_SettingsDlg.SetActive( !g_SettingsDlg.IsActive() ); break;
+ case VK_OEM_MINUS:
+ g_ocean_simulation_settings.detail_level = GFSDK_WaveWorks_Simulation_DetailLevel((g_ocean_simulation_settings.detail_level + g_max_detail_level) % (g_max_detail_level+1));
+ GFSDK_WaveWorks_Simulation_UpdateProperties(g_hOceanSimulation, g_ocean_simulation_settings, g_ocean_simulation_param);
+ GFSDK_WaveWorks_Quadtree_SetFrustumCullMargin(g_pOceanSurf->m_hOceanQuadTree, GFSDK_WaveWorks_Simulation_GetConservativeMaxDisplacementEstimate(g_hOceanSimulation));
+ break;
+ case VK_OEM_PLUS:
+ g_ocean_simulation_settings.detail_level = GFSDK_WaveWorks_Simulation_DetailLevel((g_ocean_simulation_settings.detail_level + 1) % (g_max_detail_level+1));
+ GFSDK_WaveWorks_Simulation_UpdateProperties(g_hOceanSimulation, g_ocean_simulation_settings, g_ocean_simulation_param);
+ GFSDK_WaveWorks_Quadtree_SetFrustumCullMargin(g_pOceanSurf->m_hOceanQuadTree, GFSDK_WaveWorks_Simulation_GetConservativeMaxDisplacementEstimate(g_hOceanSimulation));
+ break;
+ case VK_OEM_COMMA:
+ g_ocean_param_quadtree.mesh_dim = max(g_ocean_param_quadtree.mesh_dim >> 1, 4);
+ g_pOceanSurf->initQuadTree(g_ocean_param_quadtree);
+ break;
+ case VK_OEM_PERIOD:
+ g_ocean_param_quadtree.mesh_dim = min(g_ocean_param_quadtree.mesh_dim << 1, 256);
+ g_pOceanSurf->initQuadTree(g_ocean_param_quadtree);
+ break;
+ case 'c':
+ case 'C':
+ g_DebugCam = !g_DebugCam;
+ break;
+ case 'r':
+ case 'R':
+ g_bShowRemoteMarkers = !g_bShowRemoteMarkers;
+ if(g_bShowRemoteMarkers)
+ {
+ UpdateRemoteMarkerCoords();
+ }
+ break;
+ case VK_OEM_4: // '[{' for US
+ g_bSyncMode = (SynchronizationMode)((g_bSyncMode+1)%Num_SynchronizationModes);
+ break;
+ case 'n':
+ case 'N':
+ if(1.f == g_ReadbackCoord)
+ g_ReadbackCoord = 0.f;
+ else
+ {
+ g_ReadbackCoord -= 0.5f;
+ if(g_ReadbackCoord < 0.f)
+ g_ReadbackCoord = 0.f;
+ }
+ break;
+ case 'm':
+ case 'M':
+ if(0.f == g_ReadbackCoord)
+ g_ReadbackCoord = 1.f;
+ else
+ {
+ g_ReadbackCoord += 0.5f;
+ if(g_ReadbackCoord > (ReadbackArchiveSize-1))
+ g_ReadbackCoord = (ReadbackArchiveSize-1);
+ }
+ 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;
+ case IDC_TOGGLEWIREFRAME: g_RenderWireframe = g_HUD.GetCheckBox(IDC_TOGGLEWIREFRAME)->GetChecked(); break;
+ case IDC_TOGGLERENDER: g_RenderWater = g_HUD.GetCheckBox(IDC_TOGGLERENDER)->GetChecked(); break;
+ case IDC_TOGGLESIMULATE: g_SimulateWater = g_HUD.GetCheckBox(IDC_TOGGLESIMULATE)->GetChecked(); break;
+
+ case IDC_AMPLITUDE_SLIDER:
+ if(EVENT_SLIDER_VALUE_CHANGED_UP == nEvent)
+ {
+ g_ocean_simulation_param.wave_amplitude = FLOAT(g_HUD.GetSlider(IDC_AMPLITUDE_SLIDER)->GetValue())/kAmplitudeSliderScaleFactor;
+ GFSDK_WaveWorks_Simulation_UpdateProperties(g_hOceanSimulation, g_ocean_simulation_settings, g_ocean_simulation_param);
+ GFSDK_WaveWorks_Quadtree_SetFrustumCullMargin(g_pOceanSurf->m_hOceanQuadTree, GFSDK_WaveWorks_Simulation_GetConservativeMaxDisplacementEstimate(g_hOceanSimulation));
+ }
+ break;
+
+ case IDC_CHOPPY_SCALE_SLIDER:
+ {
+ g_ocean_simulation_param.choppy_scale = FLOAT(g_HUD.GetSlider(IDC_CHOPPY_SCALE_SLIDER)->GetValue())/kChoppyScaleSliderScaleFactor;
+ GFSDK_WaveWorks_Simulation_UpdateProperties(g_hOceanSimulation, g_ocean_simulation_settings, g_ocean_simulation_param);
+ }
+ break;
+
+ case IDC_WIND_SPEED_SLIDER:
+ if(EVENT_SLIDER_VALUE_CHANGED_UP == nEvent)
+ {
+ g_ocean_simulation_param.wind_speed = FLOAT(g_HUD.GetSlider(IDC_WIND_SPEED_SLIDER)->GetValue())/kWindSpeedSliderScaleFactor;
+ GFSDK_WaveWorks_Simulation_UpdateProperties(g_hOceanSimulation, g_ocean_simulation_settings, g_ocean_simulation_param);
+ GFSDK_WaveWorks_Quadtree_SetFrustumCullMargin(g_pOceanSurf->m_hOceanQuadTree, GFSDK_WaveWorks_Simulation_GetConservativeMaxDisplacementEstimate(g_hOceanSimulation));
+ }
+ break;
+
+ case IDC_WIND_DEPENDENCY_SLIDER:
+ if(EVENT_SLIDER_VALUE_CHANGED_UP == nEvent)
+ {
+ g_ocean_simulation_param.wind_dependency = FLOAT(g_HUD.GetSlider(IDC_WIND_DEPENDENCY_SLIDER)->GetValue())/kWindDependencySliderScaleFactor;
+ GFSDK_WaveWorks_Simulation_UpdateProperties(g_hOceanSimulation, g_ocean_simulation_settings, g_ocean_simulation_param);
+ GFSDK_WaveWorks_Quadtree_SetFrustumCullMargin(g_pOceanSurf->m_hOceanQuadTree, GFSDK_WaveWorks_Simulation_GetConservativeMaxDisplacementEstimate(g_hOceanSimulation));
+ }
+ break;
+
+ case IDC_TIME_SCALE_SLIDER:
+ {
+ g_ocean_simulation_param.time_scale = FLOAT(g_HUD.GetSlider(IDC_TIME_SCALE_SLIDER)->GetValue())/kTimeScaleSliderScaleFactor;
+ GFSDK_WaveWorks_Simulation_UpdateProperties(g_hOceanSimulation, g_ocean_simulation_settings, g_ocean_simulation_param);
+ }
+ break;
+
+ case IDC_SKY_BLENDING_SLIDER:
+ {
+ g_ocean_surface_param.sky_blending = FLOAT(g_HUD.GetSlider(IDC_SKY_BLENDING_SLIDER)->GetValue())/kSkyBlendingSliderScaleFactor;
+ g_pOceanSurf->init(g_ocean_surface_param);
+ }
+ break;
+
+ case IDC_PATCH_LENGTH_SLIDER:
+ if(EVENT_SLIDER_VALUE_CHANGED_UP == nEvent)
+ {
+ g_ocean_param_quadtree.min_patch_length = FLOAT(g_HUD.GetSlider(IDC_PATCH_LENGTH_SLIDER)->GetValue());
+ g_pOceanSurf->initQuadTree(g_ocean_param_quadtree);
+ }
+ break;
+
+ case IDC_FURTHEST_COVER_SLIDER:
+ {
+ g_ocean_param_quadtree.auto_root_lod = g_HUD.GetSlider(IDC_FURTHEST_COVER_SLIDER)->GetValue();
+ g_pOceanSurf->initQuadTree(g_ocean_param_quadtree);
+ }
+ break;
+
+ case IDC_UPPER_GRID_COVER_SLIDER:
+ {
+ g_ocean_param_quadtree.upper_grid_coverage = FLOAT(g_HUD.GetSlider(IDC_UPPER_GRID_COVER_SLIDER)->GetValue());
+ g_pOceanSurf->initQuadTree(g_ocean_param_quadtree);
+ }
+ break;
+
+ case IDC_ANISO_SLIDER:
+ {
+ g_ocean_simulation_settings.aniso_level = (gfsdk_U8)g_HUD.GetSlider(IDC_ANISO_SLIDER)->GetValue();
+ GFSDK_WaveWorks_Simulation_UpdateProperties(g_hOceanSimulation, g_ocean_simulation_settings, g_ocean_simulation_param);
+ }
+ break;
+
+ case IDC_TOGGLEREADBACK:
+ {
+ g_ocean_simulation_settings.readback_displacements = g_HUD.GetCheckBox(IDC_TOGGLEREADBACK)->GetChecked();
+ GFSDK_WaveWorks_Simulation_UpdateProperties(g_hOceanSimulation, g_ocean_simulation_settings, g_ocean_simulation_param);
+ }
+ break;
+
+ case IDC_TESSELLATION_LOD_SLIDER:
+ {
+ g_ocean_param_quadtree.tessellation_lod = (float)g_HUD.GetSlider(IDC_TESSELLATION_LOD_SLIDER)->GetValue();
+ g_pOceanSurf->initQuadTree(g_ocean_param_quadtree);
+ }
+ break;
+ case IDC_FOAM_THRESHOLD_SLIDER:
+ {
+ g_ocean_simulation_param.foam_generation_threshold = FLOAT(g_HUD.GetSlider(IDC_FOAM_THRESHOLD_SLIDER)->GetValue())/kFoamGenerationThresholdFactor;
+ GFSDK_WaveWorks_Simulation_UpdateProperties(g_hOceanSimulation, g_ocean_simulation_settings, g_ocean_simulation_param);
+ }
+ break;
+ case IDC_FOAM_AMOUNT_SLIDER:
+ {
+ g_ocean_simulation_param.foam_generation_amount = FLOAT(g_HUD.GetSlider(IDC_FOAM_AMOUNT_SLIDER)->GetValue())/kFoamGenerationAmountFactor;
+ GFSDK_WaveWorks_Simulation_UpdateProperties(g_hOceanSimulation, g_ocean_simulation_settings, g_ocean_simulation_param);
+ }
+ break;
+ case IDC_FOAM_DISSIPATION_SLIDER:
+ {
+ g_ocean_simulation_param.foam_dissipation_speed = FLOAT(g_HUD.GetSlider(IDC_FOAM_DISSIPATION_SLIDER)->GetValue())/kFoamDissipationSpeedFactor;
+ GFSDK_WaveWorks_Simulation_UpdateProperties(g_hOceanSimulation, g_ocean_simulation_settings, g_ocean_simulation_param);
+ }
+ break;
+ case IDC_FOAM_FADEOUT_SLIDER:
+ {
+ g_ocean_simulation_param.foam_falloff_speed = FLOAT(g_HUD.GetSlider(IDC_FOAM_FADEOUT_SLIDER)->GetValue())/kFoamFadeoutSpeedFactor + 0.9f;
+ GFSDK_WaveWorks_Simulation_UpdateProperties(g_hOceanSimulation, g_ocean_simulation_settings, g_ocean_simulation_param);
+ }
+ break;
+ }
+
+}
+
+
+//--------------------------------------------------------------------------------------
+// Release D3D11 resources created in OnD3D11ResizedSwapChain
+//--------------------------------------------------------------------------------------
+void CALLBACK OnD3D11ReleasingSwapChain( void* pUserContext )
+{
+ g_DialogResourceManager.OnD3D11ReleasingSwapChain();
+
+ SAFE_RELEASE(g_pLogoVB);
+}
+
+
+//--------------------------------------------------------------------------------------
+// Release D3D11 resources created in OnD3D11CreateDevice
+//--------------------------------------------------------------------------------------
+void CALLBACK OnD3D11DestroyDevice( void* pUserContext )
+{
+ g_DialogResourceManager.OnD3D11DestroyDevice();
+ g_SettingsDlg.OnD3D11DestroyDevice();
+ CDXUTDirectionWidget::StaticOnD3D11DestroyDevice();
+
+ // Ocean object
+ SAFE_DELETE(g_pOceanSurf);
+
+ if(g_hOceanSimulation)
+ {
+ GFSDK_WaveWorks_Simulation_Destroy(g_hOceanSimulation);
+ g_hOceanSimulation = NULL;
+ }
+
+ SAFE_RELEASE(g_pMarkerFX);
+ SAFE_RELEASE(g_pMarkerLayout);
+
+ SAFE_RELEASE(g_pSkyboxFX);
+ SAFE_RELEASE(g_pSkyboxLayout);
+ SAFE_RELEASE(g_pSkyCubeMap);
+ SAFE_RELEASE(g_pLogoTex);
+
+ SAFE_RELEASE(g_pSkyBoxVB);
+ SAFE_RELEASE(g_pMarkerVB);
+ SAFE_RELEASE(g_pMarkerIB);
+
+ if(g_hOceanSavestate)
+ {
+ GFSDK_WaveWorks_Savestate_Destroy(g_hOceanSavestate);
+ g_hOceanSavestate = NULL;
+ }
+
+ GFSDK_WaveWorks_ReleaseD3D11(DXUTGetD3D11Device());
+
+ SAFE_DELETE(g_pTxtHelper);
+}
+
+void RenderMarkers(ID3D11DeviceContext* pDC, const gfsdk_float4* pMarkerPositions, int num_markers, const D3DXVECTOR4& color)
+{
+ g_pMarkerColor->SetFloatVector((FLOAT*)&color);
+
+ const UINT vbOffset = 0;
+ const UINT vertexStride = sizeof(D3DXVECTOR4);
+ pDC->IASetInputLayout(g_pMarkerLayout);
+ pDC->IASetVertexBuffers(0, 1, &g_pMarkerVB, &vertexStride, &vbOffset);
+ pDC->IASetIndexBuffer(g_pMarkerIB, DXGI_FORMAT_R16_UINT, 0);
+
+ pDC->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+
+ D3DXMATRIX matView = /*D3DXMATRIX(1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1) **/ *g_Camera.GetViewMatrix();
+ D3DXMATRIX matProj = *g_Camera.GetProjMatrix();
+ D3DXMATRIX matVP = matView * matProj;
+ g_pMarkerMatViewProjVariable->SetMatrix((FLOAT*)&matVP);
+
+ g_pMarkerTechnique->GetPassByIndex(0)->Apply(0,pDC);
+ for(int i = 0; i != num_markers; ++i)
+ {
+ D3DXVECTOR4 transformedMarkerPosition = D3DXVECTOR4(pMarkerPositions[i].x,pMarkerPositions[i].z + g_ocean_param_quadtree.sea_level,pMarkerPositions[i].y,1.f);
+ transformedMarkerPosition.x *= kWaterScale;
+ transformedMarkerPosition.y *= kWaterScale;
+ transformedMarkerPosition.z *= kWaterScale;
+
+ D3D11_MAPPED_SUBRESOURCE msr;
+ pDC->Map(g_pMarkerVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &msr);
+ D3DXVECTOR4* marker_verts = (D3DXVECTOR4*)msr.pData;
+
+ marker_verts[0] = transformedMarkerPosition;
+ marker_verts[1] = transformedMarkerPosition + D3DXVECTOR4( 20.f, 20.f, 20.f, 0.f);
+ marker_verts[2] = transformedMarkerPosition + D3DXVECTOR4( 20.f, 20.f,-20.f, 0.f);
+ marker_verts[3] = transformedMarkerPosition + D3DXVECTOR4(-20.f, 20.f,-20.f, 0.f);
+ marker_verts[4] = transformedMarkerPosition + D3DXVECTOR4(-20.f, 20.f, 20.f, 0.f);
+ pDC->Unmap(g_pMarkerVB, 0);
+
+ pDC->DrawIndexed(12, 0, 0);
+ }
+}
+
+enum { NumMarkersXY = 7, NumMarkers = NumMarkersXY*NumMarkersXY };
+
+gfsdk_float2 g_local_marker_coords[NumMarkers];
+gfsdk_float2 g_remote_marker_coords[NumMarkers];
+gfsdk_float4 g_local_marker_positions[NumMarkers];
+
+void RenderLocalMarkers(ID3D11DeviceContext* pDC)
+{
+ RenderMarkers(pDC, g_local_marker_positions, NumMarkers, D3DXVECTOR4(1.f,0.f,0.f,1.f));
+}
+
+void RenderRemoteMarkers(ID3D11DeviceContext* pDC)
+{
+ if(g_pNetworkClient) {
+ const gfsdk_float4* pMarkerPositions = NULL;
+ size_t numMarkers = 0;
+ if(g_pNetworkClient->GetRemoteMarkerPositions(pMarkerPositions, numMarkers)) {
+ RenderMarkers(pDC, pMarkerPositions, (int)numMarkers, D3DXVECTOR4(1.f,1.f,0.f,1.f));
+ }
+ }
+}
+
+void UpdateRemoteMarkerCoords()
+{
+ memcpy(g_remote_marker_coords,g_local_marker_coords,sizeof(g_remote_marker_coords));
+}
+
+void UpdateMarkers()
+{
+ HRESULT hr;
+
+ // Find where the camera vector intersects mean sea level
+ D3DXVECTOR3 eye_pos = *g_Camera.GetEyePt();
+ D3DXVECTOR3 lookat_pos = *g_Camera.GetLookAtPt();
+ const FLOAT intersectionHeight = g_ocean_param_quadtree.sea_level;
+ const FLOAT lambda = (intersectionHeight - eye_pos.y)/(lookat_pos.y - eye_pos.y);
+ const D3DXVECTOR3 sea_level_pos = (1.f - lambda) * eye_pos + lambda * lookat_pos;
+ const D3DXVECTOR2 sea_level_xy(sea_level_pos.x, sea_level_pos.z);
+
+ // Update local marker coords, we could need them any time for remote
+ for(int x = 0; x != NumMarkersXY; ++x)
+ {
+ for(int y = 0; y != NumMarkersXY; ++y)
+ {
+ g_local_marker_coords[y * NumMarkersXY + x] = NvFromDX(sea_level_xy/kWaterScale + D3DXVECTOR2(2.f * (x-((NumMarkersXY-1)/2)), 2.f * (y-((NumMarkersXY-1)/2))));
+ }
+ }
+
+ // Do local readback, if requested
+ if(g_ocean_simulation_settings.readback_displacements)
+ {
+ gfsdk_float4 displacements[NumMarkers];
+ if(g_ReadbackCoord >= 1.f)
+ {
+ const float coord = g_ReadbackCoord - (g_LastReadbackKickID-g_LastArchivedKickID) * 1.f/float(ReadbackArchiveInterval);
+ V(GFSDK_WaveWorks_Simulation_GetArchivedDisplacements(g_hOceanSimulation, coord, g_local_marker_coords, displacements, NumMarkers));
+ }
+ else
+ {
+ V(GFSDK_WaveWorks_Simulation_GetDisplacements(g_hOceanSimulation, g_local_marker_coords, displacements, NumMarkers));
+ }
+
+ for(int ix = 0; ix != NumMarkers; ++ix)
+ {
+ g_local_marker_positions[ix].x = displacements[ix].x + g_local_marker_coords[ix].x;
+ g_local_marker_positions[ix].y = displacements[ix].y + g_local_marker_coords[ix].y;
+ g_local_marker_positions[ix].z = displacements[ix].z;
+ g_local_marker_positions[ix].w = 1.f;
+ }
+ }
+
+ if(g_bShowRemoteMarkers && NULL != g_pNetworkClient)
+ {
+ g_pNetworkClient->RequestRemoteMarkerPositions(g_remote_marker_coords,NumMarkers);
+ }
+}
+
+void RenderSkybox(ID3D11DeviceContext* pDC)
+{
+ D3DXMATRIX matView = D3DXMATRIX(1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1) * *g_Camera.GetViewMatrix();
+ D3DXMATRIX matProj = *g_Camera.GetProjMatrix();
+ D3DXMATRIX matVP = matView * matProj;
+
+ D3D11_MAPPED_SUBRESOURCE msr;
+ pDC->Map(g_pSkyBoxVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &msr);
+
+ D3DXVECTOR4* far_plane_quad = (D3DXVECTOR4*)msr.pData;
+ far_plane_quad[0] = D3DXVECTOR4(-g_FarPlane, g_FarPlane, g_FarPlane * 0.999f, g_FarPlane);
+ far_plane_quad[1] = D3DXVECTOR4(-g_FarPlane, -g_FarPlane, g_FarPlane * 0.999f, g_FarPlane);
+ far_plane_quad[2] = D3DXVECTOR4( g_FarPlane, g_FarPlane, g_FarPlane * 0.999f, g_FarPlane);
+ far_plane_quad[3] = D3DXVECTOR4( g_FarPlane, -g_FarPlane, g_FarPlane * 0.999f, g_FarPlane);
+ D3DXMATRIX matInvVP;
+ D3DXMatrixInverse(&matInvVP, NULL, &matVP);
+ D3DXVec4TransformArray(&far_plane_quad[0], sizeof(D3DXVECTOR4), &far_plane_quad[0], sizeof(D3DXVECTOR4), &matInvVP, 4);
+ pDC->Unmap(g_pSkyBoxVB, 0);
+
+ const UINT vbOffset = 0;
+ const UINT vertexStride = sizeof(D3DXVECTOR4);
+ pDC->IASetInputLayout(g_pSkyboxLayout);
+ pDC->IASetVertexBuffers(0, 1, &g_pSkyBoxVB, &vertexStride, &vbOffset);
+ pDC->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+
+ g_pSkyBoxMatViewProjVariable->SetMatrix((FLOAT*)&matVP);
+
+ D3DXVECTOR3 eye_pos = *g_Camera.GetEyePt();
+ g_pSkyBoxEyePosVariable->SetFloatVector((FLOAT*)&eye_pos);
+
+ g_pSkyBoxSkyCubeMapVariable->SetResource(g_pSkyCubeMap);
+
+ g_pSkyBoxTechnique->GetPassByIndex(0)->Apply(0, pDC);
+ pDC->Draw(4, 0);
+}
+
+void RenderLogo(ID3D11DeviceContext* pDC)
+{
+ g_pLogoTextureVariable->SetResource(g_pLogoTex);
+
+ const UINT vbOffset = 0;
+ const UINT vertexStride = 20;
+ pDC->IASetInputLayout(g_pOceanSurf->m_pQuadLayout);
+ pDC->IASetVertexBuffers(0, 1, &g_pLogoVB, &vertexStride, &vbOffset);
+ pDC->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+
+ g_pLogoTechnique->GetPassByIndex(0)->Apply(0, pDC);
+ pDC->Draw(4, 0);
+}