diff options
Diffstat (limited to 'sample/d3d11/ocean_surface.cpp')
| -rw-r--r-- | sample/d3d11/ocean_surface.cpp | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/sample/d3d11/ocean_surface.cpp b/sample/d3d11/ocean_surface.cpp new file mode 100644 index 0000000..8483d8c --- /dev/null +++ b/sample/d3d11/ocean_surface.cpp @@ -0,0 +1,324 @@ +// 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 "SDKMisc.h" +#include "ocean_surface.h" + +#include "GFSDK_WaveWorks_D3D_Util.h" + +#pragma warning(disable:4127) + +extern HRESULT LoadFile(LPCTSTR FileName, ID3DXBuffer** ppBuffer); + +OceanSurface::OceanSurface() +{ + m_pOceanFX = NULL; + m_hOceanQuadTree = NULL; + pDistanceFieldModule = NULL; + m_pQuadLayout = NULL; + m_pRayContactLayout = NULL; + m_pRenderRayContactTechnique = NULL; + m_pContactVB = NULL; + m_pContactIB = NULL; + + UINT NumQuadtreeShaderInputs = GFSDK_WaveWorks_Quadtree_GetShaderInputCountD3D11(); + UINT NumSimulationShaderInputs = GFSDK_WaveWorks_Simulation_GetShaderInputCountD3D11(); + m_pQuadTreeShaderInputMappings_Shore = new UINT [NumQuadtreeShaderInputs]; + m_pSimulationShaderInputMappings_Shore = new UINT [NumSimulationShaderInputs]; + + m_pd3dDevice = DXUTGetD3D11Device(); +} + +OceanSurface::~OceanSurface() +{ + if(m_hOceanQuadTree) + { + GFSDK_WaveWorks_Quadtree_Destroy(m_hOceanQuadTree); + m_hOceanQuadTree = NULL; + } + SAFE_DELETE_ARRAY(m_pQuadTreeShaderInputMappings_Shore); + SAFE_DELETE_ARRAY(m_pSimulationShaderInputMappings_Shore); + SAFE_RELEASE(m_pOceanFX); + SAFE_RELEASE(m_pQuadLayout); + SAFE_RELEASE(m_pRayContactLayout); + SAFE_RELEASE(m_pContactVB); + SAFE_RELEASE(m_pContactIB); +} + +HRESULT OceanSurface::initQuadTree(const GFSDK_WaveWorks_Quadtree_Params& params) +{ + if(NULL == m_hOceanQuadTree) +{ + return GFSDK_WaveWorks_Quadtree_CreateD3D11(params, m_pd3dDevice, &m_hOceanQuadTree); + } + else + { + return GFSDK_WaveWorks_Quadtree_UpdateParams(m_hOceanQuadTree, params); + } +} + +UINT GetShaderInputRegisterMapping( ID3D11ShaderReflection* pReflectionVS, + ID3D11ShaderReflection* pReflectionHS, + ID3D11ShaderReflection* pReflectionDS, + ID3D11ShaderReflection* pReflectionPS, + const GFSDK_WaveWorks_ShaderInput_Desc& inputDesc + ) +{ + ID3D11ShaderReflection* pReflection = NULL; + switch(inputDesc.Type) + { + case GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_FloatConstant: + case GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler: + case GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture: + case GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_ConstantBuffer: + pReflection = pReflectionVS; + break; + case GFSDK_WaveWorks_ShaderInput_Desc::HullShader_FloatConstant: + case GFSDK_WaveWorks_ShaderInput_Desc::HullShader_Sampler: + case GFSDK_WaveWorks_ShaderInput_Desc::HullShader_Texture: + case GFSDK_WaveWorks_ShaderInput_Desc::HullShader_ConstantBuffer: + pReflection = pReflectionHS; + break; + case GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_FloatConstant: + case GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler: + case GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture: + case GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_ConstantBuffer: + pReflection = pReflectionDS; + break; + case GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant: + case GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler: + case GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture: + case GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_ConstantBuffer: + pReflection = pReflectionPS; + break; + default: + pReflection = NULL; + break; + } + + assert(pReflection); + D3D11_SHADER_INPUT_BIND_DESC desc; + HRESULT hr = pReflection->GetResourceBindingDescByName(inputDesc.Name, &desc); + if(FAILED(hr)) + { + // Shader doesn't use this input, mark it as unused + return 0xFFFFFFFF; + } + + return desc.BindPoint; +} + +ID3D11ShaderReflection* GetReflection(const D3DX11_PASS_SHADER_DESC& passShader) +{ + D3DX11_EFFECT_SHADER_DESC shaderDesc; + passShader.pShaderVariable->GetShaderDesc(passShader.ShaderIndex, &shaderDesc); + ID3D11ShaderReflection* pResult = NULL; + D3DReflect(shaderDesc.pBytecode, shaderDesc.BytecodeLength, IID_ID3D11ShaderReflection, (void**)&pResult); + return pResult; +} + +HRESULT OceanSurface::init() +{ + HRESULT hr = S_OK; + + if(NULL == m_pOceanFX) + { + ID3DXBuffer* pEffectBuffer = NULL; + + TCHAR path[MAX_PATH]; + DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("..\\Media\\ocean_surface_d3d11.fxo")); + V_RETURN(LoadFile(path, &pEffectBuffer)); + V_RETURN(D3DX11CreateEffectFromMemory(pEffectBuffer->GetBufferPointer(), pEffectBuffer->GetBufferSize(), 0, m_pd3dDevice, &m_pOceanFX)); + pEffectBuffer->Release(); + + // Hook up the shader mappings + m_pRenderSurfaceTechnique = m_pOceanFX->GetTechniqueByName("RenderOceanSurfTech"); + m_pRenderSurfaceShadedWithShorelinePass = m_pRenderSurfaceTechnique->GetPassByName("Pass_Solid_WithShoreline"); + + D3DX11_PASS_SHADER_DESC passShaderDesc; + + V_RETURN(m_pRenderSurfaceShadedWithShorelinePass->GetVertexShaderDesc(&passShaderDesc)); + ID3D11ShaderReflection* pShadedShoreReflectionVS = GetReflection(passShaderDesc); + + V_RETURN(m_pRenderSurfaceShadedWithShorelinePass->GetHullShaderDesc(&passShaderDesc)); + ID3D11ShaderReflection* pShadedShoreReflectionHS = GetReflection(passShaderDesc); + + V_RETURN(m_pRenderSurfaceShadedWithShorelinePass->GetDomainShaderDesc(&passShaderDesc)); + ID3D11ShaderReflection* pShadedShoreReflectionDS = GetReflection(passShaderDesc); + + V_RETURN(m_pRenderSurfaceShadedWithShorelinePass->GetPixelShaderDesc(&passShaderDesc)); + ID3D11ShaderReflection* pShadedShoreReflectionPS = GetReflection(passShaderDesc); + + UINT NumQuadtreeShaderInputs = GFSDK_WaveWorks_Quadtree_GetShaderInputCountD3D11(); + UINT NumSimulationShaderInputs = GFSDK_WaveWorks_Simulation_GetShaderInputCountD3D11(); + + for(UINT i = 0; i != NumQuadtreeShaderInputs; ++i) + { + GFSDK_WaveWorks_ShaderInput_Desc inputDesc; + GFSDK_WaveWorks_Quadtree_GetShaderInputDescD3D11(i, &inputDesc); + m_pQuadTreeShaderInputMappings_Shore[i] = GetShaderInputRegisterMapping(pShadedShoreReflectionVS, pShadedShoreReflectionHS, pShadedShoreReflectionDS, pShadedShoreReflectionPS, inputDesc); + } + + for(UINT i = 0; i != NumSimulationShaderInputs; ++i) + { + GFSDK_WaveWorks_ShaderInput_Desc inputDesc; + GFSDK_WaveWorks_Simulation_GetShaderInputDescD3D11(i, &inputDesc); + m_pSimulationShaderInputMappings_Shore[i] = GetShaderInputRegisterMapping(pShadedShoreReflectionVS, pShadedShoreReflectionHS, pShadedShoreReflectionDS, pShadedShoreReflectionPS, inputDesc); + } + + pShadedShoreReflectionVS->Release(); + pShadedShoreReflectionPS->Release(); + pShadedShoreReflectionHS->Release(); + pShadedShoreReflectionDS->Release(); + + m_pRenderSurfaceWireframeWithShorelinePass = m_pRenderSurfaceTechnique->GetPassByName("Pass_Wireframe_WithShoreline"); + } + + if(NULL == m_pQuadLayout) + { + const D3D11_INPUT_ELEMENT_DESC quad_layout[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + const UINT num_layout_elements = sizeof(quad_layout)/sizeof(quad_layout[0]); + + ID3DX11EffectTechnique* pDisplayLogoTech = m_pOceanFX->GetTechniqueByName("DisplayLogoTech"); + + D3DX11_PASS_DESC PassDesc; + V_RETURN(pDisplayLogoTech->GetPassByIndex(0)->GetDesc(&PassDesc)); + + V_RETURN(m_pd3dDevice->CreateInputLayout( quad_layout, num_layout_elements, + PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize, + &m_pQuadLayout + )); + } + + // Creating ray & contact related D3D objects + m_pRenderRayContactTechnique = m_pOceanFX->GetTechniqueByName("RenderRayContactTech"); + if(NULL == m_pRayContactLayout) + { + const D3D11_INPUT_ELEMENT_DESC ray_contact_layout[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 } + }; + const UINT num_layout_elements = sizeof(ray_contact_layout)/sizeof(ray_contact_layout[0]); + + D3DX11_PASS_DESC PassDesc; + V_RETURN(m_pRenderRayContactTechnique->GetPassByIndex(0)->GetDesc(&PassDesc)); + + V_RETURN(m_pd3dDevice->CreateInputLayout( ray_contact_layout, num_layout_elements, + PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize, + &m_pRayContactLayout + )); + } + + { + + float vertex_data[5*4] = + {0, 0, 0, 1, + 1, 1, 0, 0, + 0, 1, 1, 0, + -1, 1, 0, 0, + 0, 1,-1, 0}; + D3D11_BUFFER_DESC vBufferDesc; + vBufferDesc.ByteWidth = 5 * sizeof(D3DXVECTOR4); + vBufferDesc.Usage = D3D11_USAGE_DEFAULT; + vBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vBufferDesc.CPUAccessFlags = 0; + vBufferDesc.MiscFlags = 0; + D3D11_SUBRESOURCE_DATA vBufferData; + vBufferData.pSysMem = vertex_data; + vBufferData.SysMemPitch = 0; + vBufferData.SysMemSlicePitch = 0; + V_RETURN(m_pd3dDevice->CreateBuffer(&vBufferDesc, &vBufferData, &m_pContactVB)); + + 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(m_pd3dDevice->CreateBuffer(&iBufferDesc, &iBufferData, &m_pContactIB)); + } + + return S_OK; +} + + +void OceanSurface::renderShaded( ID3D11DeviceContext* pDC, + const D3DXMATRIX& matView, + const D3DXMATRIX& matProj, + GFSDK_WaveWorks_SimulationHandle hSim, + GFSDK_WaveWorks_SavestateHandle hSavestate, + const D3DXVECTOR2& windDir, + const float steepness, + const float amplitude, + const float wavelength, + const float speed, + const float parallelness, + const float totalTime + ) +{ + D3D11_VIEWPORT vp; + UINT NumViewports = 1; + pDC->RSGetViewports( &NumViewports, &vp ); + + if( pDistanceFieldModule != NULL) + { + // Apply data tex SRV + D3DXMATRIX topDownMatrix; + pDistanceFieldModule->GetWorldToTopDownTextureMatrix( topDownMatrix ); + m_pOceanFX->GetVariableByName("g_WorldToTopDownTextureMatrix")->AsMatrix()->SetMatrix( &topDownMatrix._11 ); + + m_pOceanFX->GetVariableByName("g_GerstnerSteepness")->AsScalar()->SetFloat( steepness ); + m_pOceanFX->GetVariableByName("g_BaseGerstnerAmplitude")->AsScalar()->SetFloat( amplitude ); + m_pOceanFX->GetVariableByName("g_BaseGerstnerWavelength")->AsScalar()->SetFloat( wavelength ); + m_pOceanFX->GetVariableByName("g_BaseGerstnerSpeed")->AsScalar()->SetFloat( speed ); + m_pOceanFX->GetVariableByName("g_BaseGerstnerParallelness")->AsScalar()->SetFloat( parallelness ); + m_pOceanFX->GetVariableByName("g_WindDirection")->AsVector()->SetFloatVector( &windDir.x ); + m_pOceanFX->GetVariableByName("g_DataTexture")->AsShaderResource()->SetResource( pDistanceFieldModule->GetDataTextureSRV() ); + m_pOceanFX->GetVariableByName("g_Time")->AsScalar()->SetFloat( totalTime ); + + m_pRenderSurfaceShadedWithShorelinePass->Apply( 0, pDC ); + GFSDK_WaveWorks_Simulation_SetRenderStateD3D11(hSim, pDC, NvFromDX(matView), m_pSimulationShaderInputMappings_Shore, hSavestate); + GFSDK_WaveWorks_Quadtree_DrawD3D11(m_hOceanQuadTree, pDC, NvFromDX(matView), NvFromDX(matProj), m_pQuadTreeShaderInputMappings_Shore, hSavestate); + + m_pOceanFX->GetVariableByName("g_DataTexture")->AsShaderResource()->SetResource( NULL ); + } + GFSDK_WaveWorks_Savestate_RestoreD3D11(hSavestate, pDC); +} + +void OceanSurface::getQuadTreeStats(GFSDK_WaveWorks_Quadtree_Stats& stats) +{ + GFSDK_WaveWorks_Quadtree_GetStats(m_hOceanQuadTree, stats); +} |