From 67e62061658d90b9491c55544bb419f91a0c5c08 Mon Sep 17 00:00:00 2001 From: Jason Maskell Date: Thu, 19 May 2016 11:56:51 +0200 Subject: D3D11 test is compiling and running with a rendering error (ocean is grey and not dark blue). D3D11 sample added but still has lots of compile errors, needs to be fully converted to use new DXUT11, etc. --- .gitignore | 1 + CMakeLists.txt | 1 + GenerateProjects.bat | 6 + cmake/FindDirectXTK.cmake | 8 +- compiler/cmake/NvWaveWorks.cmake | 24 +- compiler/cmake/sample_d3d11.cmake | 171 ++++ include/GFSDK_WaveWorks_Attributes.fxh | 2 +- sample/d3d11/Media/UI/DXUTShared.fx | 69 ++ sample/d3d11/Media/UI/Font.dds | Bin 0 -> 76128 bytes sample/d3d11/Media/UI/arrow.x | 1050 ++++++++++++++++++++ sample/d3d11/Media/UI/dxutcontrols.dds | Bin 0 -> 262272 bytes sample/d3d11/Media/ocean_surface_d3d11.fxo | Bin 0 -> 49887 bytes sample/d3d11/Media/sample_d3d11.fxo | Bin 0 -> 82321 bytes sample/d3d11/common.fx | 235 +++++ sample/d3d11/distance_field.cpp | 292 ++++++ sample/d3d11/distance_field.h | 80 ++ sample/d3d11/ocean_surface.cpp | 324 ++++++ sample/d3d11/ocean_surface.fx | 791 +++++++++++++++ sample/d3d11/ocean_surface.h | 89 ++ sample/d3d11/resource.h | 44 + sample/d3d11/sample.fx | 759 ++++++++++++++ sample/d3d11/sample_d3d11.cpp | 1307 +++++++++++++++++++++++++ sample/d3d11/sample_d3d11.rc | 106 ++ sample/d3d11/terrain.cpp | 1468 ++++++++++++++++++++++++++++ sample/d3d11/terrain.h | 172 ++++ sample/d3d11/util.cpp | 63 ++ src/Simulation.cpp | 268 +++-- test/d3d11/ocean_cufft_app.cpp | 21 +- test/d3d11/ocean_surface.cpp | 2 +- test/media/UI/Font.dds | Bin 0 -> 76128 bytes test/media/ocean_surface_d3d11.fxo | Bin 33379 -> 50313 bytes test/media/sample_d3d11.fxo | Bin 0 -> 82321 bytes 32 files changed, 7189 insertions(+), 164 deletions(-) create mode 100644 compiler/cmake/sample_d3d11.cmake create mode 100644 sample/d3d11/Media/UI/DXUTShared.fx create mode 100644 sample/d3d11/Media/UI/Font.dds create mode 100644 sample/d3d11/Media/UI/arrow.x create mode 100644 sample/d3d11/Media/UI/dxutcontrols.dds create mode 100644 sample/d3d11/Media/ocean_surface_d3d11.fxo create mode 100644 sample/d3d11/Media/sample_d3d11.fxo create mode 100644 sample/d3d11/common.fx create mode 100644 sample/d3d11/distance_field.cpp create mode 100644 sample/d3d11/distance_field.h create mode 100644 sample/d3d11/ocean_surface.cpp create mode 100644 sample/d3d11/ocean_surface.fx create mode 100644 sample/d3d11/ocean_surface.h create mode 100644 sample/d3d11/resource.h create mode 100644 sample/d3d11/sample.fx create mode 100644 sample/d3d11/sample_d3d11.cpp create mode 100644 sample/d3d11/sample_d3d11.rc create mode 100644 sample/d3d11/terrain.cpp create mode 100644 sample/d3d11/terrain.h create mode 100644 sample/d3d11/util.cpp create mode 100644 test/media/UI/Font.dds create mode 100644 test/media/sample_d3d11.fxo diff --git a/.gitignore b/.gitignore index 1596534..107ab8f 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,4 @@ test/gl2/win64/debug/cudart64_55.dll compiler/vc12win64-cmake/ src/generated/ bin/ +compiler/vc14win64-cmake/ diff --git a/CMakeLists.txt b/CMakeLists.txt index fd0787f..38b86a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -125,3 +125,4 @@ SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${FINAL_OUTPUT_DIR}) # Include all of the projects INCLUDE(compiler/cmake/NvWaveWorks.cmake) INCLUDE(compiler/cmake/test_d3d11.cmake) +INCLUDE(compiler/cmake/sample_d3d11.cmake) diff --git a/GenerateProjects.bat b/GenerateProjects.bat index 1c6ceb0..ad815e8 100644 --- a/GenerateProjects.bat +++ b/GenerateProjects.bat @@ -14,6 +14,12 @@ pushd compiler\vc12win64-cmake\ cmake ..\.. -G "Visual Studio 12 2013" -Ax64 -DTARGET_BUILD_PLATFORM=Windows -DWW_OUTPUT_DIR=bin\vc12win64-cmake\ popd +REM rmdir /s /q compiler\vc14win64-cmake\ +REM mkdir compiler\vc14win64-cmake\ +REM pushd compiler\vc14win64-cmake\ +REM cmake ..\.. -G "Visual Studio 14 2015" -Ax64 -DTARGET_BUILD_PLATFORM=Windows -DWW_OUTPUT_DIR=bin\vc14win64-cmake\ +REM popd + REM rmdir /s /q compiler\vc12-ps4-cmake\ REM mkdir compiler\vc12-ps4-cmake\ REM pushd compiler\vc12-ps4-cmake\ diff --git a/cmake/FindDirectXTK.cmake b/cmake/FindDirectXTK.cmake index 21ecbe3..e6466b4 100644 --- a/cmake/FindDirectXTK.cmake +++ b/cmake/FindDirectXTK.cmake @@ -8,10 +8,12 @@ else() set(DXTKARCH "Win32") endif() -find_path(DXTK_SDK_PATH DirectXHelpers.h - HINTS ${GW_DEPS_ROOT}/DirectXTK/Inc +find_path(DXTK_SDK_PATH Inc/DirectXHelpers.h + HINTS ${GW_DEPS_ROOT}/DirectXTK/ ) - + +MESSAGE("DXTK SDK ${DXTK_SDK_PATH}") + find_library(DXTK_LIBRARY_RELEASE NAMES DirectXTK PATHS ${DXTK_SDK_PATH}/Bin/*/${DXTKARCH}/Release) diff --git a/compiler/cmake/NvWaveWorks.cmake b/compiler/cmake/NvWaveWorks.cmake index d34f42a..87b62d8 100644 --- a/compiler/cmake/NvWaveWorks.cmake +++ b/compiler/cmake/NvWaveWorks.cmake @@ -24,7 +24,7 @@ IF(TARGET_BUILD_PLATFORM STREQUAL "Windows") # Use generator expressions to set config specific preprocessor definitions SET(WW_COMPILE_DEFS # Common to all configurations - _LIB;NVWAVEWORKS_LIB_DLL_EXPORTS;WIN32; + _LIB;NVWAVEWORKS_LIB_DLL_EXPORTS;WIN32;WAVEWORKS_ENABLE_DIRECTCOMPUTE $<$:PROFILE;_DEV;> $<$:NDEBUG;> @@ -201,20 +201,20 @@ CompileFXToH(${WW_SOURCE_DIR}/FFT_Simulation_DirectCompute_shader.hlsl ${GEN_SRC # Now the CUDA file # CUDA! -SET(CUDA_NVCC_FLAGS "-G -g -DWIN32 -D_WINDOWS -D_UNICODE -DUNICODE -D_LIB -gencode arch=compute_30,code=compute_30 -gencode arch=compute_20,code=sm_20") +# SET(CUDA_NVCC_FLAGS "-G -g -DWIN32 -D_WINDOWS -D_UNICODE -DUNICODE -D_LIB -gencode arch=compute_30,code=compute_30 -gencode arch=compute_20,code=sm_20") -CUDA_INCLUDE_DIRECTORIES( - ${CUDA_INCLUDE_DIRS} -) +# CUDA_INCLUDE_DIRECTORIES( + # ${CUDA_INCLUDE_DIRS} +# ) -SET(CUDA_PROPAGATE_HOST_FLAGS OFF) +# SET(CUDA_PROPAGATE_HOST_FLAGS OFF) -SET(CUDA_NVCC_FLAGS_DEBUG "--compiler-options=/Zi,/W4,/nologo,/Od,/MTd") -SET(CUDA_NVCC_FLAGS_RELEASE "-use_fast_math -DNDEBUG --compiler-options=/W4,/nologo,/O2,/GF,/GS-,/Gy,/fp:fast,/GR-,/MT") +# SET(CUDA_NVCC_FLAGS_DEBUG "--compiler-options=/Zi,/W4,/nologo,/Od,/MTd") +# SET(CUDA_NVCC_FLAGS_RELEASE "-use_fast_math -DNDEBUG --compiler-options=/W4,/nologo,/O2,/GF,/GS-,/Gy,/fp:fast,/GR-,/MT") -CUDA_COMPILE(GENERATED_CUDA_FILES_1 - ${WW_SOURCE_DIR}/FFT_Simulation_CUDA_kernel.cu -) +# CUDA_COMPILE(GENERATED_CUDA_FILES_1 + # ${WW_SOURCE_DIR}/FFT_Simulation_CUDA_kernel.cu +# ) ADD_LIBRARY(WaveWorks ${WW_LIBTYPE} ${WW_PLATFORM_SRC_FILES} @@ -229,7 +229,7 @@ ADD_LIBRARY(WaveWorks ${WW_LIBTYPE} ${GENERATED_HLSL_FILES} - ${GENERATED_CUDA_FILES_1} +# ${GENERATED_CUDA_FILES_1} # ${HLSL_FILES} # ${CUDA_FILES} diff --git a/compiler/cmake/sample_d3d11.cmake b/compiler/cmake/sample_d3d11.cmake new file mode 100644 index 0000000..5aa76b4 --- /dev/null +++ b/compiler/cmake/sample_d3d11.cmake @@ -0,0 +1,171 @@ +# +# Build test_d3d11 +# + +SET(GW_DEPS_ROOT $ENV{GW_DEPS_ROOT}) + +FIND_PACKAGE(DXUT REQUIRED) +FIND_PACKAGE(FX11 REQUIRED) +FIND_PACKAGE(DirectXTK REQUIRED) + +SET(SAMP_SOURCE_DIR ${PROJECT_SOURCE_DIR}/sample/d3d11) +SET(SHARED_CS_DIR ${PROJECT_SOURCE_DIR}/test/client-server) +SET(TL_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include) + +IF(TARGET_BUILD_PLATFORM STREQUAL "Windows") + + FIND_PACKAGE(DirectX REQUIRED) + + SET(WW_PLATFORM_INCLUDES + ) + + SET(WW_PLATFORM_SRC_FILES + ) + + + # Use generator expressions to set config specific preprocessor definitions + SET(WW_COMPILE_DEFS + # Common to all configurations + _LIB;NVWAVEWORKS_LIB_DLL_EXPORTS;WIN32; + + $<$:PROFILE;_DEV;> + $<$:NDEBUG;> + ) + + SET(WW_LIBTYPE SHARED) + +ELSEIF(TARGET_BUILD_PLATFORM STREQUAL "PS4") + + SET(WW_PLATFORM_INCLUDES + $ENV{SCE_ORBIS_SDK_DIR}/target/include + ) + + SET(WW_COMPILE_DEFS + + # Common to all configurations + _LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;PX_PHYSX_STATIC_LIB; + + $<$:_DEBUG;PX_DEBUG=1;PX_CHECKED=1;PX_SUPPORT_PVD=1;> + $<$:NDEBUG;PX_SUPPORT_PVD=0;> + ) + + SET(WW_LIBTYPE STATIC) + +ELSEIF(TARGET_BUILD_PLATFORM STREQUAL "XBoxOne") + SET(WW_PLATFORM_INCLUDES + ) + + # Use generator expressions to set config specific preprocessor definitions + SET(WW_COMPILE_DEFS + + # Common to all configurations + PX_PHYSX_CORE_EXPORTS;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WINAPI_FAMILY=WINAPI_FAMILY_TV_TITLE;PX_PHYSX_STATIC_LIB; + + $<$:_DEBUG;PX_DEBUG=1;PX_CHECKED=1;PX_SUPPORT_PVD=1;> + $<$:NDEBUG;PX_SUPPORT_PVD=0;> + ) + + SET(WW_LIBTYPE STATIC) + + +ELSEIF(TARGET_BUILD_PLATFORM STREQUAL "Unix") +ENDIF() + +SET(APP_FILES + ${SAMP_SOURCE_DIR}/distance_field.cpp + ${SAMP_SOURCE_DIR}/distance_field.h + + ${SAMP_SOURCE_DIR}/ocean_surface.cpp + ${SAMP_SOURCE_DIR}/ocean_surface.h + + ${SAMP_SOURCE_DIR}/sample_d3d11.cpp + + ${SAMP_SOURCE_DIR}/terrain.cpp + ${SAMP_SOURCE_DIR}/terrain.h + + ${SAMP_SOURCE_DIR}/util.cpp +) + +SET(FX_FILES + ${SAMP_SOURCE_DIR}/ocean_surface.fx + ${SAMP_SOURCE_DIR}/sample.fx +) + +INCLUDE(cmake/CompileFXToFXO.cmake) + +#ADD_CUSTOM_TARGET(fx ALL) + +ADD_CUSTOM_TARGET(samp_d3d11fx ALL) + +#FUNCTION(CompileFXToFXO FILE OUTPUT_FILE TARGET INCLUDE_DIR OPTIONS) +CompileFXToFXO(${SAMP_SOURCE_DIR}/ocean_surface.fx ${PROJECT_SOURCE_DIR}/test/media/ocean_surface_d3d11.fxo samp_d3d11fx ${TL_INCLUDE_DIR} /O3 /Tfx_5_0) +CompileFXToFXO(${SAMP_SOURCE_DIR}/sample.fx ${PROJECT_SOURCE_DIR}/test/media/sample_d3d11.fxo samp_d3d11fx ${TL_INCLUDE_DIR} /O3 /Tfx_5_0) + +ADD_EXECUTABLE(SampleD3D11 WIN32 + ${WW_PLATFORM_SRC_FILES} + + ${APP_FILES} + ${SHARED_CS_FILES} + ${FX_FILES} + +) + +SOURCE_GROUP("app" FILES ${APP_FILES}) +SOURCE_GROUP("fx" FILES ${FX_FILES}) +#SOURCE_GROUP("header" FILES ${H_FILES}) +#SOURCE_GROUP("hlsl" FILES ${HLSL_FILES}) +#SOURCE_GROUP("cuda" FILES ${CUDA_FILES}) + + + +# Target specific compile options + + +TARGET_INCLUDE_DIRECTORIES(SampleD3D11 + PRIVATE ${WW_PLATFORM_INCLUDES} + + PRIVATE ${TL_INCLUDE_DIR} + PRIVATE ${SHADER_CS_DIR} + PRIVATE ${SHARED_CS_DIR} + + PRIVATE ${DXUT_INCLUDE_DIRS} + PRIVATE ${FX11_INCLUDE_DIRS} + PRIVATE ${DXTK_INCLUDE_DIRS} +) + +TARGET_COMPILE_DEFINITIONS(SampleD3D11 + + # Common to all configurations + PRIVATE ${WW_COMPILE_DEFS} +) + + + +#TODO: Link flags + +IF(TARGET_BUILD_PLATFORM STREQUAL "Windows") + # Add linked libraries + TARGET_LINK_LIBRARIES(SampleD3D11 PUBLIC WaveWorks Ws2_32.lib comctl32.lib Usp10.lib ${CUDA_LIBRARIES} ${DirectX_DXGUID_LIBRARY} ${DirectX_D3D11_LIBRARY} ${DXUT_LIBRARIES} ${FX11_LIBRARIES} ${DXTK_LIBRARIES}) + + IF(CMAKE_CL_64) + SET(LIBPATH_SUFFIX "win64") + ELSE(CMAKE_CL_64) + SET(LIBPATH_SUFFIX "Win32") + ENDIF(CMAKE_CL_64) + + SET_TARGET_PROPERTIES(SampleD3D11 PROPERTIES + LINK_FLAGS_DEBUG "/MAP /DEBUG" + LINK_FLAGS_RELEASE "/MAP /INCREMENTAL:NO" + ) + +ELSEIF(TARGET_BUILD_PLATFORM STREQUAL "PS4") +# TARGET_LINK_LIBRARIES(SampleD3D11 PUBLIC LowLevel LowLevelAABB LowLevelCloth LowLevelDynamics LowLevelParticles SampleD3D11Common PxFoundation PxPvdSDK PxTask SceneQuery SimulationController) + +ELSEIF(TARGET_BUILD_PLATFORM STREQUAL "XBoxOne") + +# TARGET_LINK_LIBRARIES(SampleD3D11 PUBLIC LowLevel LowLevelAABB LowLevelCloth LowLevelDynamics LowLevelParticles SampleD3D11Common PxFoundation PxPvdSDK PxTask SceneQuery SimulationController) + +ELSEIF(TARGET_BUILD_PLATFORM STREQUAL "Unix") +ENDIF() + + diff --git a/include/GFSDK_WaveWorks_Attributes.fxh b/include/GFSDK_WaveWorks_Attributes.fxh index d887f8c..840243c 100644 --- a/include/GFSDK_WaveWorks_Attributes.fxh +++ b/include/GFSDK_WaveWorks_Attributes.fxh @@ -14,7 +14,7 @@ * 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 + * NVIDIA Corporation products are not authorized for use as critic * components in life support devices or systems without express written approval of * NVIDIA Corporation. * diff --git a/sample/d3d11/Media/UI/DXUTShared.fx b/sample/d3d11/Media/UI/DXUTShared.fx new file mode 100644 index 0000000..f6d590b --- /dev/null +++ b/sample/d3d11/Media/UI/DXUTShared.fx @@ -0,0 +1,69 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTShared.fx +// +// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + + +//-------------------------------------------------------------------------------------- +// Global variables +//-------------------------------------------------------------------------------------- +float4 g_MaterialDiffuseColor; // Material's diffuse color +float3 g_LightDir; // Light's direction in world space +float4x4 g_mWorld; // World matrix for object +float4x4 g_mWorldViewProjection; // World * View * Projection matrix + + + +//-------------------------------------------------------------------------------------- +// Vertex shader output structure +//-------------------------------------------------------------------------------------- +struct VS_OUTPUT +{ + float4 Position : POSITION; // vertex position + float4 Diffuse : COLOR0; // vertex diffuse color +}; + + +//-------------------------------------------------------------------------------------- +// This shader computes standard transform and lighting +//-------------------------------------------------------------------------------------- +VS_OUTPUT RenderWith1LightNoTextureVS( float4 vPos : POSITION, + float3 vNormal : NORMAL ) +{ + VS_OUTPUT Output; + + // Transform the position from object space to homogeneous projection space + Output.Position = mul(vPos, g_mWorldViewProjection); + + // Transform the normal from object space to world space + float3 vNormalWorldSpace; + vNormalWorldSpace = normalize(mul(vNormal, (float3x3)g_mWorld)); // normal (world space) + + // Compute simple directional lighting equation + Output.Diffuse.rgb = g_MaterialDiffuseColor * max(0,dot(vNormalWorldSpace, g_LightDir)); + Output.Diffuse.a = 1.0f; + + return Output; +} + + +//-------------------------------------------------------------------------------------- +float4 RenderWith1LightNoTexturePS( float4 Diffuse : COLOR0 ) : COLOR0 +{ + return Diffuse; +} + + +//-------------------------------------------------------------------------------------- +technique RenderWith1LightNoTexture +{ + pass P0 + { + VertexShader = compile vs_1_1 RenderWith1LightNoTextureVS(); + PixelShader = compile ps_1_1 RenderWith1LightNoTexturePS(); + } +} + diff --git a/sample/d3d11/Media/UI/Font.dds b/sample/d3d11/Media/UI/Font.dds new file mode 100644 index 0000000..37514f5 Binary files /dev/null and b/sample/d3d11/Media/UI/Font.dds differ diff --git a/sample/d3d11/Media/UI/arrow.x b/sample/d3d11/Media/UI/arrow.x new file mode 100644 index 0000000..da3c323 --- /dev/null +++ b/sample/d3d11/Media/UI/arrow.x @@ -0,0 +1,1050 @@ +xof 0303txt 0032 +template XSkinMeshHeader { + <3cf169ce-ff7c-44ab-93c0-f78f62d172e2> + WORD nMaxSkinWeightsPerVertex; + WORD nMaxSkinWeightsPerFace; + WORD nBones; +} + +template VertexDuplicationIndices { + + DWORD nIndices; + DWORD nOriginalVertices; + array DWORD indices[nIndices]; +} + +template SkinWeights { + <6f0d123b-bad2-4167-a0d0-80224f25fabb> + STRING transformNodeName; + DWORD nWeights; + array DWORD vertexIndices[nWeights]; + array FLOAT weights[nWeights]; + Matrix4x4 matrixOffset; +} + + +Frame Scene_Root { + + + FrameTransformMatrix { + 1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000;; + } + + Frame Arrow { + + + FrameTransformMatrix { + 0.004058,0.000000,0.000000,0.000000,0.000000,0.000000,0.004058,0.000000,0.000000,-0.004058,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000;; + } + + Frame Cylinder01 { + + + FrameTransformMatrix { + 1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000002,116.363640,0.000002,1.000000;; + } + + Frame { + + + FrameTransformMatrix { + 1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,-0.000000,0.000000,0.000003,1.000000;; + } + + Mesh { + 58; + 0.000000;0.000000;0.000000;, + 24.461134;0.000000;0.000000;, + 22.038719;-10.613288;0.000000;, + 15.251267;-19.124485;0.000000;, + 5.443114;-23.847843;0.000000;, + -5.443115;-23.847841;0.000000;, + -15.251268;-19.124485;0.000000;, + -22.038721;-10.613288;0.000000;, + -24.461134;0.000001;0.000000;, + -22.038719;10.613289;0.000000;, + -15.251266;19.124485;0.000000;, + -5.443113;23.847843;0.000000;, + 5.443115;23.847841;0.000000;, + 15.251268;19.124483;0.000000;, + 22.038721;10.613287;0.000000;, + 24.461134;0.000000;-140.000000;, + 22.038719;-10.613288;-140.000000;, + 15.251267;-19.124485;-140.000000;, + 5.443114;-23.847843;-140.000000;, + -5.443115;-23.847841;-140.000000;, + -15.251268;-19.124485;-140.000000;, + -22.038721;-10.613288;-140.000000;, + -24.461134;0.000001;-140.000000;, + -22.038719;10.613289;-140.000000;, + -15.251266;19.124485;-140.000000;, + -5.443113;23.847843;-140.000000;, + 5.443115;23.847841;-140.000000;, + 15.251268;19.124483;-140.000000;, + 22.038721;10.613287;-140.000000;, + 0.000000;0.000000;-140.000000;, + 24.461134;0.000000;0.000000;, + 22.038719;-10.613288;0.000000;, + 15.251267;-19.124485;0.000000;, + 5.443114;-23.847843;0.000000;, + -5.443115;-23.847841;0.000000;, + -15.251268;-19.124485;0.000000;, + -22.038721;-10.613288;0.000000;, + -24.461134;0.000001;0.000000;, + -22.038719;10.613289;0.000000;, + -15.251266;19.124485;0.000000;, + -5.443113;23.847843;0.000000;, + 5.443115;23.847841;0.000000;, + 15.251268;19.124483;0.000000;, + 22.038721;10.613287;0.000000;, + 24.461134;0.000000;-140.000000;, + 22.038719;-10.613288;-140.000000;, + 15.251267;-19.124485;-140.000000;, + 5.443114;-23.847843;-140.000000;, + -5.443115;-23.847841;-140.000000;, + -15.251268;-19.124485;-140.000000;, + -22.038721;-10.613288;-140.000000;, + -24.461134;0.000001;-140.000000;, + -22.038719;10.613289;-140.000000;, + -15.251266;19.124485;-140.000000;, + -5.443113;23.847843;-140.000000;, + 5.443115;23.847841;-140.000000;, + 15.251268;19.124483;-140.000000;, + 22.038721;10.613287;-140.000000;; + 56; + 3;0,2,1;, + 3;0,3,2;, + 3;0,4,3;, + 3;0,5,4;, + 3;0,6,5;, + 3;0,7,6;, + 3;0,8,7;, + 3;0,9,8;, + 3;0,10,9;, + 3;0,11,10;, + 3;0,12,11;, + 3;0,13,12;, + 3;0,14,13;, + 3;0,1,14;, + 3;30,16,15;, + 3;30,31,16;, + 3;31,17,16;, + 3;31,32,17;, + 3;32,18,17;, + 3;32,33,18;, + 3;33,19,18;, + 3;33,34,19;, + 3;34,20,19;, + 3;34,35,20;, + 3;35,21,20;, + 3;35,36,21;, + 3;36,22,21;, + 3;36,37,22;, + 3;37,23,22;, + 3;37,38,23;, + 3;38,24,23;, + 3;38,39,24;, + 3;39,25,24;, + 3;39,40,25;, + 3;40,26,25;, + 3;40,41,26;, + 3;41,27,26;, + 3;41,42,27;, + 3;42,28,27;, + 3;42,43,28;, + 3;43,15,28;, + 3;43,30,15;, + 3;29,44,45;, + 3;29,45,46;, + 3;29,46,47;, + 3;29,47,48;, + 3;29,48,49;, + 3;29,49,50;, + 3;29,50,51;, + 3;29,51,52;, + 3;29,52,53;, + 3;29,53,54;, + 3;29,54,55;, + 3;29,55,56;, + 3;29,56,57;, + 3;29,57,44;; + + MeshNormals { + 58; + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.000000;0.000000;1.000000;, + 0.997118;0.075862;0.000000;, + 0.931288;-0.364284;0.000000;, + 0.681004;-0.732279;0.000000;, + 0.295840;-0.955238;0.000000;, + -0.147920;-0.988999;0.000000;, + -0.562382;-0.826878;0.000000;, + -0.865457;-0.500983;0.000000;, + -0.997118;-0.075862;0.000000;, + -0.931288;0.364284;0.000000;, + -0.681004;0.732279;0.000000;, + -0.295840;0.955238;0.000000;, + 0.147920;0.988999;0.000000;, + 0.562382;0.826878;0.000000;, + 0.865457;0.500983;0.000000;, + 0.000000;0.000000;-1.000000;, + 0.997118;-0.075862;0.000000;, + 0.865457;-0.500983;0.000000;, + 0.562382;-0.826878;0.000000;, + 0.147920;-0.988999;0.000000;, + -0.295840;-0.955238;0.000000;, + -0.681004;-0.732279;0.000000;, + -0.931288;-0.364284;0.000000;, + -0.997118;0.075862;0.000000;, + -0.865457;0.500983;0.000000;, + -0.562382;0.826878;0.000000;, + -0.147920;0.988999;0.000000;, + 0.295840;0.955238;0.000000;, + 0.681004;0.732279;0.000000;, + 0.931288;0.364284;0.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;; + 56; + 3;0,2,1;, + 3;0,3,2;, + 3;0,4,3;, + 3;0,5,4;, + 3;0,6,5;, + 3;0,7,6;, + 3;0,8,7;, + 3;0,9,8;, + 3;0,10,9;, + 3;0,11,10;, + 3;0,12,11;, + 3;0,13,12;, + 3;0,14,13;, + 3;0,1,14;, + 3;30,16,15;, + 3;30,31,16;, + 3;31,17,16;, + 3;31,32,17;, + 3;32,18,17;, + 3;32,33,18;, + 3;33,19,18;, + 3;33,34,19;, + 3;34,20,19;, + 3;34,35,20;, + 3;35,21,20;, + 3;35,36,21;, + 3;36,22,21;, + 3;36,37,22;, + 3;37,23,22;, + 3;37,38,23;, + 3;38,24,23;, + 3;38,39,24;, + 3;39,25,24;, + 3;39,40,25;, + 3;40,26,25;, + 3;40,41,26;, + 3;41,27,26;, + 3;41,42,27;, + 3;42,28,27;, + 3;42,43,28;, + 3;43,15,28;, + 3;43,30,15;, + 3;29,44,45;, + 3;29,45,46;, + 3;29,46,47;, + 3;29,47,48;, + 3;29,48,49;, + 3;29,49,50;, + 3;29,50,51;, + 3;29,51,52;, + 3;29,52,53;, + 3;29,53,54;, + 3;29,54,55;, + 3;29,55,56;, + 3;29,56,57;, + 3;29,57,44;; + } + + VertexDuplicationIndices { + 58; + 30; + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28; + } + + MeshMaterialList { + 1; + 56; + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0; + + Material { + 1.000000;1.000000;1.000000;1.000000;; + 0.000000; + 1.000000;1.000000;1.000000;; + 0.000000;0.000000;0.000000;; + } + } + } + } + } + + Frame Cone01 { + + + FrameTransformMatrix { + 1.000000,0.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-1.000000,0.000000,0.000000,0.000000,116.363640,0.000000,1.000000;; + } + + Frame { + + + FrameTransformMatrix { + 1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000003,1.000000;; + } + + Mesh { + 98; + 0.000000;0.000000;0.000000;, + 58.922840;0.000000;0.000000;, + 56.915092;15.250354;0.000000;, + 51.028675;29.461420;0.000000;, + 41.664738;41.664742;0.000000;, + 29.461418;51.028679;0.000000;, + 15.250351;56.915092;0.000000;, + -0.000003;58.922840;0.000000;, + -15.250356;56.915092;0.000000;, + -29.461424;51.028675;0.000000;, + -41.664742;41.664738;0.000000;, + -51.028679;29.461416;0.000000;, + -56.915092;15.250349;0.000000;, + -58.922840;-0.000005;0.000000;, + -56.915092;-15.250359;0.000000;, + -51.028675;-29.461426;0.000000;, + -41.664734;-41.664745;0.000000;, + -29.461414;-51.028679;0.000000;, + -15.250346;-56.915096;0.000000;, + 0.000008;-58.922840;0.000000;, + 15.250361;-56.915092;0.000000;, + 29.461428;-51.028671;0.000000;, + 41.664745;-41.664734;0.000000;, + 51.028683;-29.461412;0.000000;, + 56.915096;-15.250343;0.000000;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 58.922840;0.000000;0.000000;, + 56.915092;15.250354;0.000000;, + 51.028675;29.461420;0.000000;, + 41.664738;41.664742;0.000000;, + 29.461418;51.028679;0.000000;, + 15.250351;56.915092;0.000000;, + -0.000003;58.922840;0.000000;, + -15.250356;56.915092;0.000000;, + -29.461424;51.028675;0.000000;, + -41.664742;41.664738;0.000000;, + -51.028679;29.461416;0.000000;, + -56.915092;15.250349;0.000000;, + -58.922840;-0.000005;0.000000;, + -56.915092;-15.250359;0.000000;, + -51.028675;-29.461426;0.000000;, + -41.664734;-41.664745;0.000000;, + -29.461414;-51.028679;0.000000;, + -15.250346;-56.915096;0.000000;, + 0.000008;-58.922840;0.000000;, + 15.250361;-56.915092;0.000000;, + 29.461428;-51.028671;0.000000;, + 41.664745;-41.664734;0.000000;, + 51.028683;-29.461412;0.000000;, + 56.915096;-15.250343;0.000000;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;, + 0.000000;0.000000;116.363632;; + 96; + 3;0,2,1;, + 3;0,3,2;, + 3;0,4,3;, + 3;0,5,4;, + 3;0,6,5;, + 3;0,7,6;, + 3;0,8,7;, + 3;0,9,8;, + 3;0,10,9;, + 3;0,11,10;, + 3;0,12,11;, + 3;0,13,12;, + 3;0,14,13;, + 3;0,15,14;, + 3;0,16,15;, + 3;0,17,16;, + 3;0,18,17;, + 3;0,19,18;, + 3;0,20,19;, + 3;0,21,20;, + 3;0,22,21;, + 3;0,23,22;, + 3;0,24,23;, + 3;0,1,24;, + 3;50,26,25;, + 3;50,51,26;, + 3;51,27,26;, + 3;51,52,27;, + 3;52,28,27;, + 3;52,53,28;, + 3;53,29,28;, + 3;53,54,29;, + 3;54,30,29;, + 3;54,55,30;, + 3;55,31,30;, + 3;55,56,31;, + 3;56,32,31;, + 3;56,57,32;, + 3;57,33,32;, + 3;57,58,33;, + 3;58,34,33;, + 3;58,59,34;, + 3;59,35,34;, + 3;59,60,35;, + 3;60,36,35;, + 3;60,61,36;, + 3;61,37,36;, + 3;61,62,37;, + 3;62,38,37;, + 3;62,63,38;, + 3;63,39,38;, + 3;63,64,39;, + 3;64,40,39;, + 3;64,65,40;, + 3;65,41,40;, + 3;65,66,41;, + 3;66,42,41;, + 3;66,67,42;, + 3;67,43,42;, + 3;67,68,43;, + 3;68,44,43;, + 3;68,69,44;, + 3;69,45,44;, + 3;69,70,45;, + 3;70,46,45;, + 3;70,71,46;, + 3;71,47,46;, + 3;71,72,47;, + 3;72,48,47;, + 3;72,73,48;, + 3;73,25,48;, + 3;73,50,25;, + 3;49,74,75;, + 3;49,75,76;, + 3;49,76,77;, + 3;49,77,78;, + 3;49,78,79;, + 3;49,79,80;, + 3;49,80,81;, + 3;49,81,82;, + 3;49,82,83;, + 3;49,83,84;, + 3;49,84,85;, + 3;49,85,86;, + 3;49,86,87;, + 3;49,87,88;, + 3;49,88,89;, + 3;49,89,90;, + 3;49,90,91;, + 3;49,91,92;, + 3;49,92,93;, + 3;49,93,94;, + 3;49,94,95;, + 3;49,95,96;, + 3;49,96,97;, + 3;49,97,74;; + + MeshNormals { + 98; + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.000000;0.000000;-1.000000;, + 0.886052;-0.116651;0.448669;, + 0.886052;0.116651;0.448669;, + 0.825669;0.342004;0.448669;, + 0.709018;0.544049;0.448669;, + 0.544049;0.709018;0.448669;, + 0.342003;0.825669;0.448669;, + 0.116651;0.886052;0.448669;, + -0.116651;0.886052;0.448669;, + -0.342003;0.825669;0.448669;, + -0.544049;0.709018;0.448669;, + -0.709018;0.544049;0.448669;, + -0.825669;0.342003;0.448669;, + -0.886052;0.116651;0.448669;, + -0.886052;-0.116651;0.448669;, + -0.825669;-0.342003;0.448669;, + -0.709018;-0.544049;0.448669;, + -0.544049;-0.709018;0.448669;, + -0.342003;-0.825669;0.448669;, + -0.116651;-0.886052;0.448669;, + 0.116651;-0.886052;0.448669;, + 0.342004;-0.825669;0.448669;, + 0.544049;-0.709018;0.448669;, + 0.709018;-0.544049;0.448669;, + 0.825669;-0.342003;0.448669;, + 1.000000;0.000000;0.000000;, + 0.892143;0.000000;0.451753;, + 0.861744;0.230904;0.451753;, + 0.772619;0.446072;0.451753;, + 0.630840;0.630840;0.451753;, + 0.446072;0.772619;0.451753;, + 0.230904;0.861744;0.451753;, + 0.000000;0.892143;0.451753;, + -0.230904;0.861744;0.451753;, + -0.446072;0.772619;0.451753;, + -0.630840;0.630840;0.451753;, + -0.772619;0.446071;0.451753;, + -0.861744;0.230904;0.451753;, + -0.892143;-0.000000;0.451753;, + -0.861744;-0.230904;0.451753;, + -0.772619;-0.446072;0.451753;, + -0.630840;-0.630841;0.451753;, + -0.446072;-0.772619;0.451753;, + -0.230904;-0.861744;0.451753;, + 0.000000;-0.892143;0.451753;, + 0.230904;-0.861744;0.451753;, + 0.446072;-0.772619;0.451753;, + 0.630840;-0.630840;0.451753;, + 0.772619;-0.446071;0.451753;, + 0.861744;-0.230903;0.451753;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;, + 1.000000;0.000000;0.000000;; + 96; + 3;0,2,1;, + 3;0,3,2;, + 3;0,4,3;, + 3;0,5,4;, + 3;0,6,5;, + 3;0,7,6;, + 3;0,8,7;, + 3;0,9,8;, + 3;0,10,9;, + 3;0,11,10;, + 3;0,12,11;, + 3;0,13,12;, + 3;0,14,13;, + 3;0,15,14;, + 3;0,16,15;, + 3;0,17,16;, + 3;0,18,17;, + 3;0,19,18;, + 3;0,20,19;, + 3;0,21,20;, + 3;0,22,21;, + 3;0,23,22;, + 3;0,24,23;, + 3;0,1,24;, + 3;50,26,25;, + 3;50,51,26;, + 3;51,27,26;, + 3;51,52,27;, + 3;52,28,27;, + 3;52,53,28;, + 3;53,29,28;, + 3;53,54,29;, + 3;54,30,29;, + 3;54,55,30;, + 3;55,31,30;, + 3;55,56,31;, + 3;56,32,31;, + 3;56,57,32;, + 3;57,33,32;, + 3;57,58,33;, + 3;58,34,33;, + 3;58,59,34;, + 3;59,35,34;, + 3;59,60,35;, + 3;60,36,35;, + 3;60,61,36;, + 3;61,37,36;, + 3;61,62,37;, + 3;62,38,37;, + 3;62,63,38;, + 3;63,39,38;, + 3;63,64,39;, + 3;64,40,39;, + 3;64,65,40;, + 3;65,41,40;, + 3;65,66,41;, + 3;66,42,41;, + 3;66,67,42;, + 3;67,43,42;, + 3;67,68,43;, + 3;68,44,43;, + 3;68,69,44;, + 3;69,45,44;, + 3;69,70,45;, + 3;70,46,45;, + 3;70,71,46;, + 3;71,47,46;, + 3;71,72,47;, + 3;72,48,47;, + 3;72,73,48;, + 3;73,25,48;, + 3;73,50,25;, + 3;49,74,75;, + 3;49,75,76;, + 3;49,76,77;, + 3;49,77,78;, + 3;49,78,79;, + 3;49,79,80;, + 3;49,80,81;, + 3;49,81,82;, + 3;49,82,83;, + 3;49,83,84;, + 3;49,84,85;, + 3;49,85,86;, + 3;49,86,87;, + 3;49,87,88;, + 3;49,88,89;, + 3;49,89,90;, + 3;49,90,91;, + 3;49,91,92;, + 3;49,92,93;, + 3;49,93,94;, + 3;49,94,95;, + 3;49,95,96;, + 3;49,96,97;, + 3;49,97,74;; + } + + VertexDuplicationIndices { + 98; + 50; + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48; + } + + MeshMaterialList { + 1; + 96; + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0; + + Material { + 1.000000;1.000000;1.000000;1.000000;; + 0.000000; + 1.000000;1.000000;1.000000;; + 0.000000;0.000000;0.000000;; + } + } + } + } + } + } +} \ No newline at end of file diff --git a/sample/d3d11/Media/UI/dxutcontrols.dds b/sample/d3d11/Media/UI/dxutcontrols.dds new file mode 100644 index 0000000..b5f52e1 Binary files /dev/null and b/sample/d3d11/Media/UI/dxutcontrols.dds differ diff --git a/sample/d3d11/Media/ocean_surface_d3d11.fxo b/sample/d3d11/Media/ocean_surface_d3d11.fxo new file mode 100644 index 0000000..0f2430f Binary files /dev/null and b/sample/d3d11/Media/ocean_surface_d3d11.fxo differ diff --git a/sample/d3d11/Media/sample_d3d11.fxo b/sample/d3d11/Media/sample_d3d11.fxo new file mode 100644 index 0000000..9040c57 Binary files /dev/null and b/sample/d3d11/Media/sample_d3d11.fxo differ diff --git a/sample/d3d11/common.fx b/sample/d3d11/common.fx new file mode 100644 index 0000000..fab5e59 --- /dev/null +++ b/sample/d3d11/common.fx @@ -0,0 +1,235 @@ +// 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. +// + +cbuffer QuadObject +{ + static const float2 QuadVertices[4] = + { + {-1.0, -1.0}, + { 1.0, -1.0}, + {-1.0, 1.0}, + { 1.0, 1.0} + }; + + static const float2 QuadTexCoordinates[4] = + { + {0.0, 1.0}, + {1.0, 1.0}, + {0.0, 0.0}, + {1.0, 0.0} + }; +} + +SamplerState SamplerPointClamp +{ + Filter = MIN_MAG_MIP_POINT; + AddressU = Clamp; + AddressV = Clamp; +}; + +SamplerState SamplerLinearClamp +{ + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Clamp; + AddressV = Clamp; +}; + +SamplerState SamplerLinearWrap +{ + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Wrap; + AddressV = Wrap; +}; + +SamplerState SamplerAnisotropicWrap +{ + Filter = ANISOTROPIC; + AddressU = Wrap; + AddressV = Wrap; + MaxAnisotropy = 16; +}; + +SamplerState SamplerCube +{ + Filter = MIN_MAG_MIP_POINT; + AddressU = Clamp; + AddressV = Clamp; + AddressW = Clamp; +}; + +SamplerState SamplerLinearMirror +{ + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Mirror; + AddressV = Mirror; +}; + +SamplerState SamplerLinearBorderBlack +{ + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Border; + AddressV = Border; + AddressW = Border; + BorderColor = float4(0, 0, 0, 0); +}; + +SamplerState SamplerLinearBorder +{ + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Border; + AddressV = Border; +}; + +SamplerComparisonState SamplerBackBufferDepth +{ + Filter = COMPARISON_MIN_MAG_LINEAR_MIP_POINT; + AddressU = Border; + AddressV = Border; + BorderColor = float4(1, 1, 1, 1); + ComparisonFunc = LESS_EQUAL; +}; + +SamplerComparisonState SamplerDepthAnisotropic +{ + Filter = COMPARISON_ANISOTROPIC; + AddressU = Border; + AddressV = Border; + ComparisonFunc = LESS; + BorderColor = float4(1, 1, 1, 0); + MaxAnisotropy = 16; +}; + +RasterizerState CullBack +{ + CullMode = Back; + FrontCounterClockwise = TRUE; +}; + +RasterizerState CullBackMS +{ + CullMode = Back; + FrontCounterClockwise = TRUE; + MultisampleEnable = TRUE; +}; + +RasterizerState CullFrontNoClip +{ + CullMode = Front; + FrontCounterClockwise = TRUE; + DepthClipEnable = FALSE; +}; + +RasterizerState CullFrontMS +{ + CullMode = Front; + FrontCounterClockwise = TRUE; + MultisampleEnable = TRUE; +}; + +RasterizerState NoCull +{ + CullMode = NONE; +}; + +RasterizerState NoCullMS +{ + CullMode = NONE; + MultisampleEnable = TRUE; +}; + +RasterizerState Wireframe +{ + CullMode = NONE; + FillMode = WIREFRAME; +}; + +RasterizerState WireframeMS +{ + CullMode = NONE; + FillMode = WIREFRAME; + MultisampleEnable = TRUE; +}; + +DepthStencilState DepthNormal +{ + DepthEnable = TRUE; + DepthWriteMask = ALL; + DepthFunc = LESS_EQUAL; + StencilEnable = FALSE; +}; + +DepthStencilState NoDepthStencil +{ + DepthEnable = FALSE; + StencilEnable = FALSE; +}; + +DepthStencilState DepthAlways +{ + DepthEnable = TRUE; + DepthWriteMask = ALL; + DepthFunc = ALWAYS; + StencilEnable = FALSE; +}; + + +BlendState NoBlending +{ + BlendEnable[0] = FALSE; +}; + +BlendState Translucent +{ + BlendEnable[0] = TRUE; + RenderTargetWriteMask[0] = 0xF; + + SrcBlend = SRC_ALPHA; + DestBlend = INV_SRC_ALPHA; + BlendOp = Add; +}; + + +float4 ColorPS(uniform float4 color) : SV_Target +{ + return color; +} + +technique11 Default +{ + pass p0 + { + SetRasterizerState(NoCull); + SetDepthStencilState(DepthNormal, 0); + SetBlendState(NoBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF); + SetVertexShader(NULL); + SetHullShader(NULL); + SetDomainShader(NULL); + SetGeometryShader(NULL); + SetPixelShader(NULL); + } +} diff --git a/sample/d3d11/distance_field.cpp b/sample/d3d11/distance_field.cpp new file mode 100644 index 0000000..ad132ec --- /dev/null +++ b/sample/d3d11/distance_field.cpp @@ -0,0 +1,292 @@ +// 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 +#include "DXUT.h" +#include "SDKMisc.h" +#include "distance_field.h" + +#include "GFSDK_WaveWorks_D3D_Util.h" + +#pragma warning(disable:4127) + +extern HRESULT LoadFile(LPCTSTR FileName, ID3DXBuffer** ppBuffer); + +const unsigned int kTopDownDataResolution = 256; + +DistanceField::DistanceField( CTerrain* const pTerrainRenderer ) + : m_pTerrainRenderer( pTerrainRenderer ) + , m_viewDirectionWS( 0, -1, 0 ) + , m_pTopDownDataSRV( NULL ) + , m_pTopDownDataRTV( NULL ) + , m_pTopDownDataTexture( NULL ) + , m_pStagingTexture( NULL ) + , m_shouldGenerateDataTexture( true ) +{ +} + +DistanceField::~DistanceField() +{ + SAFE_RELEASE( m_pTopDownDataSRV ); + SAFE_RELEASE( m_pTopDownDataRTV ); + SAFE_RELEASE( m_pTopDownDataTexture ); + SAFE_RELEASE( m_pStagingTexture ); +} + +HRESULT DistanceField::Init( ID3D11Device* const pDevice ) +{ + HRESULT hr = S_OK; + + if( NULL == m_pTopDownDataTexture ) + { + D3D11_TEXTURE2D_DESC textureDesc; + ZeroMemory(&textureDesc, sizeof(textureDesc)); + + textureDesc.ArraySize = 1; + textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; + textureDesc.CPUAccessFlags = 0; + textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + textureDesc.Height = kTopDownDataResolution; + textureDesc.Width = kTopDownDataResolution; + textureDesc.MipLevels = 1; + textureDesc.MiscFlags = 0; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Usage = D3D11_USAGE_DEFAULT; + + V_RETURN( pDevice->CreateTexture2D( &textureDesc, nullptr, &m_pTopDownDataTexture ) ); + + + textureDesc.ArraySize = 1; + textureDesc.BindFlags = 0; + textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; + textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + textureDesc.Height = kTopDownDataResolution; + textureDesc.Width = kTopDownDataResolution; + textureDesc.MipLevels = 1; + textureDesc.MiscFlags = 0; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Usage = D3D11_USAGE_STAGING; + + V_RETURN( pDevice->CreateTexture2D( &textureDesc, nullptr, &m_pStagingTexture ) ); + + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + ZeroMemory( &srvDesc, sizeof( srvDesc ) ); + srvDesc.Format = textureDesc.Format; + srvDesc.Texture2D.MipLevels = 1; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + + V_RETURN( pDevice->CreateShaderResourceView( m_pTopDownDataTexture, &srvDesc, &m_pTopDownDataSRV ) ); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + ZeroMemory( &rtvDesc, sizeof( rtvDesc ) ); + rtvDesc.Format = textureDesc.Format; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + + V_RETURN( pDevice->CreateRenderTargetView( m_pTopDownDataTexture, &rtvDesc, &m_pTopDownDataRTV ) ); + } + return S_OK; +} + +void DistanceField::GenerateDataTexture( ID3D11DeviceContext* pDC ) +{ + if( !m_shouldGenerateDataTexture ) return; + + renderTopDownData( pDC, D3DXVECTOR3( 250, 0, 250 ) ); + generateDistanceField( pDC ); + + m_shouldGenerateDataTexture = false; +} + +void DistanceField::renderTopDownData( ID3D11DeviceContext* pDC, const D3DXVECTOR3& eyePositionWS ) +{ + const float kHeightAboveSeaLevel = 300; + const float kMinHeightBelowSeaLevel = 20; + + D3D11_VIEWPORT vp; + UINT NumViewports = 1; + pDC->RSGetViewports(&NumViewports,&vp); + + ID3D11RenderTargetView* pRenderTarget; + ID3D11DepthStencilView* pDepthBuffer; + pDC->OMGetRenderTargets( 1, &pRenderTarget, &pDepthBuffer ); + + // Set the viewport + D3D11_VIEWPORT viewport; + ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT)); + + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Height = kTopDownDataResolution; + viewport.Width = kTopDownDataResolution; + + pDC->RSSetViewports(1, &viewport); + pDC->ClearRenderTargetView( m_pTopDownDataRTV, D3DXCOLOR( 0.0f, -kMinHeightBelowSeaLevel, 0.0f, 0.0f ) ); + pDC->OMSetRenderTargetsAndUnorderedAccessViews( 1, &m_pTopDownDataRTV, NULL, 0, 0, NULL, NULL ); + + m_topDownViewPositionWS = D3DXVECTOR3( eyePositionWS.x, kHeightAboveSeaLevel, eyePositionWS.z ); + + const float kOrthoSize = 700; + D3DXMatrixOrthoLH( &m_viewToProjectionMatrix, kOrthoSize, kOrthoSize, 0.3f, kHeightAboveSeaLevel + kMinHeightBelowSeaLevel ); + const D3DXVECTOR3 up = D3DXVECTOR3( 0, 0, 1 ); + D3DXMatrixLookAtLH( &m_worldToViewMatrix, &m_topDownViewPositionWS, &eyePositionWS, &up); + + m_pTerrainRenderer->RenderTerrainToHeightField( pDC, m_worldToViewMatrix, m_viewToProjectionMatrix, m_topDownViewPositionWS, m_viewDirectionWS ); + + pDC->RSSetViewports(NumViewports, &vp); + pDC->OMSetRenderTargetsAndUnorderedAccessViews( 1, &pRenderTarget, pDepthBuffer, 0, 0, NULL, NULL ); + SAFE_RELEASE( pRenderTarget ); + SAFE_RELEASE( pDepthBuffer ); +} + +void DistanceField::generateDistanceField( ID3D11DeviceContext* pDC ) +{ + float* pTextureReadData = (float*)malloc(kTopDownDataResolution * kTopDownDataResolution * 4*sizeof(float)); + + pDC->CopyResource( m_pStagingTexture, m_pTopDownDataTexture ); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + pDC->Map( m_pStagingTexture, 0, D3D11_MAP_READ_WRITE, 0, &mappedResource ); + { + memcpy( pTextureReadData, mappedResource.pData, kTopDownDataResolution * kTopDownDataResolution * 4*sizeof(float)); + + float* pTextureWriteData = reinterpret_cast( mappedResource.pData ); + + // Calculating the distance field to be stored in R channel + // Seabed level is stored in G channel, leaving it intact + for( unsigned int x=0 ; xUnmap( m_pStagingTexture, 0 ); + + pDC->CopyResource( m_pTopDownDataTexture, m_pStagingTexture ); + free(pTextureReadData); +} + +bool DistanceField::checkPixel( float* pTextureData, const int cx, const int cy, const int dx, const int dy) const +{ + const int x = (cx+dx) < 0 ? 0 : (cx+dx) >= kTopDownDataResolution ? (kTopDownDataResolution-1) : (cx+dx); + const int y = (cy+dy) < 0 ? 0 : (cy+dy) >= kTopDownDataResolution ? (kTopDownDataResolution-1) : (cy+dy); + + const int idx = (x * kTopDownDataResolution + y) * 4 + 0; // Red channel + + return pTextureData[ idx ] > 0.0f; +} + +float DistanceField::FindNearestPixel( float* pTextureData, const int cx, const int cy, float& gradientX, float& gradientY) +{ + const int kMaxDistance = 20; + float minDistance = kMaxDistance; + bool originPositive = checkPixel( pTextureData, cx, cy, 0, 0); + bool resultPositive; + for( int dx = -kMaxDistance ; dx <= kMaxDistance ; dx++ ) + { + for( int dy = -kMaxDistance + 1 ; dy < kMaxDistance ; dy++ ) + { + resultPositive = checkPixel( pTextureData, cx, cy, dx, dy); + float pixelDistance = sqrtf((float)(dx * dx + dy * dy)); + if((originPositive != resultPositive) && (pixelDistance < minDistance)) + { + minDistance = pixelDistance; + gradientX = dx / (pixelDistance+0.001f); + gradientY = dy/ (pixelDistance+0.001f); + if(!originPositive) + { + gradientX=-gradientX; + gradientY=-gradientY; + + } + } + } + } + return originPositive ? -minDistance/kMaxDistance : minDistance/kMaxDistance; +} + +void DistanceField::GetWorldToTopDownTextureMatrix( D3DXMATRIX& worldToTopDownMatrix ) +{ + worldToTopDownMatrix = m_worldToViewMatrix * m_viewToProjectionMatrix; +} \ No newline at end of file diff --git a/sample/d3d11/distance_field.h b/sample/d3d11/distance_field.h new file mode 100644 index 0000000..bbc217d --- /dev/null +++ b/sample/d3d11/distance_field.h @@ -0,0 +1,80 @@ +// 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. +// + +#ifndef _SHORELINE_INTERACTION_H +#define _SHORELINE_INTERACTION_H + +#include "terrain.h" +#include + +#include + +struct DistanceField +{ + explicit DistanceField( CTerrain* const pTerrainRenderer ); + ~DistanceField(); + + HRESULT Init( ID3D11Device* const pDevice ); + + // --------------------------------- Accessors ----------------------------------- + ID3D11ShaderResourceView* GetDataTextureSRV() const { return m_pTopDownDataSRV; } + void GetWorldToTopDownTextureMatrix( XMMATRIX& worldToTopDownMatrix ); + + // --------------------------------- Rendering routines ----------------------------------- + void GenerateDataTexture(ID3D11DeviceContext* pDC ); + +private: + DistanceField() + : m_pTerrainRenderer( NULL ) + {} + DistanceField& operator=(const DistanceField &tmp); + + // ---------------------------------- Not owned refrences ------------------------------------ + CTerrain* const m_pTerrainRenderer; // Not owned. + + // ---------------------------------- GPU shading data ------------------------------------ + ID3D11ShaderResourceView* m_pTopDownDataSRV; + ID3D11RenderTargetView* m_pTopDownDataRTV; + ID3D11Texture2D* m_pTopDownDataTexture; + ID3D11Texture2D* m_pStagingTexture; + + // ---------------------------------- Top down camera data ------------------------------------ + XMVECTOR m_topDownViewPositionWS; + XMVECTOR m_viewDirectionWS; + XMMATRIX m_worldToViewMatrix; + XMMATRIX m_viewToProjectionMatrix; + + bool m_shouldGenerateDataTexture; + + void renderTopDownData(ID3D11DeviceContext* pDC, const XMVECTOR& eyePositionWS); + void generateDistanceField( ID3D11DeviceContext* pDC ); + bool checkPixel( float* pTextureData, const int cx, const int cy, const int dx, const int dy) const; + float FindNearestPixel( float* pTextureData, const int cx, const int cy, float&, float&); +}; + +#endif // _SHORELINE_INTERACTION_H 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); +} diff --git a/sample/d3d11/ocean_surface.fx b/sample/d3d11/ocean_surface.fx new file mode 100644 index 0000000..c34c65e --- /dev/null +++ b/sample/d3d11/ocean_surface.fx @@ -0,0 +1,791 @@ +// 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. +// + +#define GFSDK_WAVEWORKS_SM5 +#define GFSDK_WAVEWORKS_USE_TESSELLATION + +#define GFSDK_WAVEWORKS_DECLARE_GEOM_VS_CONSTANT(Type,Label,Regoff) Type Label; +#define GFSDK_WAVEWORKS_BEGIN_GEOM_VS_CBUFFER(Label) cbuffer Label { +#define GFSDK_WAVEWORKS_END_GEOM_VS_CBUFFER }; + +#define GFSDK_WAVEWORKS_DECLARE_GEOM_HS_CONSTANT(Type,Label,Regoff) Type Label; +#define GFSDK_WAVEWORKS_BEGIN_GEOM_HS_CBUFFER(Label) cbuffer Label { +#define GFSDK_WAVEWORKS_END_GEOM_HS_CBUFFER }; + +#include "GFSDK_WaveWorks_Quadtree.fxh" + +#define GFSDK_WAVEWORKS_DECLARE_ATTR_DS_CONSTANT(Type,Label,Regoff) Type Label; +#define GFSDK_WAVEWORKS_BEGIN_ATTR_DS_CBUFFER(Label) cbuffer Label { +#define GFSDK_WAVEWORKS_END_ATTR_DS_CBUFFER }; +#define GFSDK_WAVEWORKS_DECLARE_ATTR_DS_SAMPLER(Label,TextureLabel,Regoff) sampler Label; texture2D TextureLabel; + +#define GFSDK_WAVEWORKS_DECLARE_ATTR_PS_CONSTANT(Type,Label,Regoff) Type Label; +#define GFSDK_WAVEWORKS_BEGIN_ATTR_PS_CBUFFER(Label) cbuffer Label { +#define GFSDK_WAVEWORKS_END_ATTR_PS_CBUFFER }; +#define GFSDK_WAVEWORKS_DECLARE_ATTR_PS_SAMPLER(Label,TextureLabel,Regoff) sampler Label; texture2D TextureLabel; + +#include "GFSDK_WaveWorks_Attributes.fxh" +#include "common.fx" + +//------------------------------------------------------------------------------------ +// Global variables +//------------------------------------------------------------------------------------ + +// Constant + +float3 g_LightPosition; +float3 g_CameraPosition; +float4x4 g_ModelViewMatrix; +float4x4 g_ModelViewProjectionMatrix; +float4x4 g_LightModelViewProjectionMatrix; +float4x4 g_WorldToTopDownTextureMatrix; + +float3 g_WaterTransmittance = {0.065,0.028,0.035}; // light absorption per meter for coastal water, taken from here: http://www.seafriends.org.nz/phgraph/water.htm http://www.seafriends.org.nz/phgraph/phdwg34.gif +float3 g_WaterScatterColor = {0.0,0.7,0.3}; +float3 g_WaterSpecularColor = {1.1,0.8,0.5}; +float g_WaterScatterIntensity = 0.1; +float g_WaterSpecularIntensity = 10.0f; + +float3 g_FoamColor = {0.90f, 0.95f, 1.0f}; +float3 g_FoamUnderwaterColor = {0.0,0.7,0.6}; + +float g_WaterSpecularPower = 200.0; +float3 g_AtmosphereBrightColor = {1.1,0.9,0.6}; +float3 g_AtmosphereDarkColor = {0.4,0.4,0.5}; +float g_FogDensity = 1.0f/1500.0f; + +float4 g_WireframeColor = {1.0,1.0,1.0,1.0}; + +float2 g_WindDirection; + +float2 g_ScreenSizeInv; +float g_ZNear; +float g_ZFar; +float g_Time; + +float g_GerstnerSteepness; +float g_BaseGerstnerAmplitude; +float g_BaseGerstnerWavelength; +float g_BaseGerstnerSpeed; +float g_BaseGerstnerParallelness; +float g_enableShoreEffects; + +float g_Wireframe; +float2 g_WinSize = {1920.0,1080.0}; + +//----------------------------------------------------------------------------------- +// Texture & Samplers +//----------------------------------------------------------------------------------- +texture2D g_LogoTexture; +Texture2D g_ReflectionTexture; +Texture2D g_RefractionTexture; +Texture2D g_RefractionDepthTextureResolved; +Texture2D g_WaterNormalMapTexture; +Texture2D g_ShadowmapTexture; +Texture2D g_FoamIntensityTexture; +Texture2D g_FoamDiffuseTexture; +Texture2D g_DataTexture; + +// Custom trilinear sampler clamping to custom border color +sampler SamplerTrilinearBorder = +sampler_state +{ + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Border; + AddressV = Border; + BorderColor = float4(20.0,-50.0,0.0,0.0); +}; + +struct VS_OUTPUT +{ + float4 worldspace_position : VSO ; +}; + +struct DS_OUTPUT +{ + float4 positionClip : SV_Position; + GFSDK_WAVEWORKS_INTERPOLATED_VERTEX_OUTPUT NV_ocean_interp; + float3 displacementWS: TEXCOORD5; + float3 positionWS: TEXCOORD6; + float3 world_pos_undisplaced : TEXCOORD7; + float3 gerstner_displacement : TEXCOORD8; + float2 gerstner_sdfUV : TEXCOORD9; + float gerstner_multiplier : TEXCOORD10; +}; + +struct PS_INPUT +{ + float4 positionClip : SV_Position; + GFSDK_WAVEWORKS_INTERPOLATED_VERTEX_OUTPUT NV_ocean_interp; + float3 displacementWS: TEXCOORD5; + float3 positionWS: TEXCOORD6; + float3 world_pos_undisplaced : TEXCOORD7; + float3 gerstner_displacement : TEXCOORD8; + float2 gerstner_sdfUV : TEXCOORD9; + float gerstner_multiplier : TEXCOORD10; + noperspective float3 v_dist : TEXCOORD11; +}; + +struct HS_ConstantOutput +{ + float fTessFactor[3] : SV_TessFactor; + float fInsideTessFactor : SV_InsideTessFactor; +}; + + + +static const float kTopDownDataPixelsPerMeter = 256.0f/700.0; // taken from SDF generation source code, the SDF texture size is 256x256, the viewport size is 700x700 +static const float kMaxDepthBelowSea = 50.0f; +static const float kMaxDistance = 20.0f; // taken from SDF generation code +static const float kNumWaves = 1.0; // Total number of Gerster waves of different amplitude, speed etc to calculate, + // i+1-th wave has 20% smaller amplitude, + // 20% smaller phase and group speed and 20% less parallelity + // Note that all the waves will share the same gerstnerMultiplierOut (lerping between ocean waves and Gerstner waves) for simplicity + +void GetGerstnerVertexAttributes(float3 posWS, out float2 sdfUVOut, out float3 offsetOut, out float gerstnerMultiplierOut) +{ + // getting UV for fetching SDF texture + float4 topDownPosition = mul( float4( posWS.xyz, 1), g_WorldToTopDownTextureMatrix ); + float2 uv = mad( topDownPosition.xy/topDownPosition.w, 0.5f, 0.5f ); + uv.y = 1-uv.y; + + // initializing the outputs so we can exit early + sdfUVOut = uv; + offsetOut = float3 (0.0,0.0,0.0); + gerstnerMultiplierOut = 0; + + // getting SDF + const float4 tdData = g_DataTexture.SampleLevel(SamplerTrilinearBorder, uv, 0 ); + + // early out without adding gerstner waves if far from shore + if((tdData.x >= kMaxDistance - 0.1)) + { + return; + } + + // initializing variables common to all Gerstner waves + float phaseShift = g_Time; + float sdfPhase = tdData.x*kMaxDistance/kTopDownDataPixelsPerMeter; + float distanceMultiplier = saturate(1.0-tdData.x); // Shore waves linearly fade in on the edges of SDF + float depthMultiplier = saturate((g_BaseGerstnerWavelength*0.5 + tdData.y)*0.5); // Shore waves fade in when depth is less than half the wave length, we use 0.25 as this parameter also allows shore waves to heighten as the depth decreases + gerstnerMultiplierOut = distanceMultiplier*depthMultiplier; + + // initializing variables to be changed along summing up the waves + float gerstnerWavelength = g_BaseGerstnerWavelength; + float gerstnerOmega = 2.0*3.141592 / g_BaseGerstnerWavelength; // angular speed of gerstner wave + float gerstnerParallelness = g_BaseGerstnerParallelness; // "parallelness" of shore waves. 0 means the waves are parallel to shore, 1 means the waves are parallel to wind gradient + float gerstnerSpeed = g_BaseGerstnerSpeed; // phase speed of gerstner waves + float gerstnerAmplitude = g_BaseGerstnerAmplitude; + float2 windDirection = g_WindDirection; + + // summing up the waves + for(float i = 0.0; i < kNumWaves; i+=1.0) + { + float windPhase = dot(windDirection, posWS.xz); + float gerstnerPhase = 2.0*3.141592*(lerp( sdfPhase, windPhase, gerstnerParallelness)/gerstnerWavelength); + float2 propagationDirection = normalize( lerp(-tdData.zw + windDirection * 0.000001f, g_WindDirection, gerstnerParallelness*gerstnerParallelness)); + float gerstnerGroupSpeedPhase = 2.0*3.141592*(lerp( sdfPhase, windPhase, gerstnerParallelness*3.0)/gerstnerWavelength); // letting the group speed phase to be non-parallel to propagation phase, so altering parallelness modificator fot this + + float groupSpeedMultiplier = 0.5 + 0.5*cos((gerstnerGroupSpeedPhase + gerstnerOmega*gerstnerSpeed*phaseShift/2.0)/2.7); // Group speed for water waves is half of the phase speed, we allow 2.7 wavelengths to be in wave group, not so much as breaking shore waves lose energy quickly + float worldSpacePosMultiplier = 0.75 + 0.25*sin(phaseShift*0.3 + 0.5*posWS.x/gerstnerWavelength)*sin(phaseShift*0.4 + 0.5*posWS.y/gerstnerWavelength); // slowly crawling worldspace aligned checkerboard pattern that damps gerstner waves further + float depthMultiplier = saturate((gerstnerWavelength*0.5 + tdData.y)*0.5); // Shore waves fade in when depth is less than half the wave length + float gerstnerMultiplier = distanceMultiplier*depthMultiplier*groupSpeedMultiplier*worldSpacePosMultiplier; // final scale factor applied to base Gerstner amplitude and used to mix between ocean waves and shore waves + + float steepness = g_GerstnerSteepness; + float baseAmplitude = gerstnerMultiplier * gerstnerAmplitude; //amplitude gradually increases as wave runs over shallower seabed + float breakerMultiplier = saturate((baseAmplitude*2.0*1.28 + tdData.y)/gerstnerAmplitude); // Wave height is 2*amplitude, a wave will start to break when it approximately reaches a water depth of 1.28 times the wave height, empirically: http://passyworldofmathematics.com/mathematics-of-ocean-waves-and-surfing/ + + // calculating Gerstner offset + float s,c; + sincos(gerstnerPhase + gerstnerOmega*gerstnerSpeed*phaseShift, s, c); + float waveVerticalOffset = s * baseAmplitude; + offsetOut.y += waveVerticalOffset; + offsetOut.xz += c * propagationDirection * steepness * baseAmplitude; // trochoidal Gerstner wave + offsetOut.xz -= propagationDirection * s * baseAmplitude * breakerMultiplier * 2.0; // adding wave forward skew due to its bottom slowing down, so the forward wave front gradually becomes vertical + float breakerPhase = gerstnerPhase + gerstnerOmega*gerstnerSpeed*phaseShift + 3.141592*0.05; + float fp = frac(breakerPhase/(3.141592*2.0)); + offsetOut.xz -= 0.5*baseAmplitude*propagationDirection*breakerMultiplier*(saturate(fp*10.0) - saturate(-1.0 + fp*10.0)); // moving breaking area of the wave further forward + + // updating the parameters for next wave + gerstnerWavelength *= 0.66; + gerstnerOmega /= 0.66; + gerstnerSpeed *= 0.66; + gerstnerAmplitude *= 0.66; + gerstnerParallelness *= 0.66; + windDirection.xy *= float2(-1.0,1.0)*windDirection.yx; // rotating wind direction + + offsetOut.y += baseAmplitude*1.2; // Adding vertical displacement as the wave increases while rolling on the shallow area + } + +} + +void GetGerstnerSurfaceAttributes( float2 sdfUV, float2 posWS, out float3 normalOut, out float breakerOut, out float foamTrailOut) +{ + // initializing the outputs + normalOut = float3 (0.0,1.0,0.0); + foamTrailOut = 0.0; + breakerOut = 0.0; + + // getting SDF + const float4 tdData = g_DataTexture.SampleLevel(SamplerTrilinearBorder, sdfUV, 0 ); + + // initializing variables common to all Gerstner waves + float phaseShift = g_Time; + float sdfPhase = tdData.x*kMaxDistance/kTopDownDataPixelsPerMeter; + float distanceMultiplier = saturate(1.0-tdData.x); // Shore waves linearly fade in on the edges of SDF + + // initializing variables to be changed along summing up the waves + float gerstnerWavelength = g_BaseGerstnerWavelength; + float gerstnerOmega = 2.0*3.141592 / g_BaseGerstnerWavelength; // angular speed of gerstner wave + float gerstnerParallelness = g_BaseGerstnerParallelness; // "parallelness" of shore waves. 0 means the waves are parallel to shore, 1 means the waves are parallel to wind gradient + float gerstnerSpeed = g_BaseGerstnerSpeed; // phase speed of gerstner waves + float gerstnerAmplitude = g_BaseGerstnerAmplitude; + float2 windDirection = g_WindDirection; + + // summing up the waves + for(float i = 0.0; i < kNumWaves; i+=1.0) + { + float windPhase = dot(windDirection, posWS.xy); + float gerstnerPhase = 2.0*3.141592*(lerp( sdfPhase, windPhase, gerstnerParallelness)/gerstnerWavelength); + float2 propagationDirection = normalize( lerp(-tdData.zw + windDirection * 0.000001f, g_WindDirection, gerstnerParallelness*gerstnerParallelness)); + float gerstnerGroupSpeedPhase = 2.0*3.141592*(lerp( sdfPhase, windPhase, gerstnerParallelness*3.0)/gerstnerWavelength); // letting the group speed phase to be non-parallel to propagation phase, so altering parallelness modificator fot this + + float groupSpeedMultiplier = 0.5 + 0.5*cos((gerstnerGroupSpeedPhase + gerstnerOmega*gerstnerSpeed*phaseShift/2.0)/2.7); // Group speed for water waves is half of the phase speed, we allow 2.7 wavelengths to be in wave group, not so much as breaking shore waves lose energy quickly + float worldSpacePosMultiplier = 0.75 + 0.25*sin(phaseShift*0.3 + 0.5*posWS.x/gerstnerWavelength)*sin(phaseShift*0.4 + 0.5*posWS.y/gerstnerWavelength); // slowly crawling worldspace aligned checkerboard pattern that damps gerstner waves further + float depthMultiplier = saturate((gerstnerWavelength*0.5 + tdData.y)*0.5); // Shore waves fade in when depth is less than half the wave length + float gerstnerMultiplier = distanceMultiplier*depthMultiplier*groupSpeedMultiplier*worldSpacePosMultiplier; // final scale factor applied to base Gerstner amplitude and used to mix between ocean waves and shore waves + + float steepness = g_GerstnerSteepness; + float baseAmplitude = gerstnerMultiplier * gerstnerAmplitude; //amplitude gradually increases as wave runs over shallower seabed + + // calculating normal + float s,c; + sincos(gerstnerPhase + gerstnerOmega*gerstnerSpeed*phaseShift, s, c); + normalOut.y -= gerstnerOmega*steepness*baseAmplitude*s; + normalOut.xz -= gerstnerOmega*baseAmplitude*c*propagationDirection; // orienting normal according to direction of wave propagation. No need to normalize, it is unit length. + + // calculating foam parameters + float breakerMultiplier = saturate((baseAmplitude*2.0*1.28 + tdData.y)/gerstnerAmplitude); // Wave height is 2*amplitude, a wave will start to break when it approximately reaches a water depth of 1.28 times the wave height, empirically: http://passyworldofmathematics.com/mathematics-of-ocean-waves-and-surfing/ + + float foamTrailPhase = gerstnerPhase + gerstnerOmega*gerstnerSpeed*phaseShift + 3.141592*0.05; // delaying foam trail a bit so it's following the breaker + float fp = frac(foamTrailPhase/(3.141592*2.0)); + foamTrailOut += gerstnerMultiplier*breakerMultiplier*(saturate(fp*10.0) - saturate(fp*1.1)); // only breaking waves leave foamy trails + breakerOut += gerstnerMultiplier*breakerMultiplier*(saturate(fp*10.0) - saturate(-1.0 + fp*10.0)); // making narrow sawtooth pattern + + // updating the parameters for next wave + gerstnerWavelength *= 0.66; + gerstnerOmega /= 0.66; + gerstnerSpeed *= 0.66; + gerstnerAmplitude *= 0.66; + gerstnerParallelness *= 0.66; + windDirection.xy *= float2(-1.0,1.0)*windDirection.yx; // rotating wind direction + } +} + +//----------------------------------------------------------------------------- +// Name: OceanWaveVS +// Type: Vertex shader +// Desc: +//----------------------------------------------------------------------------- +VS_OUTPUT OceanWaveVS(GFSDK_WAVEWORKS_VERTEX_INPUT In) +{ + VS_OUTPUT Output; + Output.worldspace_position = float4(GFSDK_WaveWorks_GetUndisplacedVertexWorldPosition(In),0.0); + return Output; +} + + +//----------------------------------------------------------------------------- +// Name: HS_Constant +// Type: Hull shader +// Desc: +//----------------------------------------------------------------------------- +HS_ConstantOutput HS_Constant( InputPatch I ) +{ + HS_ConstantOutput O; + O.fTessFactor[0] = GFSDK_WaveWorks_GetEdgeTessellationFactor(I[1].worldspace_position,I[2].worldspace_position); + O.fTessFactor[1] = GFSDK_WaveWorks_GetEdgeTessellationFactor(I[2].worldspace_position,I[0].worldspace_position); + O.fTessFactor[2] = GFSDK_WaveWorks_GetEdgeTessellationFactor(I[0].worldspace_position,I[1].worldspace_position); + O.fInsideTessFactor = (O.fTessFactor[0] + O.fTessFactor[1] + O.fTessFactor[2])/3.0f; + return O; +} + +[domain("tri")] +[partitioning("fractional_odd")] +[outputtopology("triangle_cw")] +[patchconstantfunc("HS_Constant")] +[outputcontrolpoints(3)] +VS_OUTPUT HS_FlatTriangles( InputPatch I, uint uCPID : SV_OutputControlPointID ) +{ + VS_OUTPUT O = (VS_OUTPUT)I[uCPID]; + return O; +} + +//-------------------------------------------------------------------------------------- +// This domain shader applies contol point weighting to the barycentric coords produced by the FF tessellator +//-------------------------------------------------------------------------------------- +[domain("tri")] +DS_OUTPUT DS_FlatTriangles_Shore( HS_ConstantOutput HSConstantData, const OutputPatch I, float3 f3BarycentricCoords : SV_DomainLocation ) +{ + DS_OUTPUT Output = (DS_OUTPUT)0; + + GFSDK_WAVEWORKS_VERTEX_OUTPUT NV_ocean = GFSDK_WaveWorks_GetDisplacedVertexAfterTessellation(I[0].worldspace_position, I[1].worldspace_position, I[2].worldspace_position, f3BarycentricCoords); + + float3 gerstnerDisplacement = float3(0,0,0); + float2 sdfUV = float2(0,0); + float gerstnerMultiplier = 0; + + if(g_enableShoreEffects > 0) + { + GetGerstnerVertexAttributes(NV_ocean.pos_world_undisplaced.xzy, sdfUV, gerstnerDisplacement, gerstnerMultiplier); + } + + NV_ocean.world_displacement *= 1.0 - 0.7*gerstnerMultiplier; + NV_ocean.world_displacement += gerstnerDisplacement.xzy*gerstnerMultiplier; + + NV_ocean.pos_world = NV_ocean.pos_world_undisplaced + NV_ocean.world_displacement; + Output.positionWS = NV_ocean.pos_world; + Output.displacementWS = NV_ocean.world_displacement; + Output.positionClip = mul(float4(NV_ocean.pos_world,1.0), g_ModelViewProjectionMatrix); + Output.world_pos_undisplaced = NV_ocean.pos_world_undisplaced; + Output.gerstner_displacement = gerstnerDisplacement.xzy; + Output.gerstner_sdfUV = sdfUV; + Output.gerstner_multiplier = gerstnerMultiplier; + Output.NV_ocean_interp = NV_ocean.interp; + + return Output; +} + +//-------------------------------------------------------------------------------------- +// This geometry shader enables solid wireframe mode +//-------------------------------------------------------------------------------------- +[maxvertexcount(3)] +void GSSolidWire( triangle DS_OUTPUT input[3], inout TriangleStream outStream ) +{ + PS_INPUT output; + + float2 p0 = g_WinSize * input[0].positionClip.xy/input[0].positionClip.w; + float2 p1 = g_WinSize * input[1].positionClip.xy/input[1].positionClip.w; + float2 p2 = g_WinSize * input[2].positionClip.xy/input[2].positionClip.w; + float2 v0 = p2 - p1; + float2 v1 = p2 - p0; + float2 v2 = p1 - p0; + float area = abs(v1.x*v2.y - v1.y * v2.x); + + + + // Generate vertices + output.positionClip = input[0].positionClip; + output.NV_ocean_interp = input[0].NV_ocean_interp; + output.displacementWS = input[0].displacementWS; + output.positionWS = input[0].positionWS; + output.world_pos_undisplaced = input[0].world_pos_undisplaced; + output.gerstner_displacement = input[0].gerstner_displacement; + output.gerstner_sdfUV = input[0].gerstner_sdfUV; + output.gerstner_multiplier = input[0].gerstner_multiplier; + output.v_dist = float3(area/length(v0),0,0); + outStream.Append( output ); + + output.positionClip = input[1].positionClip; + output.NV_ocean_interp = input[1].NV_ocean_interp; + output.displacementWS = input[1].displacementWS; + output.positionWS = input[1].positionWS; + output.world_pos_undisplaced = input[1].world_pos_undisplaced; + output.gerstner_displacement = input[1].gerstner_displacement; + output.gerstner_sdfUV = input[1].gerstner_sdfUV; + output.gerstner_multiplier = input[1].gerstner_multiplier; + output.v_dist = float3(0,area/length(v1),0); + outStream.Append( output ); + + output.positionClip = input[2].positionClip; + output.NV_ocean_interp = input[2].NV_ocean_interp; + output.displacementWS = input[2].displacementWS; + output.positionWS = input[2].positionWS; + output.world_pos_undisplaced = input[2].world_pos_undisplaced; + output.gerstner_displacement = input[2].gerstner_displacement; + output.gerstner_sdfUV = input[2].gerstner_sdfUV; + output.gerstner_multiplier = input[2].gerstner_multiplier; + output.v_dist = float3(0,0,area/length(v2)); + outStream.Append( output ); + + outStream.RestartStrip(); +} + +float GetRefractionDepth(float2 position) +{ + return g_RefractionDepthTextureResolved.SampleLevel(SamplerLinearClamp,position,0).r; +} + +// primitive simulation of non-uniform atmospheric fog +float3 CalculateFogColor(float3 pixel_to_light_vector, float3 pixel_to_eye_vector) +{ + return lerp(g_AtmosphereDarkColor,g_AtmosphereBrightColor,0.5*dot(pixel_to_light_vector,-pixel_to_eye_vector)+0.5); +} + +//----------------------------------------------------------------------------- +// Name: OceanWaveShorePS +// Type: Pixel shader +// Desc: +//----------------------------------------------------------------------------- +float4 OceanWaveShorePS(PS_INPUT In) : SV_Target +{ + float3 color; + float3 normal; + float fresnel_factor; + float specular_factor; + float scatter_factor; + float3 refraction_color; + float3 reflection_color; + float4 disturbance_eyespace; + + + float water_depth; + + float3 water_vertex_positionWS = In.positionWS.xzy; + + float3 pixel_to_light_vector = normalize(g_LightPosition-water_vertex_positionWS); + float3 pixel_to_eye_vector = normalize(g_CameraPosition-water_vertex_positionWS); + + GFSDK_WAVEWORKS_SURFACE_ATTRIBUTES surface_attributes = GFSDK_WaveWorks_GetSurfaceAttributes(In.NV_ocean_interp); + + float3 gerstner_normal = float3(0.0,1.0,0.0); + float gerstner_breaker = 0; + float gerstner_foamtrail = 0; + + if(g_enableShoreEffects > 0) + { + if(In.gerstner_multiplier > 0) + { + GetGerstnerSurfaceAttributes( In.gerstner_sdfUV, In.world_pos_undisplaced.xy, gerstner_normal, gerstner_breaker, gerstner_foamtrail); + } + surface_attributes.normal = lerp(float3(0,1,0),surface_attributes.normal.xzy, 1.0-0.9*In.gerstner_multiplier*In.gerstner_multiplier); // Leaving just 10% of original open ocean normals in areas affected by shore waves + surface_attributes.foam_turbulent_energy += gerstner_foamtrail*3.0; + surface_attributes.foam_wave_hats += gerstner_breaker*15.0; // 15.0*breaker so the breaker foam has rough edges + + // using PD normal combination + normal = normalize(float3(surface_attributes.normal.xz*gerstner_normal.y + gerstner_normal.xz*surface_attributes.normal.y, surface_attributes.normal.y*gerstner_normal.y)); + normal = normal.xzy; + } + else + { + normal = surface_attributes.normal.xzy; + } + + float3 reflected_eye_to_pixel_vector=-pixel_to_eye_vector+2*dot(pixel_to_eye_vector,normal)*normal; + + // calculating pixel position in light space + float4 positionLS = mul(float4(water_vertex_positionWS,1),g_LightModelViewProjectionMatrix); + positionLS.xyz/=positionLS.w; + positionLS.x=(positionLS.x+1)*0.5; + positionLS.y=(1-positionLS.y)*0.5; + positionLS.z = min(0.99,positionLS.z); + + // calculating shadow multiplier to be applied to diffuse/scatter/specular light components + float shadow_factor = g_ShadowmapTexture.SampleCmp(SamplerDepthAnisotropic,positionLS.xy,positionLS.z* 0.995f).r; + + // simulating scattering/double refraction: light hits the side of wave, travels some distance in water, and leaves wave on the other side + // it's difficult to do it physically correct without photon mapping/ray tracing, so using simple but plausible emulation below + + // only the crests of water waves generate double refracted light + scatter_factor = g_WaterScatterIntensity* + // the waves that lie between camera and light projection on water plane generate maximal amount of double refracted light + pow(max(0.0,dot(normalize(float3(pixel_to_light_vector.x,0.0,pixel_to_light_vector.z)),-pixel_to_eye_vector)),2.0)* + // the slopes of waves that are oriented back to light generate maximal amount of double refracted light + shadow_factor*pow(max(0.0,1.0-dot(pixel_to_light_vector,normal)),2.0); + + scatter_factor += g_WaterScatterIntensity* + // the scattered light is best seen if observing direction is normal to slope surface + max(0,dot(pixel_to_eye_vector,normal));//* + + // calculating fresnel factor + float r=(1.0 - 1.33)*(1.0 - 1.33)/((1.0 + 1.33)*(1.0 + 1.33)); + fresnel_factor = r + (1.0-r)*pow(saturate(1.0 - dot(normal,pixel_to_eye_vector)),5.0); + + + // calculating specular factor + specular_factor=shadow_factor*pow(max(0,dot(pixel_to_light_vector,reflected_eye_to_pixel_vector)),g_WaterSpecularPower); + + // calculating disturbance which has to be applied to planar reflections/refractions to give plausible results + disturbance_eyespace=mul(float4(normal.x,normal.z,0,0),g_ModelViewMatrix); + + float2 reflection_disturbance = float2(disturbance_eyespace.x,disturbance_eyespace.z)*0.06; + float2 refraction_disturbance = float2(-disturbance_eyespace.x,disturbance_eyespace.y)*0.9* + // fading out refraction disturbance at distance so refraction doesn't look noisy at distance + (100.0/(100+length(g_CameraPosition-water_vertex_positionWS))); + + // picking refraction depth at non-displaced point, need it to scale the refraction texture displacement amount according to water depth + float refraction_depth = GetRefractionDepth(In.positionClip.xy*g_ScreenSizeInv); + refraction_depth = g_ZFar*g_ZNear / (g_ZFar-refraction_depth*(g_ZFar-g_ZNear)); + float4 vertex_in_viewspace = mul(float4(In.positionWS.xyz,1),g_ModelViewMatrix); + water_depth = refraction_depth-vertex_in_viewspace.z; + + if(water_depth < 0) + { + refraction_disturbance = 0; + } + water_depth = max(0,water_depth); + refraction_disturbance *= min(1.0f,water_depth*0.03); + + // getting refraction depth again, at displaced point now + refraction_depth = GetRefractionDepth(In.positionClip.xy*g_ScreenSizeInv+refraction_disturbance); + refraction_depth = g_ZFar*g_ZNear / (g_ZFar-refraction_depth*(g_ZFar-g_ZNear)); + vertex_in_viewspace= mul(float4(In.positionWS.xyz,1),g_ModelViewMatrix); + water_depth = max(water_depth,refraction_depth-vertex_in_viewspace.z); + water_depth = max(0,water_depth); + float depth_damper = min(1,water_depth*3.0); + float depth_damper_sss = min(1,water_depth*0.5); + + // getting reflection and refraction color at disturbed texture coordinates + reflection_color = g_ReflectionTexture.SampleLevel(SamplerLinearClamp,float2(In.positionClip.x*g_ScreenSizeInv.x,1.0-In.positionClip.y*g_ScreenSizeInv.y)+reflection_disturbance,0).rgb; + refraction_color = g_RefractionTexture.SampleLevel(SamplerLinearClamp,In.positionClip.xy*g_ScreenSizeInv+refraction_disturbance,0).rgb; + + // fading fresnel factor to 0 to soften water surface edges + fresnel_factor*=depth_damper; + + // fading fresnel factor to 0 for rays that reflect below water surface + fresnel_factor*= 1.0 - 1.0*saturate(-2.0*reflected_eye_to_pixel_vector.y); + + // applying water absorbtion according to distance that refracted ray travels in water + // note that we multiply this by 2 since light travels through water twice: from light to seafloor then from seafloor back to eye + refraction_color.r *= exp(-1.0*water_depth*2.0*g_WaterTransmittance.r); + refraction_color.g *= exp(-1.0*water_depth*2.0*g_WaterTransmittance.g); + refraction_color.b *= exp(-1.0*water_depth*2.0*g_WaterTransmittance.b); + + // applying water scatter factor + refraction_color += scatter_factor*shadow_factor*g_WaterScatterColor*depth_damper_sss; + + // adding milkiness due to mixed-in foam + refraction_color += g_FoamUnderwaterColor*saturate(surface_attributes.foam_turbulent_energy*0.2)*depth_damper_sss; + + // combining final water color + color = lerp(refraction_color, reflection_color, fresnel_factor); + // adding specular + color.rgb += specular_factor*g_WaterSpecularIntensity*g_WaterSpecularColor*shadow_factor*depth_damper; + + // applying surface foam provided by turbulent energy + + // low frequency foam map + float foam_intensity_map_lf = 1.0*g_FoamIntensityTexture.Sample(SamplerLinearWrap, In.world_pos_undisplaced.xy*0.04*float2(1,1)).x - 1.0; + + // high frequency foam map + float foam_intensity_map_hf = 1.0*g_FoamIntensityTexture.Sample(SamplerLinearWrap, In.world_pos_undisplaced.xy*0.15*float2(1,1)).x - 1.0; + + // ultra high frequency foam map + float foam_intensity_map_uhf = 1.0*g_FoamIntensityTexture.Sample(SamplerLinearWrap, In.world_pos_undisplaced.xy*0.3*float2(1,1)).x; + + float foam_intensity; + foam_intensity = saturate(foam_intensity_map_hf + min(3.5,1.0*surface_attributes.foam_turbulent_energy-0.2)); + foam_intensity += (foam_intensity_map_lf + min(1.5,1.0*surface_attributes.foam_turbulent_energy)); + + + foam_intensity -= 0.1*saturate(-surface_attributes.foam_surface_folding); + + foam_intensity = max(0,foam_intensity); + + foam_intensity *= 1.0+0.8*saturate(surface_attributes.foam_surface_folding); + + float foam_bubbles = g_FoamDiffuseTexture.Sample(SamplerLinearWrap, In.world_pos_undisplaced.xy*0.5).r; + foam_bubbles = saturate(5.0*(foam_bubbles-0.8)); + + // applying foam hats + foam_intensity += max(0,foam_intensity_map_uhf*2.0*surface_attributes.foam_wave_hats); + + foam_intensity = pow(foam_intensity, 0.7); + foam_intensity = saturate(foam_intensity*foam_bubbles*1.0); + + foam_intensity*=depth_damper; + + // foam diffuse color + float foam_diffuse_factor = max(0,0.8+max(0,0.2*dot(pixel_to_light_vector,surface_attributes.normal))); + + color = lerp(color, foam_diffuse_factor*float3(1.0,1.0,1.0),foam_intensity); + + // applying atmospheric fog to water surface + float fog_factor = min(1,exp(-length(g_CameraPosition-water_vertex_positionWS)*g_FogDensity)); + color = lerp(color, CalculateFogColor(normalize(g_LightPosition),pixel_to_eye_vector).rgb, fresnel_factor*(1.0-fog_factor)); + + // applying solid wireframe + float d = min(In.v_dist.x,min(In.v_dist.y,In.v_dist.z)); + float I = exp2(-2.0*d*d); + return float4(color + g_Wireframe*I*0.5, 1.0); +} + +//----------------------------------------------------------------------------- +// Name: OceanWaveTech +// Type: Technique +// Desc: +//----------------------------------------------------------------------------- +technique11 RenderOceanSurfTech +{ + + // With shoreline + pass Pass_Solid_WithShoreline + { + SetVertexShader( CompileShader( vs_5_0, OceanWaveVS() ) ); + SetHullShader( CompileShader( hs_5_0, HS_FlatTriangles() ) ); + SetDomainShader( CompileShader( ds_5_0, DS_FlatTriangles_Shore() ) ); + SetGeometryShader( CompileShader( gs_5_0, GSSolidWire() ) ); + SetPixelShader( CompileShader( ps_5_0, OceanWaveShorePS() ) ); + + SetDepthStencilState( DepthNormal, 0 ); + SetRasterizerState( CullBackMS ); + SetBlendState(NoBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF); + } +} + + +struct VS_LOGO_OUTPUT +{ + float4 positionClip : SV_Position; + float2 tex_coord : TEXCOORD1; +}; + +//----------------------------------------------------------------------------- +// Name: DisplayLogoVS +// Type: Vertex shader +//----------------------------------------------------------------------------- +VS_LOGO_OUTPUT DisplayLogoVS(float4 vPos : POSITION, float2 vTexCoord : TEXCOORD0) +{ + VS_LOGO_OUTPUT Output; + Output.positionClip = vPos; + Output.tex_coord = vTexCoord; + return Output; +} + +//----------------------------------------------------------------------------- +// Name: DisplayLogoPS +// Type: Pixel shader +//----------------------------------------------------------------------------- +float4 DisplayLogoPS(VS_LOGO_OUTPUT In) : SV_Target +{ + return g_LogoTexture.Sample(SamplerLinearWrap, In.tex_coord); +} + +//----------------------------------------------------------------------------- +// Name: DisplayBufferTech +// Type: Technique +// Desc: Logo rendering +//----------------------------------------------------------------------------- +technique11 DisplayLogoTech +{ + pass P0 + { + SetVertexShader( CompileShader( vs_5_0, DisplayLogoVS() ) ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_5_0, DisplayLogoPS() ) ); + + SetDepthStencilState( DepthAlways, 0 ); + SetRasterizerState( NoCullMS ); + SetBlendState( Translucent, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); + } +} + +float4 g_OriginPosition; +float4 g_ContactPosition; +float4 g_RayDirection; + +struct RAY_CONTACT_VS_INPUT +{ + float4 PositionWS : POSITION; +}; + +struct RAY_CONTACT_VS_OUTPUT +{ + float4 PositionClip : SV_Position; +}; + +//----------------------------------------------------------------------------- +// Name: ContactVS +// Type: Vertex shader +// Desc: +//----------------------------------------------------------------------------- +RAY_CONTACT_VS_OUTPUT ContactVS(RAY_CONTACT_VS_INPUT In) +{ + RAY_CONTACT_VS_OUTPUT Output; + Output.PositionClip = mul(float4(In.PositionWS.xzy*0.5 + g_ContactPosition.xyz, 1.0), g_ModelViewProjectionMatrix); + return Output; +} + +//----------------------------------------------------------------------------- +// Name: RayVS +// Type: Vertex shader +// Desc: +//----------------------------------------------------------------------------- +RAY_CONTACT_VS_OUTPUT RayVS(RAY_CONTACT_VS_INPUT In) +{ + RAY_CONTACT_VS_OUTPUT Output; + Output.PositionClip = mul(float4(g_OriginPosition.xzy + In.PositionWS.y*g_RayDirection.xzy,1.0), g_ModelViewProjectionMatrix); + return Output; +} + +//----------------------------------------------------------------------------- +// Name: RayContactPS +// Type: Pixel shader +// Desc: +//----------------------------------------------------------------------------- +float4 RayContactPS(RAY_CONTACT_VS_OUTPUT In) : SV_Target +{ + return float4(0, 1.0, 0, 1.0); +} + +//----------------------------------------------------------------------------- +// Name: RenderRayContactTech +// Type: Technique +// Desc: +//----------------------------------------------------------------------------- +technique11 RenderRayContactTech +{ + + // Contact + pass Pass_Contact + { + SetVertexShader( CompileShader( vs_5_0, ContactVS() ) ); + SetHullShader( NULL ); + SetDomainShader( NULL ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_5_0, RayContactPS() ) ); + + SetDepthStencilState( DepthNormal, 0 ); + SetRasterizerState( NoCullMS ); + SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); + } + + // Ray + pass Pass_Ray + { + SetVertexShader( CompileShader( vs_5_0, RayVS() ) ); + SetHullShader( NULL ); + SetDomainShader( NULL ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_5_0, RayContactPS() ) ); + + SetDepthStencilState( DepthNormal, 0 ); + SetRasterizerState( Wireframe ); + SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); + } +} diff --git a/sample/d3d11/ocean_surface.h b/sample/d3d11/ocean_surface.h new file mode 100644 index 0000000..ab16964 --- /dev/null +++ b/sample/d3d11/ocean_surface.h @@ -0,0 +1,89 @@ +// 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. +// + +#ifndef _OCEAN_WAVE_H +#define _OCEAN_WAVE_H + +#include + +#include +#include "distance_field.h" + +class OceanSurface +{ +public: + OceanSurface(); + ~OceanSurface(); + + HRESULT init(); + + // ---------------------------------- GPU shading data ------------------------------------ + + // D3D objects + ID3D11Device* m_pd3dDevice; + + ID3DX11Effect* m_pOceanFX; + ID3DX11EffectTechnique* m_pRenderSurfaceTechnique; + ID3DX11EffectPass* m_pRenderSurfaceShadedWithShorelinePass; + ID3DX11EffectPass* m_pRenderSurfaceWireframeWithShorelinePass; + + ID3D11InputLayout* m_pQuadLayout; + ID3D11InputLayout* m_pRayContactLayout; + ID3DX11EffectTechnique* m_pRenderRayContactTechnique; + ID3D11Buffer* m_pContactVB; + ID3D11Buffer* m_pContactIB; + + DistanceField* pDistanceFieldModule; // Not owned! + void AttachDistanceFieldModule( DistanceField* pDistanceField ) { pDistanceFieldModule = pDistanceField; } + + // --------------------------------- Rendering routines ----------------------------------- + // Rendering + void renderShaded( ID3D11DeviceContext* pDC, + const XMMATRIX& matView, + const XMMATRIX& matProj, + GFSDK_WaveWorks_SimulationHandle hSim, + GFSDK_WaveWorks_SavestateHandle hSavestate, + const XMFLOAT2& windDir, + const float steepness, + const float amplitude, + const float wavelength, + const float speed, + const float parallelness, + const float totalTime + ); + void getQuadTreeStats(GFSDK_WaveWorks_Quadtree_Stats& stats); + + // --------------------------------- Surface geometry ----------------------------------- + GFSDK_WaveWorks_QuadtreeHandle m_hOceanQuadTree; + HRESULT initQuadTree(const GFSDK_WaveWorks_Quadtree_Params& params); + + UINT* m_pQuadTreeShaderInputMappings_Shore; + UINT* m_pSimulationShaderInputMappings_Shore; +}; + +#endif // _OCEAN_WAVE_H diff --git a/sample/d3d11/resource.h b/sample/d3d11/resource.h new file mode 100644 index 0000000..1777be2 --- /dev/null +++ b/sample/d3d11/resource.h @@ -0,0 +1,44 @@ +// 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. +// + + //{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by water_lib_d3d11_demo.rc +// +#define IDI_MAIN_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 113 +#define _APS_NEXT_COMMAND_VALUE 40029 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/sample/d3d11/sample.fx b/sample/d3d11/sample.fx new file mode 100644 index 0000000..4d85e07 --- /dev/null +++ b/sample/d3d11/sample.fx @@ -0,0 +1,759 @@ +// 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 "common.fx" + +//-------------------------------------------------------------------------------------- +// Textures +//-------------------------------------------------------------------------------------- + +// static textures +Texture2D g_HeightfieldTexture; +Texture2D g_LayerdefTexture; +Texture2D g_RockBumpTexture; +Texture2D g_FoamIntensityTexture; +Texture2D g_FoamDiffuseTexture; + +// rendertarget textures +Texture2D g_SkyTexture; +Texture2D g_ShadowmapTexture; +Texture2D g_MainTexture; +Texture2DMS g_RefractionDepthTextureMS1; +Texture2DMS g_RefractionDepthTextureMS2; +Texture2DMS g_RefractionDepthTextureMS4; + + + +//-------------------------------------------------------------------------------------- +// Shader Inputs/Outputs +//-------------------------------------------------------------------------------------- +struct VSIn_Diffuse +{ + float3 position : POSITION; + float2 texcoord : TEXCOORD; + float3 normal : NORMAL; +}; + +struct PSIn_Diffuse +{ + float4 position : SV_Position; + centroid float3 normal : NORMAL; + centroid float3 positionWS : TEXCOORD0; + centroid float4 layerdef : TEXCOORD1; + centroid float brightness : TEXCOORD2; +}; + +struct PSIn_Quad +{ + float4 position : SV_Position; + float2 texcoord : TEXCOORD0; +}; + +struct VSIn_Default +{ + float4 position : POSITION; + float2 texcoord : TEXCOORD; +}; + + +struct DUMMY +{ + float Dummmy : DUMMY; +}; + +struct HSIn_Heightfield +{ + float2 origin : ORIGIN; + float2 size : SIZE; +}; + + +struct PatchData +{ + float Edges[4] : SV_TessFactor; + float Inside[2] : SV_InsideTessFactor; + + float2 origin : ORIGIN; + float2 size : SIZE; +}; + +//-------------------------------------------------------------------------------------- +// Global variables +//-------------------------------------------------------------------------------------- + +// rendering control variables +float g_DynamicTessFactor; +float g_HalfSpaceCullSign; +float g_HalfSpaceCullPosition; +int g_MSSamples; + +// view/time dependent variables +float4x4 g_ModelViewMatrix; +float4x4 g_ModelViewProjectionMatrix; +float4x4 g_ModelViewProjectionMatrixInv; +float4x4 g_LightModelViewProjectionMatrix; +float4x4 g_LightModelViewProjectionMatrixInv; +float3 g_CameraPosition; +float3 g_CameraDirection; + +float3 g_LightPosition; +float2 g_ScreenSizeInv; +float g_MainBufferSizeMultiplier; +float g_ZNear; +float g_ZFar; +float g_ApplyFog; + +// constants defining visual appearance +float2 g_RockBumpTexcoordScale={10.0,10.0}; +float g_RockBumpHeightScale=3.0; +float3 g_AtmosphereBrightColor={1.1,0.9,0.6}; +float3 g_AtmosphereDarkColor={0.4,0.4,0.5}; +float g_FogDensity = 1.0f/1500.0f; +float2 g_HeightFieldOrigin = float2(0, 0); +float g_HeightFieldSize = 512; + +// Shoreline rendering related variables +float4x4 g_WorldToTopDownTextureMatrix; +Texture2D g_DataTexture; +float g_Time; +float g_GerstnerSteepness; +float g_BaseGerstnerAmplitude; +float g_BaseGerstnerWavelength; +float g_BaseGerstnerSpeed; +float g_BaseGerstnerParallelness; +float2 g_WindDirection; +float g_enableShoreEffects; + +//-------------------------------------------------------------------------------------- +// Misc functions +//-------------------------------------------------------------------------------------- + +// calculating tessellation factor. +float CalculateTessellationFactor(float distance) +{ + return g_DynamicTessFactor*(1.0/(0.015*distance)); +} + +// to avoid vertex swimming while tessellation varies, one can use mipmapping for displacement maps +// it's not always the best choice, but it effificiently suppresses high frequencies at zero cost +float CalculateMIPLevelForDisplacementTextures(float distance) +{ + return log2(128/CalculateTessellationFactor(distance)); +} + +// primitive simulation of non-uniform atmospheric fog +float3 CalculateFogColor(float3 pixel_to_light_vector, float3 pixel_to_eye_vector) +{ + return lerp(g_AtmosphereDarkColor,g_AtmosphereBrightColor,0.5*dot(pixel_to_light_vector,-pixel_to_eye_vector)+0.5); +} + +//-------------------------------------------------------------------------------------- +// Sky shaders +//-------------------------------------------------------------------------------------- + +struct PSIn_Sky +{ + float4 position : SV_Position; + centroid float2 texcoord : TEXCOORD0; + centroid float3 positionWS : TEXCOORD1; +}; + +PSIn_Sky SkyVS(VSIn_Default input) +{ + PSIn_Sky output; + + output.position = mul(input.position, g_ModelViewProjectionMatrix); + output.positionWS=input.position.xyz; + output.texcoord = input.texcoord; + return output; +} + +float4 SkyPS(PSIn_Sky input) : SV_Target +{ + float4 color; + float3 acolor; + float3 pixel_to_eye_vector = normalize(g_CameraPosition-input.positionWS); + + color=1.5*g_SkyTexture.Sample(SamplerLinearWrap,float2(input.texcoord.x,input.texcoord.y))-0.3; + acolor =CalculateFogColor(normalize(g_LightPosition),pixel_to_eye_vector); + color.rgb = lerp(color.rgb,acolor,pow(saturate(input.texcoord.y),3)); + color.a =1; + return color; +} + +//-------------------------------------------------------------------------------------- +// Heightfield shaders +//-------------------------------------------------------------------------------------- + +HSIn_Heightfield PassThroughVS(float4 PatchParams : PATCH_PARAMETERS) +{ + HSIn_Heightfield output; + output.origin = PatchParams.xy; + output.size = PatchParams.zw; + return output; +} + +PatchData PatchConstantHS( InputPatch inputPatch ) +{ + PatchData output; + + float distance_to_camera; + float tesselation_factor; + float inside_tessellation_factor=0; + float in_frustum=0; + + output.origin = inputPatch[0].origin; + output.size = inputPatch[0].size; + + float2 texcoord0to1 = (inputPatch[0].origin + inputPatch[0].size/2.0)/g_HeightFieldSize; + texcoord0to1.y=1-texcoord0to1.y; + + // conservative frustum culling + float3 patch_center=float3(inputPatch[0].origin.x+inputPatch[0].size.x*0.5,g_HeightfieldTexture.SampleLevel(SamplerLinearWrap, texcoord0to1,0).w,inputPatch[0].origin.y+inputPatch[0].size.y*0.5); + float3 camera_to_patch_vector = patch_center-g_CameraPosition; + float3 patch_to_camera_direction_vector = g_CameraDirection*dot(camera_to_patch_vector,g_CameraDirection)-camera_to_patch_vector; + float3 patch_center_realigned=patch_center+normalize(patch_to_camera_direction_vector)*min(2*inputPatch[0].size.x,length(patch_to_camera_direction_vector)); + float4 patch_screenspace_center = mul(float4(patch_center_realigned, 1.0), g_ModelViewProjectionMatrix); + + if(((patch_screenspace_center.x/patch_screenspace_center.w>-1.0) && (patch_screenspace_center.x/patch_screenspace_center.w<1.0) + && (patch_screenspace_center.y/patch_screenspace_center.w>-1.0) && (patch_screenspace_center.y/patch_screenspace_center.w<1.0) + && (patch_screenspace_center.w>0)) || (length(patch_center-g_CameraPosition)<2*inputPatch[0].size.x)) + { + in_frustum=1; + } + + if(in_frustum) + { + distance_to_camera=length(g_CameraPosition.xz-inputPatch[0].origin-float2(0,inputPatch[0].size.y*0.5)); + tesselation_factor=CalculateTessellationFactor(distance_to_camera); + output.Edges[0] = tesselation_factor; + inside_tessellation_factor+=tesselation_factor; + + + distance_to_camera=length(g_CameraPosition.xz-inputPatch[0].origin-float2(inputPatch[0].size.x*0.5,0)); + tesselation_factor=CalculateTessellationFactor(distance_to_camera); + output.Edges[1] = tesselation_factor; + inside_tessellation_factor+=tesselation_factor; + + distance_to_camera=length(g_CameraPosition.xz-inputPatch[0].origin-float2(inputPatch[0].size.x,inputPatch[0].size.y*0.5)); + tesselation_factor=CalculateTessellationFactor(distance_to_camera); + output.Edges[2] = tesselation_factor; + inside_tessellation_factor+=tesselation_factor; + + distance_to_camera=length(g_CameraPosition.xz-inputPatch[0].origin-float2(inputPatch[0].size.x*0.5,inputPatch[0].size.y)); + tesselation_factor=CalculateTessellationFactor(distance_to_camera); + output.Edges[3] = tesselation_factor; + inside_tessellation_factor+=tesselation_factor; + output.Inside[0] = output.Inside[1] = inside_tessellation_factor*0.25; + } + else + { + output.Edges[0]=-1; + output.Edges[1]=-1; + output.Edges[2]=-1; + output.Edges[3]=-1; + output.Inside[0]=-1; + output.Inside[1]=-1; + } + + return output; +} + +[domain("quad")] +[partitioning("fractional_odd")] +[outputtopology("triangle_cw")] +[outputcontrolpoints(1)] +[patchconstantfunc("PatchConstantHS")] +DUMMY PatchHS( InputPatch inputPatch ) +{ + return (DUMMY)0; +} + +[domain("quad")] +PSIn_Diffuse HeightFieldPatchDS( PatchData input, + float2 uv : SV_DomainLocation, + OutputPatch inputPatch ) +{ + PSIn_Diffuse output; + float3 vertexPosition; + float4 base_texvalue; + float2 texcoord0to1 = (input.origin + uv * input.size)/g_HeightFieldSize; + float3 base_normal; + float3 detail_normal; + float3 detail_normal_rotated; + float4 detail_texvalue; + float detail_height; + float3x3 normal_rotation_matrix; + float4 layerdef; + float distance_to_camera; + float detailmap_miplevel; + texcoord0to1.y=1-texcoord0to1.y; + + // fetching base heightmap,normal and moving vertices along y axis + base_texvalue=g_HeightfieldTexture.SampleLevel(SamplerLinearWrap, texcoord0to1,0); + base_normal=base_texvalue.xyz; + base_normal.z=-base_normal.z; + vertexPosition.xz = input.origin + uv * input.size; + vertexPosition.y = base_texvalue.w; + + // calculating MIP level for detail texture fetches + distance_to_camera=length(g_CameraPosition-vertexPosition); + detailmap_miplevel= CalculateMIPLevelForDisplacementTextures(distance_to_camera); + + // fetching layer definition texture + layerdef=g_LayerdefTexture.SampleLevel(SamplerLinearWrap, texcoord0to1,0); + + // rock detail texture + detail_texvalue = g_RockBumpTexture.SampleLevel(SamplerLinearWrap, texcoord0to1*g_RockBumpTexcoordScale,detailmap_miplevel).rbga; + detail_normal = normalize(lerp(float3(0.0,1.0,0.0),2.0*detail_texvalue.xyz-float3(1,1,1),layerdef.w)); + detail_height = (detail_texvalue.w-0.5)*g_RockBumpHeightScale*layerdef.w; + + // moving vertices by detail height along base normal + vertexPosition+=base_normal*detail_height; + + //calculating base normal rotation matrix + normal_rotation_matrix[1]=base_normal; + normal_rotation_matrix[2]=normalize(cross(float3(-1.0,0.0,0.0),normal_rotation_matrix[1])); + normal_rotation_matrix[0]=normalize(cross(normal_rotation_matrix[2],normal_rotation_matrix[1])); + + //applying base rotation matrix to detail normal + detail_normal_rotated = mul(detail_normal,normal_rotation_matrix); + + // writing output params + output.position = mul(float4(vertexPosition, 1.0), g_ModelViewProjectionMatrix); + output.normal = detail_normal_rotated; + output.positionWS = vertexPosition; + output.layerdef = layerdef; + output.brightness = detail_height; + return output; +} + +static const float kTopDownDataPixelsPerMeter = 256.0f/700.0; // taken from SDF generation source code, the SDF texture size is 256x256, the viewport size is 700x700 +static const float kMaxDepthBelowSea = 50.0f; +static const float kMaxDistance = 20.0f; // taken from SDF generation code +static const float kNumWaves = 1.0; // Total number of Gerster waves of different amplitude, speed etc to calculate, + // i+1-th wave has 20% smaller amplitude, + // 20% smaller phase and group speed and 20% less parallelity + // Note that all the waves will share the same gerstnerMultiplierOut (lerping between ocean waves and Gerstner waves) for simplicity +static const float kBackWaveSpeed = 0.5; // the speed of wave rolling back from shore, in vertical dimension, in meters/sec + +void GetGerstnerShoreAttributes(float3 posWS, out float waveOut, out float3 normalOut, out float foamTrailOut, out float2 foamWSShift, out float waterLayerOut, out float waterLayerSlowOut) +{ + // getting UV for fetching SDF texture + float4 topDownPosition = mul( float4( posWS.xyz, 1), g_WorldToTopDownTextureMatrix ); + float2 uv = mad( topDownPosition.xy/topDownPosition.w, 0.5f, 0.5f ); + uv.y = 1-uv.y; + + // initializing the outputs + normalOut = float3(0.0,1.0,0.0); + waveOut = 0; + foamWSShift = float2(0.0,0.0); + foamTrailOut = 0; + waterLayerOut = 0; + waterLayerSlowOut = 0; + + // getting SDF + const float4 tdData = g_DataTexture.SampleLevel(SamplerLinearBorder, uv, 0 ); + + // getting terrain altitude gradient in y meters per xz meter + float terrain_dy = 0.25*(tdData.y - g_DataTexture.SampleLevel(SamplerLinearBorder, uv - kTopDownDataPixelsPerMeter*float2(tdData.z,-tdData.w)/256.0, 0 ).y); + + // initializing variables common to all Gerstner waves + float phaseShift = g_Time; + float sdfPhase = tdData.x*kMaxDistance/kTopDownDataPixelsPerMeter; + float distanceMultiplier = saturate(1.0-tdData.x); // Shore waves linearly fade in on the edges of SDF + float depthMultiplier = saturate((g_BaseGerstnerWavelength*0.5 + tdData.y)); // Shore waves fade in when depth is less than half the wave length + + // initializing variables to be changed along summing up the waves + float gerstnerWavelength = g_BaseGerstnerWavelength; + float gerstnerOmega = 2.0*3.141592 / g_BaseGerstnerWavelength; // angular speed of gerstner wave + float gerstnerParallelness = g_BaseGerstnerParallelness; // "parallelness" of shore waves. 0 means the waves are parallel to shore, 1 means the waves are parallel to wind gradient + float gerstnerSpeed = g_BaseGerstnerSpeed; // phase speed of gerstner waves + float gerstnerAmplitude = g_BaseGerstnerAmplitude; + float2 windDirection = g_WindDirection; + + // summing up the waves + for(float i = 0.0; i < kNumWaves; i+=1.0) + { + float windPhase = dot(windDirection, posWS.xz); + float gerstnerPhase = 2.0*3.141592*(lerp( sdfPhase, windPhase, gerstnerParallelness)/gerstnerWavelength); + float2 propagationDirection = normalize( lerp(-tdData.zw + windDirection * 0.000001f, g_WindDirection, gerstnerParallelness*gerstnerParallelness)); + float gerstnerGroupSpeedPhase = 2.0*3.141592*(lerp( sdfPhase, windPhase, gerstnerParallelness*3.0)/gerstnerWavelength); // letting the group speed phase to be non-parallel to propagation phase, so altering parallelness modificator fot this + + float groupSpeedMultiplier = 0.5 + 0.5*cos((gerstnerGroupSpeedPhase + gerstnerOmega*gerstnerSpeed*phaseShift/2.0)/2.7); // Group speed for water waves is half of the phase speed, we allow 2.7 wavelengths to be in wave group, not so much as breaking shore waves lose energy quickly + float worldSpacePosMultiplier = 0.75 + 0.25*sin(phaseShift*0.3 + 0.5*posWS.x/gerstnerWavelength)*sin(phaseShift*0.4 + 0.5*posWS.y/gerstnerWavelength); // slowly crawling worldspace aligned checkerboard pattern that damps gerstner waves further + float depthMultiplier = saturate((gerstnerWavelength*0.5 + tdData.y)*0.5); // Shore waves fade in when depth is less than half the wave length + float gerstnerMultiplier = distanceMultiplier*depthMultiplier*worldSpacePosMultiplier*groupSpeedMultiplier; + + float steepness = gerstnerMultiplier * g_GerstnerSteepness; // steepness gradually increases as wave runs over shallower seabed + float baseAmplitude = gerstnerMultiplier * gerstnerAmplitude; //amplitude gradually increases as wave runs over shallower seabed + float skewMultiplier = saturate((baseAmplitude*2.0*1.28 + tdData.y)/gerstnerAmplitude); // Wave height is 2*amplitude, a wave will start to break when it approximately reaches a water depth of 1.28 times the wave height, empirically: http://passyworldofmathematics.com/mathematics-of-ocean-waves-and-surfing/ + float breakerMultiplier = saturate((baseAmplitude*2.0*1.28 + tdData.y)/gerstnerAmplitude); // Wave height is 2*amplitude, a wave will start to break when it approximately reaches a water depth of 1.28 times the wave height, empirically: http://passyworldofmathematics.com/mathematics-of-ocean-waves-and-surfing/ + + // calculating Gerstner offset + float s,c; + sincos(gerstnerPhase + gerstnerOmega*gerstnerSpeed*phaseShift, s, c); + float waveVerticalOffset = (s*0.5+0.5)*(s*0.5+0.5); + + // calculating normal + normalOut.y -= gerstnerOmega*steepness*baseAmplitude*s; + normalOut.xz -= gerstnerOmega*baseAmplitude*c*propagationDirection; // orienting normal according to direction of wave propagation. No need to normalize, it is unit length. + + // calculating foam parameters + foamTrailOut += gerstnerMultiplier*breakerMultiplier; + + // calculating wave falling edges moving slow and fast + float foamTrailPhase = gerstnerPhase + gerstnerOmega*gerstnerSpeed*phaseShift + 3.141592*0.05; // delaying foam trail a bit so it's following the breaker + float fp = frac(foamTrailPhase/(3.141592*2.0)); + + float k = kBackWaveSpeed*terrain_dy/((gerstnerSpeed/gerstnerWavelength)*baseAmplitude); + float sawtooth = 1.0 - k + k*(saturate(fp*10.0) - saturate(fp*1.1)); + waterLayerOut += sawtooth*baseAmplitude + baseAmplitude; + + k = kBackWaveSpeed/(gerstnerOmega*gerstnerSpeed); + sawtooth = k*(saturate(fp*10.0) - saturate(fp*1.1)); + + foamWSShift += 10.0*sawtooth*propagationDirection*gerstnerAmplitude; + + k = 0.33*kBackWaveSpeed*terrain_dy/((gerstnerSpeed/gerstnerWavelength)*baseAmplitude); + sawtooth = 1.0 - k + k*(saturate(fp*10.0) - saturate(fp*1.1)); + waterLayerSlowOut += sawtooth*baseAmplitude + baseAmplitude; + + waveOut += waveVerticalOffset*baseAmplitude; + + // updating the parameters for next wave + gerstnerWavelength *= 0.66; + gerstnerOmega /= 0.66; + gerstnerSpeed *= 0.66; + gerstnerAmplitude *= 0.66; + gerstnerParallelness *= 0.66; + windDirection.xy *= float2(-1.0,1.0)*windDirection.yx; // rotating wind direction + + } +} + +float4 HeightFieldPatchPS(PSIn_Diffuse input) : SV_Target +{ + float3 color; + float3 pixel_to_light_vector = normalize(g_LightPosition-input.positionWS); + float3 pixel_to_eye_vector = normalize(g_CameraPosition-input.positionWS); + + // culling halfspace if needed + clip(g_HalfSpaceCullSign*(input.positionWS.y-g_HalfSpaceCullPosition)); + + float darkening_change_rate = min(1.0,1.0/(3.0*g_BaseGerstnerAmplitude)); + float shore_darkening_factor = saturate((input.positionWS.y + 1.0)*darkening_change_rate); + + // getting diffuse color + color = float3(0.3,0.3,0.3); + + // adding per-vertex lighting defined by displacement of vertex + color*=0.5+0.5*min(1.0,max(0.0, input.brightness/3.0f+0.5f)); + + // calculating pixel position in light view space + float4 positionLS = mul(float4(input.positionWS,1),g_LightModelViewProjectionMatrix); + positionLS.xyz/=positionLS.w; + positionLS.x=(positionLS.x+1)*0.5; + positionLS.y=(1-positionLS.y)*0.5; + + // fetching shadowmap and shading + float dsf = 0.66f/4096.0f; + float shadow_factor = 0.2*g_ShadowmapTexture.SampleCmp(SamplerDepthAnisotropic,positionLS.xy,positionLS.z* 0.99f).r; + shadow_factor+=0.2*g_ShadowmapTexture.SampleCmp(SamplerDepthAnisotropic,positionLS.xy+float2(dsf,dsf),positionLS.z* 0.99f).r; + shadow_factor+=0.2*g_ShadowmapTexture.SampleCmp(SamplerDepthAnisotropic,positionLS.xy+float2(-dsf,dsf),positionLS.z* 0.99f).r; + shadow_factor+=0.2*g_ShadowmapTexture.SampleCmp(SamplerDepthAnisotropic,positionLS.xy+float2(dsf,-dsf),positionLS.z* 0.99f).r; + shadow_factor+=0.2*g_ShadowmapTexture.SampleCmp(SamplerDepthAnisotropic,positionLS.xy+float2(-dsf,-dsf),positionLS.z* 0.99f).r; + color *= g_AtmosphereBrightColor*max(0,dot(pixel_to_light_vector,input.normal))*shadow_factor; + + // making all brighter + color*=2.0; + // adding light from the sky + color += (0.0+0.2*max(0,(dot(float3(0,1,0),input.normal))))*g_AtmosphereDarkColor; + + + // calculating shore effects + if((g_enableShoreEffects > 0) && (shore_darkening_factor < 1.0)) + { + float3 normal; + float foam_trail; + float water_layer; + float water_layer_slow; + float wave_pos; + float2 foamWSShift; + + GetGerstnerShoreAttributes(input.positionWS, wave_pos, normal, foam_trail, foamWSShift, water_layer, water_layer_slow); + + float waterlayer_change_rate = max(2.0,1.0/(0.1 + water_layer_slow - water_layer)); + + float underwater_factor = saturate((input.positionWS.y - wave_pos + 2.0)*5.0); + float darkening_factor = saturate((input.positionWS.y - g_BaseGerstnerAmplitude*2.0 + 2.0)*1.0); + float fresnel_damp_factor = saturate((input.positionWS.y + 0.1 - wave_pos + 2.0)*5.0); + float shore_waterlayer_factor_windy = saturate((input.positionWS.y - water_layer + 2.0)*waterlayer_change_rate); + float shore_waterlayer_factor_calm = saturate((input.positionWS.y + 2.0)*10.0); + float shore_waterlayer_factor = lerp(shore_waterlayer_factor_calm, shore_waterlayer_factor_windy, saturate(g_BaseGerstnerAmplitude*5.0)); + float shore_foam_lower_bound_factor = saturate((input.positionWS.y + g_BaseGerstnerAmplitude - wave_pos + 2.0)*min(3.0,3.0/(2.0*g_BaseGerstnerAmplitude))); + + + float3 reflected_eye_to_pixel_vector=-pixel_to_eye_vector+2*dot(pixel_to_eye_vector,input.normal)*input.normal; + float specular_light = pow(max(0,dot(reflected_eye_to_pixel_vector,pixel_to_light_vector)),40.0); + + // calculating fresnel factor + float r = (1.0 - 1.33)*(1.0 - 1.33)/((1.0 + 1.33)*(1.0 + 1.33)); + float fresnel_factor = r + (1.0-r)*pow(saturate(1.0 - dot(input.normal,pixel_to_eye_vector)),5.0); + + fresnel_factor *= (1.0-shore_waterlayer_factor)*fresnel_damp_factor; + + // darkening the terrain close to water + color *= 0.6 + 0.4*darkening_factor; + // darkening terrain underwater + color *= min(1.0,exp((input.positionWS.y + 2.0))); + + // adding specular + color += 5.0*g_AtmosphereBrightColor*specular_light*shadow_factor*fresnel_factor; + + // calculating reflection color + float3 reflection_color = CalculateFogColor(pixel_to_light_vector,-reflected_eye_to_pixel_vector); + + color = lerp(color, reflection_color.rgb, fresnel_factor); + + // adding foam + float2 positionWS_shifted = input.positionWS.xz + foamWSShift; + float foam_intensity_map_lf = g_FoamIntensityTexture.Sample(SamplerLinearWrap, positionWS_shifted*0.04*float2(1,1)).x - 1.0; + float foam_intensity_map_hf = g_FoamIntensityTexture.Sample(SamplerLinearWrap, positionWS_shifted*0.15*float2(1,1)).x - 1.0; + + float foam_intensity; + float k = 1.5; + float ff2 = (2.0/g_BaseGerstnerAmplitude)*saturate(input.positionWS.y - water_layer*0.8 + 2.0); + float ff = (1.0-ff2)*shore_foam_lower_bound_factor*foam_trail; + foam_intensity = saturate(foam_intensity_map_hf + min(3.5,k*ff-0.2)); + foam_intensity += (foam_intensity_map_lf + min(1.5,k*ff)); + foam_intensity = max(0.0, foam_intensity); + float foam_bubbles = g_FoamDiffuseTexture.Sample(SamplerLinearWrap, positionWS_shifted*0.5).r; + foam_bubbles = saturate(5.0*(foam_bubbles-0.8)); + foam_intensity = pow(foam_intensity, 0.7); + foam_intensity = saturate(foam_intensity*foam_bubbles*1.0); + + // foam diffuse color + float foam_diffuse_factor = max(0,0.8+max(0,0.2*dot(pixel_to_light_vector,normal))); + + color = lerp(color, foam_diffuse_factor*float3(1.0,1.0,1.0),foam_intensity); + } + + // applying fog + if(g_ApplyFog > 0) + { + color = lerp(CalculateFogColor(pixel_to_light_vector,pixel_to_eye_vector).rgb, color, min(1,exp(-length(g_CameraPosition-input.positionWS)*g_FogDensity))); + } + + + return float4(color, length(g_CameraPosition-input.positionWS)); +} + +float4 HeightFieldPatchDataPS( PSIn_Diffuse input ) : SV_Target +{ + float y_biased = input.positionWS.y + 2.0; + return float4( y_biased, y_biased, 0, 0 ); +} + + +//-------------------------------------------------------------------------------------- +// Fullscreen shaders +//-------------------------------------------------------------------------------------- + +PSIn_Quad FullScreenQuadVS(uint VertexId: SV_VertexID) +{ + PSIn_Quad output; + + output.position = float4(QuadVertices[VertexId],0,1); + output.texcoord = QuadTexCoordinates[VertexId]; + + return output; +} + +float4 MainToBackBufferPS(PSIn_Quad input) : SV_Target +{ + float4 color; + color.rgb = g_MainTexture.SampleLevel(SamplerLinearWrap,float2((input.texcoord.x-0.5)/g_MainBufferSizeMultiplier+0.5f,(input.texcoord.y-0.5)/g_MainBufferSizeMultiplier+0.5f),0).rgb; + color.a=0; + return color; +} + +float RefractionDepthManualResolvePS1(PSIn_Quad input) : SV_Target +{ + return g_RefractionDepthTextureMS1.Load(input.position.xy,0,int2(0,0)).r; +} + +float RefractionDepthManualResolvePS2(PSIn_Quad input) : SV_Target +{ + return g_RefractionDepthTextureMS2.Load(input.position.xy,0,int2(0,0)).r; +} + +float RefractionDepthManualResolvePS4(PSIn_Quad input) : SV_Target +{ + return g_RefractionDepthTextureMS4.Load(input.position.xy,0,int2(0,0)).r; +} + +//-------------------------------------------------------------------------------------- +// Techniques +//-------------------------------------------------------------------------------------- + +technique11 RefractionDepthManualResolve +{ + pass MS1 + { + SetRasterizerState(NoCullMS); + SetDepthStencilState(NoDepthStencil, 0); + SetBlendState(NoBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF); + SetVertexShader(CompileShader(vs_4_0, FullScreenQuadVS())); + SetHullShader(NULL); + SetDomainShader(NULL); + SetGeometryShader(NULL); + SetPixelShader(CompileShader(ps_4_0, RefractionDepthManualResolvePS1())); + } + pass MS2 + { + SetRasterizerState(NoCullMS); + SetDepthStencilState(NoDepthStencil, 0); + SetBlendState(NoBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF); + SetVertexShader(CompileShader(vs_4_0, FullScreenQuadVS())); + SetHullShader(NULL); + SetDomainShader(NULL); + SetGeometryShader(NULL); + SetPixelShader(CompileShader(ps_4_0, RefractionDepthManualResolvePS2())); + } + pass MS4 + { + SetRasterizerState(NoCullMS); + SetDepthStencilState(NoDepthStencil, 0); + SetBlendState(NoBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF); + SetVertexShader(CompileShader(vs_4_0, FullScreenQuadVS())); + SetHullShader(NULL); + SetDomainShader(NULL); + SetGeometryShader(NULL); + SetPixelShader(CompileShader(ps_4_0, RefractionDepthManualResolvePS4())); + } +} + +technique11 MainToBackBuffer +{ + pass Solid + { + SetRasterizerState(NoCullMS); + SetDepthStencilState(NoDepthStencil, 0); + SetBlendState(NoBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF); + + SetVertexShader(CompileShader(vs_4_0, FullScreenQuadVS())); + SetHullShader(NULL); + SetDomainShader(NULL); + SetGeometryShader(NULL); + SetPixelShader(CompileShader(ps_4_0, MainToBackBufferPS())); + } +} + +technique11 RenderHeightfield +{ + pass Solid + { + SetRasterizerState(CullBackMS); + SetDepthStencilState(DepthNormal, 0); + SetBlendState(NoBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF); + + SetVertexShader(CompileShader(vs_4_0, PassThroughVS())); + SetHullShader(CompileShader(hs_5_0, PatchHS())); + SetDomainShader(CompileShader(ds_5_0, HeightFieldPatchDS())); + SetGeometryShader(NULL); + SetPixelShader(CompileShader(ps_4_0, HeightFieldPatchPS())); + } + pass Wireframe + { + SetRasterizerState(WireframeMS); + SetDepthStencilState(DepthNormal, 0); + SetBlendState(NoBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF); + + SetVertexShader(CompileShader(vs_4_0, PassThroughVS())); + SetHullShader(CompileShader(hs_5_0, PatchHS())); + SetDomainShader(CompileShader(ds_5_0, HeightFieldPatchDS())); + SetGeometryShader(NULL); + SetPixelShader(CompileShader(ps_4_0, ColorPS(float4(1.0f, 1.0f, 1.0f, 0.0f)))); + } + + pass DepthOnly + { + SetRasterizerState(CullBackMS); + SetDepthStencilState(DepthNormal, 0); + SetBlendState(NoBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF); + + SetVertexShader(CompileShader(vs_4_0, PassThroughVS())); + SetHullShader(CompileShader(hs_5_0, PatchHS())); + SetDomainShader(CompileShader(ds_5_0, HeightFieldPatchDS())); + SetGeometryShader(NULL); + SetPixelShader(NULL); + } + + pass DataPass + { + SetRasterizerState(CullBackMS); + SetDepthStencilState(DepthNormal, 0); + SetBlendState(NoBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF); + + SetVertexShader(CompileShader(vs_4_0, PassThroughVS())); + SetHullShader(CompileShader(hs_5_0, PatchHS())); + SetDomainShader(CompileShader(ds_5_0, HeightFieldPatchDS())); + SetGeometryShader(NULL); + SetPixelShader(CompileShader(ps_4_0, HeightFieldPatchDataPS())); + } +} + + +technique11 RenderSky +{ + pass Solid + { + SetRasterizerState(NoCullMS); + SetDepthStencilState(DepthNormal, 0); + SetBlendState(NoBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF); + + SetVertexShader(CompileShader(vs_4_0, SkyVS())); + SetHullShader(NULL); + SetDomainShader(NULL); + SetGeometryShader(NULL); + SetPixelShader(CompileShader(ps_4_0, SkyPS())); + } + pass Wireframe + { + SetRasterizerState(WireframeMS); + SetDepthStencilState(DepthNormal, 0); + SetBlendState(NoBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF); + + SetVertexShader(CompileShader(vs_4_0, SkyVS())); + SetHullShader(NULL); + SetDomainShader(NULL); + SetGeometryShader(NULL); + SetPixelShader(CompileShader(ps_4_0, ColorPS(float4(1.0f, 1.0f, 1.0f, 0.0f)))); + } +} diff --git a/sample/d3d11/sample_d3d11.cpp b/sample/d3d11/sample_d3d11.cpp new file mode 100644 index 0000000..5e5b896 --- /dev/null +++ b/sample/d3d11/sample_d3d11.cpp @@ -0,0 +1,1307 @@ +// 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 "DXUTcamera.h" +#include "DXUTgui.h" +#include "DXUTsettingsdlg.h" +#include "SDKmisc.h" + +#include "resource.h" +#include "ocean_surface.h" +#include "distance_field.h" +#include "GFSDK_WaveWorks.h" +#include "GFSDK_WaveWorks_D3D_Util.h" +#include "terrain.h" +#include // for QueryPerformanceFrequency/QueryPerformanceCounter + +//#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 +bool g_bShowUI = true; // UI can be hidden e.g. for video capture +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 + +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 = 50 }; +enum { ReadbackArchiveInterval = 5 }; +float g_ReadbackCoord = 0.f; + +OceanSurface* g_pOceanSurf = NULL; +DistanceField* g_pDistanceField = NULL; + +GFSDK_WaveWorks_Simulation_Params g_ocean_simulation_param; +GFSDK_WaveWorks_Simulation_Settings g_ocean_simulation_settings; +GFSDK_WaveWorks_Simulation_Stats g_ocean_simulation_stats; +GFSDK_WaveWorks_Simulation_Stats g_ocean_simulation_stats_filtered; + +GFSDK_WaveWorks_Quadtree_Params g_ocean_quadtree_param; +GFSDK_WaveWorks_Quadtree_Stats g_ocean_quadtree_stats; +GFSDK_WaveWorks_Simulation_DetailLevel g_max_detail_level = GFSDK_WaveWorks_Simulation_DetailLevel_Normal; + +D3DXVECTOR2 g_WindDir = D3DXVECTOR2(0.8f, 0.6f); +bool g_Wireframe = false; +bool g_SimulateWater = true; +bool g_ForceKick = false; +bool g_QueryStats = false; +bool g_enableShoreEffects = true; +float g_TessellationLOD = 50.0f; +float g_NearPlane = 1.0f; +float g_FarPlane = 25000.0f; +double g_SimulationTime = 0.0; +float g_FrameTime = 0.0f; + +float g_GerstnerSteepness = 1.0f; +float g_BaseGerstnerAmplitude = 0.279f; +float g_BaseGerstnerWavelength = 3.912f; +float g_BaseGerstnerSpeed = 2.472f; +float g_GerstnerParallelity = 0.2f; +float g_ShoreTime = 0.0f; + +CTerrain g_Terrain; +ID3DX11Effect* g_pEffect = NULL; + +ID3DX11EffectTechnique* g_pLogoTechnique = NULL; +ID3DX11EffectShaderResourceVariable* g_pLogoTextureVariable = NULL; +ID3D11ShaderResourceView* g_pLogoTex = NULL; +ID3D11Buffer* g_pLogoVB = NULL; +ID3D11InputLayout* g_pSkyboxLayout = NULL; + + + +D3D11_QUERY_DATA_PIPELINE_STATISTICS g_PipelineQueryData; +ID3D11Query* g_pPipelineQuery= NULL; + +// Readbacks and raycasts related globals +enum { NumMarkersXY = 10, NumMarkers = NumMarkersXY*NumMarkersXY }; + +gfsdk_float2 g_readback_marker_coords[NumMarkers]; +gfsdk_float4 g_readback_marker_positions[NumMarkers]; + +D3DXVECTOR3 g_raycast_origins[NumMarkers]; +D3DXVECTOR3 g_raycast_directions[NumMarkers]; +D3DXVECTOR3 g_raycast_hitpoints[NumMarkers]; +bool g_raycast_hittestresults[NumMarkers]; +static LARGE_INTEGER g_IntersectRaysPerfCounter, g_IntersectRaysPerfCounterOld, g_IntersectRaysPerfFrequency; +float g_IntersectRaysTime; + +//-------------------------------------------------------------------------------------- +// UI control IDs +//-------------------------------------------------------------------------------------- +#define IDC_TOGGLEFULLSCREEN 1 +#define IDC_TOGGLEREF 2 +#define IDC_CHANGEDEVICE 3 +#define IDC_WIND_SPEED_SLIDER 4 +#define IDC_WIND_DEPENDENCY_SLIDER 5 +#define IDC_TIME_SCALE_SLIDER 6 +#define IDC_TOGGLEWIREFRAME 7 +#define IDC_TOGGLESIMULATE 8 +#define IDC_TESSELLATION_LOD_SLIDER 9 +#define IDC_TOGGLEQUERYSTATS 10 +#define IDC_DETAIL_LEVEL_COMBO 11 +#define IDC_TOGGLEUSESHOREEFFECTS 12 + +CDXUTComboBox* g_pDetailLevelCombo = NULL; + +const INT kSliderRange = 100; +const FLOAT kMinWindDep = 0.f; +const FLOAT kMaxWindDep = 1.f; +const FLOAT kMinTimeScale = 0.25f; +const FLOAT kMaxTimeScale = 1.f; +const FLOAT kMinWindSpeedBeaufort = 2.0f; +const FLOAT kMaxWindSpeedBeaufort = 4.0f; + +//-------------------------------------------------------------------------------------- +// 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 UpdateReadbackPositions(); +void UpdateRaycastPositions(); + +HRESULT a; + +enum SynchronizationMode +{ + SynchronizationMode_None = 0, + SynchronizationMode_RenderOnly, + SynchronizationMode_Readback, + Num_SynchronizationModes +}; +SynchronizationMode g_bSyncMode = SynchronizationMode_None; + +//-------------------------------------------------------------------------------------- +// 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 + // 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_11_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(); + + return DXUTGetExitCode(); +} + + +//-------------------------------------------------------------------------------------- +// Initialize the app +//-------------------------------------------------------------------------------------- +void InitApp() +{ + g_ocean_quadtree_param.min_patch_length = 40.f; + g_ocean_quadtree_param.upper_grid_coverage = 64.0f; + g_ocean_quadtree_param.mesh_dim = 128; + g_ocean_quadtree_param.sea_level = -2.f; + g_ocean_quadtree_param.auto_root_lod = 10; + g_ocean_quadtree_param.use_tessellation = true; + g_ocean_quadtree_param.tessellation_lod = 50.0f; + g_ocean_quadtree_param.geomorphing_degree = 1.f; + g_ocean_quadtree_param.enable_CPU_timers = true; + + g_ocean_simulation_param.time_scale = 0.75f; + g_ocean_simulation_param.wave_amplitude = 0.8f; + g_ocean_simulation_param.wind_dir = NvFromDX(g_WindDir); + g_ocean_simulation_param.wind_speed = 2.52f; + g_ocean_simulation_param.wind_dependency = 0.85f; + g_ocean_simulation_param.choppy_scale = 1.2f; + 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 = 400.0f; + g_ocean_simulation_settings.detail_level = GFSDK_WaveWorks_Simulation_DetailLevel_Normal; + g_ocean_simulation_settings.readback_displacements = true; + g_ocean_simulation_settings.num_readback_FIFO_entries = ReadbackArchiveSize; + g_ocean_simulation_settings.aniso_level = 16; + g_ocean_simulation_settings.CPU_simulation_threading_model = GFSDK_WaveWorks_Simulation_CPU_Threading_Model_Automatic; + g_ocean_simulation_settings.use_Beaufort_scale = true; + 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; + + // 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); + + const D3DCOLOR kHUDBackgroundColor = 0x5F2F2F2F; + g_HUD.SetBackgroundColors(kHUDBackgroundColor); + g_HUD.SetCallback( OnGUIEvent ); + g_SampleUI.SetCallback( OnGUIEvent ); + + AddGUISet(); +} + +void UpdateDetailLevelCombo() +{ + if(NULL == g_pDetailLevelCombo) + return; + + g_pDetailLevelCombo->RemoveAllItems(); + + for(int detail_level = 0; detail_level <= g_max_detail_level; ++detail_level) + { + switch(detail_level) + { + case GFSDK_WaveWorks_Simulation_DetailLevel_Normal: + g_pDetailLevelCombo->AddItem( L"Normal", NULL ); + break; + case GFSDK_WaveWorks_Simulation_DetailLevel_High: + g_pDetailLevelCombo->AddItem( L"High", NULL ); + break; + case GFSDK_WaveWorks_Simulation_DetailLevel_Extreme: + g_pDetailLevelCombo->AddItem( L"Extreme", NULL ); + break; + } + } + + g_pDetailLevelCombo->SetSelectedByIndex(g_ocean_simulation_settings.detail_level); + g_pDetailLevelCombo->SetDropHeight(32); +} + +void AddGUISet() +{ + int iY = 10; + const int kElementSize = 15; + + g_HUD.AddButton(IDC_TOGGLEFULLSCREEN, L"Toggle Full Screen", 10, iY, 180, kElementSize); + g_HUD.AddButton(IDC_CHANGEDEVICE, L"Change Device", 10, iY += 20, 180, kElementSize, VK_F2); + iY += 20; + + g_HUD.AddCheckBox(IDC_TOGGLESIMULATE, L"Simulate Water", 10, iY += 20, 180, kElementSize, g_SimulateWater); + g_HUD.AddCheckBox(IDC_TOGGLEQUERYSTATS, L"Show Stats", 10, iY += 20, 180, kElementSize, g_QueryStats); + g_HUD.AddCheckBox(IDC_TOGGLEUSESHOREEFFECTS, L"Shore Effects", 10, iY += 20, 180, kElementSize, g_enableShoreEffects); + g_HUD.AddCheckBox(IDC_TOGGLEWIREFRAME, L"Wireframe", 10, iY += 20, 180, kElementSize, g_Wireframe); + iY += 20; + + g_HUD.AddStatic(IDC_WIND_SPEED_SLIDER, L"Wind speed", 10, iY += kElementSize, 180, kElementSize); + g_HUD.AddSlider(IDC_WIND_SPEED_SLIDER, 10, iY += 20, 180, kElementSize, 0, kSliderRange, int(float(kSliderRange) * (g_ocean_simulation_param.wind_speed-kMinWindSpeedBeaufort)/(kMaxWindSpeedBeaufort-kMinWindSpeedBeaufort))); + + g_HUD.AddStatic(IDC_WIND_DEPENDENCY_SLIDER, L"Wind dependency: %.2f", 10, iY += kElementSize, 180, kElementSize); + g_HUD.AddSlider(IDC_WIND_DEPENDENCY_SLIDER, 10, iY += 20, 180, kElementSize, 0, 100, int(float(kSliderRange) * (g_ocean_simulation_param.wind_dependency-kMinWindDep)/(kMaxWindDep-kMinWindDep))); + + g_HUD.AddStatic(IDC_TIME_SCALE_SLIDER, L"Time scale", 10, iY += kElementSize, 180, kElementSize); + g_HUD.AddSlider(IDC_TIME_SCALE_SLIDER, 10, iY += 20, 180, kElementSize, 0, kSliderRange, int(float(kSliderRange) * (g_ocean_simulation_param.time_scale-kMinTimeScale)/(kMaxTimeScale-kMinTimeScale))); + + iY += 20; + + g_HUD.AddStatic(IDC_TESSELLATION_LOD_SLIDER, L"Tessellation LOD", 10, iY += kElementSize, 180, kElementSize); + g_HUD.AddSlider(IDC_TESSELLATION_LOD_SLIDER, 10, iY += 20, 180, kElementSize, 0, 200, int(g_TessellationLOD)); + + g_HUD.AddStatic(0, L"Detail Level", 10, iY += kElementSize, 180, kElementSize); + g_HUD.AddComboBox( IDC_DETAIL_LEVEL_COMBO, 10, iY += 20, 180, kElementSize, 0, false, &g_pDetailLevelCombo ); + + iY += 20; +} + +//-------------------------------------------------------------------------------------- +// 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 ) +{ + 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, void* pUserContext ) +{ + static bool s_bFirstTime = true; + if( s_bFirstTime ) + { + s_bFirstTime = false; + + // 16x CSAA + pDeviceSettings->d3d11.sd.SampleDesc.Count = 1; + pDeviceSettings->d3d11.sd.SampleDesc.Quality = 0; + g_Terrain.MultiSampleCount = 1; + g_Terrain.MultiSampleQuality = 0; + + // Turn off vsync + pDeviceSettings->d3d11.SyncInterval = 0; + } + else + { + if(pDeviceSettings->d3d11.sd.SampleDesc.Count>4) + pDeviceSettings->d3d11.sd.SampleDesc.Count = 4; + g_Terrain.MultiSampleCount = pDeviceSettings->d3d11.sd.SampleDesc.Count; + g_Terrain.MultiSampleQuality = pDeviceSettings->d3d11.sd.SampleDesc.Quality; + } + + // 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(pDeviceSettings->d3d11.AdapterOrdinal,&pAdapter); + if(FAILED(hr) || NULL == pAdapter) + return false; + + // Check detail level support + int detail_level = 0; + for(; detail_level != Num_GFSDK_WaveWorks_Simulation_DetailLevels; ++detail_level) { + if(!GFSDK_WaveWorks_Simulation_DetailLevelIsSupported_D3D11(pAdapter, (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 = g_max_detail_level; + + SAFE_RELEASE(pAdapter); + UpdateDetailLevelCombo(); + + 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; + TCHAR path[MAX_PATH]; + static int first_time=0; + + 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 ); + + if(first_time==0) + { + // Setup the camera's view parameters + XMVECTOR vecEye = XMVectorSet(-100.f, 8.0f, 200.f, 0); + XMVECTOR vecAt = XMVectorSet(100.f, 0.f, 200.f, 0); + + g_Camera.SetViewParams(vecEye, vecAt); + g_Camera.SetScalers(0.005f, 50.0f); + + } + + float aspectRatio = (float)pBackBufferSurfaceDesc->Width / (float)pBackBufferSurfaceDesc->Height; + g_Camera.SetProjParams(camera_fov * D3DX_PI / 360.0f, aspectRatio, scene_z_near, scene_z_far); + + // Ocean sim + GFSDK_WaveWorks_InitD3D11(pd3dDevice,NULL,GFSDK_WAVEWORKS_API_GUID); + + 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; + + // Ocean object + g_pOceanSurf = new OceanSurface(); + g_pOceanSurf->init(); + g_pOceanSurf->initQuadTree(g_ocean_quadtree_param); + 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)); + + // Effect hooks borrowed from ocean object + g_pLogoTechnique = g_pOceanSurf->m_pOceanFX->GetTechniqueByName("DisplayLogoTech"); + g_pLogoTextureVariable = g_pOceanSurf->m_pOceanFX->GetVariableByName("g_LogoTexture")->AsShaderResource(); + + ID3D11Resource* pD3D11Resource = NULL; + DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("..\\media\\nvidia_logo.dds")); + V_RETURN(D3DX11CreateTextureFromFile(pd3dDevice, path, NULL, NULL, &pD3D11Resource, NULL)); + V_RETURN(pd3dDevice->CreateShaderResourceView(pD3D11Resource, NULL, &g_pLogoTex)); + SAFE_RELEASE(pD3D11Resource); + + // Terrain and sky fx + ID3DXBuffer* pEffectBuffer = NULL; + DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("..\\Media\\sample_d3d11.fxo")); + V_RETURN(LoadFile(path, &pEffectBuffer)); + V_RETURN(D3DX11CreateEffectFromMemory(pEffectBuffer->GetBufferPointer(), pEffectBuffer->GetBufferSize(), 0, pd3dDevice, &g_pEffect)); + SAFE_RELEASE(pEffectBuffer); + + // Initialize shoreline interaction. + g_pDistanceField = new DistanceField( &g_Terrain ); + g_pDistanceField->Init( pd3dDevice ); + g_pOceanSurf->AttachDistanceFieldModule( g_pDistanceField ); + + // Initialize terrain + g_Terrain.Initialize(pd3dDevice,g_pEffect); + V_RETURN(g_Terrain.LoadTextures()); + g_Terrain.BackbufferWidth=(float)pBackBufferSurfaceDesc->Width; + g_Terrain.BackbufferHeight=(float)pBackBufferSurfaceDesc->Height; + g_Terrain.ReCreateBuffers(); + + // Creating pipeline query + D3D11_QUERY_DESC queryDesc; + queryDesc.Query = D3D11_QUERY_PIPELINE_STATISTICS; + queryDesc.MiscFlags = 0; + pd3dDevice->CreateQuery(&queryDesc, &g_pPipelineQuery); + + 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) ); + + float aspectRatio = (float)pBackBufferSurfaceDesc->Width / (float)pBackBufferSurfaceDesc->Height; + g_Camera.SetProjParams(camera_fov * D3DX_PI / 360.0f, aspectRatio, scene_z_near, scene_z_far); + + // UI + g_HUD.SetLocation(pBackBufferSurfaceDesc->Width-240, 8); + g_HUD.SetSize(232, 704); + + g_Terrain.BackbufferWidth = (float)pBackBufferSurfaceDesc->Width; + g_Terrain.BackbufferHeight = (float)pBackBufferSurfaceDesc->Height; + + g_Terrain.ReCreateBuffers(); + + // Logo VB + float width = (float)200/pBackBufferSurfaceDesc->Width; + float height = (float)160/pBackBufferSurfaceDesc->Height; + float half_tex = 0; + float vertices0[] = {-0.98f, -0.96f + height, 0, half_tex, half_tex, + -0.98f, -0.96f, 0, half_tex, half_tex+1.0f, + -0.98f + width, -0.96f + height, 0, half_tex+1.0f, half_tex, + -0.98f + width, -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; + g_Terrain.BackbufferWidth = (float)pBackBufferSurfaceDesc->Width; + g_Terrain.BackbufferHeight = (float)pBackBufferSurfaceDesc->Height; + + V_RETURN(pd3dDevice->CreateBuffer(&vBufferDesc, &vSrd, &g_pLogoVB)); + + return S_OK; +} + +//-------------------------------------------------------------------------------------- +// Handle updates to the scene. This is called regardless of which D3D API is used +//-------------------------------------------------------------------------------------- +void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext ) +{ + g_SimulationTime += fElapsedTime; + if(g_SimulateWater) + { + g_ShoreTime += fElapsedTime*g_ocean_simulation_param.time_scale; + } + + // Update the camera's position based on user input + g_Camera.FrameMove( fElapsedTime ); +} + +//-------------------------------------------------------------------------------------- +// Render the scene using the D3D11 device +//-------------------------------------------------------------------------------------- +void CALLBACK OnD3D11FrameRender( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pDC, double fTime, + float fElapsedTime, void* pUserContext ) +{ + CDXUTStatic* static_being_updated; + WCHAR number_string[256]; + + 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_simulation_stats); + + // Performing treadbacks and raycasts + UpdateReadbackPositions(); + UpdateRaycastPositions(); + + // exponential filtering for stats + g_ocean_simulation_stats_filtered.CPU_main_thread_wait_time = g_ocean_simulation_stats_filtered.CPU_main_thread_wait_time*0.98f + 0.02f*g_ocean_simulation_stats.CPU_main_thread_wait_time; + g_ocean_simulation_stats_filtered.CPU_threads_start_to_finish_time = g_ocean_simulation_stats_filtered.CPU_threads_start_to_finish_time*0.98f + 0.02f*g_ocean_simulation_stats.CPU_threads_start_to_finish_time; + g_ocean_simulation_stats_filtered.CPU_threads_total_time = g_ocean_simulation_stats_filtered.CPU_threads_total_time*0.98f + 0.02f*g_ocean_simulation_stats.CPU_threads_total_time; + g_ocean_simulation_stats_filtered.GPU_simulation_time = g_ocean_simulation_stats_filtered.GPU_simulation_time*0.98f + 0.02f*g_ocean_simulation_stats.GPU_simulation_time; + g_ocean_simulation_stats_filtered.GPU_FFT_simulation_time = g_ocean_simulation_stats_filtered.GPU_FFT_simulation_time*0.98f + 0.02f*g_ocean_simulation_stats.GPU_FFT_simulation_time; + g_ocean_simulation_stats_filtered.GPU_gfx_time = g_ocean_simulation_stats_filtered.GPU_gfx_time*0.98f + 0.02f*g_ocean_simulation_stats.GPU_gfx_time; + g_ocean_simulation_stats_filtered.GPU_update_time = g_ocean_simulation_stats_filtered.GPU_update_time*0.98f + 0.02f*g_ocean_simulation_stats.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; + } + + g_FrameTime = fElapsedTime; + + D3DXVECTOR2 ScreenSizeInv(1.0f / (g_Terrain.BackbufferWidth*main_buffer_size_multiplier), 1.0f / (g_Terrain.BackbufferHeight*main_buffer_size_multiplier)); + + ID3DX11Effect* oceanFX = g_pOceanSurf->m_pOceanFX; + + oceanFX->GetVariableByName("g_ZNear")->AsScalar()->SetFloat(scene_z_near); + oceanFX->GetVariableByName("g_ZFar")->AsScalar()->SetFloat(scene_z_far); + D3DXVECTOR3 light_pos = D3DXVECTOR3(140000.0f,65000.0f,40000.0f); + g_pEffect->GetVariableByName("g_LightPosition")->AsVector()->SetFloatVector(light_pos); + g_pEffect->GetVariableByName("g_ScreenSizeInv")->AsVector()->SetFloatVector(ScreenSizeInv); + oceanFX->GetVariableByName("g_ScreenSizeInv")->AsVector()->SetFloatVector(ScreenSizeInv); + g_pEffect->GetVariableByName("g_DynamicTessFactor")->AsScalar()->SetFloat(g_ocean_quadtree_param.tessellation_lod * 0.25f + 0.1f); + + g_pOceanSurf->m_pOceanFX->GetVariableByName("g_enableShoreEffects")->AsScalar()->SetFloat(g_enableShoreEffects? 1.0f:0.0f); + g_Terrain.pEffect->GetVariableByName("g_enableShoreEffects")->AsScalar()->SetFloat(g_enableShoreEffects? 1.0f:0.0f); + + g_Terrain.Render(&g_Camera); + g_pDistanceField->GenerateDataTexture( pDC ); + + + + RenderLogo(pDC); + + if(g_bShowUI) { + + const WCHAR* windSpeedFormatString = g_ocean_simulation_settings.use_Beaufort_scale ? L"Beaufort: %.1f" : L"Wind speed: %.1f"; + swprintf_s(number_string, 255, windSpeedFormatString, g_ocean_simulation_param.wind_speed); + static_being_updated = g_HUD.GetStatic(IDC_WIND_SPEED_SLIDER); + static_being_updated->SetText(number_string); + + swprintf_s(number_string, 255, L"Wind dependency: %.2f", g_ocean_simulation_param.wind_dependency); + static_being_updated = g_HUD.GetStatic(IDC_WIND_DEPENDENCY_SLIDER); + static_being_updated->SetText(number_string); + + swprintf_s(number_string, 255, L"Time scale: %.1f", g_ocean_simulation_param.time_scale); + static_being_updated = g_HUD.GetStatic(IDC_TIME_SCALE_SLIDER); + static_being_updated->SetText(number_string); + + swprintf_s(number_string, 255, L"Tessellation LOD: %.0f", g_ocean_quadtree_param.tessellation_lod); + static_being_updated = g_HUD.GetStatic(IDC_TESSELLATION_LOD_SLIDER); + static_being_updated->SetText(number_string); + + g_HUD.OnRender( fElapsedTime ); + g_SampleUI.OnRender( fElapsedTime ); + RenderText( fTime ); + } + + pDC->GSSetShader(NULL,NULL,0); +} + + +//-------------------------------------------------------------------------------------- +// Render the help and statistics text. This function uses the ID3DXFont interface for +// efficient text rendering. +//-------------------------------------------------------------------------------------- +void RenderText( double fTime ) +{ + + WCHAR number_string[256]; + WCHAR number_string_with_spaces[256]; + const UINT buffer_len = 2048; + WCHAR buffer[buffer_len]; + + // Output statistics + g_pTxtHelper->Begin(); + g_pTxtHelper->SetInsertionPos( 2, 0 ); + g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 0.9f, 0.9f, 0.9f, 1.0f ) ); + + swprintf_s(buffer, buffer_len, L"Lib build: %S\n", GFSDK_WaveWorks_GetBuildString()); + g_pTxtHelper->DrawTextLine(buffer); + + g_pTxtHelper->DrawTextLine( DXUTGetFrameStats(true) ); + g_pTxtHelper->DrawTextLine( DXUTGetDeviceStats() ); + + if(g_QueryStats) + { + g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) ); + g_pTxtHelper->DrawTextLine(L"----------"); + wsprintf(buffer, L"Quad patches drawn : %d\n", g_ocean_quadtree_stats.num_patches_drawn); + g_pTxtHelper->DrawTextLine(buffer); + + g_pTxtHelper->DrawTextLine(L"----------"); + g_pTxtHelper->DrawTextLine(L"Pipeline Stats for water surface"); + + wsprintf(number_string, L"%d", (UINT)g_PipelineQueryData.IAPrimitives); + number_string_with_spaces[0]=NULL; + for(int i=0;i<(int)wcslen(number_string);i++) + { + if((((int)wcslen(number_string)-i)%3==0)&&(i!=0)) wcsncat_s(&number_string_with_spaces[0],256,L",",1); + wcsncat_s(&number_string_with_spaces[0],256,&number_string[i],1); + } + wsprintf(buffer, L"Input Primitives : %s", number_string_with_spaces); + g_pTxtHelper->DrawTextLine(buffer); + + + wsprintf(number_string, L"%d", (UINT)g_PipelineQueryData.CInvocations); + number_string_with_spaces[0]=NULL; + for(int i=0;i<(int)wcslen(number_string);i++) + { + if((((int)wcslen(number_string)-i)%3==0)&&(i!=0)) wcsncat_s(&number_string_with_spaces[0],256,L",",1); + wcsncat_s(&number_string_with_spaces[0],256,&number_string[i],1); + } + wsprintf(buffer, L"Primitives created : %s", number_string_with_spaces); + g_pTxtHelper->DrawTextLine(buffer); + + + wsprintf(number_string, L"%d", (UINT)((float)g_PipelineQueryData.CInvocations*(1.0f/g_FrameTime)/1000000.0f)); + number_string_with_spaces[0]=NULL; + for(int i=0;i<(int)wcslen(number_string);i++) + { + if((((int)wcslen(number_string)-i)%3==0)&&(i!=0)) wcsncat_s(&number_string_with_spaces[0],256,L",",1); + wcsncat_s(&number_string_with_spaces[0],256,&number_string[i],1); + } + wsprintf(buffer, L"Primitives created / sec : %sM", number_string_with_spaces); + g_pTxtHelper->DrawTextLine(buffer); + + wsprintf(number_string, L"%d", (UINT)g_PipelineQueryData.CPrimitives); + number_string_with_spaces[0]=NULL; + for(int i=0;i<(int)wcslen(number_string);i++) + { + if((((int)wcslen(number_string)-i)%3==0)&&(i!=0)) wcsncat_s(&number_string_with_spaces[0],256,L",",1); + wcsncat_s(&number_string_with_spaces[0],256,&number_string[i],1); + } + wsprintf(buffer, L"Primitives passed clipping : %s", number_string_with_spaces); + g_pTxtHelper->DrawTextLine(buffer); + + if(g_PipelineQueryData.IAPrimitives>0) + { + wsprintf(number_string, L"%d", (UINT)(g_PipelineQueryData.CInvocations/g_PipelineQueryData.IAPrimitives)); + number_string_with_spaces[0]=NULL; + for(int i=0;i<(int)wcslen(number_string);i++) + { + if((((int)wcslen(number_string)-i)%3==0)&&(i!=0)) wcsncat_s(&number_string_with_spaces[0],256,L",",1); + wcsncat_s(&number_string_with_spaces[0],256,&number_string[i],1); + } + wsprintf(buffer, L"Average expansion ratio : %s", number_string_with_spaces); + } + else + { + wsprintf(buffer, L"Average expansion ratio : N/A"); + } + g_pTxtHelper->DrawTextLine(buffer); + g_pTxtHelper->DrawTextLine(L"----------"); + + swprintf_s(buffer,buffer_len,L"GPU_gfx_time : %3.3f msec",g_ocean_simulation_stats_filtered.GPU_gfx_time); + g_pTxtHelper->DrawTextLine(buffer); + swprintf_s(buffer,buffer_len,L"GPU_update_time : %3.3f msec",g_ocean_simulation_stats_filtered.GPU_update_time); + g_pTxtHelper->DrawTextLine(buffer); + swprintf_s(buffer,buffer_len,L"CPU_main_thread_wait_time : %3.3f msec",g_ocean_simulation_stats_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_simulation_stats_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_simulation_stats_filtered.CPU_threads_total_time); + g_pTxtHelper->DrawTextLine(buffer); + swprintf_s(buffer,buffer_len,L"GPU_simulation_time : %3.3f msec",g_ocean_simulation_stats_filtered.GPU_simulation_time); + g_pTxtHelper->DrawTextLine(buffer); + swprintf_s(buffer,buffer_len,L"GPU_FFT_simulation_time : %3.3f msec",g_ocean_simulation_stats_filtered.GPU_FFT_simulation_time); + g_pTxtHelper->DrawTextLine(buffer); + swprintf_s(buffer,buffer_len,L"CPU_quadtree_update_time : %3.3f msec",g_ocean_quadtree_stats.CPU_quadtree_update_time); + 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 : "); + g_pTxtHelper->DrawTextLine(buffer); + } + + swprintf_s(buffer,buffer_len,L"Num of raycasts : %i",NumMarkers); + g_pTxtHelper->DrawTextLine(buffer); + swprintf_s(buffer,buffer_len,L"Total time for raycasts : %3.3f msec", 1000.0f * g_IntersectRaysTime); + g_pTxtHelper->DrawTextLine(buffer); + swprintf_s(buffer,buffer_len,L"Time per raycast : %3.3f msec", 1000.0f * g_IntersectRaysTime / NumMarkers); + g_pTxtHelper->DrawTextLine(buffer); + g_pTxtHelper->DrawTextLine(L"----------"); + swprintf_s(buffer,buffer_len,L"Readback cache coordinate : %3.3f", g_ReadbackCoord); + g_pTxtHelper->DrawTextLine(buffer); + } + + // Draw help + if( g_bShowHelp ) + { + g_pTxtHelper->DrawTextLine(L"----------"); + g_pTxtHelper->DrawTextLine( L"Controls:" ); + g_pTxtHelper->DrawTextLine( L"Camera control: left mouse\n"); + g_pTxtHelper->DrawTextLine( L"W/S/A/D/Q/E to move camera" ); + g_pTxtHelper->DrawTextLine( L"'[' to cycle readback mode" ); + g_pTxtHelper->DrawTextLine( L"'N'/'M' to change readback cache coordinate" ); + g_pTxtHelper->DrawTextLine( L"'U' to toggle UI" ); + g_pTxtHelper->DrawTextLine( L"Hide help: F1\nQuit: ESC\n" ); + } + else + { + g_pTxtHelper->DrawTextLine(L"----------"); + g_pTxtHelper->DrawTextLine( L"Press F1 for help" ); + } + 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 'u': + case 'U': + g_bShowUI = !g_bShowUI; + 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_TOGGLESIMULATE: g_SimulateWater = g_HUD.GetCheckBox(IDC_TOGGLESIMULATE)->GetChecked(); break; + case IDC_TOGGLEQUERYSTATS: g_QueryStats = g_HUD.GetCheckBox(IDC_TOGGLEQUERYSTATS)->GetChecked(); break; + + + case IDC_TOGGLEUSESHOREEFFECTS: + { + g_enableShoreEffects = !g_enableShoreEffects; + break; + } + + case IDC_TOGGLEWIREFRAME: + { + g_Wireframe = !g_Wireframe; + break; + } + + case IDC_WIND_SPEED_SLIDER: + if(EVENT_SLIDER_VALUE_CHANGED_UP == nEvent) + { + g_ocean_simulation_param.wind_speed = kMinWindSpeedBeaufort + FLOAT(g_HUD.GetSlider(IDC_WIND_SPEED_SLIDER)->GetValue()) * (kMaxWindSpeedBeaufort-kMinWindSpeedBeaufort)/float(kSliderRange); + 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)); + g_BaseGerstnerAmplitude = (GFSDK_WaveWorks_Simulation_GetConservativeMaxDisplacementEstimate(g_hOceanSimulation)/4.0f); // The estimate is based on significant wave height with 4x confidence: http://en.wikipedia.org/wiki/Significant_wave_height, we take it as our shore wave + g_BaseGerstnerWavelength = 14.0f*g_BaseGerstnerAmplitude; // 7.0 is the min possible, according to Bascom reports: http://hyperphysics.phy-astr.gsu.edu/hbase/waves/watwav2.html + g_BaseGerstnerSpeed = sqrtf(9.81f*g_BaseGerstnerWavelength/6.28f); // m/sec, let's use equation for deep water waves for simplicity, and slow it down a bit as we're working with shallow water + break; + } + break; + + case IDC_WIND_DEPENDENCY_SLIDER: + if(EVENT_SLIDER_VALUE_CHANGED_UP == nEvent) + { + g_ocean_simulation_param.wind_dependency = kMinWindDep + FLOAT(g_HUD.GetSlider(IDC_WIND_DEPENDENCY_SLIDER)->GetValue()) * (kMaxWindDep-kMinWindDep)/float(kSliderRange); + 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 = kMinTimeScale + FLOAT(g_HUD.GetSlider(IDC_TIME_SCALE_SLIDER)->GetValue()) * (kMaxTimeScale-kMinTimeScale)/float(kSliderRange); + GFSDK_WaveWorks_Simulation_UpdateProperties(g_hOceanSimulation, g_ocean_simulation_settings, g_ocean_simulation_param); + } + break; + + case IDC_TESSELLATION_LOD_SLIDER: + { + g_ocean_quadtree_param.tessellation_lod = (float)g_HUD.GetSlider(IDC_TESSELLATION_LOD_SLIDER)->GetValue(); + g_pOceanSurf->initQuadTree(g_ocean_quadtree_param); + } + break; + + case IDC_DETAIL_LEVEL_COMBO: + { + g_ocean_simulation_settings.detail_level = (GFSDK_WaveWorks_Simulation_DetailLevel)g_HUD.GetComboBox(IDC_DETAIL_LEVEL_COMBO)->GetSelectedIndex(); + 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); + SAFE_DELETE(g_pDistanceField); + + if(g_hOceanSimulation) + { + GFSDK_WaveWorks_Simulation_Destroy(g_hOceanSimulation); + g_hOceanSimulation = NULL; + } + SAFE_RELEASE(g_pLogoTex); + SAFE_RELEASE(g_pEffect); + SAFE_DELETE(g_pTxtHelper); + g_Terrain.DeInitialize(); + + if(g_hOceanSavestate) + { + GFSDK_WaveWorks_Savestate_Destroy(g_hOceanSavestate); + g_hOceanSavestate = NULL; + } + + GFSDK_WaveWorks_ReleaseD3D11(DXUTGetD3D11Device()); + + SAFE_RELEASE(g_pPipelineQuery); +} + +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); + pDC->GSSetShader(NULL,NULL,0); + pDC->HSSetShader(NULL,NULL,0); + pDC->DSSetShader(NULL,NULL,0); + g_pLogoTechnique->GetPassByIndex(0)->Apply(0, pDC); + pDC->Draw(4, 0); +} + +void UpdateReadbackPositions() +{ + for(int x = 0; x != NumMarkersXY; ++x) + { + for(int y = 0; y != NumMarkersXY; ++y) + { + g_readback_marker_coords[y * NumMarkersXY + x].x = 5.0f*x; + g_readback_marker_coords[y * NumMarkersXY + x].y = 5.0f*y; + } + } + + 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 + 1); + GFSDK_WaveWorks_Simulation_GetArchivedDisplacements(g_hOceanSimulation, coord, g_readback_marker_coords, displacements, NumMarkers); + } + else + { + GFSDK_WaveWorks_Simulation_GetDisplacements(g_hOceanSimulation, g_readback_marker_coords, displacements, NumMarkers); + } + + for(int ix = 0; ix != NumMarkers; ++ix) + { + g_readback_marker_positions[ix].x = displacements[ix].x + g_readback_marker_coords[ix].x; + g_readback_marker_positions[ix].y = displacements[ix].y + g_readback_marker_coords[ix].y; + g_readback_marker_positions[ix].z = displacements[ix].z + g_ocean_quadtree_param.sea_level; + g_readback_marker_positions[ix].w = 1.f; + } + } +} + +// Returns true and sets Result to intersection point if intersection is found, or returns false and does not update Result +// NB: The function does trace the water surface from above or from inside the water volume, but can be easily changed to trace from below water volume +// NB: y axiz is up +bool intersectRayWithOcean(D3DXVECTOR3& Result, D3DXVECTOR3 Position, D3DXVECTOR3 Direction, GFSDK_WaveWorks_SimulationHandle hSim, float sea_level) +{ + gfsdk_float2 test_point; // x,z coordinates of current test point + gfsdk_float2 old_test_point; // x,z coordinates of current test point + gfsdk_float4 displacements; // displacements returned by GFSDK_WaveWorks library + float t; // distance traveled along the ray while tracing + int num_steps = 0; // number of steps we've done while tracing + float max_displacement = GFSDK_WaveWorks_Simulation_GetConservativeMaxDisplacementEstimate(hSim); + // the maximal possible displacements of ocean surface along y axis, + // defining volume we have to trace + const int max_num_successive_steps = 16; // we limit ourselves on #of successive steps + const int max_num_binary_steps = 16; // we limit ourselves on #of binary search steps + const float t_threshold = 0.05f; // we stop successive tracing when we don't progress more than 5 cm each step + const float refinement_threshold_sqr = 0.1f*0.1f; // we stop refinement step when we don't progress more than 10cm while doing refinement of current water altitude + const float t_multiplier = 1.8f/(fabs(Direction.y) + 1.0f); // we increase step length at steep angles to speed up the tracing, + // but less than 2 to make sure the process converges + // and to add some safety to minimize chance of overshooting + D3DXVECTOR3 PositionBSStart; // Vectors used at binary search step + D3DXVECTOR3 PositionBSEnd; + + // normalizing direction + D3DXVec3Normalize(&Direction, &Direction); + + // checking if ray is outside of ocean surface volume + if((Position.y >= max_displacement + sea_level) && (Direction.y >=0)) return false; + + // getting to the top edge of volume where we can start + if(Position.y > max_displacement + sea_level) + { + t = -(Position.y - max_displacement - sea_level) / Direction.y; + Position += t*Direction; + } + + // tracing the ocean surface: + // moving along the ray by distance defined by vertical distance form current test point, increased/decreased by safety multiplier + // this process will converge despite our assumption on local flatness of the surface because curvature of the surface is smooth + // NB: this process guarantees we don't shoot through wave tips + while(1) + { + displacements.x = 0; + displacements.y = 0; + old_test_point.x = 0; + old_test_point.y = 0; + for(int k = 0; k < 4; k++) // few refinement steps to converge at correct intersection point + { + // moving back sample points by the displacements read initially, + // to get a guess on which undisturbed water surface point moved to the actual sample point + // due to x,y motion of water surface, assuming the x,y disturbances are locally constant + test_point.x = Position.x - displacements.x; + test_point.y = Position.z - displacements.y; + GFSDK_WaveWorks_Simulation_GetDisplacements( hSim, &test_point, &displacements, 1 ); + if(refinement_threshold_sqr > (old_test_point.x - test_point.x)*(old_test_point.x - test_point.x) + (old_test_point.y - test_point.y)*(old_test_point.y - test_point.y)) break; + old_test_point.x = test_point.x; + old_test_point.y = test_point.y; + } + // getting t to travel along the ray + t = t_multiplier * (Position.y - displacements.z - sea_level); + + // traveling along the ray + Position += t*Direction; + + if(num_steps >= max_num_successive_steps) break; + if(t < t_threshold) break; + ++num_steps; + } + + // exited the loop, checking if intersection is found + if(t < t_threshold) + { + Result.x = Position.x; + Result.y = Position.y; + Result.z = Position.z; + return true; + } + + // if we're looking down and we did not hit water surface, doing binary search to make sure we hit water surface, + // but there is risk of shooting through wave tips if we are tracing at extremely steep angles + if(Direction.y < 0) + { + PositionBSStart = Position; + + // getting to the bottom edge of volume where we can start + t = -(Position.y + max_displacement - sea_level) / Direction.y; + PositionBSEnd = Position + t*Direction; + + for(int i = 0; i < max_num_binary_steps; i++) + { + Position = (PositionBSStart + PositionBSEnd)*0.5f; + old_test_point.x = 0; + old_test_point.y = 0; + for(int k = 0; k < 4; k++) + { + test_point.x = Position.x - displacements.x; + test_point.y = Position.z - displacements.y; + GFSDK_WaveWorks_Simulation_GetDisplacements( hSim, &test_point, &displacements, 1 ); + if(refinement_threshold_sqr > (old_test_point.x - test_point.x)*(old_test_point.x - test_point.x) + (old_test_point.y - test_point.y)*(old_test_point.y - test_point.y)) break; + old_test_point.x = test_point.x; + old_test_point.y = test_point.y; + } + if(Position.y - displacements.z - sea_level > 0) + { + PositionBSStart = Position; + } + else + { + PositionBSEnd = Position; + } + } + Result.x = Position.x; + Result.y = Position.y; + Result.z = Position.z; + return true; + } + return false; +} + +void UpdateRaycastPositions() +{ + for(int x = 0; x != NumMarkersXY; ++x) + { + for(int y = 0; y != NumMarkersXY; ++y) + { + int i = x + y*NumMarkersXY; + g_raycast_origins[i].x = 0; + g_raycast_origins[i].y = 10; + g_raycast_origins[i].z = terrain_gridpoints*terrain_geometry_scale; + g_raycast_directions[i].x = 5.0f*float(x - NumMarkersXY/2.0f); + g_raycast_directions[i].y = -10.0f; + g_raycast_directions[i].z = 5.0f*float(y - NumMarkersXY/2.0f); + D3DXVec3Normalize(&g_raycast_directions[i], &g_raycast_directions[i]); + } + } + g_IntersectRaysTime = 0.f; + // Performing water hit test for rays + QueryPerformanceFrequency(&g_IntersectRaysPerfFrequency); + QueryPerformanceCounter(&g_IntersectRaysPerfCounterOld); + for(int i = 0; i < NumMarkers; i++) + { + g_raycast_hittestresults[i] = intersectRayWithOcean(g_raycast_hitpoints[i], g_raycast_origins[i], g_raycast_directions[i], g_hOceanSimulation, g_ocean_quadtree_param.sea_level); + } + QueryPerformanceCounter(&g_IntersectRaysPerfCounter); + g_IntersectRaysTime = (float)(((double)(g_IntersectRaysPerfCounter.QuadPart) - (double)(g_IntersectRaysPerfCounterOld.QuadPart))/(double)g_IntersectRaysPerfFrequency.QuadPart); +} diff --git a/sample/d3d11/sample_d3d11.rc b/sample/d3d11/sample_d3d11.rc new file mode 100644 index 0000000..af4d459 --- /dev/null +++ b/sample/d3d11/sample_d3d11.rc @@ -0,0 +1,106 @@ +// 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. +// + +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define IDC_STATIC -1 +#include + + + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_MAIN_ICON ICON "common\\directx.ico" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#define IDC_STATIC -1\r\n" + "#include \r\n" + "\r\n" + "\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/sample/d3d11/terrain.cpp b/sample/d3d11/terrain.cpp new file mode 100644 index 0000000..5e10537 --- /dev/null +++ b/sample/d3d11/terrain.cpp @@ -0,0 +1,1468 @@ +// 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 "terrain.h" +#include + +#include "ocean_surface.h" +#include "DDSTextureLoader.h" + +#ifndef PI +#define PI 3.14159265358979323846f +#endif + +extern OceanSurface *g_pOceanSurf; +extern GFSDK_WaveWorks_SimulationHandle g_hOceanSimulation; +extern GFSDK_WaveWorks_SavestateHandle g_hOceanSavestate; +extern GFSDK_WaveWorks_Quadtree_Stats g_ocean_quadtree_stats; + + +extern D3D11_QUERY_DATA_PIPELINE_STATISTICS g_PipelineQueryData; +extern ID3D11Query* g_pPipelineQuery; +extern bool g_QueryStats; + +extern float g_GerstnerSteepness; +extern float g_BaseGerstnerAmplitude; +extern float g_BaseGerstnerWavelength; +extern float g_BaseGerstnerSpeed; +extern float g_GerstnerParallelity; +extern float g_ShoreTime; +extern XMFLOAT3 g_WindDir; +extern bool g_Wireframe; + +enum { NumMarkersXY = 10, NumMarkers = NumMarkersXY*NumMarkersXY }; + +extern gfsdk_float2 g_readback_marker_coords[NumMarkers]; +extern gfsdk_float4 g_readback_marker_positions[NumMarkers]; + +extern XMFLOAT3 g_raycast_origins[NumMarkers]; +extern XMFLOAT3 g_raycast_directions[NumMarkers]; +extern XMFLOAT3 g_raycast_hitpoints[NumMarkers]; + +int gp_wrap( int a) +{ + if(a<0) return (a+terrain_gridpoints); + if(a>=terrain_gridpoints) return (a-terrain_gridpoints); + return a; +} + +void CTerrain::Initialize(ID3D11Device* device, ID3DX11Effect * effect) +{ + pEffect = effect; + pDevice = device; + + + const D3D11_INPUT_ELEMENT_DESC TerrainLayout = + { "PATCH_PARAMETERS", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; + + D3DX11_PASS_DESC passDesc; + effect->GetTechniqueByName("RenderHeightfield")->GetPassByIndex(0)->GetDesc(&passDesc); + + device->CreateInputLayout( &TerrainLayout, 1, passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, &heightfield_inputlayout ); + + const D3D11_INPUT_ELEMENT_DESC SkyLayout [] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 } + }; + + effect->GetTechniqueByName("RenderSky")->GetPassByIndex(0)->GetDesc(&passDesc); + + device->CreateInputLayout( SkyLayout, + 2, + passDesc.pIAInputSignature, + passDesc.IAInputSignatureSize, + &trianglestrip_inputlayout ); + + CreateTerrain(); +} + +void CTerrain::ReCreateBuffers() +{ + + D3D11_TEXTURE2D_DESC tex_desc; + D3D11_SHADER_RESOURCE_VIEW_DESC textureSRV_desc; + D3D11_DEPTH_STENCIL_VIEW_DESC DSV_desc; + + + + SAFE_RELEASE(main_color_resource); + SAFE_RELEASE(main_color_resourceSRV); + SAFE_RELEASE(main_color_resourceRTV); + + SAFE_RELEASE(main_color_resource_resolved); + SAFE_RELEASE(main_color_resource_resolvedSRV); + + SAFE_RELEASE(main_depth_resource); + SAFE_RELEASE(main_depth_resourceDSV); + SAFE_RELEASE(main_depth_resourceSRV); + + SAFE_RELEASE(reflection_color_resource); + SAFE_RELEASE(reflection_color_resourceSRV); + SAFE_RELEASE(reflection_color_resourceRTV); + SAFE_RELEASE(refraction_color_resource); + SAFE_RELEASE(refraction_color_resourceSRV); + SAFE_RELEASE(refraction_color_resourceRTV); + + SAFE_RELEASE(reflection_depth_resource); + SAFE_RELEASE(reflection_depth_resourceDSV); + SAFE_RELEASE(refraction_depth_resource); + SAFE_RELEASE(refraction_depth_resourceSRV); + SAFE_RELEASE(refraction_depth_resourceRTV); + + SAFE_RELEASE(shadowmap_resource); + SAFE_RELEASE(shadowmap_resourceDSV); + SAFE_RELEASE(shadowmap_resourceSRV); + + // recreating main color buffer + + ZeroMemory(&textureSRV_desc,sizeof(textureSRV_desc)); + ZeroMemory(&tex_desc,sizeof(tex_desc)); + + tex_desc.Width = (UINT)(BackbufferWidth*main_buffer_size_multiplier); + tex_desc.Height = (UINT)(BackbufferHeight*main_buffer_size_multiplier); + tex_desc.MipLevels = 1; + tex_desc.ArraySize = 1; + tex_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + tex_desc.SampleDesc.Count = MultiSampleCount; + tex_desc.SampleDesc.Quality = MultiSampleQuality; + tex_desc.Usage = D3D11_USAGE_DEFAULT; + tex_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + tex_desc.CPUAccessFlags = 0; + tex_desc.MiscFlags = 0; + + textureSRV_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + textureSRV_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + textureSRV_desc.Texture2D.MipLevels = tex_desc.MipLevels; + textureSRV_desc.Texture2D.MostDetailedMip = 0; + + + pDevice->CreateTexture2D ( &tex_desc, NULL, &main_color_resource ); + pDevice->CreateShaderResourceView( main_color_resource, &textureSRV_desc, &main_color_resourceSRV ); + pDevice->CreateRenderTargetView ( main_color_resource, NULL, &main_color_resourceRTV ); + + + ZeroMemory(&textureSRV_desc,sizeof(textureSRV_desc)); + ZeroMemory(&tex_desc,sizeof(tex_desc)); + + tex_desc.Width = (UINT)(BackbufferWidth*main_buffer_size_multiplier); + tex_desc.Height = (UINT)(BackbufferHeight*main_buffer_size_multiplier); + tex_desc.MipLevels = 1; + tex_desc.ArraySize = 1; + tex_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + tex_desc.SampleDesc.Count = 1; + tex_desc.SampleDesc.Quality = 0; + tex_desc.Usage = D3D11_USAGE_DEFAULT; + tex_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + tex_desc.CPUAccessFlags = 0; + tex_desc.MiscFlags = 0; + + textureSRV_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + textureSRV_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + textureSRV_desc.Texture2D.MipLevels = tex_desc.MipLevels; + textureSRV_desc.Texture2D.MostDetailedMip = 0; + + pDevice->CreateTexture2D ( &tex_desc, NULL, &main_color_resource_resolved ); + pDevice->CreateShaderResourceView( main_color_resource_resolved, &textureSRV_desc, &main_color_resource_resolvedSRV ); + + // recreating main depth buffer + + ZeroMemory(&textureSRV_desc,sizeof(textureSRV_desc)); + ZeroMemory(&tex_desc,sizeof(tex_desc)); + + tex_desc.Width = (UINT)(BackbufferWidth*main_buffer_size_multiplier); + tex_desc.Height = (UINT)(BackbufferHeight*main_buffer_size_multiplier); + tex_desc.MipLevels = 1; + tex_desc.ArraySize = 1; + tex_desc.Format = DXGI_FORMAT_R32_TYPELESS; + tex_desc.SampleDesc.Count = MultiSampleCount; + tex_desc.SampleDesc.Quality = MultiSampleQuality; + tex_desc.Usage = D3D11_USAGE_DEFAULT; + tex_desc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; + tex_desc.CPUAccessFlags = 0; + tex_desc.MiscFlags = 0; + + DSV_desc.Format = DXGI_FORMAT_D32_FLOAT; + DSV_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; + DSV_desc.Flags = 0; + DSV_desc.Texture2D.MipSlice = 0; + + textureSRV_desc.Format = DXGI_FORMAT_R32_FLOAT; + textureSRV_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + textureSRV_desc.Texture2D.MipLevels = 1; + textureSRV_desc.Texture2D.MostDetailedMip = 0; + + pDevice->CreateTexture2D( &tex_desc, NULL, &main_depth_resource ); + pDevice->CreateDepthStencilView(main_depth_resource, &DSV_desc, &main_depth_resourceDSV ); + pDevice->CreateShaderResourceView( main_depth_resource, &textureSRV_desc, &main_depth_resourceSRV ); + + // recreating reflection and refraction color buffers + + ZeroMemory(&textureSRV_desc,sizeof(textureSRV_desc)); + ZeroMemory(&tex_desc,sizeof(tex_desc)); + + tex_desc.Width = (UINT)(BackbufferWidth*reflection_buffer_size_multiplier); + tex_desc.Height = (UINT)(BackbufferHeight*reflection_buffer_size_multiplier); + tex_desc.MipLevels = (UINT)std::max(1.0f, log(std::max((float)tex_desc.Width,(float)tex_desc.Height))/(float)log(2.0f)); + tex_desc.ArraySize = 1; + tex_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + tex_desc.SampleDesc.Count = 1; + tex_desc.SampleDesc.Quality = 0; + tex_desc.Usage = D3D11_USAGE_DEFAULT; + tex_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + tex_desc.CPUAccessFlags = 0; + tex_desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; + + textureSRV_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + textureSRV_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + textureSRV_desc.Texture2D.MipLevels = tex_desc.MipLevels; + textureSRV_desc.Texture2D.MostDetailedMip = 0; + + pDevice->CreateTexture2D ( &tex_desc, NULL, &reflection_color_resource ); + pDevice->CreateShaderResourceView( reflection_color_resource, &textureSRV_desc, &reflection_color_resourceSRV ); + pDevice->CreateRenderTargetView ( reflection_color_resource, NULL, &reflection_color_resourceRTV ); + + + ZeroMemory(&textureSRV_desc,sizeof(textureSRV_desc)); + ZeroMemory(&tex_desc,sizeof(tex_desc)); + + tex_desc.Width = (UINT)(BackbufferWidth*refraction_buffer_size_multiplier); + tex_desc.Height = (UINT)(BackbufferHeight*refraction_buffer_size_multiplier); + tex_desc.MipLevels = (UINT)std::max(1.0f,log(std::max((float)tex_desc.Width,(float)tex_desc.Height))/(float)log(2.0f)); + tex_desc.ArraySize = 1; + tex_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + tex_desc.SampleDesc.Count = 1; + tex_desc.SampleDesc.Quality = 0; + tex_desc.Usage = D3D11_USAGE_DEFAULT; + tex_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + tex_desc.CPUAccessFlags = 0; + tex_desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; + + textureSRV_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + textureSRV_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + textureSRV_desc.Texture2D.MipLevels = tex_desc.MipLevels; + textureSRV_desc.Texture2D.MostDetailedMip = 0; + + pDevice->CreateTexture2D ( &tex_desc, NULL, &refraction_color_resource ); + pDevice->CreateShaderResourceView( refraction_color_resource, &textureSRV_desc, &refraction_color_resourceSRV ); + pDevice->CreateRenderTargetView ( refraction_color_resource, NULL, &refraction_color_resourceRTV ); + + ZeroMemory(&textureSRV_desc,sizeof(textureSRV_desc)); + ZeroMemory(&tex_desc,sizeof(tex_desc)); + + // recreating reflection and refraction depth buffers + + tex_desc.Width = (UINT)(BackbufferWidth*reflection_buffer_size_multiplier); + tex_desc.Height = (UINT)(BackbufferHeight*reflection_buffer_size_multiplier); + tex_desc.MipLevels = 1; + tex_desc.ArraySize = 1; + tex_desc.Format = DXGI_FORMAT_R32_TYPELESS; + tex_desc.SampleDesc.Count = 1; + tex_desc.SampleDesc.Quality = 0; + tex_desc.Usage = D3D11_USAGE_DEFAULT; + tex_desc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; + tex_desc.CPUAccessFlags = 0; + tex_desc.MiscFlags = 0; + + DSV_desc.Format = DXGI_FORMAT_D32_FLOAT; + DSV_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + DSV_desc.Flags = 0; + DSV_desc.Texture2D.MipSlice = 0; + + pDevice->CreateTexture2D( &tex_desc, NULL, &reflection_depth_resource ); + pDevice->CreateDepthStencilView(reflection_depth_resource, &DSV_desc, &reflection_depth_resourceDSV ); + + + tex_desc.Width = (UINT)(BackbufferWidth*refraction_buffer_size_multiplier); + tex_desc.Height = (UINT)(BackbufferHeight*refraction_buffer_size_multiplier); + tex_desc.MipLevels = 1; + tex_desc.ArraySize = 1; + tex_desc.Format = DXGI_FORMAT_R32_FLOAT; + tex_desc.SampleDesc.Count = 1; + tex_desc.SampleDesc.Quality = 0; + tex_desc.Usage = D3D11_USAGE_DEFAULT; + tex_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + tex_desc.CPUAccessFlags = 0; + tex_desc.MiscFlags = 0; + + textureSRV_desc.Format = DXGI_FORMAT_R32_FLOAT; + textureSRV_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + textureSRV_desc.Texture2D.MipLevels = 1; + textureSRV_desc.Texture2D.MostDetailedMip = 0; + + pDevice->CreateTexture2D( &tex_desc, NULL, &refraction_depth_resource ); + pDevice->CreateRenderTargetView (refraction_depth_resource, NULL, &refraction_depth_resourceRTV ); + pDevice->CreateShaderResourceView(refraction_depth_resource, &textureSRV_desc, &refraction_depth_resourceSRV ); + + // recreating shadowmap resource + tex_desc.Width = shadowmap_resource_buffer_size_xy; + tex_desc.Height = shadowmap_resource_buffer_size_xy; + tex_desc.MipLevels = 1; + tex_desc.ArraySize = 1; + tex_desc.Format = DXGI_FORMAT_R32_TYPELESS; + tex_desc.SampleDesc.Count = 1; + tex_desc.SampleDesc.Quality = 0; + tex_desc.Usage = D3D11_USAGE_DEFAULT; + tex_desc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; + tex_desc.CPUAccessFlags = 0; + tex_desc.MiscFlags = 0; + + DSV_desc.Format = DXGI_FORMAT_D32_FLOAT; + DSV_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + DSV_desc.Flags = 0; + DSV_desc.Texture2D.MipSlice=0; + + textureSRV_desc.Format = DXGI_FORMAT_R32_FLOAT; + textureSRV_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + textureSRV_desc.Texture2D.MipLevels = 1; + textureSRV_desc.Texture2D.MostDetailedMip = 0; + + pDevice->CreateTexture2D( &tex_desc, NULL, &shadowmap_resource); + pDevice->CreateShaderResourceView( shadowmap_resource, &textureSRV_desc, &shadowmap_resourceSRV ); + pDevice->CreateDepthStencilView(shadowmap_resource, &DSV_desc, &shadowmap_resourceDSV ); + +} + +void CTerrain::DeInitialize() +{ + SAFE_RELEASE(heightmap_texture); + SAFE_RELEASE(heightmap_textureSRV); + + SAFE_RELEASE(rock_bump_textureSRV); + + SAFE_RELEASE(layerdef_texture); + SAFE_RELEASE(layerdef_textureSRV); + + SAFE_RELEASE(depthmap_texture); + SAFE_RELEASE(depthmap_textureSRV); + + SAFE_RELEASE(sky_textureSRV); + + SAFE_RELEASE(foam_intensity_textureSRV); + + SAFE_RELEASE(foam_diffuse_textureSRV); + + SAFE_RELEASE(main_color_resource); + SAFE_RELEASE(main_color_resourceSRV); + SAFE_RELEASE(main_color_resourceRTV); + + SAFE_RELEASE(main_color_resource_resolved); + SAFE_RELEASE(main_color_resource_resolvedSRV); + + SAFE_RELEASE(main_depth_resource); + SAFE_RELEASE(main_depth_resourceDSV); + SAFE_RELEASE(main_depth_resourceSRV); + + SAFE_RELEASE(reflection_color_resource); + SAFE_RELEASE(reflection_color_resourceSRV); + SAFE_RELEASE(reflection_color_resourceRTV); + SAFE_RELEASE(refraction_color_resource); + SAFE_RELEASE(refraction_color_resourceSRV); + SAFE_RELEASE(refraction_color_resourceRTV); + + SAFE_RELEASE(reflection_depth_resource); + SAFE_RELEASE(reflection_depth_resourceDSV); + SAFE_RELEASE(refraction_depth_resource); + SAFE_RELEASE(refraction_depth_resourceRTV); + SAFE_RELEASE(refraction_depth_resourceSRV); + + SAFE_RELEASE(shadowmap_resource); + SAFE_RELEASE(shadowmap_resourceDSV); + SAFE_RELEASE(shadowmap_resourceSRV); + + SAFE_RELEASE(sky_vertexbuffer); + SAFE_RELEASE(trianglestrip_inputlayout); + + SAFE_RELEASE(heightfield_vertexbuffer); + SAFE_RELEASE(heightfield_inputlayout); + +} +void CTerrain::CreateTerrain() +{ + int i,j,k,l; + float x,z; + int ix,iz; + float * backterrain; + int currentstep=terrain_gridpoints; + float mv,rm; + float offset=0,yscale=0,maxheight=0,minheight=0; + + float *height_linear_array; + float *patches_rawdata; + HRESULT result; + D3D11_SUBRESOURCE_DATA subresource_data; + D3D11_TEXTURE2D_DESC tex_desc; + D3D11_SHADER_RESOURCE_VIEW_DESC textureSRV_desc; + + backterrain = (float *) malloc((terrain_gridpoints+1)*(terrain_gridpoints+1)*sizeof(float)); + rm=terrain_fractalinitialvalue; + backterrain[0]=0; + backterrain[0+terrain_gridpoints*terrain_gridpoints]=0; + backterrain[terrain_gridpoints]=0; + backterrain[terrain_gridpoints+terrain_gridpoints*terrain_gridpoints]=0; + currentstep=terrain_gridpoints; + srand(3); + + // generating fractal terrain using square-diamond method + while (currentstep>1) + { + //square step; + i=0; + j=0; + + + while (imaxheight) maxheight=height[i][j]; + if(height[i][j] 0.02f) + { + mv -= 0.02f; + } + if(mv < -3.00f) + { + mv += 0.5f; + } + height[i][j]=mv; + } + } + + XMVECTOR vec1, vec2, vec3; + + // smoothing + for(k=0;kterrain_rockfactor)||(height[i][j]<1.2f))) + { + rm=terrain_smoothfactor1; + mv=height[i][j]*(1.0f-rm) +rm*0.25f*(height[gp_wrap(i-1)][j]+height[i][gp_wrap(j-1)]+height[gp_wrap(i+1)][j]+height[i][gp_wrap(j+1)]); + backterrain[i+terrain_gridpoints*j]=mv; + } + else + { + rm=terrain_smoothfactor2; + mv=height[i][j]*(1.0f-rm) +rm*0.25f*(height[gp_wrap(i-1)][j]+height[i][gp_wrap(j-1)]+height[gp_wrap(i+1)][j]+height[i][gp_wrap(j+1)]); + backterrain[i+terrain_gridpoints*j]=mv; + } + + } + for (i=0;iterrain_height_underwater_start)&&(rm<=terrain_height_underwater_end)) + { + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+0]=255; + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+1]=0; + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+2]=0; + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+3]=0; + } + + if((rm>terrain_height_sand_start)&&(rm<=terrain_height_sand_end)) + { + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+0]=0; + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+1]=255; + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+2]=0; + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+3]=0; + } + + if((rm>terrain_height_grass_start)&&(rm<=terrain_height_grass_end)) + { + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+0]=0; + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+1]=0; + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+2]=255; + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+3]=0; + } + + mv=bilinear_interpolation(x-ix,z-iz,normal[ix][iz].y,normal[ix+1][iz].y,normal[ix+1][iz+1][1],normal[ix][iz+1].y); + + if((mvterrain_height_sand_end)) + { + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+0]=0; + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+1]=0; + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+2]=0; + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+3]=0; + } + + if((mvterrain_height_rocks_start)) + { + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+0]=0; + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+1]=0; + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+2]=0; + temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+3]=255; + } + + } + for(i=0;iCreateTexture2D(&tex_desc,&subresource_data,&layerdef_texture); + + ZeroMemory(&textureSRV_desc,sizeof(textureSRV_desc)); + textureSRV_desc.Format=tex_desc.Format; + textureSRV_desc.ViewDimension=D3D11_SRV_DIMENSION_TEXTURE2D; + textureSRV_desc.Texture2D.MipLevels=tex_desc.MipLevels; + textureSRV_desc.Texture2D.MostDetailedMip=0; + pDevice->CreateShaderResourceView(layerdef_texture,&textureSRV_desc,&layerdef_textureSRV); + + free(temp_layerdef_map_texture_pixels); + free(layerdef_map_texture_pixels); + + height_linear_array = new float [terrain_gridpoints*terrain_gridpoints*4]; + patches_rawdata = new float [terrain_numpatches_1d*terrain_numpatches_1d*4]; + + for(int i=0;iCreateTexture2D(&tex_desc,&subresource_data,&heightmap_texture); + + free(height_linear_array); + + ZeroMemory(&textureSRV_desc,sizeof(textureSRV_desc)); + textureSRV_desc.Format=tex_desc.Format; + textureSRV_desc.ViewDimension=D3D11_SRV_DIMENSION_TEXTURE2D; + textureSRV_desc.Texture2D.MipLevels=tex_desc.MipLevels; + pDevice->CreateShaderResourceView(heightmap_texture,&textureSRV_desc,&heightmap_textureSRV); + + //building depthmap + byte * depth_shadow_map_texture_pixels=(byte *)malloc(terrain_depth_shadow_map_texture_size*terrain_depth_shadow_map_texture_size*4); + for(i=0;i0) + { + depth_shadow_map_texture_pixels[(j*terrain_depth_shadow_map_texture_size+i)*4+0]=0; + depth_shadow_map_texture_pixels[(j*terrain_depth_shadow_map_texture_size+i)*4+1]=0; + depth_shadow_map_texture_pixels[(j*terrain_depth_shadow_map_texture_size+i)*4+2]=0; + } + else + { + float no=(1.0f*255.0f*(rm/(terrain_minheight*terrain_geometry_scale)))-1.0f; + if(no>255) no=255; + if(no<0) no=0; + depth_shadow_map_texture_pixels[(j*terrain_depth_shadow_map_texture_size+i)*4+0]=(byte)no; + + no=(10.0f*255.0f*(rm/(terrain_minheight*terrain_geometry_scale)))-80.0f; + if(no>255) no=255; + if(no<0) no=0; + depth_shadow_map_texture_pixels[(j*terrain_depth_shadow_map_texture_size+i)*4+1]=(byte)no; + + no=(100.0f*255.0f*(rm/(terrain_minheight*terrain_geometry_scale)))-300.0f; + if(no>255) no=255; + if(no<0) no=0; + depth_shadow_map_texture_pixels[(j*terrain_depth_shadow_map_texture_size+i)*4+2]=(byte)no; + } + depth_shadow_map_texture_pixels[(j*terrain_depth_shadow_map_texture_size+i)*4+3]=0; + } + + subresource_data.pSysMem = depth_shadow_map_texture_pixels; + subresource_data.SysMemPitch = terrain_depth_shadow_map_texture_size*4; + subresource_data.SysMemSlicePitch = 0; + + tex_desc.Width = terrain_depth_shadow_map_texture_size; + tex_desc.Height = terrain_depth_shadow_map_texture_size; + tex_desc.MipLevels = 1; + tex_desc.ArraySize = 1; + tex_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + tex_desc.SampleDesc.Count = 1; + tex_desc.SampleDesc.Quality = 0; + tex_desc.Usage = D3D11_USAGE_DEFAULT; + tex_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + tex_desc.CPUAccessFlags = 0; + tex_desc.MiscFlags = 0; + result=pDevice->CreateTexture2D(&tex_desc,&subresource_data,&depthmap_texture); + + ZeroMemory(&textureSRV_desc,sizeof(textureSRV_desc)); + textureSRV_desc.Format=tex_desc.Format; + textureSRV_desc.ViewDimension=D3D11_SRV_DIMENSION_TEXTURE2D; + textureSRV_desc.Texture2D.MipLevels=tex_desc.MipLevels; + pDevice->CreateShaderResourceView(depthmap_texture,&textureSRV_desc,&depthmap_textureSRV); + + free(depth_shadow_map_texture_pixels); + + // creating terrain vertex buffer + for(int i=0;iCreateBuffer(&buf_desc,&subresource_data,&heightfield_vertexbuffer); + free (patches_rawdata); + + // creating sky vertex buffer + float *sky_vertexdata; + int floatnum; + sky_vertexdata = new float [sky_gridpoints*(sky_gridpoints+2)*2*6]; + + for(int j=0;jCreateBuffer(&buf_desc,&subresource_data,&sky_vertexbuffer); + + free (sky_vertexdata); +} + +HRESULT CTerrain::LoadTextures() +{ + WCHAR path[MAX_PATH]; + + HRESULT hr; + + ID3D11Resource* pD3D11Resource = NULL; + V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("rock_bump6.dds"))); + V_RETURN(DirectX::CreateDDSTextureFromFile(pDevice, static_cast(path), &pD3D11Resource, &rock_bump_textureSRV)); + SAFE_RELEASE(pD3D11Resource); + + V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("SunsetFair.dds"))); + V_RETURN(DirectX::CreateDDSTextureFromFile(pDevice, static_cast(path), &pD3D11Resource, &sky_textureSRV)); + SAFE_RELEASE(pD3D11Resource); + + V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("foam_intensity_perlin2.dds"))); + V_RETURN(DirectX::CreateDDSTextureFromFile(pDevice, static_cast(path), &pD3D11Resource, &foam_intensity_textureSRV)); + SAFE_RELEASE(pD3D11Resource); + + V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("foam.dds"))); + V_RETURN(DirectX::CreateDDSTextureFromFile(pDevice, static_cast(path), &pD3D11Resource, &foam_diffuse_textureSRV)); + SAFE_RELEASE(pD3D11Resource); +} + + +void CTerrain::RenderTerrainToHeightField(ID3D11DeviceContext* const pContext, const XMMATRIX& worldToViewMatrix, const XMMATRIX& viewToProjectionMatrix, const XMVECTOR eyePositionWS, const XMVECTOR viewDirectionWS) +{ + float origin[2]={0,0}; + UINT stride=sizeof(float)*4; + UINT offset=0; + + pEffect->GetVariableByName("g_HeightfieldTexture")->AsShaderResource()->SetResource(heightmap_textureSRV); + pEffect->GetVariableByName("g_LayerdefTexture")->AsShaderResource()->SetResource(layerdef_textureSRV); + pEffect->GetVariableByName("g_RockBumpTexture")->AsShaderResource()->SetResource(rock_bump_textureSRV); + pEffect->GetVariableByName("g_SkyTexture")->AsShaderResource()->SetResource(sky_textureSRV); + pEffect->GetVariableByName("g_HeightFieldOrigin")->AsVector()->SetFloatVector(origin); + pEffect->GetVariableByName("g_HeightFieldSize")->AsScalar()->SetFloat(terrain_gridpoints*terrain_geometry_scale); + + XMMATRIX worldToProjectionMatrix = worldToViewMatrix * viewToProjectionMatrix; + XMMATRIX projectionToWorldMatrix = XMMatrixInverse(&XMVectorSet(0, 0, 0, 0), worldToProjectionMatrix); +// D3DXMatrixInverse(&projectionToWorldMatrix, NULL, &worldToProjectionMatrix); + + pEffect->GetVariableByName("g_ModelViewMatrix")->AsMatrix()->SetMatrix( worldToViewMatrix ); + pEffect->GetVariableByName("g_ModelViewProjectionMatrix")->AsMatrix()->SetMatrix( worldToProjectionMatrix ); + pEffect->GetVariableByName("g_ModelViewProjectionMatrixInv")->AsMatrix()->SetMatrix( projectionToWorldMatrix ); + pEffect->GetVariableByName("g_CameraPosition")->AsVector()->SetFloatVector( eyePositionWS ); + pEffect->GetVariableByName("g_CameraDirection")->AsVector()->SetFloatVector( viewDirectionWS ); + + pEffect->GetVariableByName("g_HalfSpaceCullSign")->AsScalar()->SetFloat(1.0); + pEffect->GetVariableByName("g_HalfSpaceCullPosition")->AsScalar()->SetFloat(terrain_minheight*20); + + // drawing terrain to main buffer + pEffect->GetVariableByName("g_ApplyFog")->AsScalar()->SetFloat(0.0f); + + enum PassPermutation + { + kPermutationSolid = 0, + kPermutationWireframe, + kPermutationDepthOnly, + kPermutationDataOnly + }; + + pContext->IASetInputLayout(heightfield_inputlayout); + pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST); + pEffect->GetTechniqueByName("RenderHeightfield")->GetPassByIndex( kPermutationDataOnly )->Apply( 0, pContext ); + stride = sizeof(float) * 4; + pContext->IASetVertexBuffers( 0, 1, &heightfield_vertexbuffer, &stride,&offset ); + pContext->Draw(terrain_numpatches_1d*terrain_numpatches_1d, 0); +} + + +void CTerrain::Render(CFirstPersonCamera *cam) +{ + ID3D11DeviceContext* pContext; + float origin[2]={0,0}; + UINT stride=sizeof(float)*4; + UINT offset=0; + UINT cRT = 1; + + pDevice->GetImmediateContext(&pContext); + + pEffect->GetVariableByName("g_HeightfieldTexture")->AsShaderResource()->SetResource(heightmap_textureSRV); + pEffect->GetVariableByName("g_LayerdefTexture")->AsShaderResource()->SetResource(layerdef_textureSRV); + pEffect->GetVariableByName("g_RockBumpTexture")->AsShaderResource()->SetResource(rock_bump_textureSRV); + pEffect->GetVariableByName("g_SkyTexture")->AsShaderResource()->SetResource(sky_textureSRV); + pEffect->GetVariableByName("g_HeightFieldOrigin")->AsVector()->SetFloatVector(origin); + pEffect->GetVariableByName("g_HeightFieldSize")->AsScalar()->SetFloat(terrain_gridpoints*terrain_geometry_scale); + + ID3D11RenderTargetView *colorBuffer = DXUTGetD3D11RenderTargetView(); + ID3D11DepthStencilView *backBuffer = DXUTGetD3D11DepthStencilView(); + D3D11_VIEWPORT currentViewport; + D3D11_VIEWPORT reflection_Viewport; + D3D11_VIEWPORT refraction_Viewport; + D3D11_VIEWPORT shadowmap_resource_viewport; + D3D11_VIEWPORT water_normalmap_resource_viewport; + D3D11_VIEWPORT main_Viewport; + + float ClearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + float RefractionClearColor[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; + + reflection_Viewport.Width=(float)BackbufferWidth*reflection_buffer_size_multiplier; + reflection_Viewport.Height=(float)BackbufferHeight*reflection_buffer_size_multiplier; + reflection_Viewport.MaxDepth=1; + reflection_Viewport.MinDepth=0; + reflection_Viewport.TopLeftX=0; + reflection_Viewport.TopLeftY=0; + + refraction_Viewport.Width=(float)BackbufferWidth*refraction_buffer_size_multiplier; + refraction_Viewport.Height=(float)BackbufferHeight*refraction_buffer_size_multiplier; + refraction_Viewport.MaxDepth=1; + refraction_Viewport.MinDepth=0; + refraction_Viewport.TopLeftX=0; + refraction_Viewport.TopLeftY=0; + + main_Viewport.Width=(float)BackbufferWidth*main_buffer_size_multiplier; + main_Viewport.Height=(float)BackbufferHeight*main_buffer_size_multiplier; + main_Viewport.MaxDepth=1; + main_Viewport.MinDepth=0; + main_Viewport.TopLeftX=0; + main_Viewport.TopLeftY=0; + + shadowmap_resource_viewport.Width=shadowmap_resource_buffer_size_xy; + shadowmap_resource_viewport.Height=shadowmap_resource_buffer_size_xy; + shadowmap_resource_viewport.MaxDepth=1; + shadowmap_resource_viewport.MinDepth=0; + shadowmap_resource_viewport.TopLeftX=0; + shadowmap_resource_viewport.TopLeftY=0; + + water_normalmap_resource_viewport.Width=water_normalmap_resource_buffer_size_xy; + water_normalmap_resource_viewport.Height=water_normalmap_resource_buffer_size_xy; + water_normalmap_resource_viewport.MaxDepth=1; + water_normalmap_resource_viewport.MinDepth=0; + water_normalmap_resource_viewport.TopLeftX=0; + water_normalmap_resource_viewport.TopLeftY=0; + + + //saving scene color buffer and back buffer to constants + pContext->RSGetViewports( &cRT, ¤tViewport); + pContext->OMGetRenderTargets( 1, &colorBuffer, &backBuffer ); + + + // selecting shadowmap_resource rendertarget + pEffect->GetVariableByName("g_ShadowmapTexture")->AsShaderResource()->SetResource(NULL); + + pContext->RSSetViewports(1,&shadowmap_resource_viewport); + pContext->OMSetRenderTargets( 0, NULL, shadowmap_resourceDSV); + pContext->ClearDepthStencilView( shadowmap_resourceDSV, D3D11_CLEAR_DEPTH, 1.0, 0 ); + + //drawing terrain to shadowmap + SetupLightView(cam); + + pEffect->GetVariableByName("g_ShadowmapTexture")->AsShaderResource()->SetResource(NULL); + + pEffect->GetVariableByName("g_ApplyFog")->AsScalar()->SetFloat(0.0f); + + pContext->IASetInputLayout(heightfield_inputlayout); + pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST); + pEffect->GetTechniqueByName("RenderHeightfield")->GetPassByIndex(2)->Apply(0, pContext); + stride=sizeof(float)*4; + pContext->IASetVertexBuffers(0,1,&heightfield_vertexbuffer,&stride,&offset); + pContext->Draw(terrain_numpatches_1d*terrain_numpatches_1d, 0); + + pEffect->GetTechniqueByName("Default")->GetPassByIndex(0)->Apply(0, pContext); + + pEffect->GetVariableByName("g_ShadowmapTexture")->AsShaderResource()->SetResource(shadowmap_resourceSRV); + + + // setting up reflection rendertarget + pContext->RSSetViewports(1,&reflection_Viewport); + pContext->OMSetRenderTargets( 1, &reflection_color_resourceRTV, reflection_depth_resourceDSV); + pContext->ClearRenderTargetView( reflection_color_resourceRTV, RefractionClearColor ); + pContext->ClearDepthStencilView( reflection_depth_resourceDSV, D3D11_CLEAR_DEPTH, 1.0, 0 ); + + SetupReflectionView(cam); + // drawing sky to reflection RT + pEffect->GetTechniqueByName("RenderSky")->GetPassByIndex(0)->Apply(0, pContext); + pContext->IASetInputLayout(trianglestrip_inputlayout); + pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + stride=sizeof(float)*6; + pContext->IASetVertexBuffers(0,1,&sky_vertexbuffer,&stride,&offset); + pContext->Draw(sky_gridpoints*(sky_gridpoints+2)*2, 0); + + // drawing terrain to reflection RT + pEffect->GetVariableByName("g_ApplyFog")->AsScalar()->SetFloat(0.0f); + pContext->IASetInputLayout(heightfield_inputlayout); + pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST); + pEffect->GetTechniqueByName("RenderHeightfield")->GetPassByIndex(0)->Apply(0, pContext); + stride=sizeof(float)*4; + pContext->IASetVertexBuffers(0,1,&heightfield_vertexbuffer,&stride,&offset); + pContext->Draw(terrain_numpatches_1d*terrain_numpatches_1d, 0); + + + pEffect->GetTechniqueByName("Default")->GetPassByIndex(0)->Apply(0, pContext); + + // setting up main rendertarget + pContext->RSSetViewports(1,&main_Viewport); + pContext->OMSetRenderTargets( 1, &main_color_resourceRTV, main_depth_resourceDSV); + pContext->ClearRenderTargetView( main_color_resourceRTV, ClearColor ); + pContext->ClearDepthStencilView( main_depth_resourceDSV, D3D11_CLEAR_DEPTH, 1.0, 0 ); + SetupNormalView(cam); + + // drawing terrain to main buffer + + pEffect->GetVariableByName("g_ApplyFog")->AsScalar()->SetFloat(1.0f); + pEffect->GetVariableByName("g_FoamIntensityTexture")->AsShaderResource()->SetResource(foam_intensity_textureSRV); + pEffect->GetVariableByName("g_FoamDiffuseTexture")->AsShaderResource()->SetResource(foam_diffuse_textureSRV); + D3DXMATRIX topDownMatrix; + g_pOceanSurf->pDistanceFieldModule->GetWorldToTopDownTextureMatrix( topDownMatrix ); + pEffect->GetVariableByName("g_WorldToTopDownTextureMatrix" )->AsMatrix()->SetMatrix(&topDownMatrix._11); + pEffect->GetVariableByName("g_Time" )->AsScalar()->SetFloat( g_ShoreTime ); + pEffect->GetVariableByName("g_DataTexture" )->AsShaderResource()->SetResource( g_pOceanSurf->pDistanceFieldModule->GetDataTextureSRV() ); + pEffect->GetVariableByName("g_GerstnerSteepness")->AsScalar()->SetFloat( g_GerstnerSteepness ); + pEffect->GetVariableByName("g_BaseGerstnerAmplitude")->AsScalar()->SetFloat( g_BaseGerstnerAmplitude ); + pEffect->GetVariableByName("g_BaseGerstnerWavelength")->AsScalar()->SetFloat( g_BaseGerstnerWavelength ); + pEffect->GetVariableByName("g_BaseGerstnerSpeed")->AsScalar()->SetFloat( g_BaseGerstnerSpeed ); + pEffect->GetVariableByName("g_BaseGerstnerParallelness")->AsScalar()->SetFloat( g_GerstnerParallelity ); + pEffect->GetVariableByName("g_WindDirection")->AsVector()->SetFloatVector( &g_WindDir.x ); + + pContext->IASetInputLayout(heightfield_inputlayout); + pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST); + pEffect->GetTechniqueByName("RenderHeightfield")->GetPassByIndex(0)->Apply(0, pContext); + stride=sizeof(float)*4; + pContext->IASetVertexBuffers(0,1,&heightfield_vertexbuffer,&stride,&offset); + pContext->Draw(terrain_numpatches_1d*terrain_numpatches_1d, 0); + + + // resolving main buffer color to refraction color resource + pContext->ResolveSubresource(refraction_color_resource,0,main_color_resource,0,DXGI_FORMAT_R8G8B8A8_UNORM); + pContext->GenerateMips(refraction_color_resourceSRV); + + // resolving main buffer depth to refraction depth resource manually + pContext->RSSetViewports( 1, &main_Viewport ); + pContext->OMSetRenderTargets( 1, &refraction_depth_resourceRTV, NULL); + pContext->ClearRenderTargetView(refraction_depth_resourceRTV, ClearColor); + + pContext->IASetInputLayout(trianglestrip_inputlayout); + pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + switch(MultiSampleCount) + { + case 1: + pEffect->GetVariableByName("g_RefractionDepthTextureMS1")->AsShaderResource()->SetResource(main_depth_resourceSRV); + pEffect->GetTechniqueByName("RefractionDepthManualResolve")->GetPassByIndex(0)->Apply(0, pContext); + break; + case 2: + pEffect->GetVariableByName("g_RefractionDepthTextureMS2")->AsShaderResource()->SetResource(main_depth_resourceSRV); + pEffect->GetTechniqueByName("RefractionDepthManualResolve")->GetPassByIndex(1)->Apply(0, pContext); + break; + case 4: + pEffect->GetVariableByName("g_RefractionDepthTextureMS4")->AsShaderResource()->SetResource(main_depth_resourceSRV); + pEffect->GetTechniqueByName("RefractionDepthManualResolve")->GetPassByIndex(2)->Apply(0, pContext); + break; + default: + pEffect->GetVariableByName("g_RefractionDepthTextureMS1")->AsShaderResource()->SetResource(main_depth_resourceSRV); + pEffect->GetTechniqueByName("RefractionDepthManualResolve1")->GetPassByIndex(0)->Apply(0, pContext); + break; + } + + + + stride=sizeof(float)*6; + pContext->IASetVertexBuffers(0,1,&heightfield_vertexbuffer,&stride,&offset); + pContext->Draw(4, 0); // just need to pass 4 vertices to shader + pEffect->GetTechniqueByName("Default")->GetPassByIndex(0)->Apply(0, pContext); + + // clearing resource bindings + switch(MultiSampleCount) + { + case 1: + pEffect->GetVariableByName("g_RefractionDepthTextureMS1")->AsShaderResource()->SetResource(NULL); + pEffect->GetTechniqueByName("RefractionDepthManualResolve")->GetPassByIndex(0)->Apply(0, pContext); + break; + case 2: + pEffect->GetVariableByName("g_RefractionDepthTextureMS2")->AsShaderResource()->SetResource(NULL); + pEffect->GetTechniqueByName("RefractionDepthManualResolve")->GetPassByIndex(1)->Apply(0, pContext); + break; + case 4: + pEffect->GetVariableByName("g_RefractionDepthTextureMS4")->AsShaderResource()->SetResource(NULL); + pEffect->GetTechniqueByName("RefractionDepthManualResolve")->GetPassByIndex(2)->Apply(0, pContext); + break; + default: + pEffect->GetVariableByName("g_RefractionDepthTextureMS1")->AsShaderResource()->SetResource(NULL); + pEffect->GetTechniqueByName("RefractionDepthManualResolve1")->GetPassByIndex(0)->Apply(0, pContext); + break; + } + pEffect->GetTechniqueByName("Default")->GetPassByIndex(0)->Apply(0, pContext); + + // getting back to rendering to main buffer + pContext->RSSetViewports(1,&main_Viewport); + pContext->OMSetRenderTargets( 1, &main_color_resourceRTV, main_depth_resourceDSV); + + // drawing water surface to main buffer + if(g_QueryStats) + { + pContext->Begin(g_pPipelineQuery); + } + + ID3DX11Effect* oceanFX = g_pOceanSurf->m_pOceanFX; + + oceanFX->GetVariableByName("g_ReflectionTexture")->AsShaderResource()->SetResource(reflection_color_resourceSRV); + oceanFX->GetVariableByName("g_RefractionTexture")->AsShaderResource()->SetResource(refraction_color_resourceSRV); + oceanFX->GetVariableByName("g_RefractionDepthTextureResolved")->AsShaderResource()->SetResource(refraction_depth_resourceSRV); + oceanFX->GetVariableByName("g_ShadowmapTexture")->AsShaderResource()->SetResource(shadowmap_resourceSRV); + oceanFX->GetVariableByName("g_FoamIntensityTexture")->AsShaderResource()->SetResource(foam_intensity_textureSRV); + oceanFX->GetVariableByName("g_FoamDiffuseTexture")->AsShaderResource()->SetResource(foam_diffuse_textureSRV); + + const D3DXMATRIX matView = D3DXMATRIX(1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1) * *cam->GetViewMatrix(); + const D3DXMATRIX matProj = *cam->GetProjMatrix(); + D3DXVECTOR3 cameraPosition = *cam->GetEyePt(); + D3DXVECTOR3 lightPosition = D3DXVECTOR3(14000.0f,6500.0f,4000.0f); + + oceanFX->GetVariableByName("g_ModelViewMatrix")->AsMatrix()->SetMatrix(matView); + oceanFX->GetVariableByName("g_ModelViewProjectionMatrix")->AsMatrix()->SetMatrix(matView*matProj); + oceanFX->GetVariableByName("g_CameraPosition")->AsVector()->SetFloatVector(cameraPosition); + oceanFX->GetVariableByName("g_LightPosition")->AsVector()->SetFloatVector(lightPosition); + oceanFX->GetVariableByName("g_Wireframe")->AsScalar()->SetFloat(g_Wireframe ? 1.0f : 0.0f); + oceanFX->GetVariableByName("g_WinSize")->AsVector()->SetFloatVector(D3DXVECTOR4(main_Viewport.Width,main_Viewport.Height,0,0)); + g_pOceanSurf->renderShaded(pContext, matView,matProj,g_hOceanSimulation, g_hOceanSavestate, g_WindDir, g_GerstnerSteepness, g_BaseGerstnerAmplitude, g_BaseGerstnerWavelength, g_BaseGerstnerSpeed, g_GerstnerParallelity, g_ShoreTime); + + g_pOceanSurf->getQuadTreeStats(g_ocean_quadtree_stats); + + if(g_QueryStats) + { + pContext->End(g_pPipelineQuery); + while(S_OK != pContext->GetData(g_pPipelineQuery, &g_PipelineQueryData, sizeof(g_PipelineQueryData), 0)); + } + + // clearing resource bindings + oceanFX->GetVariableByName("g_ReflectionTexture")->AsShaderResource()->SetResource(NULL); + oceanFX->GetVariableByName("g_RefractionTexture")->AsShaderResource()->SetResource(NULL); + oceanFX->GetVariableByName("g_RefractionDepthTextureResolved")->AsShaderResource()->SetResource(NULL); + oceanFX->GetVariableByName("g_ShadowmapTexture")->AsShaderResource()->SetResource(NULL); + oceanFX->GetTechniqueByName("RenderOceanSurfTech")->GetPassByIndex(0)->Apply(0, pContext); + + // drawing readback markers to main buffer + const UINT vbOffset = 0; + const UINT vertexStride = sizeof(D3DXVECTOR4); + pContext->IASetInputLayout(g_pOceanSurf->m_pRayContactLayout); + pContext->IASetVertexBuffers(0, 1, &g_pOceanSurf->m_pContactVB, &vertexStride, &vbOffset); + pContext->IASetIndexBuffer(g_pOceanSurf->m_pContactIB, DXGI_FORMAT_R16_UINT, 0); + pContext->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + for( int i = 0; i < NumMarkers; i++) + { + g_pOceanSurf->m_pOceanFX->GetVariableByName("g_ContactPosition")->AsVector()->SetFloatVector(D3DXVECTOR4(g_readback_marker_positions[i].x,g_readback_marker_positions[i].y,g_readback_marker_positions[i].z,0)); + g_pOceanSurf->m_pRenderRayContactTechnique->GetPassByIndex(0)->Apply(0, pContext); + pContext->DrawIndexed(12, 0, 0); + } + + + // drawing raycast contacts to main buffer + pContext->IASetInputLayout(g_pOceanSurf->m_pRayContactLayout); + pContext->IASetVertexBuffers(0, 1, &g_pOceanSurf->m_pContactVB, &vertexStride, &vbOffset); + pContext->IASetIndexBuffer(g_pOceanSurf->m_pContactIB, DXGI_FORMAT_R16_UINT, 0); + pContext->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + for( int i = 0; i < NumMarkers; i++) + { + g_pOceanSurf->m_pOceanFX->GetVariableByName("g_ContactPosition")->AsVector()->SetFloatVector(D3DXVECTOR4(g_raycast_hitpoints[i].x, g_raycast_hitpoints[i].z, g_raycast_hitpoints[i].y, 0.0f)); + g_pOceanSurf->m_pRenderRayContactTechnique->GetPassByIndex(0)->Apply(0, pContext); + pContext->DrawIndexed(12, 0, 0); + } + // drawing rays to main buffer + pContext->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP); + for( int i = 0; i < NumMarkers; i++) + { + g_pOceanSurf->m_pOceanFX->GetVariableByName("g_OriginPosition")->AsVector()->SetFloatVector(g_raycast_origins[i]); + g_pOceanSurf->m_pOceanFX->GetVariableByName("g_RayDirection")->AsVector()->SetFloatVector(g_raycast_directions[i]*100.0f); + g_pOceanSurf->m_pRenderRayContactTechnique->GetPassByIndex(1)->Apply(0, pContext); + pContext->DrawIndexed(2, 0, 0); + } + + //drawing sky to main buffer + pEffect->GetTechniqueByName("RenderSky")->GetPassByIndex(0)->Apply(0, pContext); + + pContext->IASetInputLayout(trianglestrip_inputlayout); + pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + stride=sizeof(float)*6; + pContext->IASetVertexBuffers(0,1,&sky_vertexbuffer,&stride,&offset); + pContext->Draw(sky_gridpoints*(sky_gridpoints+2)*2, 0); + + pEffect->GetTechniqueByName("Default")->GetPassByIndex(0)->Apply(0, pContext); + + //restoring scene color buffer and back buffer + pContext->OMSetRenderTargets( 1, &colorBuffer, backBuffer); + pContext->ClearDepthStencilView(backBuffer, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.f, 0); + pContext->ClearRenderTargetView(colorBuffer, ClearColor); + pContext->RSSetViewports( 1, ¤tViewport ); + + //resolving main buffer + pContext->ResolveSubresource(main_color_resource_resolved,0,main_color_resource,0,DXGI_FORMAT_R8G8B8A8_UNORM); + + //drawing main buffer to back buffer + pEffect->GetVariableByName("g_MainTexture")->AsShaderResource()->SetResource(main_color_resource_resolvedSRV); + pEffect->GetVariableByName("g_MainBufferSizeMultiplier")->AsScalar()->SetFloat(main_buffer_size_multiplier); + + pContext->IASetInputLayout(trianglestrip_inputlayout); + pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + pEffect->GetTechniqueByName("MainToBackBuffer")->GetPassByIndex(0)->Apply(0, pContext); + stride=sizeof(float)*6; + pContext->IASetVertexBuffers(0,1,&heightfield_vertexbuffer,&stride,&offset); + pContext->Draw(4, 0); // just need to pass 4 vertices to shader + pEffect->GetTechniqueByName("Default")->GetPassByIndex(0)->Apply(0, pContext); + + pEffect->GetVariableByName("g_MainTexture")->AsShaderResource()->SetResource(NULL); + + SAFE_RELEASE ( colorBuffer ); + SAFE_RELEASE ( backBuffer ); + + pContext->Release(); +} + +float bilinear_interpolation(float fx, float fy, float a, float b, float c, float d) +{ + float s1,s2,s3,s4; + s1=fx*fy; + s2=(1-fx)*fy; + s3=(1-fx)*(1-fy); + s4=fx*(1-fy); + return((a*s3+b*s4+c*s1+d*s2)); +} + +void CTerrain::SetupReflectionView(CFirstPersonCamera *cam) +{ + + float aspectRatio = BackbufferWidth / BackbufferHeight; + + D3DXVECTOR3 EyePoint; + D3DXVECTOR3 LookAtPoint; + + EyePoint =*cam->GetEyePt(); + LookAtPoint =*cam->GetLookAtPt(); + EyePoint.y=-1.0f*EyePoint.y+1.0f; + LookAtPoint.y=-1.0f*LookAtPoint.y+1.0f; + + + D3DXMATRIX mView; + D3DXMATRIX mProj; + D3DXMATRIX mViewProj; + D3DXMATRIX mViewProjInv; + + D3DXMATRIX mWorld; + mView = *cam->GetViewMatrix(); + mWorld = *cam->GetWorldMatrix(); + + mWorld._42=-mWorld._42-1.0f; + + mWorld._21*=-1.0f; + mWorld._23*=-1.0f; + + mWorld._32*=-1.0f; + + D3DXMatrixInverse(&mView, NULL, &mWorld); + D3DXMatrixPerspectiveFovLH(&mProj,camera_fov * D3DX_PI / 360.0f,aspectRatio,scene_z_near,scene_z_far); + mViewProj=mView*mProj; + D3DXMatrixInverse(&mViewProjInv, NULL, &mViewProj); + + pEffect->GetVariableByName("g_ModelViewProjectionMatrix")->AsMatrix()->SetMatrix(mViewProj); + pEffect->GetVariableByName("g_CameraPosition")->AsVector()->SetFloatVector(EyePoint); + D3DXVECTOR3 direction = LookAtPoint - EyePoint; + D3DXVECTOR3 normalized_direction = *D3DXVec3Normalize(&normalized_direction,&direction); + pEffect->GetVariableByName("g_CameraDirection")->AsVector()->SetFloatVector(normalized_direction); + + pEffect->GetVariableByName("g_HalfSpaceCullSign")->AsScalar()->SetFloat(1.0f); + pEffect->GetVariableByName("g_HalfSpaceCullPosition")->AsScalar()->SetFloat(0); +} + +void CTerrain::SetupRefractionView(CFirstPersonCamera *cam) +{ + pEffect->GetVariableByName("g_HalfSpaceCullSign")->AsScalar()->SetFloat(-1.0f); + pEffect->GetVariableByName("g_HalfSpaceCullPosition")->AsScalar()->SetFloat(terrain_minheight); +} +void CTerrain::SetupLightView(CFirstPersonCamera *cam) +{ + + D3DXVECTOR3 EyePoint= D3DXVECTOR3(14000.0f,6500.0f,4000.0f); + D3DXVECTOR3 LookAtPoint = D3DXVECTOR3(terrain_far_range/2.0f,0.0f,terrain_far_range/2.0f); + D3DXVECTOR3 lookUp = D3DXVECTOR3(0,1,0); + D3DXVECTOR3 cameraPosition = *cam->GetEyePt(); + + float nr, fr; + nr=sqrt(EyePoint.x*EyePoint.x+EyePoint.y*EyePoint.y+EyePoint.z*EyePoint.z)-terrain_far_range*1.0f; + fr=sqrt(EyePoint.x*EyePoint.x+EyePoint.y*EyePoint.y+EyePoint.z*EyePoint.z)+terrain_far_range*1.0f; + + D3DXMATRIX mView = *D3DXMatrixLookAtLH(&mView,&EyePoint,&LookAtPoint,&lookUp); + D3DXMATRIX mProjMatrix = *D3DXMatrixOrthoLH(&mProjMatrix,terrain_far_range*1.5,terrain_far_range,nr,fr); + D3DXMATRIX mViewProj = mView * mProjMatrix; + D3DXMATRIX mViewProjInv; + D3DXMatrixInverse(&mViewProjInv, NULL, &mViewProj); + + ID3DX11Effect* oceanFX = g_pOceanSurf->m_pOceanFX; + oceanFX->GetVariableByName("g_LightModelViewProjectionMatrix")->AsMatrix()->SetMatrix(mViewProj); + + pEffect->GetVariableByName("g_ModelViewProjectionMatrix")->AsMatrix()->SetMatrix(mViewProj); + pEffect->GetVariableByName("g_LightModelViewProjectionMatrix")->AsMatrix()->SetMatrix(mViewProj); + pEffect->GetVariableByName("g_LightModelViewProjectionMatrixInv")->AsMatrix()->SetMatrix(mViewProjInv); + pEffect->GetVariableByName("g_CameraPosition")->AsVector()->SetFloatVector(cameraPosition); + D3DXVECTOR3 direction = *cam->GetLookAtPt() - *cam->GetEyePt(); + D3DXVECTOR3 normalized_direction = *D3DXVec3Normalize(&normalized_direction,&direction); + pEffect->GetVariableByName("g_CameraDirection")->AsVector()->SetFloatVector(normalized_direction); + + pEffect->GetVariableByName("g_HalfSpaceCullSign")->AsScalar()->SetFloat(1.0); + pEffect->GetVariableByName("g_HalfSpaceCullPosition")->AsScalar()->SetFloat(terrain_minheight*2); + +} + +void CTerrain::SetupNormalView(CFirstPersonCamera *cam) +{ + D3DXVECTOR3 EyePoint; + D3DXVECTOR3 LookAtPoint; + + EyePoint =*cam->GetEyePt(); + LookAtPoint =*cam->GetLookAtPt(); + D3DXMATRIX mView = *cam->GetViewMatrix(); + D3DXMATRIX mProjMatrix = *cam->GetProjMatrix(); + D3DXMATRIX mViewProj = mView * mProjMatrix; + D3DXMATRIX mViewProjInv; + D3DXMatrixInverse(&mViewProjInv, NULL, &mViewProj); + D3DXVECTOR3 cameraPosition = *cam->GetEyePt(); + + pEffect->GetVariableByName("g_ModelViewMatrix")->AsMatrix()->SetMatrix(mView); + pEffect->GetVariableByName("g_ModelViewProjectionMatrix")->AsMatrix()->SetMatrix(mViewProj); + pEffect->GetVariableByName("g_ModelViewProjectionMatrixInv")->AsMatrix()->SetMatrix(mViewProjInv); + pEffect->GetVariableByName("g_CameraPosition")->AsVector()->SetFloatVector(cameraPosition); + D3DXVECTOR3 direction = LookAtPoint - EyePoint; + D3DXVECTOR3 normalized_direction = *D3DXVec3Normalize(&normalized_direction,&direction); + pEffect->GetVariableByName("g_CameraDirection")->AsVector()->SetFloatVector(normalized_direction); + pEffect->GetVariableByName("g_HalfSpaceCullSign")->AsScalar()->SetFloat(1.0); + pEffect->GetVariableByName("g_HalfSpaceCullPosition")->AsScalar()->SetFloat(terrain_minheight*20); + +} diff --git a/sample/d3d11/terrain.h b/sample/d3d11/terrain.h new file mode 100644 index 0000000..e692679 --- /dev/null +++ b/sample/d3d11/terrain.h @@ -0,0 +1,172 @@ +// 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. +// + +#ifndef _TERRAIN_H +#define _TERRAIN_H + +#include "DXUT.h" +#include "DXUTcamera.h" +#include "SDKMisc.h" +#include "d3dx11effect.h" +#include "d3d11.h" +#include "DirectXMath.h" + +using namespace DirectX; + +#define terrain_gridpoints 512 +#define terrain_numpatches_1d 64 +#define terrain_geometry_scale 1.0f +#define terrain_maxheight 35.0f +#define terrain_minheight -30.0f +#define terrain_fractalfactor 0.51f; +#define terrain_fractalinitialvalue 100.0f +#define terrain_smoothfactor1 0.9f +#define terrain_smoothfactor2 -0.03f +#define terrain_rockfactor 0.97f +#define terrain_smoothsteps 40 + +#define terrain_height_underwater_start -100.0f +#define terrain_height_underwater_end -8.0f +#define terrain_height_sand_start -30.0f +#define terrain_height_sand_end 1.7f +#define terrain_height_grass_start 1.7f +#define terrain_height_grass_end 30.0f +#define terrain_height_rocks_start -2.0f +#define terrain_height_trees_start 4.0f +#define terrain_height_trees_end 30.0f +#define terrain_slope_grass_start 0.96f +#define terrain_slope_rocks_start 0.85f + +#define terrain_far_range terrain_gridpoints*terrain_geometry_scale + +#define shadowmap_resource_buffer_size_xy 4096 +#define water_normalmap_resource_buffer_size_xy 2048 +#define terrain_layerdef_map_texture_size 1024 +#define terrain_depth_shadow_map_texture_size 512 + +#define sky_gridpoints 20 +#define sky_texture_angle 0.34f + +#define main_buffer_size_multiplier 1.1f +#define reflection_buffer_size_multiplier 1.1f +#define refraction_buffer_size_multiplier 1.1f + +#define scene_z_near 1.0f +#define scene_z_far 25000.0f +#define camera_fov 110.0f + +class CTerrain +{ + public: + + + void Initialize(ID3D11Device*, ID3DX11Effect*); + void DeInitialize(); + void ReCreateBuffers(); + HRESULT LoadTextures(); + void Render(CFirstPersonCamera *); + void RenderTerrainToHeightField(ID3D11DeviceContext* const pContext, const XMMATRIX& worldToViewMatrix, const XMMATRIX& viewToProjectionMatrix, const XMVECTOR eyePositionWS, const XMVECTOR viewDirectionWS); + void CreateTerrain(); + + float DynamicTesselationFactor; + void SetupNormalView(CFirstPersonCamera *); + void SetupReflectionView(CFirstPersonCamera *); + void SetupRefractionView(CFirstPersonCamera *); + void SetupLightView(CFirstPersonCamera * ); + float BackbufferWidth; + float BackbufferHeight; + + UINT MultiSampleCount; + UINT MultiSampleQuality; + + ID3D11ShaderResourceView *rock_bump_textureSRV; + + ID3D11ShaderResourceView *sky_textureSRV; + + ID3D11ShaderResourceView *foam_intensity_textureSRV; + + ID3D11ShaderResourceView *foam_diffuse_textureSRV; + + ID3D11Texture2D *reflection_color_resource; + ID3D11ShaderResourceView *reflection_color_resourceSRV; + ID3D11RenderTargetView *reflection_color_resourceRTV; + ID3D11Texture2D *refraction_color_resource; + ID3D11ShaderResourceView *refraction_color_resourceSRV; + ID3D11RenderTargetView *refraction_color_resourceRTV; + + ID3D11Texture2D *shadowmap_resource; + ID3D11ShaderResourceView *shadowmap_resourceSRV; + ID3D11DepthStencilView *shadowmap_resourceDSV; + + ID3D11Texture2D *reflection_depth_resource; + ID3D11DepthStencilView *reflection_depth_resourceDSV; + + ID3D11Texture2D *refraction_depth_resource; + ID3D11RenderTargetView *refraction_depth_resourceRTV; + ID3D11ShaderResourceView *refraction_depth_resourceSRV; + + ID3D11Texture2D *main_color_resource; + ID3D11ShaderResourceView *main_color_resourceSRV; + ID3D11RenderTargetView *main_color_resourceRTV; + ID3D11Texture2D *main_depth_resource; + ID3D11DepthStencilView *main_depth_resourceDSV; + ID3D11ShaderResourceView *main_depth_resourceSRV; + ID3D11Texture2D *main_color_resource_resolved; + ID3D11ShaderResourceView *main_color_resource_resolvedSRV; + + ID3D11Device* pDevice; + ID3DX11Effect* pEffect; + + + + + float height[terrain_gridpoints+1][terrain_gridpoints+1]; + XMFLOAT3 normal[terrain_gridpoints+1][terrain_gridpoints+1]; + XMFLOAT3 tangent[terrain_gridpoints + 1][terrain_gridpoints + 1]; + XMFLOAT3 binormal[terrain_gridpoints + 1][terrain_gridpoints + 1]; + + ID3D11Texture2D *heightmap_texture; + ID3D11ShaderResourceView *heightmap_textureSRV; + + ID3D11Texture2D *layerdef_texture; + ID3D11ShaderResourceView *layerdef_textureSRV; + + ID3D11Texture2D *depthmap_texture; + ID3D11ShaderResourceView *depthmap_textureSRV; + + ID3D11Buffer *heightfield_vertexbuffer; + ID3D11Buffer *sky_vertexbuffer; + + ID3D11InputLayout *heightfield_inputlayout; + ID3D11InputLayout *trianglestrip_inputlayout; + +}; + +float bilinear_interpolation(float fx, float fy, float a, float b, float c, float d); + +#endif // _TERRAIN_H \ No newline at end of file diff --git a/sample/d3d11/util.cpp b/sample/d3d11/util.cpp new file mode 100644 index 0000000..0803ce0 --- /dev/null +++ b/sample/d3d11/util.cpp @@ -0,0 +1,63 @@ +// 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" + +HRESULT LoadFile(LPCTSTR FileName, ID3DBlob** ppBuffer) +{ + FILE* pF = NULL; + ID3DBlob* pBuffer = NULL; + + if(_wfopen_s(&pF, FileName, L"rb")) + goto error; + + if(fseek(pF,0,SEEK_END)) + goto error; + + const DWORD fileSize = ftell(pF); + + if(fseek(pF,0,SEEK_SET)) + goto error; + + if(FAILED(D3DCreateBlob(fileSize, &pBuffer))) + goto error; + + if(fileSize != fread(pBuffer->GetBufferPointer(), 1, fileSize, pF)) + goto error; + + fclose(pF); + + *ppBuffer = pBuffer; + return S_OK; + +error: + fclose(pF); + SAFE_RELEASE(pBuffer); + + return E_FAIL; +} diff --git a/src/Simulation.cpp b/src/Simulation.cpp index ef20f51..c166ed5 100644 --- a/src/Simulation.cpp +++ b/src/Simulation.cpp @@ -59,13 +59,7 @@ namespace { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-variable" #endif - #include "Attributes_map.h" - namespace CalcGradients { - #include "CalcGradient_map.h" - } - namespace FoamGeneration { - #include "FoamGeneration_map.h" - } + #ifdef __GNUC__ #pragma GCC diagnostic pop #endif @@ -307,141 +301,141 @@ enum ShaderInputsGL2 // NB: These should be kept synchronisd with the shader source #if WAVEWORKS_ENABLE_D3D9 const GFSDK_WaveWorks_ShaderInput_Desc ShaderInputDescsD3D9[NumShaderInputsD3D9] = { - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, nvsf_g_samplerDisplacementMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, nvsf_g_samplerDisplacementMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, nvsf_g_samplerDisplacementMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, nvsf_g_samplerDisplacementMap3, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, nvsf_g_samplerGradientMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, nvsf_g_samplerGradientMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, nvsf_g_samplerGradientMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, nvsf_g_samplerGradientMap3, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_FloatConstant, nvsf_g_WorldEye, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_FloatConstant, nvsf_g_Pad1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_FloatConstant, nvsf_g_UVScaleCascade0123, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, nvsf_g_TexelLength_x2_PS, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, nvsf_g_Cascade1Scale_PS, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, nvsf_g_Cascade1TexelScale_PS, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, nvsf_g_Cascade1UVOffset_PS, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, nvsf_g_Cascade2Scale_PS, 4 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, nvsf_g_Cascade2TexelScale_PS, 5 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, nvsf_g_Cascade2UVOffset_PS, 6 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, nvsf_g_Cascade3Scale_PS, 7 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, nvsf_g_Cascade3TexelScale_PS, 8 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, nvsf_g_Cascade3UVOffset_PS, 9 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, "nvsf_g_samplerDisplacementMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, "nvsf_g_samplerDisplacementMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, "nvsf_g_samplerDisplacementMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, "nvsf_g_samplerDisplacementMap3", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, "nvsf_g_samplerGradientMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, "nvsf_g_samplerGradientMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, "nvsf_g_samplerGradientMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, "nvsf_g_samplerGradientMap3", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_FloatConstant, "nvsf_g_WorldEye", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_FloatConstant, "nvsf_g_Pad1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_FloatConstant, "nvsf_g_UVScaleCascade0123", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, "nvsf_g_TexelLength_x2_PS", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, "nvsf_g_Cascade1Scale_PS", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, "nvsf_g_Cascade1TexelScale_PS", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, "nvsf_g_Cascade1UVOffset_PS", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, "nvsf_g_Cascade2Scale_PS", 4 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, "nvsf_g_Cascade2TexelScale_PS", 5 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, "nvsf_g_Cascade2UVOffset_PS", 6 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, "nvsf_g_Cascade3Scale_PS", 7 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, "nvsf_g_Cascade3TexelScale_PS", 8 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_FloatConstant, "nvsf_g_Cascade3UVOffset_PS", 9 }, }; #endif // WAVEWORKS_ENABLE_D3D9 #if WAVEWORKS_ENABLE_D3D10 const GFSDK_WaveWorks_ShaderInput_Desc ShaderInputDescsD3D10[NumShaderInputsD3D10] = { - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_ConstantBuffer, nvsf_attr_vs_buffer, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, nvsf_g_samplerDisplacementMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, nvsf_g_samplerDisplacementMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, nvsf_g_samplerDisplacementMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, nvsf_g_samplerDisplacementMap3, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, nvsf_g_textureDisplacementMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, nvsf_g_textureDisplacementMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, nvsf_g_textureDisplacementMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, nvsf_g_textureDisplacementMap3, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_ConstantBuffer, nvsf_attr_ps_buffer, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, nvsf_g_samplerGradientMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, nvsf_g_samplerGradientMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, nvsf_g_samplerGradientMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, nvsf_g_samplerGradientMap3, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, nvsf_g_textureGradientMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, nvsf_g_textureGradientMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, nvsf_g_textureGradientMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, nvsf_g_textureGradientMap3, 3 } + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_ConstantBuffer, "nvsf_attr_vs_buffer", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, "nvsf_g_samplerDisplacementMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, "nvsf_g_samplerDisplacementMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, "nvsf_g_samplerDisplacementMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, "nvsf_g_samplerDisplacementMap3", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, "nvsf_g_textureDisplacementMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, "nvsf_g_textureDisplacementMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, "nvsf_g_textureDisplacementMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, "nvsf_g_textureDisplacementMap3", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_ConstantBuffer, "nvsf_attr_ps_buffer", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, "nvsf_g_samplerGradientMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, "nvsf_g_samplerGradientMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, "nvsf_g_samplerGradientMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, "nvsf_g_samplerGradientMap3", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, "nvsf_g_textureGradientMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, "nvsf_g_textureGradientMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, "nvsf_g_textureGradientMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, "nvsf_g_textureGradientMap3", 3 } }; #endif // WAVEWORKS_ENABLE_D3D10 #if WAVEWORKS_ENABLE_D3D11 const GFSDK_WaveWorks_ShaderInput_Desc ShaderInputDescsD3D11[NumShaderInputsD3D11] = { - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_ConstantBuffer, nvsf_attr_vs_buffer, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, nvsf_g_samplerDisplacementMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, nvsf_g_samplerDisplacementMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, nvsf_g_samplerDisplacementMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, nvsf_g_samplerDisplacementMap3, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, nvsf_g_textureDisplacementMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, nvsf_g_textureDisplacementMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, nvsf_g_textureDisplacementMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, nvsf_g_textureDisplacementMap3, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_ConstantBuffer, nvsf_attr_vs_buffer, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler, nvsf_g_samplerDisplacementMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler, nvsf_g_samplerDisplacementMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler, nvsf_g_samplerDisplacementMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler, nvsf_g_samplerDisplacementMap3, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture, nvsf_g_textureDisplacementMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture, nvsf_g_textureDisplacementMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture, nvsf_g_textureDisplacementMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture, nvsf_g_textureDisplacementMap3, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_ConstantBuffer, nvsf_attr_ps_buffer, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, nvsf_g_samplerGradientMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, nvsf_g_samplerGradientMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, nvsf_g_samplerGradientMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, nvsf_g_samplerGradientMap3, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, nvsf_g_textureGradientMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, nvsf_g_textureGradientMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, nvsf_g_textureGradientMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, nvsf_g_textureGradientMap3, 3 } + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_ConstantBuffer, "nvsf_attr_vs_buffer", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, "nvsf_g_samplerDisplacementMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, "nvsf_g_samplerDisplacementMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, "nvsf_g_samplerDisplacementMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, "nvsf_g_samplerDisplacementMap3", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, "nvsf_g_textureDisplacementMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, "nvsf_g_textureDisplacementMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, "nvsf_g_textureDisplacementMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, "nvsf_g_textureDisplacementMap3", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_ConstantBuffer, "nvsf_attr_vs_buffer", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler, "nvsf_g_samplerDisplacementMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler, "nvsf_g_samplerDisplacementMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler, "nvsf_g_samplerDisplacementMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler, "nvsf_g_samplerDisplacementMap3", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture, "nvsf_g_textureDisplacementMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture, "nvsf_g_textureDisplacementMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture, "nvsf_g_textureDisplacementMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture, "nvsf_g_textureDisplacementMap3", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_ConstantBuffer, "nvsf_attr_ps_buffer", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, "nvsf_g_samplerGradientMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, "nvsf_g_samplerGradientMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, "nvsf_g_samplerGradientMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, "nvsf_g_samplerGradientMap3", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, "nvsf_g_textureGradientMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, "nvsf_g_textureGradientMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, "nvsf_g_textureGradientMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, "nvsf_g_textureGradientMap3", 3 } }; #endif // WAVEWORKS_ENABLE_D3D11 #if WAVEWORKS_ENABLE_GNM const GFSDK_WaveWorks_ShaderInput_Desc ShaderInputDescsGnm[NumShaderInputsGnm] = { - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_ConstantBuffer, nvsf_attr_vs_buffer, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, nvsf_g_samplerDisplacementMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, nvsf_g_samplerDisplacementMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, nvsf_g_samplerDisplacementMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, nvsf_g_samplerDisplacementMap3, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, nvsf_g_textureDisplacementMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, nvsf_g_textureDisplacementMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, nvsf_g_textureDisplacementMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, nvsf_g_textureDisplacementMap3, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_ConstantBuffer, nvsf_attr_vs_buffer, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler, nvsf_g_samplerDisplacementMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler, nvsf_g_samplerDisplacementMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler, nvsf_g_samplerDisplacementMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler, nvsf_g_samplerDisplacementMap3, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture, nvsf_g_textureDisplacementMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture, nvsf_g_textureDisplacementMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture, nvsf_g_textureDisplacementMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture, nvsf_g_textureDisplacementMap3, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_ConstantBuffer, nvsf_attr_ps_buffer, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, nvsf_g_samplerGradientMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, nvsf_g_samplerGradientMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, nvsf_g_samplerGradientMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, nvsf_g_samplerGradientMap3, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, nvsf_g_textureGradientMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, nvsf_g_textureGradientMap1, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, nvsf_g_textureGradientMap2, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, nvsf_g_textureGradientMap3, 3 } + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_ConstantBuffer, "nvsf_attr_vs_buffer", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, "nvsf_g_samplerDisplacementMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, "nvsf_g_samplerDisplacementMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, "nvsf_g_samplerDisplacementMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Sampler, "nvsf_g_samplerDisplacementMap3", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, "nvsf_g_textureDisplacementMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, "nvsf_g_textureDisplacementMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, "nvsf_g_textureDisplacementMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::VertexShader_Texture, "nvsf_g_textureDisplacementMap3", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_ConstantBuffer, "nvsf_attr_vs_buffer", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler, "nvsf_g_samplerDisplacementMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler, "nvsf_g_samplerDisplacementMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler, "nvsf_g_samplerDisplacementMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Sampler, "nvsf_g_samplerDisplacementMap3", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture, "nvsf_g_textureDisplacementMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture, "nvsf_g_textureDisplacementMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture, "nvsf_g_textureDisplacementMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::DomainShader_Texture, "nvsf_g_textureDisplacementMap3", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_ConstantBuffer, "nvsf_attr_ps_buffer", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, "nvsf_g_samplerGradientMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, "nvsf_g_samplerGradientMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, "nvsf_g_samplerGradientMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Sampler, "nvsf_g_samplerGradientMap3", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, "nvsf_g_textureGradientMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, "nvsf_g_textureGradientMap1", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, "nvsf_g_textureGradientMap2", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::PixelShader_Texture, "nvsf_g_textureGradientMap3", 3 } }; #endif // WAVEWORKS_ENABLE_GNM #if WAVEWORKS_ENABLE_GL const GFSDK_WaveWorks_ShaderInput_Desc ShaderInputDescsGL2[NumShaderInputsGL2] = { - { GFSDK_WaveWorks_ShaderInput_Desc::GL_VertexShader_TextureBindLocation, nvsf_g_samplerDisplacementMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_VertexShader_TextureBindLocation, nvsf_g_samplerDisplacementMap1, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_VertexShader_TextureBindLocation, nvsf_g_samplerDisplacementMap2, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_VertexShader_TextureBindLocation, nvsf_g_samplerDisplacementMap3, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_TextureBindLocation, nvsf_g_samplerGradientMap0, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_TextureBindLocation, nvsf_g_samplerGradientMap1, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_TextureBindLocation, nvsf_g_samplerGradientMap2, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_TextureBindLocation, nvsf_g_samplerGradientMap3, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_VertexShader_TextureArrayBindLocation, nvsf_g_samplerDisplacementMapTextureArray, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_TextureArrayBindLocation, nvsf_g_samplerGradientMapTextureArray, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_VertexShader_UniformLocation, nvsf_g_WorldEye, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_VertexShader_UniformLocation, nvsf_g_UseTextureArrays, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_VertexShader_UniformLocation, nvsf_g_UVScaleCascade0123, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, nvsf_g_TexelLength_x2_PS, 0 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, nvsf_g_Cascade1Scale_PS, 1 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, nvsf_g_Cascade1TexelScale_PS, 2 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, nvsf_g_Cascade1UVOffset_PS, 3 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, nvsf_g_Cascade2Scale_PS, 4 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, nvsf_g_Cascade2TexelScale_PS, 5 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, nvsf_g_Cascade2UVOffset_PS, 6 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, nvsf_g_Cascade3Scale_PS, 7 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, nvsf_g_Cascade3TexelScale_PS, 8 }, - { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, nvsf_g_Cascade3UVOffset_PS, 9 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_VertexShader_TextureBindLocation, "nvsf_g_samplerDisplacementMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_VertexShader_TextureBindLocation, "nvsf_g_samplerDisplacementMap1", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_VertexShader_TextureBindLocation, "nvsf_g_samplerDisplacementMap2", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_VertexShader_TextureBindLocation, "nvsf_g_samplerDisplacementMap3", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_TextureBindLocation, "nvsf_g_samplerGradientMap0", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_TextureBindLocation, "nvsf_g_samplerGradientMap1", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_TextureBindLocation, "nvsf_g_samplerGradientMap2", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_TextureBindLocation, "nvsf_g_samplerGradientMap3", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_VertexShader_TextureArrayBindLocation, "nvsf_g_samplerDisplacementMapTextureArray", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_TextureArrayBindLocation, "nvsf_g_samplerGradientMapTextureArray", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_VertexShader_UniformLocation, "nvsf_g_WorldEye", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_VertexShader_UniformLocation, "nvsf_g_UseTextureArrays", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_VertexShader_UniformLocation, "nvsf_g_UVScaleCascade0123", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, "nvsf_g_TexelLength_x2_PS", 0 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, "nvsf_g_Cascade1Scale_PS", 1 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, "nvsf_g_Cascade1TexelScale_PS", 2 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, "nvsf_g_Cascade1UVOffset_PS", 3 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, "nvsf_g_Cascade2Scale_PS", 4 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, "nvsf_g_Cascade2TexelScale_PS", 5 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, "nvsf_g_Cascade2UVOffset_PS", 6 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, "nvsf_g_Cascade3Scale_PS", 7 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, "nvsf_g_Cascade3TexelScale_PS", 8 }, + { GFSDK_WaveWorks_ShaderInput_Desc::GL_FragmentShader_UniformLocation, "nvsf_g_Cascade3UVOffset_PS", 9 }, }; #endif // __GL__ struct ps_calcgradient_cbuffer @@ -1076,15 +1070,15 @@ HRESULT GFSDK_WaveWorks_Simulation::initShaders() if(m_d3d._GL2.m_GradCalcProgram == 0) return E_FAIL; // Gradient calculation program binding - m_d3d._GL2.m_GradCalcUniformLocation_Scales = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_GradCalcProgram,::CalcGradients::nvsf_g_Scales); CHECK_GL_ERRORS; - m_d3d._GL2.m_GradCalcUniformLocation_OneBack = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_GradCalcProgram,::CalcGradients::nvsf_g_OneTexel_Back); CHECK_GL_ERRORS; - m_d3d._GL2.m_GradCalcUniformLocation_OneFront = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_GradCalcProgram,::CalcGradients::nvsf_g_OneTexel_Front); CHECK_GL_ERRORS; - m_d3d._GL2.m_GradCalcUniformLocation_OneLeft = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_GradCalcProgram,::CalcGradients::nvsf_g_OneTexel_Left); CHECK_GL_ERRORS; - m_d3d._GL2.m_GradCalcUniformLocation_OneRight = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_GradCalcProgram,::CalcGradients::nvsf_g_OneTexel_Right); CHECK_GL_ERRORS; - m_d3d._GL2.m_GradCalcTextureBindLocation_DisplacementMap = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_GradCalcProgram,::CalcGradients::nvsf_g_samplerDisplacementMap); CHECK_GL_ERRORS; + m_d3d._GL2.m_GradCalcUniformLocation_Scales = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_GradCalcProgram,"nvsf_g_Scales"); CHECK_GL_ERRORS; + m_d3d._GL2.m_GradCalcUniformLocation_OneBack = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_GradCalcProgram,"nvsf_g_OneTexel_Back"); CHECK_GL_ERRORS; + m_d3d._GL2.m_GradCalcUniformLocation_OneFront = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_GradCalcProgram,"nvsf_g_OneTexel_Front"); CHECK_GL_ERRORS; + m_d3d._GL2.m_GradCalcUniformLocation_OneLeft = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_GradCalcProgram,"nvsf_g_OneTexel_Left"); CHECK_GL_ERRORS; + m_d3d._GL2.m_GradCalcUniformLocation_OneRight = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_GradCalcProgram,"nvsf_g_OneTexel_Right"); CHECK_GL_ERRORS; + m_d3d._GL2.m_GradCalcTextureBindLocation_DisplacementMap = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_GradCalcProgram,"nvsf_g_samplerDisplacementMap"); CHECK_GL_ERRORS; m_d3d._GL2.m_GradCalcTextureUnit_DisplacementMap = 0; - m_d3d._GL2.m_GradCalcAttributeLocation_Pos = NVSDK_GLFunctions.glGetAttribLocation(m_d3d._GL2.m_GradCalcProgram, ::CalcGradients::nvsf_vInPos); CHECK_GL_ERRORS; - m_d3d._GL2.m_GradCalcAttributeLocation_TexCoord = NVSDK_GLFunctions.glGetAttribLocation(m_d3d._GL2.m_GradCalcProgram, ::CalcGradients::nvsf_vInTexCoord); CHECK_GL_ERRORS; + m_d3d._GL2.m_GradCalcAttributeLocation_Pos = NVSDK_GLFunctions.glGetAttribLocation(m_d3d._GL2.m_GradCalcProgram, "nvsf_vInPos"); CHECK_GL_ERRORS; + m_d3d._GL2.m_GradCalcAttributeLocation_TexCoord = NVSDK_GLFunctions.glGetAttribLocation(m_d3d._GL2.m_GradCalcProgram, "nvsf_vInTexCoord"); CHECK_GL_ERRORS; // Creating foam generation program if(m_d3d._GL2.m_FoamGenProgram != 0) NVSDK_GLFunctions.glDeleteProgram(m_d3d._GL2.m_FoamGenProgram); CHECK_GL_ERRORS; @@ -1092,13 +1086,13 @@ HRESULT GFSDK_WaveWorks_Simulation::initShaders() if(m_d3d._GL2.m_FoamGenProgram == 0) return E_FAIL; // Foam accumulation program binding - m_d3d._GL2.m_FoamGenUniformLocation_DissipationFactors = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_FoamGenProgram,::FoamGeneration::nvsf_g_DissipationFactors); CHECK_GL_ERRORS; - m_d3d._GL2.m_FoamGenUniformLocation_SourceComponents = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_FoamGenProgram,::FoamGeneration::nvsf_g_SourceComponents); CHECK_GL_ERRORS; - m_d3d._GL2.m_FoamGenUniformLocation_UVOffsets = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_FoamGenProgram,::FoamGeneration::nvsf_g_UVOffsets); CHECK_GL_ERRORS; - m_d3d._GL2.m_FoamGenTextureBindLocation_EnergyMap = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_FoamGenProgram,::FoamGeneration::nvsf_g_samplerEnergyMap); CHECK_GL_ERRORS; + m_d3d._GL2.m_FoamGenUniformLocation_DissipationFactors = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_FoamGenProgram,"nvsf_g_DissipationFactors"); CHECK_GL_ERRORS; + m_d3d._GL2.m_FoamGenUniformLocation_SourceComponents = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_FoamGenProgram,"nvsf_g_SourceComponents"); CHECK_GL_ERRORS; + m_d3d._GL2.m_FoamGenUniformLocation_UVOffsets = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_FoamGenProgram,"nvsf_g_UVOffsets"); CHECK_GL_ERRORS; + m_d3d._GL2.m_FoamGenTextureBindLocation_EnergyMap = NVSDK_GLFunctions.glGetUniformLocation(m_d3d._GL2.m_FoamGenProgram,"nvsf_g_samplerEnergyMap"); CHECK_GL_ERRORS; m_d3d._GL2.m_FoamGenTextureUnit_EnergyMap = 0; - m_d3d._GL2.m_FoamGenAttributeLocation_Pos = NVSDK_GLFunctions.glGetAttribLocation(m_d3d._GL2.m_FoamGenProgram, ::FoamGeneration::nvsf_vInPos); CHECK_GL_ERRORS; - m_d3d._GL2.m_FoamGenAttributeLocation_TexCoord = NVSDK_GLFunctions.glGetAttribLocation(m_d3d._GL2.m_FoamGenProgram, ::FoamGeneration::nvsf_vInTexCoord); CHECK_GL_ERRORS; + m_d3d._GL2.m_FoamGenAttributeLocation_Pos = NVSDK_GLFunctions.glGetAttribLocation(m_d3d._GL2.m_FoamGenProgram, "nvsf_vInPos"); CHECK_GL_ERRORS; + m_d3d._GL2.m_FoamGenAttributeLocation_TexCoord = NVSDK_GLFunctions.glGetAttribLocation(m_d3d._GL2.m_FoamGenProgram, "nvsf_vInTexCoord"); CHECK_GL_ERRORS; } break; #endif diff --git a/test/d3d11/ocean_cufft_app.cpp b/test/d3d11/ocean_cufft_app.cpp index bee9978..29ca4be 100644 --- a/test/d3d11/ocean_cufft_app.cpp +++ b/test/d3d11/ocean_cufft_app.cpp @@ -95,7 +95,7 @@ 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 = true; +bool g_RenderWireframe = false; bool g_RenderWater = true; bool g_SimulateWater = true; bool g_ForceKick = false; @@ -256,6 +256,7 @@ INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR cmdline, int ) #endif g_pTestParams = new TestParams(cmdline); + g_pTestParams->MediaDirectory = "D:\\Projects\\WaveworksGit\\WWLibrary\\test\\media"; std::wstring_convert> converter; @@ -341,7 +342,7 @@ void InitApp() 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.detail_level = GFSDK_WaveWorks_Simulation_DetailLevel_High; g_ocean_simulation_settings.readback_displacements = false; g_ocean_simulation_settings.num_readback_FIFO_entries = ReadbackArchiveSize; g_ocean_simulation_settings.aniso_level = 4; @@ -558,10 +559,10 @@ HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFA 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); +// 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); @@ -582,7 +583,7 @@ HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFA // Skybox { TCHAR path[MAX_PATH]; - V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("..\\Media\\skybox_d3d11.fxo"))); + V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("skybox_d3d11.fxo"))); ID3DBlob* pEffectBuffer = NULL; V_RETURN(LoadFile(path, &pEffectBuffer)); V_RETURN(D3DX11CreateEffectFromMemory(pEffectBuffer->GetBufferPointer(), pEffectBuffer->GetBufferSize(), 0, pd3dDevice, &g_pSkyboxFX)); @@ -608,13 +609,13 @@ HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFA )); TCHAR path[MAX_PATH]; - V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("..\\Media\\sky_cube.dds"))); + V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("sky_cube.dds"))); ID3D11Resource* pD3D11Resource = NULL; V_RETURN(DirectX::CreateDDSTextureFromFile(pd3dDevice, static_cast(path), &pD3D11Resource, &g_pSkyCubeMap)); // V_RETURN(pd3dDevice->CreateShaderResourceView(pD3D11Resource, NULL, &g_pSkyCubeMap)); SAFE_RELEASE(pD3D11Resource); - V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("..\\Media\\nvidia_logo.dds"))); + V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("nvidia_logo.dds"))); V_RETURN(DirectX::CreateDDSTextureFromFile(pd3dDevice, static_cast(path), &pD3D11Resource, &g_pLogoTex)); // V_RETURN(pd3dDevice->CreateShaderResourceView(pD3D11Resource, NULL, &g_pLogoTex)); SAFE_RELEASE(pD3D11Resource); @@ -632,7 +633,7 @@ HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFA // Readback marker { TCHAR path[MAX_PATH]; - V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("..\\Media\\ocean_marker_d3d11.fxo"))) + V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("ocean_marker_d3d11.fxo"))) ID3DBlob* pEffectBuffer = NULL; V_RETURN(LoadFile(path, &pEffectBuffer)); V_RETURN(D3DX11CreateEffectFromMemory(pEffectBuffer->GetBufferPointer(), pEffectBuffer->GetBufferSize(), 0, pd3dDevice, &g_pMarkerFX)); diff --git a/test/d3d11/ocean_surface.cpp b/test/d3d11/ocean_surface.cpp index 8c86025..2495886 100644 --- a/test/d3d11/ocean_surface.cpp +++ b/test/d3d11/ocean_surface.cpp @@ -174,7 +174,7 @@ HRESULT OceanSurface::init(const OceanSurfaceParameters& params) if(NULL == m_pOceanFX) { TCHAR path[MAX_PATH]; - V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("..\\Media\\ocean_surface_d3d11.fxo"))); + V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("ocean_surface_d3d11.fxo"))); ID3DBlob* pEffectBuffer = NULL; V_RETURN(LoadFile(path, &pEffectBuffer)); V_RETURN(D3DX11CreateEffectFromMemory(pEffectBuffer->GetBufferPointer(), pEffectBuffer->GetBufferSize(), 0, m_pd3dDevice, &m_pOceanFX)); diff --git a/test/media/UI/Font.dds b/test/media/UI/Font.dds new file mode 100644 index 0000000..37514f5 Binary files /dev/null and b/test/media/UI/Font.dds differ diff --git a/test/media/ocean_surface_d3d11.fxo b/test/media/ocean_surface_d3d11.fxo index 2e18509..d35f8db 100644 Binary files a/test/media/ocean_surface_d3d11.fxo and b/test/media/ocean_surface_d3d11.fxo differ diff --git a/test/media/sample_d3d11.fxo b/test/media/sample_d3d11.fxo new file mode 100644 index 0000000..9040c57 Binary files /dev/null and b/test/media/sample_d3d11.fxo differ -- cgit v1.2.3