diff options
| author | Jason Maskell <[email protected]> | 2016-05-19 11:56:51 +0200 |
|---|---|---|
| committer | Jason Maskell <[email protected]> | 2016-05-19 11:56:51 +0200 |
| commit | 67e62061658d90b9491c55544bb419f91a0c5c08 (patch) | |
| tree | 8769085a7916ae6e8b4fa6cb61a7d56018704396 | |
| parent | Added the ability to specify the "media" directory for the test project. (diff) | |
| download | waveworks_archive-67e62061658d90b9491c55544bb419f91a0c5c08.tar.xz waveworks_archive-67e62061658d90b9491c55544bb419f91a0c5c08.zip | |
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.
32 files changed, 7189 insertions, 164 deletions
@@ -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 $<$<CONFIG:debug>:PROFILE;_DEV;> $<$<CONFIG:release>: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; + + $<$<CONFIG:debug>:PROFILE;_DEV;> + $<$<CONFIG:release>: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; + + $<$<CONFIG:debug>:_DEBUG;PX_DEBUG=1;PX_CHECKED=1;PX_SUPPORT_PVD=1;> + $<$<CONFIG:release>: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; + + $<$<CONFIG:debug>:_DEBUG;PX_DEBUG=1;PX_CHECKED=1;PX_SUPPORT_PVD=1;> + $<$<CONFIG:release>: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 Binary files differnew file mode 100644 index 0000000..37514f5 --- /dev/null +++ b/sample/d3d11/Media/UI/Font.dds 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 { + <b8d65549-d7c9-4995-89cf-53a9a8b031e3> + 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 Binary files differnew file mode 100644 index 0000000..b5f52e1 --- /dev/null +++ b/sample/d3d11/Media/UI/dxutcontrols.dds diff --git a/sample/d3d11/Media/ocean_surface_d3d11.fxo b/sample/d3d11/Media/ocean_surface_d3d11.fxo Binary files differnew file mode 100644 index 0000000..0f2430f --- /dev/null +++ b/sample/d3d11/Media/ocean_surface_d3d11.fxo diff --git a/sample/d3d11/Media/sample_d3d11.fxo b/sample/d3d11/Media/sample_d3d11.fxo Binary files differnew file mode 100644 index 0000000..9040c57 --- /dev/null +++ b/sample/d3d11/Media/sample_d3d11.fxo 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 <DirectXMath.h> +#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<float*>( 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 ; x<kTopDownDataResolution ; x++ ) + { + for( unsigned int y=0 ; y<kTopDownDataResolution ; y++ ) + { + float gradientX, gradientY; + float distanceToNearestPixel = FindNearestPixel( pTextureReadData, x, y , gradientX, gradientY); + pTextureWriteData[ (x * kTopDownDataResolution + y) * 4 + 0 ] = distanceToNearestPixel; + pTextureWriteData[ (x * kTopDownDataResolution + y) * 4 + 2] = gradientY; + pTextureWriteData[ (x * kTopDownDataResolution + y) * 4 + 3] = gradientX; + + } + } + + + // now blurring the distance field a bit to smoothen the harsh edges, using channel B as temporaty storage, + for( unsigned int x = 1 ; x < kTopDownDataResolution - 1 ; x++ ) + { + for( unsigned int y = 1 ; y < kTopDownDataResolution - 1; y++ ) + { + pTextureWriteData[ (x * kTopDownDataResolution + y) * 4 + 2] = (pTextureWriteData[ ((x + 1)* kTopDownDataResolution + y + 0) * 4 + 0] + + pTextureWriteData[ ((x - 1)* kTopDownDataResolution + y + 0) * 4 + 0] + + pTextureWriteData[ ((x + 0)* kTopDownDataResolution + y - 1) * 4 + 0] + + pTextureWriteData[ ((x + 0)* kTopDownDataResolution + y + 1) * 4 + 0] + + pTextureWriteData[ ((x + 0)* kTopDownDataResolution + y + 1) * 4 + 0])*0.2f; + } + } + for( unsigned int x = 1 ; x < kTopDownDataResolution - 1; x++ ) + { + for( unsigned int y = 1 ; y < kTopDownDataResolution - 1; y++ ) + { + pTextureWriteData[ (x * kTopDownDataResolution + y) * 4 + 0] = (pTextureWriteData[ ((x + 1)* kTopDownDataResolution + y + 0) * 4 + 2] + + pTextureWriteData[ ((x - 1)* kTopDownDataResolution + y + 0) * 4 + 2] + + pTextureWriteData[ ((x + 0)* kTopDownDataResolution + y - 1) * 4 + 2] + + pTextureWriteData[ ((x + 0)* kTopDownDataResolution + y + 1) * 4 + 2] + + pTextureWriteData[ ((x + 0)* kTopDownDataResolution + y + 0) * 4 + 2])*0.2f; + } + } + + // calculating SDF gradients to be stored in B, A channels of the SDF texture + + for( unsigned int x = 1 ; x < kTopDownDataResolution - 1; x++ ) + { + for( unsigned int y = 1 ; y < kTopDownDataResolution - 1; y++ ) + { + float value_center = pTextureWriteData[ ((x + 0)* kTopDownDataResolution + y + 0) * 4 + 0]; + float value_left = pTextureWriteData[ ((x - 1)* kTopDownDataResolution + y + 0) * 4 + 0]; + float value_right = pTextureWriteData[ ((x + 1)* kTopDownDataResolution + y + 0) * 4 + 0]; + float value_bottom = pTextureWriteData[ ((x + 0)* kTopDownDataResolution + y - 1) * 4 + 0]; + float value_top = pTextureWriteData[ ((x + 0)* kTopDownDataResolution + y + 1) * 4 + 0]; + float gdx = value_right - value_left; + float gdy = value_top - value_bottom; + float length = sqrtf(gdx*gdx + gdy*gdy + 0.001f); + gdx /= length; + gdy /= length; + pTextureWriteData[ (x * kTopDownDataResolution + y) * 4 + 2] = -gdy; + pTextureWriteData[ (x * kTopDownDataResolution + y) * 4 + 3] = gdx; + } + } + + } + pDC->Unmap( 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 <D3DX11Effect.h> + +#include <GFSDK_WaveWorks.h> + +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<VS_OUTPUT, 3> 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<VS_OUTPUT, 3> 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<VS_OUTPUT, 3> 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<PS_INPUT> 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 <D3DX11Effect.h> + +#include <GFSDK_WaveWorks.h> +#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<float,1> g_RefractionDepthTextureMS1; +Texture2DMS<float,2> g_RefractionDepthTextureMS2; +Texture2DMS<float,4> 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<HSIn_Heightfield, 1> 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<HSIn_Heightfield, 1> inputPatch ) +{ + return (DUMMY)0; +} + +[domain("quad")] +PSIn_Diffuse HeightFieldPatchDS( PatchData input, + float2 uv : SV_DomainLocation, + OutputPatch<DUMMY, 1> 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 <windows.h> // 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 : <NONE-AVAILABLE>"); + 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 <winresrc.h> + + + +///////////////////////////////////////////////////////////////////////////// +#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 <winresrc.h>\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 <time.h> + +#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 (i<terrain_gridpoints) + { + j=0; + while (j<terrain_gridpoints) + { + + mv=backterrain[i+terrain_gridpoints*j]; + mv+=backterrain[(i+currentstep)+terrain_gridpoints*j]; + mv+=backterrain[(i+currentstep)+terrain_gridpoints*(j+currentstep)]; + mv+=backterrain[i+terrain_gridpoints*(j+currentstep)]; + mv/=4.0; + backterrain[i+currentstep/2+terrain_gridpoints*(j+currentstep/2)]=(float)(mv+rm*((rand()%1000)/1000.0f-0.5f)); + j+=currentstep; + } + i+=currentstep; + } + + //diamond step; + i=0; + j=0; + + while (i<terrain_gridpoints) + { + j=0; + while (j<terrain_gridpoints) + { + + mv=0; + mv=backterrain[i+terrain_gridpoints*j]; + mv+=backterrain[(i+currentstep)+terrain_gridpoints*j]; + mv+=backterrain[(i+currentstep/2)+terrain_gridpoints*(j+currentstep/2)]; + mv+=backterrain[i+currentstep/2+terrain_gridpoints*gp_wrap(j-currentstep/2)]; + mv/=4; + backterrain[i+currentstep/2+terrain_gridpoints*j]=(float)(mv+rm*((rand()%1000)/1000.0f-0.5f)); + + mv=0; + mv=backterrain[i+terrain_gridpoints*j]; + mv+=backterrain[i+terrain_gridpoints*(j+currentstep)]; + mv+=backterrain[(i+currentstep/2)+terrain_gridpoints*(j+currentstep/2)]; + mv+=backterrain[gp_wrap(i-currentstep/2)+terrain_gridpoints*(j+currentstep/2)]; + mv/=4; + backterrain[i+terrain_gridpoints*(j+currentstep/2)]=(float)(mv+rm*((rand()%1000)/1000.0f-0.5f)); + + mv=0; + mv=backterrain[i+currentstep+terrain_gridpoints*j]; + mv+=backterrain[i+currentstep+terrain_gridpoints*(j+currentstep)]; + mv+=backterrain[(i+currentstep/2)+terrain_gridpoints*(j+currentstep/2)]; + mv+=backterrain[gp_wrap(i+currentstep/2+currentstep)+terrain_gridpoints*(j+currentstep/2)]; + mv/=4; + backterrain[i+currentstep+terrain_gridpoints*(j+currentstep/2)]=(float)(mv+rm*((rand()%1000)/1000.0f-0.5f)); + + mv=0; + mv=backterrain[i+currentstep+terrain_gridpoints*(j+currentstep)]; + mv+=backterrain[i+terrain_gridpoints*(j+currentstep)]; + mv+=backterrain[(i+currentstep/2)+terrain_gridpoints*(j+currentstep/2)]; + mv+=backterrain[i+currentstep/2+terrain_gridpoints*gp_wrap(j+currentstep/2+currentstep)]; + mv/=4; + backterrain[i+currentstep/2+terrain_gridpoints*(j+currentstep)]=(float)(mv+rm*((rand()%1000)/1000.0f-0.5f)); + j+=currentstep; + } + i+=currentstep; + } + //changing current step; + currentstep/=2; + rm*=terrain_fractalfactor; + } + + // scaling to minheight..maxheight range + for (i=0;i<terrain_gridpoints+1;i++) + for (j=0;j<terrain_gridpoints+1;j++) + { + height[i][j]=backterrain[i+terrain_gridpoints*j]; + } + maxheight=height[0][0]; + minheight=height[0][0]; + for(i=0;i<terrain_gridpoints+1;i++) + for(j=0;j<terrain_gridpoints+1;j++) + { + if(height[i][j]>maxheight) maxheight=height[i][j]; + if(height[i][j]<minheight) minheight=height[i][j]; + } + offset=minheight-terrain_minheight; + yscale=(terrain_maxheight-terrain_minheight)/(maxheight-minheight); + + for(i=0;i<terrain_gridpoints+1;i++) + for(j=0;j<terrain_gridpoints+1;j++) + { + height[i][j]-=minheight; + height[i][j]*=yscale; + height[i][j]+=terrain_minheight; + } + + // moving down edges of heightmap + for (i=0;i<terrain_gridpoints+1;i++) + for (j=0;j<terrain_gridpoints+1;j++) + { + mv=(float)((i-terrain_gridpoints/2.0f)*(i-terrain_gridpoints/2.0f)+(j-terrain_gridpoints/2.0f)*(j-terrain_gridpoints/2.0f)); + rm=(float)((terrain_gridpoints*0.7f)*(terrain_gridpoints*0.7f)/4.0f); + height[i][j]-=((mv-rm)/900.0f)*terrain_geometry_scale; + } + + + // terrain banks + for(k=0;k<4;k++) + { + for(i=0;i<terrain_gridpoints+1;i++) + for(j=0;j<terrain_gridpoints+1;j++) + { + mv=height[i][j]; + if((mv) > 0.02f) + { + mv -= 0.02f; + } + if(mv < -3.00f) + { + mv += 0.5f; + } + height[i][j]=mv; + } + } + + XMVECTOR vec1, vec2, vec3; + + // smoothing + for(k=0;k<terrain_smoothsteps;k++) + { + for(i=0;i<terrain_gridpoints+1;i++) + for(j=0;j<terrain_gridpoints+1;j++) + { + vec1 = XMVectorSet(2 * terrain_geometry_scale, terrain_geometry_scale*(height[gp_wrap(i + 1)][j] - height[gp_wrap(i - 1)][j]), 0, 0); + vec2 = XMVectorSet(0, -terrain_geometry_scale*(height[i][gp_wrap(j + 1)] - height[i][gp_wrap(j - 1)]), -2 * terrain_geometry_scale, 0); + +// vec1.x=2*terrain_geometry_scale; +// vec1.y=terrain_geometry_scale*(height[gp_wrap(i+1)][j]-height[gp_wrap(i-1)][j]); +// vec1.z=0; +// vec2.x=0; +// vec2.y=-terrain_geometry_scale*(height[i][gp_wrap(j+1)]-height[i][gp_wrap(j-1)]); +// vec2.z=-2*terrain_geometry_scale; + + XMVECTOR vec3 = XMVector3Cross(vec1, vec2); + vec3 = XMVector3Normalize(vec3); + + if(((XMVectorGetY(vec3)>terrain_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;i<terrain_gridpoints+1;i++) + for (j=0;j<terrain_gridpoints+1;j++) + { + height[i][j]=(backterrain[i+terrain_gridpoints*j]); + } + } + for(i=0;i<terrain_gridpoints+1;i++) + for(j=0;j<terrain_gridpoints+1;j++) + { + rm=0.5f; + 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;i<terrain_gridpoints+1;i++) + for (j=0;j<terrain_gridpoints+1;j++) + { + height[i][j]=(backterrain[i+terrain_gridpoints*j]); + } + + + free(backterrain); + + //calculating normals + for (i=0;i<terrain_gridpoints+1;i++) + for (j=0;j<terrain_gridpoints+1;j++) + { + vec1 = XMVectorSet(2 * terrain_geometry_scale, terrain_geometry_scale*(height[gp_wrap(i + 1)][j] - height[gp_wrap(i - 1)][j]), 0, 0); + vec2 = XMVectorSet(0, -terrain_geometry_scale*(height[i][gp_wrap(j + 1)] - height[i][gp_wrap(j - 1)]), -2 * terrain_geometry_scale, 0); + +// vec1.x=2*terrain_geometry_scale; +// vec1.y=terrain_geometry_scale*(height[gp_wrap(i+1)][j]-height[gp_wrap(i-1)][j]); +// vec1.z=0; +// vec2.x=0; +// vec2.y=-terrain_geometry_scale*(height[i][gp_wrap(j+1)]-height[i][gp_wrap(j-1)]); +// vec2.z=-2*terrain_geometry_scale; + + vec3 = XMVector3Cross(vec1, vec2); + vec3 = XMVector3Normalize(vec3); + + XMStoreFloat3(&normal[i][j], vec3); + } + + + // buiding layerdef + byte* temp_layerdef_map_texture_pixels=(byte *)malloc(terrain_layerdef_map_texture_size*terrain_layerdef_map_texture_size*4); + byte* layerdef_map_texture_pixels=(byte *)malloc(terrain_layerdef_map_texture_size*terrain_layerdef_map_texture_size*4); + for(i=0;i<terrain_layerdef_map_texture_size;i++) + for(j=0;j<terrain_layerdef_map_texture_size;j++) + { + x=(float)(terrain_gridpoints)*((float)i/(float)terrain_layerdef_map_texture_size); + z=(float)(terrain_gridpoints)*((float)j/(float)terrain_layerdef_map_texture_size); + ix=(int)floor(x); + iz=(int)floor(z); + rm=bilinear_interpolation(x-ix,z-iz,height[ix][iz],height[ix+1][iz],height[ix+1][iz+1],height[ix][iz+1])*terrain_geometry_scale; + + 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((rm>terrain_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((mv<terrain_slope_grass_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]=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((mv<terrain_slope_rocks_start)&&(rm>terrain_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;i<terrain_layerdef_map_texture_size;i++) + for(j=0;j<terrain_layerdef_map_texture_size;j++) + { + layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+0]=temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+0]; + layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+1]=temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+1]; + layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+2]=temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+2]; + layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+3]=temp_layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+3]; + } + + + for(i=2;i<terrain_layerdef_map_texture_size-2;i++) + for(j=2;j<terrain_layerdef_map_texture_size-2;j++) + { + int n1=0; + int n2=0; + int n3=0; + int n4=0; + for(k=-2;k<3;k++) + for(l=-2;l<3;l++) + { + n1+=temp_layerdef_map_texture_pixels[((j+k)*terrain_layerdef_map_texture_size+i+l)*4+0]; + n2+=temp_layerdef_map_texture_pixels[((j+k)*terrain_layerdef_map_texture_size+i+l)*4+1]; + n3+=temp_layerdef_map_texture_pixels[((j+k)*terrain_layerdef_map_texture_size+i+l)*4+2]; + n4+=temp_layerdef_map_texture_pixels[((j+k)*terrain_layerdef_map_texture_size+i+l)*4+3]; + } + layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+0]=(byte)(n1/25); + layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+1]=(byte)(n2/25); + layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+2]=(byte)(n3/25); + layerdef_map_texture_pixels[(j*terrain_layerdef_map_texture_size+i)*4+3]=(byte)(n4/25); + } + + // putting the generated data to textures + subresource_data.pSysMem = layerdef_map_texture_pixels; + subresource_data.SysMemPitch = terrain_layerdef_map_texture_size*4; + subresource_data.SysMemSlicePitch = 0; + + tex_desc.Width = terrain_layerdef_map_texture_size; + tex_desc.Height = terrain_layerdef_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,&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;i<terrain_gridpoints;i++) + for(int j=0; j<terrain_gridpoints;j++) + { + height_linear_array[(i+j*terrain_gridpoints)*4+0]=normal[i][j].x; + height_linear_array[(i+j*terrain_gridpoints)*4+1]=normal[i][j].y; + height_linear_array[(i+j*terrain_gridpoints)*4+2]=normal[i][j].z; + height_linear_array[(i+j*terrain_gridpoints)*4+3]=height[i][j]; + } + subresource_data.pSysMem = height_linear_array; + subresource_data.SysMemPitch = terrain_gridpoints*4*sizeof(float); + subresource_data.SysMemSlicePitch = 0; + + tex_desc.Width = terrain_gridpoints; + tex_desc.Height = terrain_gridpoints; + tex_desc.MipLevels = 1; + tex_desc.ArraySize = 1; + tex_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + 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,&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;i<terrain_depth_shadow_map_texture_size;i++) + for(j=0;j<terrain_depth_shadow_map_texture_size;j++) + { + x=(float)(terrain_gridpoints)*((float)i/(float)terrain_depth_shadow_map_texture_size); + z=(float)(terrain_gridpoints)*((float)j/(float)terrain_depth_shadow_map_texture_size); + ix=(int)floor(x); + iz=(int)floor(z); + rm=bilinear_interpolation(x-ix,z-iz,height[ix][iz],height[ix+1][iz],height[ix+1][iz+1],height[ix][iz+1])*terrain_geometry_scale; + + if(rm>0) + { + 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;i<terrain_numpatches_1d;i++) + for(int j=0;j<terrain_numpatches_1d;j++) + { + patches_rawdata[(i+j*terrain_numpatches_1d)*4+0]=i*terrain_geometry_scale*terrain_gridpoints/terrain_numpatches_1d; + patches_rawdata[(i+j*terrain_numpatches_1d)*4+1]=j*terrain_geometry_scale*terrain_gridpoints/terrain_numpatches_1d; + patches_rawdata[(i+j*terrain_numpatches_1d)*4+2]=terrain_geometry_scale*terrain_gridpoints/terrain_numpatches_1d; + patches_rawdata[(i+j*terrain_numpatches_1d)*4+3]=terrain_geometry_scale*terrain_gridpoints/terrain_numpatches_1d; + } + + D3D11_BUFFER_DESC buf_desc; + memset(&buf_desc,0,sizeof(buf_desc)); + + buf_desc.ByteWidth = terrain_numpatches_1d*terrain_numpatches_1d*4*sizeof(float); + buf_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + buf_desc.Usage = D3D11_USAGE_DEFAULT; + + subresource_data.pSysMem=patches_rawdata; + subresource_data.SysMemPitch=0; + subresource_data.SysMemSlicePitch=0; + + result=pDevice->CreateBuffer(&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;j<sky_gridpoints;j++) + { + + i=0; + floatnum=(j*(sky_gridpoints+2)*2)*6; + sky_vertexdata[floatnum+0]=terrain_gridpoints*terrain_geometry_scale*0.5f+4000.0f*cos(2.0f*PI*(float)i/(float)sky_gridpoints)*cos(-0.5f*PI+PI*(float)j/(float)sky_gridpoints); + sky_vertexdata[floatnum+1]=4000.0f*sin(-0.5f*PI+PI*(float)(j)/(float)sky_gridpoints); + sky_vertexdata[floatnum+2]=terrain_gridpoints*terrain_geometry_scale*0.5f+4000.0f*sin(2.0f*PI*(float)i/(float)sky_gridpoints)*cos(-0.5f*PI+PI*(float)j/(float)sky_gridpoints); + sky_vertexdata[floatnum+3]=1; + sky_vertexdata[floatnum+4]=(sky_texture_angle+(float)i/(float)sky_gridpoints); + sky_vertexdata[floatnum+5]=2.0f-2.0f*(float)(j+0)/(float)sky_gridpoints; + floatnum+=6; + for(i=0;i<sky_gridpoints+1;i++) + { + sky_vertexdata[floatnum+0]=terrain_gridpoints*terrain_geometry_scale*0.5f+4000.0f*cos(2.0f*PI*(float)i/(float)sky_gridpoints)*cos(-0.5f*PI+PI*(float)j/(float)sky_gridpoints); + sky_vertexdata[floatnum+1]=4000.0f*sin(-0.5f*PI+PI*(float)(j)/(float)sky_gridpoints); + sky_vertexdata[floatnum+2]=terrain_gridpoints*terrain_geometry_scale*0.5f+4000.0f*sin(2.0f*PI*(float)i/(float)sky_gridpoints)*cos(-0.5f*PI+PI*(float)j/(float)sky_gridpoints); + sky_vertexdata[floatnum+3]=1; + sky_vertexdata[floatnum+4]=(sky_texture_angle+(float)i/(float)sky_gridpoints); + sky_vertexdata[floatnum+5]=2.0f-2.0f*(float)(j+0)/(float)sky_gridpoints; + floatnum+=6; + sky_vertexdata[floatnum+0]=terrain_gridpoints*terrain_geometry_scale*0.5f+4000.0f*cos(2.0f*PI*(float)i/(float)sky_gridpoints)*cos(-0.5f*PI+PI*(float)(j+1)/(float)sky_gridpoints); + sky_vertexdata[floatnum+1]=4000.0f*sin(-0.5f*PI+PI*(float)(j+1)/(float)sky_gridpoints); + sky_vertexdata[floatnum+2]=terrain_gridpoints*terrain_geometry_scale*0.5f+4000.0f*sin(2.0f*PI*(float)i/(float)sky_gridpoints)*cos(-0.5f*PI+PI*(float)(j+1)/(float)sky_gridpoints); + sky_vertexdata[floatnum+3]=1; + sky_vertexdata[floatnum+4]=(sky_texture_angle+(float)i/(float)sky_gridpoints); + sky_vertexdata[floatnum+5]=2.0f-2.0f*(float)(j+1)/(float)sky_gridpoints; + floatnum+=6; + } + i=sky_gridpoints; + sky_vertexdata[floatnum+0]=terrain_gridpoints*terrain_geometry_scale*0.5f+4000.0f*cos(2.0f*PI*(float)i/(float)sky_gridpoints)*cos(-0.5f*PI+PI*(float)(j+1)/(float)sky_gridpoints); + sky_vertexdata[floatnum+1]=4000.0f*sin(-0.5f*PI+PI*(float)(j+1)/(float)sky_gridpoints); + sky_vertexdata[floatnum+2]=terrain_gridpoints*terrain_geometry_scale*0.5f+4000.0f*sin(2.0f*PI*(float)i/(float)sky_gridpoints)*cos(-0.5f*PI+PI*(float)(j+1)/(float)sky_gridpoints); + sky_vertexdata[floatnum+3]=1; + sky_vertexdata[floatnum+4]=(sky_texture_angle+(float)i/(float)sky_gridpoints); + sky_vertexdata[floatnum+5]=2.0f-2.0f*(float)(j+1)/(float)sky_gridpoints; + floatnum+=6; + } + + memset(&buf_desc,0,sizeof(buf_desc)); + + buf_desc.ByteWidth = sky_gridpoints*(sky_gridpoints+2)*2*6*sizeof(float); + buf_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + buf_desc.Usage = D3D11_USAGE_DEFAULT; + + subresource_data.pSysMem=sky_vertexdata; + subresource_data.SysMemPitch=0; + subresource_data.SysMemSlicePitch=0; + + result=pDevice->CreateBuffer(&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<const wchar_t *>(path), &pD3D11Resource, &rock_bump_textureSRV)); + SAFE_RELEASE(pD3D11Resource); + + V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("SunsetFair.dds"))); + V_RETURN(DirectX::CreateDDSTextureFromFile(pDevice, static_cast<const wchar_t *>(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<const wchar_t *>(path), &pD3D11Resource, &foam_intensity_textureSRV)); + SAFE_RELEASE(pD3D11Resource); + + V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, TEXT("foam.dds"))); + V_RETURN(DirectX::CreateDDSTextureFromFile(pDevice, static_cast<const wchar_t *>(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<std::codecvt_utf8_utf16<wchar_t>> 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<const wchar_t *>(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<const wchar_t *>(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 Binary files differnew file mode 100644 index 0000000..37514f5 --- /dev/null +++ b/test/media/UI/Font.dds diff --git a/test/media/ocean_surface_d3d11.fxo b/test/media/ocean_surface_d3d11.fxo Binary files differindex 2e18509..d35f8db 100644 --- a/test/media/ocean_surface_d3d11.fxo +++ b/test/media/ocean_surface_d3d11.fxo diff --git a/test/media/sample_d3d11.fxo b/test/media/sample_d3d11.fxo Binary files differnew file mode 100644 index 0000000..9040c57 --- /dev/null +++ b/test/media/sample_d3d11.fxo |