aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Hoobler <[email protected]>2016-03-22 11:40:34 -0400
committerNathan Hoobler <[email protected]>2016-03-22 11:40:34 -0400
commitb4ab266c9010aaff5404f6a508a2e592eb367d36 (patch)
tree1e9eefa78e90485397b50ce5e780a1d0cb38b493
downloadvolumetriclighting-b4ab266c9010aaff5404f6a508a2e592eb367d36.tar.xz
volumetriclighting-b4ab266c9010aaff5404f6a508a2e592eb367d36.zip
initial commit
-rw-r--r--README.md16
-rw-r--r--doc/html/arrowdown.pngbin0 -> 246 bytes
-rw-r--r--doc/html/arrowright.pngbin0 -> 229 bytes
-rw-r--r--doc/html/bc_s.pngbin0 -> 676 bytes
-rw-r--r--doc/html/bdwn.pngbin0 -> 147 bytes
-rw-r--r--doc/html/closed.pngbin0 -> 132 bytes
-rw-r--r--doc/html/doc.pngbin0 -> 746 bytes
-rw-r--r--doc/html/doxygen.css1475
-rw-r--r--doc/html/doxygen.pngbin0 -> 3779 bytes
-rw-r--r--doc/html/dynsections.js97
-rw-r--r--doc/html/folderclosed.pngbin0 -> 616 bytes
-rw-r--r--doc/html/folderopen.pngbin0 -> 597 bytes
-rw-r--r--doc/html/index.html74
-rw-r--r--doc/html/jquery.js68
-rw-r--r--doc/html/nav_f.pngbin0 -> 153 bytes
-rw-r--r--doc/html/nav_g.pngbin0 -> 95 bytes
-rw-r--r--doc/html/nav_h.pngbin0 -> 98 bytes
-rw-r--r--doc/html/navtree.css143
-rw-r--r--doc/html/navtree.js523
-rw-r--r--doc/html/navtreedata.js12
-rw-r--r--doc/html/navtreeindex0.js5
-rw-r--r--doc/html/open.pngbin0 -> 123 bytes
-rw-r--r--doc/html/resize.js97
-rw-r--r--doc/html/splitbar.pngbin0 -> 314 bytes
-rw-r--r--doc/html/sync_off.pngbin0 -> 853 bytes
-rw-r--r--doc/html/sync_on.pngbin0 -> 845 bytes
-rw-r--r--doc/html/tab_a.pngbin0 -> 142 bytes
-rw-r--r--doc/html/tab_b.pngbin0 -> 169 bytes
-rw-r--r--doc/html/tab_h.pngbin0 -> 177 bytes
-rw-r--r--doc/html/tab_s.pngbin0 -> 184 bytes
-rw-r--r--doc/html/tabs.css60
-rw-r--r--external/NvFoundation/1.1/doc/NvFoundation.chmbin0 -> 255890 bytes
-rw-r--r--external/NvFoundation/1.1/doc/ReadMe.txt8
-rw-r--r--external/NvFoundation/1.1/doc/create_docs.cmd7
-rw-r--r--external/NvFoundation/1.1/doc/docs.doxyfile10
-rw-r--r--external/NvFoundation/1.1/include/Nv.h89
-rw-r--r--external/NvFoundation/1.1/include/NvAllocatorCallback.h95
-rw-r--r--external/NvFoundation/1.1/include/NvAssert.h97
-rw-r--r--external/NvFoundation/1.1/include/NvBounds3.h480
-rw-r--r--external/NvFoundation/1.1/include/NvCTypes.h124
-rw-r--r--external/NvFoundation/1.1/include/NvErrorCallback.h73
-rw-r--r--external/NvFoundation/1.1/include/NvErrors.h93
-rw-r--r--external/NvFoundation/1.1/include/NvFlags.h375
-rw-r--r--external/NvFoundation/1.1/include/NvFoundationInterface.h37
-rw-r--r--external/NvFoundation/1.1/include/NvFoundationMath.h42
-rw-r--r--external/NvFoundation/1.1/include/NvIO.h138
-rw-r--r--external/NvFoundation/1.1/include/NvIntrinsics.h53
-rw-r--r--external/NvFoundation/1.1/include/NvMat33.h392
-rw-r--r--external/NvFoundation/1.1/include/NvMat44.h376
-rw-r--r--external/NvFoundation/1.1/include/NvMath.h338
-rw-r--r--external/NvFoundation/1.1/include/NvPlane.h145
-rw-r--r--external/NvFoundation/1.1/include/NvPreprocessor.h540
-rw-r--r--external/NvFoundation/1.1/include/NvProfiler.h219
-rw-r--r--external/NvFoundation/1.1/include/NvQuat.h398
-rw-r--r--external/NvFoundation/1.1/include/NvSimpleTypes.h72
-rw-r--r--external/NvFoundation/1.1/include/NvTransform.h215
-rw-r--r--external/NvFoundation/1.1/include/NvVec2.h347
-rw-r--r--external/NvFoundation/1.1/include/NvVec3.h393
-rw-r--r--external/NvFoundation/1.1/include/NvVec4.h376
-rw-r--r--external/NvFoundation/1.1/include/ps3/NvPS3Assert.h55
-rw-r--r--external/NvFoundation/1.1/include/ps3/NvPS3Error.h51
-rw-r--r--external/NvFoundation/1.1/include/ps3/NvPS3Intrinsics.h219
-rw-r--r--external/NvFoundation/1.1/include/psp2/NvPSP2Intrinsics.h180
-rw-r--r--external/NvFoundation/1.1/include/unix/NvUnixIntrinsics.h174
-rw-r--r--external/NvFoundation/1.1/include/wiiu/NvWiiUIntrinsics.h179
-rw-r--r--external/NvFoundation/1.1/include/windows/NvWindowsIntrinsics.h188
-rw-r--r--external/NvFoundation/1.1/include/xbox360/NvXbox360Intrinsics.h189
-rw-r--r--external/NvFoundation/1.1/include/xboxone/NvXboxOneIntrinsics.h188
-rw-r--r--include/Nv/VolumetricLighting/NvVolumetricLighting.h511
-rw-r--r--lib/win64/NvVolumetricLighting.win64.libbin0 -> 7998 bytes
-rw-r--r--redist/win64/NvVolumetricLighting.win64.dllbin0 -> 2093568 bytes
-rw-r--r--redist/win64/NvVolumetricLighting.win64.dll.pdbbin0 -> 946176 bytes
-rw-r--r--samples/VolumetricLightingTest/common.h264
-rw-r--r--samples/VolumetricLightingTest/d3d11/DeviceManager.cpp609
-rw-r--r--samples/VolumetricLightingTest/d3d11/DeviceManager.h148
-rw-r--r--samples/VolumetricLightingTest/d3d11/compiled_shaders_d3d11.cpp36
-rw-r--r--samples/VolumetricLightingTest/d3d11/compiled_shaders_d3d11.h45
-rw-r--r--samples/VolumetricLightingTest/d3d11/d3d11_main.cpp478
-rw-r--r--samples/VolumetricLightingTest/d3d11/d3d11_util.cpp347
-rw-r--r--samples/VolumetricLightingTest/d3d11/d3d11_util.h234
-rw-r--r--samples/VolumetricLightingTest/main.cpp68
-rw-r--r--samples/VolumetricLightingTest/scene.cpp609
-rw-r--r--samples/VolumetricLightingTest/scene.h150
-rw-r--r--samples/VolumetricLightingTest/shaders/post_PS.hlsl56
-rw-r--r--samples/VolumetricLightingTest/shaders/quad_VS.hlsl47
-rw-r--r--samples/VolumetricLightingTest/shaders/scene_GS.hlsl141
-rw-r--r--samples/VolumetricLightingTest/shaders/scene_PS.hlsl177
-rw-r--r--samples/VolumetricLightingTest/shaders/scene_VS.hlsl117
-rw-r--r--samples/bin/NvVolumetricLighting.win64.dllbin0 -> 2093568 bytes
-rw-r--r--samples/bin/VolumetricLightingTest.win64.exebin0 -> 110592 bytes
-rw-r--r--samples/bin/VolumetricLightingTest_Readme.txt15
-rw-r--r--samples/build/vs2012/VolumetricLightingTest.vcxproj338
-rw-r--r--samples/build/vs2012/VolumetricLightingTest.vcxproj.filters69
-rw-r--r--samples/build/vs2012/VolumetricLighting_Samples.sln30
-rw-r--r--samples/build/vs2013/VolumetricLightingTest.vcxproj338
-rw-r--r--samples/build/vs2013/VolumetricLightingTest.vcxproj.filters69
-rw-r--r--samples/build/vs2013/VolumetricLighting_Samples.sln30
-rw-r--r--src/NvVolumetricLighting.cpp250
-rw-r--r--src/build/vs2012/NvVolumetricLighting.sln30
-rw-r--r--src/build/vs2012/NvVolumetricLighting.vcxproj454
-rw-r--r--src/build/vs2012/NvVolumetricLighting.vcxproj.filters96
-rw-r--r--src/build/vs2013/NvVolumetricLighting.sln30
-rw-r--r--src/build/vs2013/NvVolumetricLighting.vcxproj454
-rw-r--r--src/build/vs2013/NvVolumetricLighting.vcxproj.filters96
-rw-r--r--src/common.h261
-rw-r--r--src/context_common.cpp431
-rw-r--r--src/context_common.h249
-rw-r--r--src/d3d11/compiled_shaders_d3d11.cpp43
-rw-r--r--src/d3d11/compiled_shaders_d3d11.h52
-rw-r--r--src/d3d11/context_d3d11.cpp1257
-rw-r--r--src/d3d11/context_d3d11.h191
-rw-r--r--src/d3d11/d3d11_util.cpp347
-rw-r--r--src/d3d11/d3d11_util.h234
-rw-r--r--src/shaders/Apply_PS.hlsl176
-rw-r--r--src/shaders/ComputeLightLUT_CS.hlsl192
-rw-r--r--src/shaders/ComputePhaseLookup_PS.hlsl150
-rw-r--r--src/shaders/Debug_PS.hlsl42
-rw-r--r--src/shaders/DownsampleDepth_PS.hlsl82
-rw-r--r--src/shaders/Quad_VS.hlsl46
-rw-r--r--src/shaders/RenderVolume_DS.hlsl181
-rw-r--r--src/shaders/RenderVolume_HS.hlsl182
-rw-r--r--src/shaders/RenderVolume_PS.hlsl403
-rw-r--r--src/shaders/RenderVolume_VS.hlsl204
-rw-r--r--src/shaders/Resolve_PS.hlsl179
-rw-r--r--src/shaders/ShaderCommon.h265
-rw-r--r--src/shaders/TemporalFilter_PS.hlsl207
-rw-r--r--tools/shadermux.exebin0 -> 5131986 bytes
127 files changed, 21235 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..953aa0c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,16 @@
+NVIDIA Gameworks Volumetric Lighting 1.0
+========================================
+
+Directory Structure
+-------------------
+./doc/ - Library documentation
+./external/ - External code dependencies
+./include/ - Library-specific headers
+./lib/ - Static libraries to link with the application (divided by platform)
+./redist/ - DLLs to distribute to end-users with application
+./samples/ - Code samples
+./samples/bin/ - Pre-built sample binaries
+./samples/build/ - Project files for building samples (divided by platform)
+./src/ - Source for library internals
+./src/build/ - Project files for building the library (divided by platform)
+./tools/ - Tools needed to build the library or facilitate its use
diff --git a/doc/html/arrowdown.png b/doc/html/arrowdown.png
new file mode 100644
index 0000000..0b63f6d
--- /dev/null
+++ b/doc/html/arrowdown.png
Binary files differ
diff --git a/doc/html/arrowright.png b/doc/html/arrowright.png
new file mode 100644
index 0000000..c6ee22f
--- /dev/null
+++ b/doc/html/arrowright.png
Binary files differ
diff --git a/doc/html/bc_s.png b/doc/html/bc_s.png
new file mode 100644
index 0000000..224b29a
--- /dev/null
+++ b/doc/html/bc_s.png
Binary files differ
diff --git a/doc/html/bdwn.png b/doc/html/bdwn.png
new file mode 100644
index 0000000..940a0b9
--- /dev/null
+++ b/doc/html/bdwn.png
Binary files differ
diff --git a/doc/html/closed.png b/doc/html/closed.png
new file mode 100644
index 0000000..98cc2c9
--- /dev/null
+++ b/doc/html/closed.png
Binary files differ
diff --git a/doc/html/doc.png b/doc/html/doc.png
new file mode 100644
index 0000000..17edabf
--- /dev/null
+++ b/doc/html/doc.png
Binary files differ
diff --git a/doc/html/doxygen.css b/doc/html/doxygen.css
new file mode 100644
index 0000000..1425ec5
--- /dev/null
+++ b/doc/html/doxygen.css
@@ -0,0 +1,1475 @@
+/* The standard CSS for doxygen 1.8.11 */
+
+body, table, div, p, dl {
+ font: 400 14px/22px Roboto,sans-serif;
+}
+
+/* @group Heading Levels */
+
+h1.groupheader {
+ font-size: 150%;
+}
+
+.title {
+ font: 400 14px/28px Roboto,sans-serif;
+ font-size: 150%;
+ font-weight: bold;
+ margin: 10px 2px;
+}
+
+h2.groupheader {
+ border-bottom: 1px solid #879ECB;
+ color: #354C7B;
+ font-size: 150%;
+ font-weight: normal;
+ margin-top: 1.75em;
+ padding-top: 8px;
+ padding-bottom: 4px;
+ width: 100%;
+}
+
+h3.groupheader {
+ font-size: 100%;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ -webkit-transition: text-shadow 0.5s linear;
+ -moz-transition: text-shadow 0.5s linear;
+ -ms-transition: text-shadow 0.5s linear;
+ -o-transition: text-shadow 0.5s linear;
+ transition: text-shadow 0.5s linear;
+ margin-right: 15px;
+}
+
+h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow {
+ text-shadow: 0 0 15px cyan;
+}
+
+dt {
+ font-weight: bold;
+}
+
+div.multicol {
+ -moz-column-gap: 1em;
+ -webkit-column-gap: 1em;
+ -moz-column-count: 3;
+ -webkit-column-count: 3;
+}
+
+p.startli, p.startdd {
+ margin-top: 2px;
+}
+
+p.starttd {
+ margin-top: 0px;
+}
+
+p.endli {
+ margin-bottom: 0px;
+}
+
+p.enddd {
+ margin-bottom: 4px;
+}
+
+p.endtd {
+ margin-bottom: 2px;
+}
+
+/* @end */
+
+caption {
+ font-weight: bold;
+}
+
+span.legend {
+ font-size: 70%;
+ text-align: center;
+}
+
+h3.version {
+ font-size: 90%;
+ text-align: center;
+}
+
+div.qindex, div.navtab{
+ background-color: #EBEFF6;
+ border: 1px solid #A3B4D7;
+ text-align: center;
+}
+
+div.qindex, div.navpath {
+ width: 100%;
+ line-height: 140%;
+}
+
+div.navtab {
+ margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+ color: #3D578C;
+ font-weight: normal;
+ text-decoration: none;
+}
+
+.contents a:visited {
+ color: #4665A2;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+a.qindex {
+ font-weight: bold;
+}
+
+a.qindexHL {
+ font-weight: bold;
+ background-color: #9CAFD4;
+ color: #ffffff;
+ border: 1px double #869DCA;
+}
+
+.contents a.qindexHL:visited {
+ color: #ffffff;
+}
+
+a.el {
+ font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code, a.code:visited, a.line, a.line:visited {
+ color: #4665A2;
+}
+
+a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited {
+ color: #4665A2;
+}
+
+/* @end */
+
+dl.el {
+ margin-left: -1cm;
+}
+
+pre.fragment {
+ border: 1px solid #C4CFE5;
+ background-color: #FBFCFD;
+ padding: 4px 6px;
+ margin: 4px 8px 4px 2px;
+ overflow: auto;
+ word-wrap: break-word;
+ font-size: 9pt;
+ line-height: 125%;
+ font-family: monospace, fixed;
+ font-size: 105%;
+}
+
+div.fragment {
+ padding: 4px 6px;
+ margin: 4px 8px 4px 2px;
+ background-color: #FBFCFD;
+ border: 1px solid #C4CFE5;
+}
+
+div.line {
+ font-family: monospace, fixed;
+ font-size: 13px;
+ min-height: 13px;
+ line-height: 1.0;
+ text-wrap: unrestricted;
+ white-space: -moz-pre-wrap; /* Moz */
+ white-space: -pre-wrap; /* Opera 4-6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ white-space: pre-wrap; /* CSS3 */
+ word-wrap: break-word; /* IE 5.5+ */
+ text-indent: -53px;
+ padding-left: 53px;
+ padding-bottom: 0px;
+ margin: 0px;
+ -webkit-transition-property: background-color, box-shadow;
+ -webkit-transition-duration: 0.5s;
+ -moz-transition-property: background-color, box-shadow;
+ -moz-transition-duration: 0.5s;
+ -ms-transition-property: background-color, box-shadow;
+ -ms-transition-duration: 0.5s;
+ -o-transition-property: background-color, box-shadow;
+ -o-transition-duration: 0.5s;
+ transition-property: background-color, box-shadow;
+ transition-duration: 0.5s;
+}
+
+div.line:after {
+ content:"\000A";
+ white-space: pre;
+}
+
+div.line.glow {
+ background-color: cyan;
+ box-shadow: 0 0 10px cyan;
+}
+
+
+span.lineno {
+ padding-right: 4px;
+ text-align: right;
+ border-right: 2px solid #0F0;
+ background-color: #E8E8E8;
+ white-space: pre;
+}
+span.lineno a {
+ background-color: #D8D8D8;
+}
+
+span.lineno a:hover {
+ background-color: #C8C8C8;
+}
+
+div.ah, span.ah {
+ background-color: black;
+ font-weight: bold;
+ color: #ffffff;
+ margin-bottom: 3px;
+ margin-top: 3px;
+ padding: 0.2em;
+ border: solid thin #333;
+ border-radius: 0.5em;
+ -webkit-border-radius: .5em;
+ -moz-border-radius: .5em;
+ box-shadow: 2px 2px 3px #999;
+ -webkit-box-shadow: 2px 2px 3px #999;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
+ background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%);
+}
+
+div.classindex ul {
+ list-style: none;
+ padding-left: 0;
+}
+
+div.classindex span.ai {
+ display: inline-block;
+}
+
+div.groupHeader {
+ margin-left: 16px;
+ margin-top: 12px;
+ font-weight: bold;
+}
+
+div.groupText {
+ margin-left: 16px;
+ font-style: italic;
+}
+
+body {
+ background-color: white;
+ color: black;
+ margin: 0;
+}
+
+div.contents {
+ margin-top: 10px;
+ margin-left: 12px;
+ margin-right: 8px;
+}
+
+td.indexkey {
+ background-color: #EBEFF6;
+ font-weight: bold;
+ border: 1px solid #C4CFE5;
+ margin: 2px 0px 2px 0;
+ padding: 2px 10px;
+ white-space: nowrap;
+ vertical-align: top;
+}
+
+td.indexvalue {
+ background-color: #EBEFF6;
+ border: 1px solid #C4CFE5;
+ padding: 2px 10px;
+ margin: 2px 0px;
+}
+
+tr.memlist {
+ background-color: #EEF1F7;
+}
+
+p.formulaDsp {
+ text-align: center;
+}
+
+img.formulaDsp {
+
+}
+
+img.formulaInl {
+ vertical-align: middle;
+}
+
+div.center {
+ text-align: center;
+ margin-top: 0px;
+ margin-bottom: 0px;
+ padding: 0px;
+}
+
+div.center img {
+ border: 0px;
+}
+
+address.footer {
+ text-align: right;
+ padding-right: 12px;
+}
+
+img.footer {
+ border: 0px;
+ vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+ color: #008000
+}
+
+span.keywordtype {
+ color: #604020
+}
+
+span.keywordflow {
+ color: #e08000
+}
+
+span.comment {
+ color: #800000
+}
+
+span.preprocessor {
+ color: #806020
+}
+
+span.stringliteral {
+ color: #002080
+}
+
+span.charliteral {
+ color: #008080
+}
+
+span.vhdldigit {
+ color: #ff00ff
+}
+
+span.vhdlchar {
+ color: #000000
+}
+
+span.vhdlkeyword {
+ color: #700070
+}
+
+span.vhdllogic {
+ color: #ff0000
+}
+
+blockquote {
+ background-color: #F7F8FB;
+ border-left: 2px solid #9CAFD4;
+ margin: 0 24px 0 4px;
+ padding: 0 12px 0 16px;
+}
+
+/* @end */
+
+/*
+.search {
+ color: #003399;
+ font-weight: bold;
+}
+
+form.search {
+ margin-bottom: 0px;
+ margin-top: 0px;
+}
+
+input.search {
+ font-size: 75%;
+ color: #000080;
+ font-weight: normal;
+ background-color: #e8eef2;
+}
+*/
+
+td.tiny {
+ font-size: 75%;
+}
+
+.dirtab {
+ padding: 4px;
+ border-collapse: collapse;
+ border: 1px solid #A3B4D7;
+}
+
+th.dirtab {
+ background: #EBEFF6;
+ font-weight: bold;
+}
+
+hr {
+ height: 0px;
+ border: none;
+ border-top: 1px solid #4A6AAA;
+}
+
+hr.footer {
+ height: 1px;
+}
+
+/* @group Member Descriptions */
+
+table.memberdecls {
+ border-spacing: 0px;
+ padding: 0px;
+}
+
+.memberdecls td, .fieldtable tr {
+ -webkit-transition-property: background-color, box-shadow;
+ -webkit-transition-duration: 0.5s;
+ -moz-transition-property: background-color, box-shadow;
+ -moz-transition-duration: 0.5s;
+ -ms-transition-property: background-color, box-shadow;
+ -ms-transition-duration: 0.5s;
+ -o-transition-property: background-color, box-shadow;
+ -o-transition-duration: 0.5s;
+ transition-property: background-color, box-shadow;
+ transition-duration: 0.5s;
+}
+
+.memberdecls td.glow, .fieldtable tr.glow {
+ background-color: cyan;
+ box-shadow: 0 0 15px cyan;
+}
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+ background-color: #F9FAFC;
+ border: none;
+ margin: 4px;
+ padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+ padding: 0px 8px 4px 8px;
+ color: #555;
+}
+
+.memSeparator {
+ border-bottom: 1px solid #DEE4F0;
+ line-height: 1px;
+ margin: 0px;
+ padding: 0px;
+}
+
+.memItemLeft, .memTemplItemLeft {
+ white-space: nowrap;
+}
+
+.memItemRight {
+ width: 100%;
+}
+
+.memTemplParams {
+ color: #4665A2;
+ white-space: nowrap;
+ font-size: 80%;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtemplate {
+ font-size: 80%;
+ color: #4665A2;
+ font-weight: normal;
+ margin-left: 9px;
+}
+
+.memnav {
+ background-color: #EBEFF6;
+ border: 1px solid #A3B4D7;
+ text-align: center;
+ margin: 2px;
+ margin-right: 15px;
+ padding: 2px;
+}
+
+.mempage {
+ width: 100%;
+}
+
+.memitem {
+ padding: 0;
+ margin-bottom: 10px;
+ margin-right: 5px;
+ -webkit-transition: box-shadow 0.5s linear;
+ -moz-transition: box-shadow 0.5s linear;
+ -ms-transition: box-shadow 0.5s linear;
+ -o-transition: box-shadow 0.5s linear;
+ transition: box-shadow 0.5s linear;
+ display: table !important;
+ width: 100%;
+}
+
+.memitem.glow {
+ box-shadow: 0 0 15px cyan;
+}
+
+.memname {
+ font-weight: bold;
+ margin-left: 6px;
+}
+
+.memname td {
+ vertical-align: bottom;
+}
+
+.memproto, dl.reflist dt {
+ border-top: 1px solid #A8B8D9;
+ border-left: 1px solid #A8B8D9;
+ border-right: 1px solid #A8B8D9;
+ padding: 6px 0px 6px 0px;
+ color: #253555;
+ font-weight: bold;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ background-image:url('nav_f.png');
+ background-repeat:repeat-x;
+ background-color: #E2E8F2;
+ /* opera specific markup */
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+ /* firefox specific markup */
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ -moz-border-radius-topright: 4px;
+ -moz-border-radius-topleft: 4px;
+ /* webkit specific markup */
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ -webkit-border-top-right-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+
+}
+
+.memdoc, dl.reflist dd {
+ border-bottom: 1px solid #A8B8D9;
+ border-left: 1px solid #A8B8D9;
+ border-right: 1px solid #A8B8D9;
+ padding: 6px 10px 2px 10px;
+ background-color: #FBFCFD;
+ border-top-width: 0;
+ background-image:url('nav_g.png');
+ background-repeat:repeat-x;
+ background-color: #FFFFFF;
+ /* opera specific markup */
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ /* firefox specific markup */
+ -moz-border-radius-bottomleft: 4px;
+ -moz-border-radius-bottomright: 4px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ /* webkit specific markup */
+ -webkit-border-bottom-left-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+}
+
+dl.reflist dt {
+ padding: 5px;
+}
+
+dl.reflist dd {
+ margin: 0px 0px 10px 0px;
+ padding: 5px;
+}
+
+.paramkey {
+ text-align: right;
+}
+
+.paramtype {
+ white-space: nowrap;
+}
+
+.paramname {
+ color: #602020;
+ white-space: nowrap;
+}
+.paramname em {
+ font-style: normal;
+}
+.paramname code {
+ line-height: 14px;
+}
+
+.params, .retval, .exception, .tparams {
+ margin-left: 0px;
+ padding-left: 0px;
+}
+
+.params .paramname, .retval .paramname {
+ font-weight: bold;
+ vertical-align: top;
+}
+
+.params .paramtype {
+ font-style: italic;
+ vertical-align: top;
+}
+
+.params .paramdir {
+ font-family: "courier new",courier,monospace;
+ vertical-align: top;
+}
+
+table.mlabels {
+ border-spacing: 0px;
+}
+
+td.mlabels-left {
+ width: 100%;
+ padding: 0px;
+}
+
+td.mlabels-right {
+ vertical-align: bottom;
+ padding: 0px;
+ white-space: nowrap;
+}
+
+span.mlabels {
+ margin-left: 8px;
+}
+
+span.mlabel {
+ background-color: #728DC1;
+ border-top:1px solid #5373B4;
+ border-left:1px solid #5373B4;
+ border-right:1px solid #C4CFE5;
+ border-bottom:1px solid #C4CFE5;
+ text-shadow: none;
+ color: white;
+ margin-right: 4px;
+ padding: 2px 3px;
+ border-radius: 3px;
+ font-size: 7pt;
+ white-space: nowrap;
+ vertical-align: middle;
+}
+
+
+
+/* @end */
+
+/* these are for tree view inside a (index) page */
+
+div.directory {
+ margin: 10px 0px;
+ border-top: 1px solid #9CAFD4;
+ border-bottom: 1px solid #9CAFD4;
+ width: 100%;
+}
+
+.directory table {
+ border-collapse:collapse;
+}
+
+.directory td {
+ margin: 0px;
+ padding: 0px;
+ vertical-align: top;
+}
+
+.directory td.entry {
+ white-space: nowrap;
+ padding-right: 6px;
+ padding-top: 3px;
+}
+
+.directory td.entry a {
+ outline:none;
+}
+
+.directory td.entry a img {
+ border: none;
+}
+
+.directory td.desc {
+ width: 100%;
+ padding-left: 6px;
+ padding-right: 6px;
+ padding-top: 3px;
+ border-left: 1px solid rgba(0,0,0,0.05);
+}
+
+.directory tr.even {
+ padding-left: 6px;
+ background-color: #F7F8FB;
+}
+
+.directory img {
+ vertical-align: -30%;
+}
+
+.directory .levels {
+ white-space: nowrap;
+ width: 100%;
+ text-align: right;
+ font-size: 9pt;
+}
+
+.directory .levels span {
+ cursor: pointer;
+ padding-left: 2px;
+ padding-right: 2px;
+ color: #3D578C;
+}
+
+.arrow {
+ color: #9CAFD4;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ cursor: pointer;
+ font-size: 80%;
+ display: inline-block;
+ width: 16px;
+ height: 22px;
+}
+
+.icon {
+ font-family: Arial, Helvetica;
+ font-weight: bold;
+ font-size: 12px;
+ height: 14px;
+ width: 16px;
+ display: inline-block;
+ background-color: #728DC1;
+ color: white;
+ text-align: center;
+ border-radius: 4px;
+ margin-left: 2px;
+ margin-right: 2px;
+}
+
+.icona {
+ width: 24px;
+ height: 22px;
+ display: inline-block;
+}
+
+.iconfopen {
+ width: 24px;
+ height: 18px;
+ margin-bottom: 4px;
+ background-image:url('folderopen.png');
+ background-position: 0px -4px;
+ background-repeat: repeat-y;
+ vertical-align:top;
+ display: inline-block;
+}
+
+.iconfclosed {
+ width: 24px;
+ height: 18px;
+ margin-bottom: 4px;
+ background-image:url('folderclosed.png');
+ background-position: 0px -4px;
+ background-repeat: repeat-y;
+ vertical-align:top;
+ display: inline-block;
+}
+
+.icondoc {
+ width: 24px;
+ height: 18px;
+ margin-bottom: 4px;
+ background-image:url('doc.png');
+ background-position: 0px -4px;
+ background-repeat: repeat-y;
+ vertical-align:top;
+ display: inline-block;
+}
+
+table.directory {
+ font: 400 14px Roboto,sans-serif;
+}
+
+/* @end */
+
+div.dynheader {
+ margin-top: 8px;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+address {
+ font-style: normal;
+ color: #2A3D61;
+}
+
+table.doxtable caption {
+ caption-side: top;
+}
+
+table.doxtable {
+ border-collapse:collapse;
+ margin-top: 4px;
+ margin-bottom: 4px;
+}
+
+table.doxtable td, table.doxtable th {
+ border: 1px solid #2D4068;
+ padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+ background-color: #374F7F;
+ color: #FFFFFF;
+ font-size: 110%;
+ padding-bottom: 4px;
+ padding-top: 5px;
+}
+
+table.fieldtable {
+ /*width: 100%;*/
+ margin-bottom: 10px;
+ border: 1px solid #A8B8D9;
+ border-spacing: 0px;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+ -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+ box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+}
+
+.fieldtable td, .fieldtable th {
+ padding: 3px 7px 2px;
+}
+
+.fieldtable td.fieldtype, .fieldtable td.fieldname {
+ white-space: nowrap;
+ border-right: 1px solid #A8B8D9;
+ border-bottom: 1px solid #A8B8D9;
+ vertical-align: top;
+}
+
+.fieldtable td.fieldname {
+ padding-top: 3px;
+}
+
+.fieldtable td.fielddoc {
+ border-bottom: 1px solid #A8B8D9;
+ /*width: 100%;*/
+}
+
+.fieldtable td.fielddoc p:first-child {
+ margin-top: 0px;
+}
+
+.fieldtable td.fielddoc p:last-child {
+ margin-bottom: 2px;
+}
+
+.fieldtable tr:last-child td {
+ border-bottom: none;
+}
+
+.fieldtable th {
+ background-image:url('nav_f.png');
+ background-repeat:repeat-x;
+ background-color: #E2E8F2;
+ font-size: 90%;
+ color: #253555;
+ padding-bottom: 4px;
+ padding-top: 5px;
+ text-align:left;
+ -moz-border-radius-topleft: 4px;
+ -moz-border-radius-topright: 4px;
+ -webkit-border-top-left-radius: 4px;
+ -webkit-border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom: 1px solid #A8B8D9;
+}
+
+
+.tabsearch {
+ top: 0px;
+ left: 10px;
+ height: 36px;
+ background-image: url('tab_b.png');
+ z-index: 101;
+ overflow: hidden;
+ font-size: 13px;
+}
+
+.navpath ul
+{
+ font-size: 11px;
+ background-image:url('tab_b.png');
+ background-repeat:repeat-x;
+ background-position: 0 -5px;
+ height:30px;
+ line-height:30px;
+ color:#8AA0CC;
+ border:solid 1px #C2CDE4;
+ overflow:hidden;
+ margin:0px;
+ padding:0px;
+}
+
+.navpath li
+{
+ list-style-type:none;
+ float:left;
+ padding-left:10px;
+ padding-right:15px;
+ background-image:url('bc_s.png');
+ background-repeat:no-repeat;
+ background-position:right;
+ color:#364D7C;
+}
+
+.navpath li.navelem a
+{
+ height:32px;
+ display:block;
+ text-decoration: none;
+ outline: none;
+ color: #283A5D;
+ font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ text-decoration: none;
+}
+
+.navpath li.navelem a:hover
+{
+ color:#6884BD;
+}
+
+.navpath li.footer
+{
+ list-style-type:none;
+ float:right;
+ padding-left:10px;
+ padding-right:15px;
+ background-image:none;
+ background-repeat:no-repeat;
+ background-position:right;
+ color:#364D7C;
+ font-size: 8pt;
+}
+
+
+div.summary
+{
+ float: right;
+ font-size: 8pt;
+ padding-right: 5px;
+ width: 50%;
+ text-align: right;
+}
+
+div.summary a
+{
+ white-space: nowrap;
+}
+
+table.classindex
+{
+ margin: 10px;
+ white-space: nowrap;
+ margin-left: 3%;
+ margin-right: 3%;
+ width: 94%;
+ border: 0;
+ border-spacing: 0;
+ padding: 0;
+}
+
+div.ingroups
+{
+ font-size: 8pt;
+ width: 50%;
+ text-align: left;
+}
+
+div.ingroups a
+{
+ white-space: nowrap;
+}
+
+div.header
+{
+ background-image:url('nav_h.png');
+ background-repeat:repeat-x;
+ background-color: #F9FAFC;
+ margin: 0px;
+ border-bottom: 1px solid #C4CFE5;
+}
+
+div.headertitle
+{
+ padding: 5px 5px 5px 10px;
+}
+
+dl
+{
+ padding: 0 0 0 10px;
+}
+
+/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */
+dl.section
+{
+ margin-left: 0px;
+ padding-left: 0px;
+}
+
+dl.note
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #D0C000;
+}
+
+dl.warning, dl.attention
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #FF0000;
+}
+
+dl.pre, dl.post, dl.invariant
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #00D000;
+}
+
+dl.deprecated
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #505050;
+}
+
+dl.todo
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #00C0E0;
+}
+
+dl.test
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #3030E0;
+}
+
+dl.bug
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #C08050;
+}
+
+dl.section dd {
+ margin-bottom: 6px;
+}
+
+
+#projectlogo
+{
+ text-align: center;
+ vertical-align: bottom;
+ border-collapse: separate;
+}
+
+#projectlogo img
+{
+ border: 0px none;
+}
+
+#projectalign
+{
+ vertical-align: middle;
+}
+
+#projectname
+{
+ font: 300% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 2px 0px;
+}
+
+#projectbrief
+{
+ font: 120% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+
+#projectnumber
+{
+ font: 50% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+
+#titlearea
+{
+ padding: 0px;
+ margin: 0px;
+ width: 100%;
+ border-bottom: 1px solid #5373B4;
+}
+
+.image
+{
+ text-align: center;
+}
+
+.dotgraph
+{
+ text-align: center;
+}
+
+.mscgraph
+{
+ text-align: center;
+}
+
+.diagraph
+{
+ text-align: center;
+}
+
+.caption
+{
+ font-weight: bold;
+}
+
+div.zoom
+{
+ border: 1px solid #90A5CE;
+}
+
+dl.citelist {
+ margin-bottom:50px;
+}
+
+dl.citelist dt {
+ color:#334975;
+ float:left;
+ font-weight:bold;
+ margin-right:10px;
+ padding:5px;
+}
+
+dl.citelist dd {
+ margin:2px 0;
+ padding:5px 0;
+}
+
+div.toc {
+ padding: 14px 25px;
+ background-color: #F4F6FA;
+ border: 1px solid #D8DFEE;
+ border-radius: 7px 7px 7px 7px;
+ float: right;
+ height: auto;
+ margin: 0 8px 10px 10px;
+ width: 200px;
+}
+
+div.toc li {
+ background: url("bdwn.png") no-repeat scroll 0 5px transparent;
+ font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif;
+ margin-top: 5px;
+ padding-left: 10px;
+ padding-top: 2px;
+}
+
+div.toc h3 {
+ font: bold 12px/1.2 Arial,FreeSans,sans-serif;
+ color: #4665A2;
+ border-bottom: 0 none;
+ margin: 0;
+}
+
+div.toc ul {
+ list-style: none outside none;
+ border: medium none;
+ padding: 0px;
+}
+
+div.toc li.level1 {
+ margin-left: 0px;
+}
+
+div.toc li.level2 {
+ margin-left: 15px;
+}
+
+div.toc li.level3 {
+ margin-left: 30px;
+}
+
+div.toc li.level4 {
+ margin-left: 45px;
+}
+
+.inherit_header {
+ font-weight: bold;
+ color: gray;
+ cursor: pointer;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.inherit_header td {
+ padding: 6px 0px 2px 5px;
+}
+
+.inherit {
+ display: none;
+}
+
+tr.heading h2 {
+ margin-top: 12px;
+ margin-bottom: 4px;
+}
+
+/* tooltip related style info */
+
+.ttc {
+ position: absolute;
+ display: none;
+}
+
+#powerTip {
+ cursor: default;
+ white-space: nowrap;
+ background-color: white;
+ border: 1px solid gray;
+ border-radius: 4px 4px 4px 4px;
+ box-shadow: 1px 1px 7px gray;
+ display: none;
+ font-size: smaller;
+ max-width: 80%;
+ opacity: 0.9;
+ padding: 1ex 1em 1em;
+ position: absolute;
+ z-index: 2147483647;
+}
+
+#powerTip div.ttdoc {
+ color: grey;
+ font-style: italic;
+}
+
+#powerTip div.ttname a {
+ font-weight: bold;
+}
+
+#powerTip div.ttname {
+ font-weight: bold;
+}
+
+#powerTip div.ttdeci {
+ color: #006318;
+}
+
+#powerTip div {
+ margin: 0px;
+ padding: 0px;
+ font: 12px/16px Roboto,sans-serif;
+}
+
+#powerTip:before, #powerTip:after {
+ content: "";
+ position: absolute;
+ margin: 0px;
+}
+
+#powerTip.n:after, #powerTip.n:before,
+#powerTip.s:after, #powerTip.s:before,
+#powerTip.w:after, #powerTip.w:before,
+#powerTip.e:after, #powerTip.e:before,
+#powerTip.ne:after, #powerTip.ne:before,
+#powerTip.se:after, #powerTip.se:before,
+#powerTip.nw:after, #powerTip.nw:before,
+#powerTip.sw:after, #powerTip.sw:before {
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+}
+
+#powerTip.n:after, #powerTip.s:after,
+#powerTip.w:after, #powerTip.e:after,
+#powerTip.nw:after, #powerTip.ne:after,
+#powerTip.sw:after, #powerTip.se:after {
+ border-color: rgba(255, 255, 255, 0);
+}
+
+#powerTip.n:before, #powerTip.s:before,
+#powerTip.w:before, #powerTip.e:before,
+#powerTip.nw:before, #powerTip.ne:before,
+#powerTip.sw:before, #powerTip.se:before {
+ border-color: rgba(128, 128, 128, 0);
+}
+
+#powerTip.n:after, #powerTip.n:before,
+#powerTip.ne:after, #powerTip.ne:before,
+#powerTip.nw:after, #powerTip.nw:before {
+ top: 100%;
+}
+
+#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after {
+ border-top-color: #ffffff;
+ border-width: 10px;
+ margin: 0px -10px;
+}
+#powerTip.n:before {
+ border-top-color: #808080;
+ border-width: 11px;
+ margin: 0px -11px;
+}
+#powerTip.n:after, #powerTip.n:before {
+ left: 50%;
+}
+
+#powerTip.nw:after, #powerTip.nw:before {
+ right: 14px;
+}
+
+#powerTip.ne:after, #powerTip.ne:before {
+ left: 14px;
+}
+
+#powerTip.s:after, #powerTip.s:before,
+#powerTip.se:after, #powerTip.se:before,
+#powerTip.sw:after, #powerTip.sw:before {
+ bottom: 100%;
+}
+
+#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after {
+ border-bottom-color: #ffffff;
+ border-width: 10px;
+ margin: 0px -10px;
+}
+
+#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before {
+ border-bottom-color: #808080;
+ border-width: 11px;
+ margin: 0px -11px;
+}
+
+#powerTip.s:after, #powerTip.s:before {
+ left: 50%;
+}
+
+#powerTip.sw:after, #powerTip.sw:before {
+ right: 14px;
+}
+
+#powerTip.se:after, #powerTip.se:before {
+ left: 14px;
+}
+
+#powerTip.e:after, #powerTip.e:before {
+ left: 100%;
+}
+#powerTip.e:after {
+ border-left-color: #ffffff;
+ border-width: 10px;
+ top: 50%;
+ margin-top: -10px;
+}
+#powerTip.e:before {
+ border-left-color: #808080;
+ border-width: 11px;
+ top: 50%;
+ margin-top: -11px;
+}
+
+#powerTip.w:after, #powerTip.w:before {
+ right: 100%;
+}
+#powerTip.w:after {
+ border-right-color: #ffffff;
+ border-width: 10px;
+ top: 50%;
+ margin-top: -10px;
+}
+#powerTip.w:before {
+ border-right-color: #808080;
+ border-width: 11px;
+ top: 50%;
+ margin-top: -11px;
+}
+
+@media print
+{
+ #top { display: none; }
+ #side-nav { display: none; }
+ #nav-path { display: none; }
+ body { overflow:visible; }
+ h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }
+ .summary { display: none; }
+ .memitem { page-break-inside: avoid; }
+ #doc-content
+ {
+ margin-left:0 !important;
+ height:auto !important;
+ width:auto !important;
+ overflow:inherit;
+ display:inline;
+ }
+}
+
diff --git a/doc/html/doxygen.png b/doc/html/doxygen.png
new file mode 100644
index 0000000..3ff17d8
--- /dev/null
+++ b/doc/html/doxygen.png
Binary files differ
diff --git a/doc/html/dynsections.js b/doc/html/dynsections.js
new file mode 100644
index 0000000..85e1836
--- /dev/null
+++ b/doc/html/dynsections.js
@@ -0,0 +1,97 @@
+function toggleVisibility(linkObj)
+{
+ var base = $(linkObj).attr('id');
+ var summary = $('#'+base+'-summary');
+ var content = $('#'+base+'-content');
+ var trigger = $('#'+base+'-trigger');
+ var src=$(trigger).attr('src');
+ if (content.is(':visible')===true) {
+ content.hide();
+ summary.show();
+ $(linkObj).addClass('closed').removeClass('opened');
+ $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png');
+ } else {
+ content.show();
+ summary.hide();
+ $(linkObj).removeClass('closed').addClass('opened');
+ $(trigger).attr('src',src.substring(0,src.length-10)+'open.png');
+ }
+ return false;
+}
+
+function updateStripes()
+{
+ $('table.directory tr').
+ removeClass('even').filter(':visible:even').addClass('even');
+}
+
+function toggleLevel(level)
+{
+ $('table.directory tr').each(function() {
+ var l = this.id.split('_').length-1;
+ var i = $('#img'+this.id.substring(3));
+ var a = $('#arr'+this.id.substring(3));
+ if (l<level+1) {
+ i.removeClass('iconfopen iconfclosed').addClass('iconfopen');
+ a.html('&#9660;');
+ $(this).show();
+ } else if (l==level+1) {
+ i.removeClass('iconfclosed iconfopen').addClass('iconfclosed');
+ a.html('&#9658;');
+ $(this).show();
+ } else {
+ $(this).hide();
+ }
+ });
+ updateStripes();
+}
+
+function toggleFolder(id)
+{
+ // the clicked row
+ var currentRow = $('#row_'+id);
+
+ // all rows after the clicked row
+ var rows = currentRow.nextAll("tr");
+
+ var re = new RegExp('^row_'+id+'\\d+_$', "i"); //only one sub
+
+ // only match elements AFTER this one (can't hide elements before)
+ var childRows = rows.filter(function() { return this.id.match(re); });
+
+ // first row is visible we are HIDING
+ if (childRows.filter(':first').is(':visible')===true) {
+ // replace down arrow by right arrow for current row
+ var currentRowSpans = currentRow.find("span");
+ currentRowSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
+ currentRowSpans.filter(".arrow").html('&#9658;');
+ rows.filter("[id^=row_"+id+"]").hide(); // hide all children
+ } else { // we are SHOWING
+ // replace right arrow by down arrow for current row
+ var currentRowSpans = currentRow.find("span");
+ currentRowSpans.filter(".iconfclosed").removeClass("iconfclosed").addClass("iconfopen");
+ currentRowSpans.filter(".arrow").html('&#9660;');
+ // replace down arrows by right arrows for child rows
+ var childRowsSpans = childRows.find("span");
+ childRowsSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
+ childRowsSpans.filter(".arrow").html('&#9658;');
+ childRows.show(); //show all children
+ }
+ updateStripes();
+}
+
+
+function toggleInherit(id)
+{
+ var rows = $('tr.inherit.'+id);
+ var img = $('tr.inherit_header.'+id+' img');
+ var src = $(img).attr('src');
+ if (rows.filter(':first').is(':visible')===true) {
+ rows.css('display','none');
+ $(img).attr('src',src.substring(0,src.length-8)+'closed.png');
+ } else {
+ rows.css('display','table-row'); // using show() causes jump in firefox
+ $(img).attr('src',src.substring(0,src.length-10)+'open.png');
+ }
+}
+
diff --git a/doc/html/folderclosed.png b/doc/html/folderclosed.png
new file mode 100644
index 0000000..bb8ab35
--- /dev/null
+++ b/doc/html/folderclosed.png
Binary files differ
diff --git a/doc/html/folderopen.png b/doc/html/folderopen.png
new file mode 100644
index 0000000..d6c7f67
--- /dev/null
+++ b/doc/html/folderopen.png
Binary files differ
diff --git a/doc/html/index.html b/doc/html/index.html
new file mode 100644
index 0000000..d6bc0a3
--- /dev/null
+++ b/doc/html/index.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.11"/>
+<title>NVIDIA Gameworks Volumetric Lighting: Main Page</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+ $(document).ready(initResizable);
+ $(window).load(resizeHeight);
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">NVIDIA Gameworks Volumetric Lighting
+ &#160;<span id="projectnumber">1.0</span>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.11 -->
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li class="current"><a href="index.html"><span>Main&#160;Page</span></a></li>
+ </ul>
+ </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('index.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+ <div class="headertitle">
+<div class="title">NVIDIA Gameworks Volumetric Lighting Documentation</div> </div>
+</div><!--header-->
+<div class="contents">
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by
+ <a href="http://www.doxygen.org/index.html">
+ <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
+ </ul>
+</div>
+</body>
+</html>
diff --git a/doc/html/jquery.js b/doc/html/jquery.js
new file mode 100644
index 0000000..1f4d0b4
--- /dev/null
+++ b/doc/html/jquery.js
@@ -0,0 +1,68 @@
+/*!
+ * jQuery JavaScript Library v1.7.1
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Mon Nov 21 21:11:03 2011 -0500
+ */
+(function(bb,L){var av=bb.document,bu=bb.navigator,bl=bb.location;var b=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD)},bU=bb.jQuery,bH=bb.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b4<b3;b4++){if((b9=arguments[b4])!=null){for(b2 in b9){b0=b5[b2];b1=b9[b2];if(b5===b1){continue}if(b8&&b1&&(bF.isPlainObject(b1)||(b6=bF.isArray(b1)))){if(b6){b6=false;b7=b0&&bF.isArray(b0)?b0:[]}else{b7=b0&&bF.isPlainObject(b0)?b0:{}}b5[b2]=bF.extend(b8,b7,b1)}else{if(b1!==L){b5[b2]=b1}}}}}return b5};bF.extend({noConflict:function(b0){if(bb.$===bF){bb.$=bH}if(b0&&bb.jQuery===bF){bb.jQuery=bU}return bF},isReady:false,readyWait:1,holdReady:function(b0){if(b0){bF.readyWait++}else{bF.ready(true)}},ready:function(b0){if((b0===true&&!--bF.readyWait)||(b0!==true&&!bF.isReady)){if(!av.body){return setTimeout(bF.ready,1)}bF.isReady=true;if(b0!==true&&--bF.readyWait>0){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b4<b5;){if(b6.apply(b3[b4++],b2)===false){break}}}}else{if(b0){for(b1 in b3){if(b6.call(b3[b1],b1,b3[b1])===false){break}}}else{for(;b4<b5;){if(b6.call(b3[b4],b4,b3[b4++])===false){break}}}}return b3},trim:bO?function(b0){return b0==null?"":bO.call(b0)}:function(b0){return b0==null?"":b0.toString().replace(bI,"").replace(bE,"")},makeArray:function(b3,b1){var b0=b1||[];if(b3!=null){var b2=bF.type(b3);if(b3.length==null||b2==="string"||b2==="function"||b2==="regexp"||bF.isWindow(b3)){bz.call(b0,b3)}else{bF.merge(b0,b3)}}return b0},inArray:function(b2,b3,b1){var b0;if(b3){if(bv){return bv.call(b3,b2,b1)}b0=b3.length;b1=b1?b1<0?Math.max(0,b0+b1):b1:0;for(;b1<b0;b1++){if(b1 in b3&&b3[b1]===b2){return b1}}}return -1},merge:function(b4,b2){var b3=b4.length,b1=0;if(typeof b2.length==="number"){for(var b0=b2.length;b1<b0;b1++){b4[b3++]=b2[b1]}}else{while(b2[b1]!==L){b4[b3++]=b2[b1++]}}b4.length=b3;return b4},grep:function(b1,b6,b0){var b2=[],b5;b0=!!b0;for(var b3=0,b4=b1.length;b3<b4;b3++){b5=!!b6(b1[b3],b3);if(b0!==b5){b2.push(b1[b3])}}return b2},map:function(b0,b7,b8){var b5,b6,b4=[],b2=0,b1=b0.length,b3=b0 instanceof bF||b1!==L&&typeof b1==="number"&&((b1>0&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b2<b1;b2++){b5=b7(b0[b2],b2,b8);if(b5!=null){b4[b4.length]=b5}}}else{for(b6 in b0){b5=b7(b0[b6],b6,b8);if(b5!=null){b4[b4.length]=b5}}}return b4.concat.apply([],b4)},guid:1,proxy:function(b4,b3){if(typeof b3==="string"){var b2=b4[b3];b3=b4;b4=b2}if(!bF.isFunction(b4)){return L}var b0=bK.call(arguments,2),b1=function(){return b4.apply(b3,b0.concat(bK.call(arguments)))};b1.guid=b4.guid=b4.guid||b1.guid||bF.guid++;return b1},access:function(b0,b8,b6,b2,b5,b7){var b1=b0.length;if(typeof b8==="object"){for(var b3 in b8){bF.access(b0,b3,b8[b3],b2,b5,b6)}return b0}if(b6!==L){b2=!b7&&b2&&bF.isFunction(b6);for(var b4=0;b4<b1;b4++){b5(b0[b4],b8,b2?b6.call(b0[b4],b4,b5(b0[b4],b8)):b6,b7)}return b0}return b1?b5(b0[0],b8):L},now:function(){return(new Date()).getTime()},uaMatch:function(b1){b1=b1.toLowerCase();var b0=by.exec(b1)||bR.exec(b1)||bQ.exec(b1)||b1.indexOf("compatible")<0&&bS.exec(b1)||[];return{browser:b0[1]||"",version:b0[2]||"0"}},sub:function(){function b0(b3,b4){return new b0.fn.init(b3,b4)}bF.extend(true,b0,this);b0.superclass=this;b0.fn=b0.prototype=this();b0.fn.constructor=b0;b0.sub=this.sub;b0.fn.init=function b2(b3,b4){if(b4&&b4 instanceof bF&&!(b4 instanceof b0)){b4=b0(b4)}return bF.fn.init.call(this,b3,b4,b1)};b0.fn.init.prototype=b0.fn;var b1=b0(av);return b0},browser:{}});bF.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(b1,b0){bx["[object "+b0+"]"]=b0.toLowerCase()});bV=bF.uaMatch(bX);if(bV.browser){bF.browser[bV.browser]=true;bF.browser.version=bV.version}if(bF.browser.webkit){bF.browser.safari=true}if(bM.test("\xA0")){bI=/^[\s\xA0]+/;bE=/[\s\xA0]+$/}bD=bF(av);if(av.addEventListener){e=function(){av.removeEventListener("DOMContentLoaded",e,false);bF.ready()}}else{if(av.attachEvent){e=function(){if(av.readyState==="complete"){av.detachEvent("onreadystatechange",e);bF.ready()}}}}function bw(){if(bF.isReady){return}try{av.documentElement.doScroll("left")}catch(b0){setTimeout(bw,1);return}bF.ready()}return bF})();var a2={};function X(e){var bv=a2[e]={},bw,bx;e=e.split(/\s+/);for(bw=0,bx=e.length;bw<bx;bw++){bv[e[bw]]=true}return bv}b.Callbacks=function(bw){bw=bw?(a2[bw]||X(bw)):{};var bB=[],bC=[],bx,by,bv,bz,bA,bE=function(bF){var bG,bJ,bI,bH,bK;for(bG=0,bJ=bF.length;bG<bJ;bG++){bI=bF[bG];bH=b.type(bI);if(bH==="array"){bE(bI)}else{if(bH==="function"){if(!bw.unique||!bD.has(bI)){bB.push(bI)}}}}},e=function(bG,bF){bF=bF||[];bx=!bw.memory||[bG,bF];by=true;bA=bv||0;bv=0;bz=bB.length;for(;bB&&bA<bz;bA++){if(bB[bA].apply(bG,bF)===false&&bw.stopOnFalse){bx=true;break}}by=false;if(bB){if(!bw.once){if(bC&&bC.length){bx=bC.shift();bD.fireWith(bx[0],bx[1])}}else{if(bx===true){bD.disable()}else{bB=[]}}}},bD={add:function(){if(bB){var bF=bB.length;bE(arguments);if(by){bz=bB.length}else{if(bx&&bx!==true){bv=bF;e(bx[0],bx[1])}}}return this},remove:function(){if(bB){var bF=arguments,bH=0,bI=bF.length;for(;bH<bI;bH++){for(var bG=0;bG<bB.length;bG++){if(bF[bH]===bB[bG]){if(by){if(bG<=bz){bz--;if(bG<=bA){bA--}}}bB.splice(bG--,1);if(bw.unique){break}}}}}return this},has:function(bG){if(bB){var bF=0,bH=bB.length;for(;bF<bH;bF++){if(bG===bB[bF]){return true}}}return false},empty:function(){bB=[];return this},disable:function(){bB=bC=bx=L;return this},disabled:function(){return !bB},lock:function(){bC=L;if(!bx||bx===true){bD.disable()}return this},locked:function(){return !bC},fireWith:function(bG,bF){if(bC){if(by){if(!bw.once){bC.push([bG,bF])}}else{if(!(bw.once&&bx)){e(bG,bF)}}}return this},fire:function(){bD.fireWith(this,arguments);return this},fired:function(){return !!bx}};return bD};var aJ=[].slice;b.extend({Deferred:function(by){var bx=b.Callbacks("once memory"),bw=b.Callbacks("once memory"),bv=b.Callbacks("memory"),e="pending",bA={resolve:bx,reject:bw,notify:bv},bC={done:bx.add,fail:bw.add,progress:bv.add,state:function(){return e},isResolved:bx.fired,isRejected:bw.fired,then:function(bE,bD,bF){bB.done(bE).fail(bD).progress(bF);return this},always:function(){bB.done.apply(bB,arguments).fail.apply(bB,arguments);return this},pipe:function(bF,bE,bD){return b.Deferred(function(bG){b.each({done:[bF,"resolve"],fail:[bE,"reject"],progress:[bD,"notify"]},function(bI,bL){var bH=bL[0],bK=bL[1],bJ;if(b.isFunction(bH)){bB[bI](function(){bJ=bH.apply(this,arguments);if(bJ&&b.isFunction(bJ.promise)){bJ.promise().then(bG.resolve,bG.reject,bG.notify)}else{bG[bK+"With"](this===bB?bG:this,[bJ])}})}else{bB[bI](bG[bK])}})}).promise()},promise:function(bE){if(bE==null){bE=bC}else{for(var bD in bC){bE[bD]=bC[bD]}}return bE}},bB=bC.promise({}),bz;for(bz in bA){bB[bz]=bA[bz].fire;bB[bz+"With"]=bA[bz].fireWith}bB.done(function(){e="resolved"},bw.disable,bv.lock).fail(function(){e="rejected"},bx.disable,bv.lock);if(by){by.call(bB,bB)}return bB},when:function(bA){var bx=aJ.call(arguments,0),bv=0,e=bx.length,bB=new Array(e),bw=e,by=e,bC=e<=1&&bA&&b.isFunction(bA.promise)?bA:b.Deferred(),bE=bC.promise();function bD(bF){return function(bG){bx[bF]=arguments.length>1?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv<e;bv++){if(bx[bv]&&bx[bv].promise&&b.isFunction(bx[bv].promise)){bx[bv].promise().then(bD(bv),bC.reject,bz(bv))}else{--bw}}if(!bw){bC.resolveWith(bC,bx)}}else{if(bC!==bA){bC.resolveWith(bC,e?[bA]:[])}}return bE}});b.support=(function(){var bJ,bI,bF,bG,bx,bE,bA,bD,bz,bK,bB,by,bw,bv=av.createElement("div"),bH=av.documentElement;bv.setAttribute("className","t");bv.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav></:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="<div "+e+"><div></div></div><table "+e+" cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="<div style='width:4px;'></div>";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA<bz;bA++){delete bB[bv[bA]]}if(!(by?S:b.isEmptyObject)(bB)){return}}}if(!by){delete e[bw].data;if(!S(e[bw])){return}}if(b.support.deleteExpando||!e.setInterval){delete e[bw]}else{e[bw]=null}if(bD){if(b.support.deleteExpando){delete bx[bC]}else{if(bx.removeAttribute){bx.removeAttribute(bC)}else{bx[bC]=null}}}},_data:function(bv,e,bw){return b.data(bv,e,bw,true)},acceptData:function(bv){if(bv.nodeName){var e=b.noData[bv.nodeName.toLowerCase()];if(e){return !(e===true||bv.getAttribute("classid")!==e)}}return true}});b.fn.extend({data:function(by,bA){var bB,e,bw,bz=null;if(typeof by==="undefined"){if(this.length){bz=b.data(this[0]);if(this[0].nodeType===1&&!b._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var bx=0,bv=e.length;bx<bv;bx++){bw=e[bx].name;if(bw.indexOf("data-")===0){bw=b.camelCase(bw.substring(5));a5(this[0],bw,bz[bw])}}b._data(this[0],"parsedAttrs",true)}}return bz}else{if(typeof by==="object"){return this.each(function(){b.data(this,by)})}}bB=by.split(".");bB[1]=bB[1]?"."+bB[1]:"";if(bA===L){bz=this.triggerHandler("getData"+bB[1]+"!",[bB[0]]);if(bz===L&&this.length){bz=b.data(this[0],by);bz=a5(this[0],by,bz)}return bz===L&&bB[1]?this.data(bB[0]):bz}else{return this.each(function(){var bC=b(this),bD=[bB[0],bA];bC.triggerHandler("setData"+bB[1]+"!",bD);b.data(this,by,bA);bC.triggerHandler("changeData"+bB[1]+"!",bD)})}},removeData:function(e){return this.each(function(){b.removeData(this,e)})}});function a5(bx,bw,by){if(by===L&&bx.nodeType===1){var bv="data-"+bw.replace(aA,"-$1").toLowerCase();by=bx.getAttribute(bv);if(typeof by==="string"){try{by=by==="true"?true:by==="false"?false:by==="null"?null:b.isNumeric(by)?parseFloat(by):aS.test(by)?b.parseJSON(by):by}catch(bz){}b.data(bx,bw,by)}else{by=L}}return by}function S(bv){for(var e in bv){if(e==="data"&&b.isEmptyObject(bv[e])){continue}if(e!=="toJSON"){return false}}return true}function bi(by,bx,bA){var bw=bx+"defer",bv=bx+"queue",e=bx+"mark",bz=b._data(by,bw);if(bz&&(bA==="queue"||!b._data(by,bv))&&(bA==="mark"||!b._data(by,e))){setTimeout(function(){if(!b._data(by,bv)&&!b._data(by,e)){b.removeData(by,bw,true);bz.fire()}},0)}}b.extend({_mark:function(bv,e){if(bv){e=(e||"fx")+"mark";b._data(bv,e,(b._data(bv,e)||0)+1)}},_unmark:function(by,bx,bv){if(by!==true){bv=bx;bx=by;by=false}if(bx){bv=bv||"fx";var e=bv+"mark",bw=by?0:((b._data(bx,e)||1)-1);if(bw){b._data(bx,e,bw)}else{b.removeData(bx,e,true);bi(bx,bv,"mark")}}},queue:function(bv,e,bx){var bw;if(bv){e=(e||"fx")+"queue";bw=b._data(bv,e);if(bx){if(!bw||b.isArray(bx)){bw=b._data(bv,e,b.makeArray(bx))}else{bw.push(bx)}}return bw||[]}},dequeue:function(by,bx){bx=bx||"fx";var bv=b.queue(by,bx),bw=bv.shift(),e={};if(bw==="inprogress"){bw=bv.shift()}if(bw){if(bx==="fx"){bv.unshift("inprogress")}b._data(by,bx+".run",e);bw.call(by,function(){b.dequeue(by,bx)},e)}if(!bv.length){b.removeData(by,bx+"queue "+bx+".run",true);bi(by,bx,"queue")}}});b.fn.extend({queue:function(e,bv){if(typeof e!=="string"){bv=e;e="fx"}if(bv===L){return b.queue(this[0],e)}return this.each(function(){var bw=b.queue(this,e,bv);if(e==="fx"&&bw[0]!=="inprogress"){b.dequeue(this,e)}})},dequeue:function(e){return this.each(function(){b.dequeue(this,e)})},delay:function(bv,e){bv=b.fx?b.fx.speeds[bv]||bv:bv;e=e||"fx";return this.queue(e,function(bx,bw){var by=setTimeout(bx,bv);bw.stop=function(){clearTimeout(by)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(bD,bw){if(typeof bD!=="string"){bw=bD;bD=L}bD=bD||"fx";var e=b.Deferred(),bv=this,by=bv.length,bB=1,bz=bD+"defer",bA=bD+"queue",bC=bD+"mark",bx;function bE(){if(!(--bB)){e.resolveWith(bv,[bv])}}while(by--){if((bx=b.data(bv[by],bz,L,true)||(b.data(bv[by],bA,L,true)||b.data(bv[by],bC,L,true))&&b.data(bv[by],bz,b.Callbacks("once memory"),true))){bB++;bx.add(bE)}}bE();return e.promise()}});var aP=/[\n\t\r]/g,af=/\s+/,aU=/\r/g,g=/^(?:button|input)$/i,D=/^(?:button|input|object|select|textarea)$/i,l=/^a(?:rea)?$/i,ao=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,F=b.support.getSetAttribute,be,aY,aF;b.fn.extend({attr:function(e,bv){return b.access(this,e,bv,true,b.attr)},removeAttr:function(e){return this.each(function(){b.removeAttr(this,e)})},prop:function(e,bv){return b.access(this,e,bv,true,b.prop)},removeProp:function(e){e=b.propFix[e]||e;return this.each(function(){try{this[e]=L;delete this[e]}catch(bv){}})},addClass:function(by){var bA,bw,bv,bx,bz,bB,e;if(b.isFunction(by)){return this.each(function(bC){b(this).addClass(by.call(this,bC,this.className))})}if(by&&typeof by==="string"){bA=by.split(af);for(bw=0,bv=this.length;bw<bv;bw++){bx=this[bw];if(bx.nodeType===1){if(!bx.className&&bA.length===1){bx.className=by}else{bz=" "+bx.className+" ";for(bB=0,e=bA.length;bB<e;bB++){if(!~bz.indexOf(" "+bA[bB]+" ")){bz+=bA[bB]+" "}}bx.className=b.trim(bz)}}}}return this},removeClass:function(bz){var bA,bw,bv,by,bx,bB,e;if(b.isFunction(bz)){return this.each(function(bC){b(this).removeClass(bz.call(this,bC,this.className))})}if((bz&&typeof bz==="string")||bz===L){bA=(bz||"").split(af);for(bw=0,bv=this.length;bw<bv;bw++){by=this[bw];if(by.nodeType===1&&by.className){if(bz){bx=(" "+by.className+" ").replace(aP," ");for(bB=0,e=bA.length;bB<e;bB++){bx=bx.replace(" "+bA[bB]+" "," ")}by.className=b.trim(bx)}else{by.className=""}}}}return this},toggleClass:function(bx,bv){var bw=typeof bx,e=typeof bv==="boolean";if(b.isFunction(bx)){return this.each(function(by){b(this).toggleClass(bx.call(this,by,this.className,bv),bv)})}return this.each(function(){if(bw==="string"){var bA,bz=0,by=b(this),bB=bv,bC=bx.split(af);while((bA=bC[bz++])){bB=e?bB:!by.hasClass(bA);by[bB?"addClass":"removeClass"](bA)}}else{if(bw==="undefined"||bw==="boolean"){if(this.className){b._data(this,"__className__",this.className)}this.className=this.className||bx===false?"":b._data(this,"__className__")||""}}})},hasClass:function(e){var bx=" "+e+" ",bw=0,bv=this.length;for(;bw<bv;bw++){if(this[bw].nodeType===1&&(" "+this[bw].className+" ").replace(aP," ").indexOf(bx)>-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv<bz;bv++){bx=bC[bv];if(bx.selected&&(b.support.optDisabled?!bx.disabled:bx.getAttribute("disabled")===null)&&(!bx.parentNode.disabled||!b.nodeName(bx.parentNode,"optgroup"))){bA=b(bx).val();if(bw){return bA}bB.push(bA)}}if(bw&&!bB.length&&bC.length){return b(bC[by]).val()}return bB},set:function(bv,bw){var e=b.makeArray(bw);b(bv).find("option").each(function(){this.selected=b.inArray(b(this).val(),e)>=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType;if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw<e;bw++){bv=bA[bw];if(bv){by=b.propFix[bv]||bv;b.attr(bx,bv,"");bx.removeAttribute(F?bv:by);if(ao.test(bv)&&by in bx){bx[by]=false}}}}},attrHooks:{type:{set:function(e,bv){if(g.test(e.nodeName)&&e.parentNode){b.error("type property can't be changed")}else{if(!b.support.radioValue&&bv==="radio"&&b.nodeName(e,"input")){var bw=e.value;e.setAttribute("type",bv);if(bw){e.value=bw}return bv}}}},value:{get:function(bv,e){if(be&&b.nodeName(bv,"button")){return be.get(bv,e)}return e in bv?bv.value:null},set:function(bv,bw,e){if(be&&b.nodeName(bv,"button")){return be.set(bv,bw,e)}bv.value=bw}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(bz,bx,bA){var bw,e,by,bv=bz.nodeType;if(!bz||bv===3||bv===8||bv===2){return}by=bv!==1||!b.isXMLDoc(bz);if(by){bx=b.propFix[bx]||bx;e=b.propHooks[bx]}if(bA!==L){if(e&&"set" in e&&(bw=e.set(bz,bA,bx))!==L){return bw}else{return(bz[bx]=bA)}}else{if(e&&"get" in e&&(bw=e.get(bz,bx))!==null){return bw}else{return bz[bx]}}},propHooks:{tabIndex:{get:function(bv){var e=bv.getAttributeNode("tabindex");return e&&e.specified?parseInt(e.value,10):D.test(bv.nodeName)||l.test(bv.nodeName)&&bv.href?0:L}}}});b.attrHooks.tabindex=b.propHooks.tabIndex;aY={get:function(bv,e){var bx,bw=b.prop(bv,e);return bw===true||typeof bw!=="boolean"&&(bx=bv.getAttributeNode(e))&&bx.nodeValue!==false?e.toLowerCase():L},set:function(bv,bx,e){var bw;if(bx===false){b.removeAttr(bv,e)}else{bw=b.propFix[e]||e;if(bw in bv){bv[bw]=true}bv.setAttribute(e,e.toLowerCase())}return e}};if(!F){aF={name:true,id:true};be=b.valHooks.button={get:function(bw,bv){var e;e=bw.getAttributeNode(bv);return e&&(aF[bv]?e.nodeValue!=="":e.specified)?e.nodeValue:L},set:function(bw,bx,bv){var e=bw.getAttributeNode(bv);if(!e){e=av.createAttribute(bv);bw.setAttributeNode(e)}return(e.nodeValue=bx+"")}};b.attrHooks.tabindex.set=be.set;b.each(["width","height"],function(bv,e){b.attrHooks[e]=b.extend(b.attrHooks[e],{set:function(bw,bx){if(bx===""){bw.setAttribute(e,"auto");return bx}}})});b.attrHooks.contenteditable={get:be.get,set:function(bv,bw,e){if(bw===""){bw="false"}be.set(bv,bw,e)}}}if(!b.support.hrefNormalized){b.each(["href","src","width","height"],function(bv,e){b.attrHooks[e]=b.extend(b.attrHooks[e],{get:function(bx){var bw=bx.getAttribute(e,2);return bw===null?L:bw}})})}if(!b.support.style){b.attrHooks.style={get:function(e){return e.style.cssText.toLowerCase()||L},set:function(e,bv){return(e.style.cssText=""+bv)}}}if(!b.support.optSelected){b.propHooks.selected=b.extend(b.propHooks.selected,{get:function(bv){var e=bv.parentNode;if(e){e.selectedIndex;if(e.parentNode){e.parentNode.selectedIndex}}return null}})}if(!b.support.enctype){b.propFix.enctype="encoding"}if(!b.support.checkOn){b.each(["radio","checkbox"],function(){b.valHooks[this]={get:function(e){return e.getAttribute("value")===null?"on":e.value}}})}b.each(["radio","checkbox"],function(){b.valHooks[this]=b.extend(b.valHooks[this],{set:function(e,bv){if(b.isArray(bv)){return(e.checked=b.inArray(b(e).val(),bv)>=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI<bC.length;bI++){bH=n.exec(bC[bI])||[];bF=bH[1];e=(bH[2]||"").split(".").sort();bE=b.event.special[bF]||{};bF=(by?bE.delegateType:bE.bindType)||bF;bE=b.event.special[bF]||{};bG=b.extend({type:bF,origType:bH[1],data:bA,handler:bJ,guid:bJ.guid,selector:by,quick:Y(by),namespace:e.join(".")},bv);bw=bK[bF];if(!bw){bw=bK[bF]=[];bw.delegateCount=0;if(!bE.setup||bE.setup.call(bx,bA,e,bB)===false){if(bx.addEventListener){bx.addEventListener(bF,bB,false)}else{if(bx.attachEvent){bx.attachEvent("on"+bF,bB)}}}}if(bE.add){bE.add.call(bx,bG);if(!bG.handler.guid){bG.handler.guid=bJ.guid}}if(by){bw.splice(bw.delegateCount++,0,bG)}else{bw.push(bG)}b.event.global[bF]=true}bx=null},global:{},remove:function(bJ,bE,bv,bH,bB){var bI=b.hasData(bJ)&&b._data(bJ),bF,bx,bz,bL,bC,bA,bG,bw,by,bK,bD,e;if(!bI||!(bw=bI.events)){return}bE=b.trim(bt(bE||"")).split(" ");for(bF=0;bF<bE.length;bF++){bx=n.exec(bE[bF])||[];bz=bL=bx[1];bC=bx[2];if(!bz){for(bz in bw){b.event.remove(bJ,bz+bE[bF],bv,bH,true)}continue}by=b.event.special[bz]||{};bz=(bH?by.delegateType:by.bindType)||bz;bD=bw[bz]||[];bA=bD.length;bC=bC?new RegExp("(^|\\.)"+bC.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(bG=0;bG<bD.length;bG++){e=bD[bG];if((bB||bL===e.origType)&&(!bv||bv.guid===e.guid)&&(!bC||bC.test(e.namespace))&&(!bH||bH===e.selector||bH==="**"&&e.selector)){bD.splice(bG--,1);if(e.selector){bD.delegateCount--}if(by.remove){by.remove.call(bJ,e)}}}if(bD.length===0&&bA!==bD.length){if(!by.teardown||by.teardown.call(bJ,bC)===false){b.removeEvent(bJ,bz,bI.handle)}delete bw[bz]}}if(b.isEmptyObject(bw)){bK=bI.handle;if(bK){bK.elem=null}b.removeData(bJ,["events","handle"],true)}},customEvent:{getData:true,setData:true,changeData:true},trigger:function(bv,bD,bA,bJ){if(bA&&(bA.nodeType===3||bA.nodeType===8)){return}var bG=bv.type||bv,bx=[],e,bw,bC,bH,bz,by,bF,bE,bB,bI;if(T.test(bG+b.event.triggered)){return}if(bG.indexOf("!")>=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bC<bB.length&&!bv.isPropagationStopped();bC++){bH=bB[bC][0];bv.type=bB[bC][1];bE=(b._data(bH,"events")||{})[bv.type]&&b._data(bH,"handle");if(bE){bE.apply(bH,bD)}bE=by&&bH[by];if(bE&&b.acceptData(bH)&&bE.apply(bH,bD)===false){bv.preventDefault()}}bv.type=bG;if(!bJ&&!bv.isDefaultPrevented()){if((!bF._default||bF._default.apply(bA.ownerDocument,bD)===false)&&!(bG==="click"&&b.nodeName(bA,"a"))&&b.acceptData(bA)){if(by&&bA[bG]&&((bG!=="focus"&&bG!=="blur")||bv.target.offsetWidth!==0)&&!b.isWindow(bA)){bz=bA[by];if(bz){bA[by]=null}b.event.triggered=bG;bA[bG]();b.event.triggered=L;if(bz){bA[by]=bz}}}}return bv.result},dispatch:function(e){e=b.event.fix(e||bb.event);var bz=((b._data(this,"events")||{})[e.type]||[]),bA=bz.delegateCount,bG=[].slice.call(arguments,0),by=!e.exclusive&&!e.namespace,bH=[],bC,bB,bK,bx,bF,bE,bv,bD,bI,bw,bJ;bG[0]=e;e.delegateTarget=this;if(bA&&!e.target.disabled&&!(e.button&&e.type==="click")){bx=b(this);bx.context=this.ownerDocument||this;for(bK=e.target;bK!=this;bK=bK.parentNode||this){bE={};bD=[];bx[0]=bK;for(bC=0;bC<bA;bC++){bI=bz[bC];bw=bI.selector;if(bE[bw]===L){bE[bw]=(bI.quick?j(bK,bI.quick):bx.is(bw))}if(bE[bw]){bD.push(bI)}}if(bD.length){bH.push({elem:bK,matches:bD})}}}if(bz.length>bA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC<bH.length&&!e.isPropagationStopped();bC++){bv=bH[bC];e.currentTarget=bv.elem;for(bB=0;bB<bv.matches.length&&!e.isImmediatePropagationStopped();bB++){bI=bv.matches[bB];if(by||(!e.namespace&&!bI.namespace)||e.namespace_re&&e.namespace_re.test(bI.namespace)){e.data=bI.data;e.handleObj=bI;bF=((b.event.special[bI.origType]||{}).handle||bI.handler).apply(bv.elem,bG);if(bF!==L){e.result=bF;if(bF===false){e.preventDefault();e.stopPropagation()}}}}}return e.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(bv,e){if(bv.which==null){bv.which=e.charCode!=null?e.charCode:e.keyCode}return bv}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(bx,bw){var by,bz,e,bv=bw.button,bA=bw.fromElement;if(bx.pageX==null&&bw.clientX!=null){by=bx.target.ownerDocument||av;bz=by.documentElement;e=by.body;bx.pageX=bw.clientX+(bz&&bz.scrollLeft||e&&e.scrollLeft||0)-(bz&&bz.clientLeft||e&&e.clientLeft||0);bx.pageY=bw.clientY+(bz&&bz.scrollTop||e&&e.scrollTop||0)-(bz&&bz.clientTop||e&&e.clientTop||0)}if(!bx.relatedTarget&&bA){bx.relatedTarget=bA===bx.target?bw.toElement:bA}if(!bx.which&&bv!==L){bx.which=(bv&1?1:(bv&2?3:(bv&4?2:0)))}return bx}},fix:function(bw){if(bw[b.expando]){return bw}var bv,bz,e=bw,bx=b.event.fixHooks[bw.type]||{},by=bx.props?this.props.concat(bx.props):this.props;bw=b.Event(e);for(bv=by.length;bv;){bz=by[--bv];bw[bz]=e[bz]}if(!bw.target){bw.target=e.srcElement||av}if(bw.target.nodeType===3){bw.target=bw.target.parentNode}if(bw.metaKey===L){bw.metaKey=bw.ctrlKey}return bx.filter?bx.filter(bw,e):bw},special:{ready:{setup:b.bindReady},load:{noBubble:true},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(bw,bv,e){if(b.isWindow(this)){this.onbeforeunload=e}},teardown:function(bv,e){if(this.onbeforeunload===e){this.onbeforeunload=null}}}},simulate:function(bw,by,bx,bv){var bz=b.extend(new b.Event(),bx,{type:bw,isSimulated:true,originalEvent:{}});if(bv){b.event.trigger(bz,null,by)}else{b.event.dispatch.call(by,bz)}if(bz.isDefaultPrevented()){bx.preventDefault()}}};b.event.handle=b.event.dispatch;b.removeEvent=av.removeEventListener?function(bv,e,bw){if(bv.removeEventListener){bv.removeEventListener(e,bw,false)}}:function(bv,e,bw){if(bv.detachEvent){bv.detachEvent("on"+e,bw)}};b.Event=function(bv,e){if(!(this instanceof b.Event)){return new b.Event(bv,e)}if(bv&&bv.type){this.originalEvent=bv;this.type=bv.type;this.isDefaultPrevented=(bv.defaultPrevented||bv.returnValue===false||bv.getPreventDefault&&bv.getPreventDefault())?i:bk}else{this.type=bv}if(e){b.extend(this,e)}this.timeStamp=bv&&bv.timeStamp||b.now();this[b.expando]=true};function bk(){return false}function i(){return true}b.Event.prototype={preventDefault:function(){this.isDefaultPrevented=i;var bv=this.originalEvent;if(!bv){return}if(bv.preventDefault){bv.preventDefault()}else{bv.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=i;var bv=this.originalEvent;if(!bv){return}if(bv.stopPropagation){bv.stopPropagation()}bv.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=i;this.stopPropagation()},isDefaultPrevented:bk,isPropagationStopped:bk,isImmediatePropagationStopped:bk};b.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(bv,e){b.event.special[bv]={delegateType:e,bindType:e,handle:function(bz){var bB=this,bA=bz.relatedTarget,by=bz.handleObj,bw=by.selector,bx;if(!bA||(bA!==bB&&!b.contains(bB,bA))){bz.type=by.origType;bx=by.handler.apply(this,arguments);bz.type=e}return bx}}});if(!b.support.submitBubbles){b.event.special.submit={setup:function(){if(b.nodeName(this,"form")){return false}b.event.add(this,"click._submit keypress._submit",function(bx){var bw=bx.target,bv=b.nodeName(bw,"input")||b.nodeName(bw,"button")?bw.form:L;if(bv&&!bv._submit_attached){b.event.add(bv,"submit._submit",function(e){if(this.parentNode&&!e.isTrigger){b.event.simulate("submit",this.parentNode,e,true)}});bv._submit_attached=true}})},teardown:function(){if(b.nodeName(this,"form")){return false}b.event.remove(this,"._submit")}}}if(!b.support.changeBubbles){b.event.special.change={setup:function(){if(bd.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio"){b.event.add(this,"propertychange._change",function(e){if(e.originalEvent.propertyName==="checked"){this._just_changed=true}});b.event.add(this,"click._change",function(e){if(this._just_changed&&!e.isTrigger){this._just_changed=false;b.event.simulate("change",this,e,true)}})}return false}b.event.add(this,"beforeactivate._change",function(bw){var bv=bw.target;if(bd.test(bv.nodeName)&&!bv._change_attached){b.event.add(bv,"change._change",function(e){if(this.parentNode&&!e.isSimulated&&!e.isTrigger){b.event.simulate("change",this.parentNode,e,true)}});bv._change_attached=true}})},handle:function(bv){var e=bv.target;if(this!==e||bv.isSimulated||bv.isTrigger||(e.type!=="radio"&&e.type!=="checkbox")){return bv.handleObj.handler.apply(this,arguments)}},teardown:function(){b.event.remove(this,"._change");return bd.test(this.nodeName)}}}if(!b.support.focusinBubbles){b.each({focus:"focusin",blur:"focusout"},function(bx,e){var bv=0,bw=function(by){b.event.simulate(e,by.target,b.event.fix(by),true)};b.event.special[e]={setup:function(){if(bv++===0){av.addEventListener(bx,bw,true)}},teardown:function(){if(--bv===0){av.removeEventListener(bx,bw,true)}}}})}b.fn.extend({on:function(bw,e,bz,by,bv){var bA,bx;if(typeof bw==="object"){if(typeof e!=="string"){bz=e;e=L}for(bx in bw){this.on(bx,e,bz,bw[bx],bv)}return this}if(bz==null&&by==null){by=e;bz=e=L}else{if(by==null){if(typeof e==="string"){by=bz;bz=L}else{by=bz;bz=e;e=L}}}if(by===false){by=bk}else{if(!by){return this}}if(bv===1){bA=by;by=function(bB){b().off(bB);return bA.apply(this,arguments)};by.guid=bA.guid||(bA.guid=b.guid++)}return this.each(function(){b.event.add(this,bw,by,bz,e)})},one:function(bv,e,bx,bw){return this.on.call(this,bv,e,bx,bw,1)},off:function(bw,e,by){if(bw&&bw.preventDefault&&bw.handleObj){var bv=bw.handleObj;b(bw.delegateTarget).off(bv.namespace?bv.type+"."+bv.namespace:bv.type,bv.selector,bv.handler);return this}if(typeof bw==="object"){for(var bx in bw){this.off(bx,e,bw[bx])}return this}if(e===false||typeof e==="function"){by=e;e=L}if(by===false){by=bk}return this.each(function(){b.event.remove(this,bw,by,e)})},bind:function(e,bw,bv){return this.on(e,null,bw,bv)},unbind:function(e,bv){return this.off(e,null,bv)},live:function(e,bw,bv){b(this.context).on(e,this.selector,bw,bv);return this},die:function(e,bv){b(this.context).off(e,this.selector||"**",bv);return this},delegate:function(e,bv,bx,bw){return this.on(bv,e,bx,bw)},undelegate:function(e,bv,bw){return arguments.length==1?this.off(e,"**"):this.off(bv,e,bw)},trigger:function(e,bv){return this.each(function(){b.event.trigger(e,bv,this)})},triggerHandler:function(e,bv){if(this[0]){return b.event.trigger(e,bv,this[0],true)}},toggle:function(bx){var bv=arguments,e=bx.guid||b.guid++,bw=0,by=function(bz){var bA=(b._data(this,"lastToggle"+bx.guid)||0)%bw;b._data(this,"lastToggle"+bx.guid,bA+1);bz.preventDefault();return bv[bA].apply(this,arguments)||false};by.guid=e;while(bw<bv.length){bv[bw++].guid=e}return this.click(by)},hover:function(e,bv){return this.mouseenter(e).mouseleave(bv||e)}});b.each(("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu").split(" "),function(bv,e){b.fn[e]=function(bx,bw){if(bw==null){bw=bx;bx=null}return arguments.length>0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}});
+/*!
+ * Sizzle CSS Selector Engine
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e<bR.length;e++){if(bR[e]===bR[e-1]){bR.splice(e--,1)}}}}return bR};by.matches=function(e,bR){return by(e,null,null,bR)};by.matchesSelector=function(e,bR){return by(bR,null,null,[e]).length>0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS<bU;bS++){bV=bE.order[bS];if((bT=bE.leftMatch[bV].exec(bX))){bR=bT[1];bT.splice(1,1);if(bR.substr(bR.length-1)!=="\\"){bT[1]=(bT[1]||"").replace(bK,"");bW=bE.find[bV](bT,e,bY);if(bW!=null){bX=bX.replace(bE.match[bV],"");break}}}}if(!bW){bW=typeof e.getElementsByTagName!=="undefined"?e.getElementsByTagName("*"):[]}return{set:bW,expr:bX}};by.filter=function(b1,b0,b4,bU){var bW,e,bZ,b6,b3,bR,bT,bV,b2,bS=b1,b5=[],bY=b0,bX=b0&&b0[0]&&by.isXML(b0[0]);while(b1&&b0.length){for(bZ in bE.filter){if((bW=bE.leftMatch[bZ].exec(b1))!=null&&bW[2]){bR=bE.filter[bZ];bT=bW[1];e=false;bW.splice(1,1);if(bT.substr(bT.length-1)==="\\"){continue}if(bY===b5){b5=[]}if(bE.preFilter[bZ]){bW=bE.preFilter[bZ](bW,bY,b4,b5,bU,bX);if(!bW){e=b6=true}else{if(bW===true){continue}}}if(bW){for(bV=0;(b3=bY[bV])!=null;bV++){if(b3){b6=bR(b3,bW,bV,bY);b2=bU^b6;if(b4&&b6!=null){if(b2){e=true}else{bY[bV]=false}}else{if(b2){b5.push(b3);e=true}}}}}if(b6!==L){if(!b4){bY=b5}b1=b1.replace(bE.match[bZ],"");if(!e){return[]}break}}}if(b1===bS){if(e==null){by.error(b1)}else{break}}bS=b1}return bY};by.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)};var bw=by.getText=function(bU){var bS,bT,e=bU.nodeType,bR="";if(e){if(e===1||e===9){if(typeof bU.textContent==="string"){return bU.textContent}else{if(typeof bU.innerText==="string"){return bU.innerText.replace(bO,"")}else{for(bU=bU.firstChild;bU;bU=bU.nextSibling){bR+=bw(bU)}}}}else{if(e===3||e===4){return bU.nodeValue}}}else{for(bS=0;(bT=bU[bS]);bS++){if(bT.nodeType!==8){bR+=bw(bT)}}}return bR};var bE=by.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(e){return e.getAttribute("href")},type:function(e){return e.getAttribute("type")}},relative:{"+":function(bW,bR){var bT=typeof bR==="string",bV=bT&&!bQ.test(bR),bX=bT&&!bV;if(bV){bR=bR.toLowerCase()}for(var bS=0,e=bW.length,bU;bS<e;bS++){if((bU=bW[bS])){while((bU=bU.previousSibling)&&bU.nodeType!==1){}bW[bS]=bX||bU&&bU.nodeName.toLowerCase()===bR?bU||false:bU===bR}}if(bX){by.filter(bR,bW,true)}},">":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS<e;bS++){bV=bW[bS];if(bV){var bT=bV.parentNode;bW[bS]=bT.nodeName.toLowerCase()===bR?bT:false}}}else{for(;bS<e;bS++){bV=bW[bS];if(bV){bW[bS]=bU?bV.parentNode:bV.parentNode===bR}}if(bU){by.filter(bR,bW,true)}}},"":function(bT,bR,bV){var bU,bS=bI++,e=bN;if(typeof bR==="string"&&!bQ.test(bR)){bR=bR.toLowerCase();bU=bR;e=bv}e("parentNode",bR,bS,bT,bU,bV)},"~":function(bT,bR,bV){var bU,bS=bI++,e=bN;if(typeof bR==="string"&&!bQ.test(bR)){bR=bR.toLowerCase();bU=bR;e=bv}e("previousSibling",bR,bS,bT,bU,bV)}},find:{ID:function(bR,bS,bT){if(typeof bS.getElementById!=="undefined"&&!bT){var e=bS.getElementById(bR[1]);return e&&e.parentNode?[e]:[]}},NAME:function(bS,bV){if(typeof bV.getElementsByName!=="undefined"){var bR=[],bU=bV.getElementsByName(bS[1]);for(var bT=0,e=bU.length;bT<e;bT++){if(bU[bT].getAttribute("name")===bS[1]){bR.push(bU[bT])}}return bR.length===0?null:bR}},TAG:function(e,bR){if(typeof bR.getElementsByTagName!=="undefined"){return bR.getElementsByTagName(e[1])}}},preFilter:{CLASS:function(bT,bR,bS,e,bW,bX){bT=" "+bT[1].replace(bK,"")+" ";if(bX){return bT}for(var bU=0,bV;(bV=bR[bU])!=null;bU++){if(bV){if(bW^(bV.className&&(" "+bV.className+" ").replace(/[\t\n\r]/g," ").indexOf(bT)>=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1},lt:function(bS,bR,e){return bR<e[3]-0},gt:function(bS,bR,e){return bR>e[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV<bU;bV++){if(bT[bV]===bS){return false}}return true}else{by.error(e)}}}},CHILD:function(bS,bU){var bT,b0,bW,bZ,e,bV,bY,bX=bU[1],bR=bS;switch(bX){case"only":case"first":while((bR=bR.previousSibling)){if(bR.nodeType===1){return false}}if(bX==="first"){return true}bR=bS;case"last":while((bR=bR.nextSibling)){if(bR.nodeType===1){return false}}return true;case"nth":bT=bU[2];b0=bU[3];if(bT===1&&b0===0){return true}bW=bU[0];bZ=bS.parentNode;if(bZ&&(bZ[bC]!==bW||!bS.nodeIndex)){bV=0;for(bR=bZ.firstChild;bR;bR=bR.nextSibling){if(bR.nodeType===1){bR.nodeIndex=++bV}}bZ[bC]=bW}bY=bS.nodeIndex-b0;if(bT===0){return bY===0}else{return(bY%bT===0&&bY/bT>=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS<e;bS++){bR.push(bU[bS])}}else{for(;bU[bS];bS++){bR.push(bU[bS])}}}return bR}}var bJ,bG;if(av.documentElement.compareDocumentPosition){bJ=function(bR,e){if(bR===e){bB=true;return 0}if(!bR.compareDocumentPosition||!e.compareDocumentPosition){return bR.compareDocumentPosition?-1:1}return bR.compareDocumentPosition(e)&4?-1:1}}else{bJ=function(bY,bX){if(bY===bX){bB=true;return 0}else{if(bY.sourceIndex&&bX.sourceIndex){return bY.sourceIndex-bX.sourceIndex}}var bV,bR,bS=[],e=[],bU=bY.parentNode,bW=bX.parentNode,bZ=bU;if(bU===bW){return bG(bY,bX)}else{if(!bU){return -1}else{if(!bW){return 1}}}while(bZ){bS.unshift(bZ);bZ=bZ.parentNode}bZ=bW;while(bZ){e.unshift(bZ);bZ=bZ.parentNode}bV=bS.length;bR=e.length;for(var bT=0;bT<bV&&bT<bR;bT++){if(bS[bT]!==e[bT]){return bG(bS[bT],e[bT])}}return bT===bV?bG(bY,e[bT],-1):bG(bS[bT],bX,1)};bG=function(bR,e,bS){if(bR===e){return bS}var bT=bR.nextSibling;while(bT){if(bT===e){return -1}bT=bT.nextSibling}return 1}}(function(){var bR=av.createElement("div"),bS="script"+(new Date()).getTime(),e=av.documentElement;bR.innerHTML="<a name='"+bS+"'/>";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="<a href='#'></a>";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="<p class='TEST'></p>";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="<div class='test e'></div><div class='test'></div>";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT<bS;bT++){var e=bZ[bT];if(e){var bU=false;e=e[bR];while(e){if(e[bC]===bV){bU=bZ[e.sizset];break}if(e.nodeType===1&&!bY){e[bC]=bV;e.sizset=bT}if(e.nodeName.toLowerCase()===bW){bU=e;break}e=e[bR]}bZ[bT]=bU}}}function bN(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT<bS;bT++){var e=bZ[bT];if(e){var bU=false;e=e[bR];while(e){if(e[bC]===bV){bU=bZ[e.sizset];break}if(e.nodeType===1){if(!bY){e[bC]=bV;e.sizset=bT}if(typeof bW!=="string"){if(e===bW){bU=true;break}}else{if(by.filter(bW,[e]).length>0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT<bR;bT++){by(bS,bY[bT],bX,bW)}return by.filter(bU,bX)};by.attr=b.attr;by.selectors.attrMap={};b.find=by;b.expr=by.selectors;b.expr[":"]=b.expr.filters;b.unique=by.uniqueSort;b.text=by.getText;b.isXMLDoc=by.isXML;b.contains=by.contains})();var ab=/Until$/,aq=/^(?:parents|prevUntil|prevAll)/,a9=/,/,bp=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,H=b.expr.match.POS,ay={children:true,contents:true,next:true,prev:true};b.fn.extend({find:function(e){var bw=this,by,bv;if(typeof e!=="string"){return b(e).filter(function(){for(by=0,bv=bw.length;by<bv;by++){if(b.contains(bw[by],this)){return true}}})}var bx=this.pushStack("","find",e),bA,bB,bz;for(by=0,bv=this.length;by<bv;by++){bA=bx.length;b.find(e,this[by],bx);if(by>0){for(bB=bA;bB<bx.length;bB++){for(bz=0;bz<bA;bz++){if(bx[bz]===bx[bB]){bx.splice(bB--,1);break}}}}}return bx},has:function(bv){var e=b(bv);return this.filter(function(){for(var bx=0,bw=e.length;bx<bw;bx++){if(b.contains(this,e[bx])){return true}}})},not:function(e){return this.pushStack(aG(this,e,false),"not",e)},filter:function(e){return this.pushStack(aG(this,e,true),"filter",e)},is:function(e){return !!e&&(typeof e==="string"?H.test(e)?b(e,this.context).index(this[0])>=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw<by.length;bw++){if(b(bz).is(by[bw])){bv.push({selector:by[bw],elem:bz,level:bB})}}bz=bz.parentNode;bB++}return bv}var bA=H.test(by)||typeof by!=="string"?b(by,bx||this.context):0;for(bw=0,e=this.length;bw<e;bw++){bz=this[bw];while(bz){if(bA?bA.index(bz)>-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/<tbody/i,W=/<|&#?\w+;/,ae=/<(?:script|style)/i,O=/<(?:script|object|embed|option|style)/i,ah=new RegExp("<(?:"+aR+")","i"),o=/checked\s*(?:[^=]|=\s*.checked.)/i,bm=/\/(java|ecma)script/i,aN=/^\s*<!(?:\[CDATA\[|\-\-)/,ax={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},ac=a(av);ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div<div>","</div>"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1></$2>");try{for(var bw=0,bv=this.length;bw<bv;bw++){if(this[bw].nodeType===1){b.cleanData(this[bw].getElementsByTagName("*"));this[bw].innerHTML=bx}}}catch(by){this.empty().append(bx)}}else{if(b.isFunction(bx)){this.each(function(bz){var e=b(this);e.html(bx.call(this,bz,e.html()))})}else{this.empty().append(bx)}}}return this},replaceWith:function(e){if(this[0]&&this[0].parentNode){if(b.isFunction(e)){return this.each(function(bx){var bw=b(this),bv=bw.html();bw.replaceWith(e.call(this,bx,bv))})}if(typeof e!=="string"){e=b(e).detach()}return this.each(function(){var bw=this.nextSibling,bv=this.parentNode;b(this).remove();if(bw){b(bw).before(e)}else{b(bv).append(e)}})}else{return this.length?this.pushStack(b(b.isFunction(e)?e():e),"replaceWith",e):this}},detach:function(e){return this.remove(e,true)},domManip:function(bB,bF,bE){var bx,by,bA,bD,bC=bB[0],bv=[];if(!b.support.checkClone&&arguments.length===3&&typeof bC==="string"&&o.test(bC)){return this.each(function(){b(this).domManip(bB,bF,bE,true)})}if(b.isFunction(bC)){return this.each(function(bH){var bG=b(this);bB[0]=bC.call(this,bH,bF?bG.html():L);bG.domManip(bB,bF,bE)})}if(this[0]){bD=bC&&bC.parentNode;if(b.support.parentNode&&bD&&bD.nodeType===11&&bD.childNodes.length===this.length){bx={fragment:bD}}else{bx=b.buildFragment(bB,this,bv)}bA=bx.fragment;if(bA.childNodes.length===1){by=bA=bA.firstChild}else{by=bA.firstChild}if(by){bF=bF&&b.nodeName(by,"tr");for(var bw=0,e=this.length,bz=e-1;bw<e;bw++){bE.call(bF?ba(this[bw],by):this[bw],bx.cacheable||(e>1&&bw<bz)?b.clone(bA,true,true):bA)}}if(bv.length){b.each(bv,bo)}}return this}});function ba(e,bv){return b.nodeName(e,"table")?(e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody"))):e}function t(bB,bv){if(bv.nodeType!==1||!b.hasData(bB)){return}var by,bx,e,bA=b._data(bB),bz=b._data(bv,bA),bw=bA.events;if(bw){delete bz.handle;bz.events={};for(by in bw){for(bx=0,e=bw[by].length;bx<e;bx++){b.event.add(bv,by+(bw[by][bx].namespace?".":"")+bw[by][bx].namespace,bw[by][bx],bw[by][bx].data)}}}if(bz.data){bz.data=b.extend({},bz.data)}}function ai(bv,e){var bw;if(e.nodeType!==1){return}if(e.clearAttributes){e.clearAttributes()}if(e.mergeAttributes){e.mergeAttributes(bv)}bw=e.nodeName.toLowerCase();if(bw==="object"){e.outerHTML=bv.outerHTML}else{if(bw==="input"&&(bv.type==="checkbox"||bv.type==="radio")){if(bv.checked){e.defaultChecked=e.checked=bv.checked}if(e.value!==bv.value){e.value=bv.value}}else{if(bw==="option"){e.selected=bv.defaultSelected}else{if(bw==="input"||bw==="textarea"){e.defaultValue=bv.defaultValue}}}}e.removeAttribute(b.expando)}b.buildFragment=function(bz,bx,bv){var by,e,bw,bA,bB=bz[0];if(bx&&bx[0]){bA=bx[0].ownerDocument||bx[0]}if(!bA.createDocumentFragment){bA=av}if(bz.length===1&&typeof bB==="string"&&bB.length<512&&bA===av&&bB.charAt(0)==="<"&&!O.test(bB)&&(b.support.checkClone||!o.test(bB))&&(b.support.html5Clone||!ah.test(bB))){e=true;bw=b.fragments[bB];if(bw&&bw!==1){by=bw}}if(!by){by=bA.createDocumentFragment();b.clean(bz,bA,by,bv)}if(e){b.fragments[bB]=bw?by:1}return{fragment:by,cacheable:e}};b.fragments={};b.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,bv){b.fn[e]=function(bw){var bz=[],bC=b(bw),bB=this.length===1&&this[0].parentNode;if(bB&&bB.nodeType===11&&bB.childNodes.length===1&&bC.length===1){bC[bv](this[0]);return this}else{for(var bA=0,bx=bC.length;bA<bx;bA++){var by=(bA>0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1></$2>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]==="<table>"&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB<bG;bB++){E(bz[bB])}}else{E(bz)}}if(bz.nodeType){bI.push(bz)}else{bI=b.merge(bI,bz)}}if(bH){bF=function(bL){return !bL.type||bm.test(bL.type)};for(bE=0;bI[bE];bE++){if(bA&&b.nodeName(bI[bE],"script")&&(!bI[bE].type||bI[bE].type.toLowerCase()==="text/javascript")){bA.push(bI[bE].parentNode?bI[bE].parentNode.removeChild(bI[bE]):bI[bE])}else{if(bI[bE].nodeType===1){var bJ=b.grep(bI[bE].getElementsByTagName("script"),bF);bI.splice.apply(bI,[bE+1,0].concat(bJ))}bH.appendChild(bI[bE])}}}return bI},cleanData:function(bv){var by,bw,e=b.cache,bB=b.event.special,bA=b.support.deleteExpando;for(var bz=0,bx;(bx=bv[bz])!=null;bz++){if(bx.nodeName&&b.noData[bx.nodeName.toLowerCase()]){continue}bw=bx[b.expando];if(bw){by=e[bw];if(by&&by.events){for(var bC in by.events){if(bB[bC]){b.event.remove(bx,bC)}else{b.removeEvent(bx,bC,by.handle)}}if(by.handle){by.handle.elem=null}}if(bA){delete bx[b.expando]}else{if(bx.removeAttribute){bx.removeAttribute(b.expando)}}delete e[bw]}}}});function bo(e,bv){if(bv.src){b.ajax({url:bv.src,async:false,dataType:"script"})}else{b.globalEval((bv.text||bv.textContent||bv.innerHTML||"").replace(aN,"/*$0*/"))}if(bv.parentNode){bv.parentNode.removeChild(bv)}}var ak=/alpha\([^)]*\)/i,au=/opacity=([^)]*)/,z=/([A-Z]|^ms)/g,bc=/^-?\d+(?:px)?$/i,bn=/^-?\d/,I=/^([\-+])=([\-+.\de]+)/,a7={position:"absolute",visibility:"hidden",display:"block"},an=["Left","Right"],a1=["Top","Bottom"],Z,aI,aX;b.fn.css=function(e,bv){if(arguments.length===2&&bv===L){return this}return b.access(this,e,bv,true,function(bx,bw,by){return by!==L?b.style(bx,bw,by):b.css(bx,bw)})};b.extend({cssHooks:{opacity:{get:function(bw,bv){if(bv){var e=Z(bw,"opacity","opacity");return e===""?"1":e}else{return bw.style.opacity}}}},cssNumber:{fillOpacity:true,fontWeight:true,lineHeight:true,opacity:true,orphans:true,widows:true,zIndex:true,zoom:true},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(bx,bw,bD,by){if(!bx||bx.nodeType===3||bx.nodeType===8||!bx.style){return}var bB,bC,bz=b.camelCase(bw),bv=bx.style,bE=b.cssHooks[bz];bw=b.cssProps[bz]||bz;if(bD!==L){bC=typeof bD;if(bC==="string"&&(bB=I.exec(bD))){bD=(+(bB[1]+1)*+bB[2])+parseFloat(b.css(bx,bw));bC="number"}if(bD==null||bC==="number"&&isNaN(bD)){return}if(bC==="number"&&!b.cssNumber[bz]){bD+="px"}if(!bE||!("set" in bE)||(bD=bE.set(bx,bD))!==L){try{bv[bw]=bD}catch(bA){}}}else{if(bE&&"get" in bE&&(bB=bE.get(bx,false,by))!==L){return bB}return bv[bw]}},css:function(by,bx,bv){var bw,e;bx=b.camelCase(bx);e=b.cssHooks[bx];bx=b.cssProps[bx]||bx;if(bx==="cssFloat"){bx="float"}if(e&&"get" in e&&(bw=e.get(by,true,bv))!==L){return bw}else{if(Z){return Z(by,bx)}}},swap:function(bx,bw,by){var e={};for(var bv in bw){e[bv]=bx.style[bv];bx.style[bv]=bw[bv]}by.call(bx);for(bv in bw){bx.style[bv]=e[bv]}}});b.curCSS=b.css;b.each(["height","width"],function(bv,e){b.cssHooks[e]={get:function(by,bx,bw){var bz;if(bx){if(by.offsetWidth!==0){return p(by,e,bw)}else{b.swap(by,a7,function(){bz=p(by,e,bw)})}return bz}},set:function(bw,bx){if(bc.test(bx)){bx=parseFloat(bx);if(bx>=0){return bx+"px"}}else{return bx}}}});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":""},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(ak,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return}}bx.filter=ak.test(bw)?bw.replace(ak,e):bw+" "+e}}}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw,bv){var e;b.swap(bw,{display:"inline-block"},function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}});if(av.defaultView&&av.defaultView.getComputedStyle){aI=function(by,bw){var bv,bx,e;bw=bw.replace(z,"-$1").toLowerCase();if((bx=by.ownerDocument.defaultView)&&(e=bx.getComputedStyle(by,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(by.ownerDocument.documentElement,by)){bv=b.style(by,bw)}}return bv}}if(av.documentElement.currentStyle){aX=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv===null&&bx&&(by=bx[bw])){bv=by}if(!bc.test(bv)&&bn.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left}bx.left=bw==="fontSize"?"1em":(bv||0);bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e}}return bv===""?"auto":bv}}Z=aI||aX;function p(by,bw,bv){var bA=bw==="width"?by.offsetWidth:by.offsetHeight,bz=bw==="width"?an:a1,bx=0,e=bz.length;if(bA>0){if(bv!=="border"){for(;bx<e;bx++){if(!bv){bA-=parseFloat(b.css(by,"padding"+bz[bx]))||0}if(bv==="margin"){bA+=parseFloat(b.css(by,bv+bz[bx]))||0}else{bA-=parseFloat(b.css(by,"border"+bz[bx]+"Width"))||0}}}return bA+"px"}bA=Z(by,bw,bw);if(bA<0||bA==null){bA=by.style[bw]||0}bA=parseFloat(bA)||0;if(bv){for(;bx<e;bx++){bA+=parseFloat(b.css(by,"padding"+bz[bx]))||0;if(bv!=="padding"){bA+=parseFloat(b.css(by,"border"+bz[bx]+"Width"))||0}if(bv==="margin"){bA+=parseFloat(b.css(by,bv+bz[bx]))||0}}}return bA+"px"}if(b.expr&&b.expr.filters){b.expr.filters.hidden=function(bw){var bv=bw.offsetWidth,e=bw.offsetHeight;return(bv===0&&e===0)||(!b.support.reliableHiddenOffsets&&((bw.style&&bw.style.display)||b.css(bw,"display"))==="none")};b.expr.filters.visible=function(e){return !b.expr.filters.hidden(e)}}var k=/%20/g,ap=/\[\]$/,bs=/\r?\n/g,bq=/#.*$/,aD=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,aZ=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,aM=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,aQ=/^(?:GET|HEAD)$/,c=/^\/\//,M=/\?/,a6=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,q=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,A=b.fn.load,aa={},r={},aE,s,aV=["*/"]+["*"];try{aE=bl.href}catch(aw){aE=av.createElement("a");aE.href="";aE=aE.href}s=K.exec(aE.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*"}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw<bz;bw++){bv=bx[bw];bC=/^\+/.test(bv);if(bC){bv=bv.substr(1)||"*"}bB=e[bv]=e[bv]||[];bB[bC?"unshift":"push"](bA)}}}}function aW(bv,bE,bz,bD,bB,bx){bB=bB||bE.dataTypes[0];bx=bx||{};bx[bB]=true;var bA=bv[bB],bw=0,e=bA?bA.length:0,by=(bv===aa),bC;for(;bw<e&&(by||!bC);bw++){bC=bA[bw](bE,bz,bD);if(typeof bC==="string"){if(!by||bx[bC]){bC=L}else{bE.dataTypes.unshift(bC);bC=aW(bv,bE,bz,bD,bC,bx)}}}if((by||!bC)&&!bx["*"]){bC=aW(bv,bE,bz,bD,"*",bx)}return bC}function am(bw,bx){var bv,e,by=b.ajaxSettings.flatOptions||{};for(bv in bx){if(bx[bv]!==L){(by[bv]?bw:(e||(e={})))[bv]=bx[bv]}}if(e){b.extend(true,bw,e)}}b.fn.extend({load:function(bw,bz,bA){if(typeof bw!=="string"&&A){return A.apply(this,arguments)}else{if(!this.length){return this}}var by=bw.indexOf(" ");if(by>=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by)}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST"}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE});bv.html(e?b("<div>").append(bD.replace(a6,"")).find(e):bD)}if(bA){bv.each(bA,[bD,bB,bC])}}});return this},serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||q.test(this.nodeName)||aZ.test(this.type))}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")}}):{name:bv.name,value:bw.replace(bs,"\r\n")}}).get()}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw)}});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx})}});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script")},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json")},ajaxSetup:function(bv,e){if(e){am(bv,b.ajaxSettings)}else{e=bv;bv=b.ajaxSettings}am(bv,e);return bv},ajaxSettings:{url:aE,isLocal:aM.test(s[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aV},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bb.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(r),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU}return this},getAllResponseHeaders:function(){return bA===2?bQ:null},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2]}}e=by[bT.toLowerCase()]}return e===L?null:e},overrideMimeType:function(e){if(!bA){bD.mimeType=e}return this},abort:function(e){e=e||"abort";if(bL){bL.abort(e)}bF(0,e);return this}};function bF(bZ,bU,b0,bW){if(bA===2){return}bA=2;if(bE){clearTimeout(bE)}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bj(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2}}if(bZ===304){bX="notmodified";bT=true}else{try{b4=G(bD,bY);bX="success";bT=true}catch(b1){bX="parsererror";b3=b1}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ])}else{bR.rejectWith(bS,[bJ,bX,b3])}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3])}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop")}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]]}}else{e=bT[bJ.status];bJ.then(e,e)}}return this};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,s[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=s[1]||bI[2]!=s[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(s[3]||(s[1]==="http:"?80:443))))}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional)}aW(aa,bD,bx,bJ);if(bA===2){return false}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aQ.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart")}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"")}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType)}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC])}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC])}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aV+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK])}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK])}bL=aW(r,bD,bx,bJ);if(!bL){bF(-1,"No Transport")}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD])}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout")},bD.timeout)}try{bA=1;bL.send(bH,bF)}catch(bM){if(bA<2){bF(-1,bM)}else{throw bM}}}return bJ},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA)};if(bw===L){bw=b.ajaxSettings.traditional}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value)})}else{for(var bx in e){v(bx,e[bx],bw,by)}}return bv.join("&").replace(k,"+")}});function v(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz)}else{v(bw+"["+(typeof bz==="object"||b.isArray(bz)?bA:"")+"]",bz,bv,bx)}})}else{if(!bv&&by!=null&&typeof by==="object"){for(var e in by){v(bw+"["+e+"]",by[e],bv,bx)}}else{bx(bw,by)}}}b.extend({active:0,lastModified:{},etag:{}});function bj(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA]}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type")}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break}}}if(bB[0] in bz){bx=bB[0]}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break}if(!e){e=bA}}bx=bx||e}if(bx){if(bx!==bB[0]){bB.unshift(bx)}return bz[bx]}}function G(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType)}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA<bw;bA++){if(bA===1){for(bE in bH.converters){if(typeof bE==="string"){bG[bE.toLowerCase()]=bH.converters[bE]}}}bx=bC;bC=bD[bA];if(bC==="*"){bC=bx}else{if(bx!=="*"&&bx!==bC){by=bx+" "+bC;bF=bG[by]||bG["* "+bC];if(!bF){e=L;for(bv in bG){bB=bv.split(" ");if(bB[0]===bx||bB[0]==="*"){e=bG[bB[1]+" "+bC];if(e){bv=bG[bv];if(bv===true){bF=e}else{if(e===true){bF=bv}}break}}}}if(!(bF||e)){b.error("No conversion from "+by.replace(" "," to "))}if(bF!==true){bz=bF?bF(bz):e(bv(bz))}}}}return bz}var aC=b.now(),u=/(\=)\?(&|$)|\?\?/i;b.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return b.expando+"_"+(aC++)}});b.ajaxPrefilter("json jsonp",function(bD,bA,bC){var bx=bD.contentType==="application/x-www-form-urlencoded"&&(typeof bD.data==="string");if(bD.dataTypes[0]==="jsonp"||bD.jsonp!==false&&(u.test(bD.url)||bx&&u.test(bD.data))){var bB,bw=bD.jsonpCallback=b.isFunction(bD.jsonpCallback)?bD.jsonpCallback():bD.jsonpCallback,bz=bb[bw],e=bD.url,by=bD.data,bv="$1"+bw+"$2";if(bD.jsonp!==false){e=e.replace(u,bv);if(bD.url===e){if(bx){by=by.replace(u,bv)}if(bD.data===by){e+=(/\?/.test(e)?"&":"?")+bD.jsonp+"="+bw}}}bD.url=e;bD.data=by;bb[bw]=function(bE){bB=[bE]};bC.always(function(){bb[bw]=bz;if(bB&&b.isFunction(bz)){bb[bw](bB[0])}});bD.converters["script json"]=function(){if(!bB){b.error(bw+" was not called")}return bB[0]};bD.dataTypes[0]="json";return"script"}});b.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){b.globalEval(e);return e}}});b.ajaxPrefilter("script",function(e){if(e.cache===L){e.cache=false}if(e.crossDomain){e.type="GET";e.global=false}});b.ajaxTransport("script",function(bw){if(bw.crossDomain){var e,bv=av.head||av.getElementsByTagName("head")[0]||av.documentElement;return{send:function(bx,by){e=av.createElement("script");e.async="async";if(bw.scriptCharset){e.charset=bw.scriptCharset}e.src=bw.url;e.onload=e.onreadystatechange=function(bA,bz){if(bz||!e.readyState||/loaded|complete/.test(e.readyState)){e.onload=e.onreadystatechange=null;if(bv&&e.parentNode){bv.removeChild(e)}e=L;if(!bz){by(200,"success")}}};bv.insertBefore(e,bv.firstChild)},abort:function(){if(e){e.onload(0,1)}}}}});var B=bb.ActiveXObject?function(){for(var e in N){N[e](0,1)}}:false,y=0,N;function aL(){try{return new bb.XMLHttpRequest()}catch(bv){}}function aj(){try{return new bb.ActiveXObject("Microsoft.XMLHTTP")}catch(bv){}}b.ajaxSettings.xhr=bb.ActiveXObject?function(){return !this.isLocal&&aL()||aj()}:aL;(function(e){b.extend(b.support,{ajax:!!e,cors:!!e&&("withCredentials" in e)})})(b.ajaxSettings.xhr());if(b.support.ajax){b.ajaxTransport(function(e){if(!e.crossDomain||b.support.cors){var bv;return{send:function(bB,bw){var bA=e.xhr(),bz,by;if(e.username){bA.open(e.type,e.url,e.async,e.username,e.password)}else{bA.open(e.type,e.url,e.async)}if(e.xhrFields){for(by in e.xhrFields){bA[by]=e.xhrFields[by]}}if(e.mimeType&&bA.overrideMimeType){bA.overrideMimeType(e.mimeType)}if(!e.crossDomain&&!bB["X-Requested-With"]){bB["X-Requested-With"]="XMLHttpRequest"}try{for(by in bB){bA.setRequestHeader(by,bB[by])}}catch(bx){}bA.send((e.hasContent&&e.data)||null);bv=function(bK,bE){var bF,bD,bC,bI,bH;try{if(bv&&(bE||bA.readyState===4)){bv=L;if(bz){bA.onreadystatechange=b.noop;if(B){delete N[bz]}}if(bE){if(bA.readyState!==4){bA.abort()}}else{bF=bA.status;bC=bA.getAllResponseHeaders();bI={};bH=bA.responseXML;if(bH&&bH.documentElement){bI.xml=bH}bI.text=bA.responseText;try{bD=bA.statusText}catch(bJ){bD=""}if(!bF&&e.isLocal&&!e.crossDomain){bF=bI.text?200:404}else{if(bF===1223){bF=204}}}}}catch(bG){if(!bE){bw(-1,bG)}}if(bI){bw(bF,bD,bI,bC)}};if(!e.async||bA.readyState===4){bv()}else{bz=++y;if(B){if(!N){N={};b(bb).unload(B)}N[bz]=bv}bA.onreadystatechange=bv}},abort:function(){if(bv){bv(0,1)}}}}})}var Q={},a8,m,aB=/^(?:toggle|show|hide)$/,aT=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,a3,aH=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],a4;b.fn.extend({show:function(bx,bA,bz){var bw,by;if(bx||bx===0){return this.animate(a0("show",3),bx,bA,bz)}else{for(var bv=0,e=this.length;bv<e;bv++){bw=this[bv];if(bw.style){by=bw.style.display;if(!b._data(bw,"olddisplay")&&by==="none"){by=bw.style.display=""}if(by===""&&b.css(bw,"display")==="none"){b._data(bw,"olddisplay",x(bw.nodeName))}}}for(bv=0;bv<e;bv++){bw=this[bv];if(bw.style){by=bw.style.display;if(by===""||by==="none"){bw.style.display=b._data(bw,"olddisplay")||""}}}return this}},hide:function(bx,bA,bz){if(bx||bx===0){return this.animate(a0("hide",3),bx,bA,bz)}else{var bw,by,bv=0,e=this.length;for(;bv<e;bv++){bw=this[bv];if(bw.style){by=b.css(bw,"display");if(by!=="none"&&!b._data(bw,"olddisplay")){b._data(bw,"olddisplay",by)}}}for(bv=0;bv<e;bv++){if(this[bv].style){this[bv].style.display="none"}}return this}},_toggle:b.fn.toggle,toggle:function(bw,bv,bx){var e=typeof bw==="boolean";if(b.isFunction(bw)&&b.isFunction(bv)){this._toggle.apply(this,arguments)}else{if(bw==null||e){this.each(function(){var by=e?bw:b(this).is(":hidden");b(this)[by?"show":"hide"]()})}else{this.animate(a0("toggle",3),bw,bv,bx)}}return this},fadeTo:function(e,bx,bw,bv){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:bx},e,bw,bv)},animate:function(bz,bw,by,bx){var e=b.speed(bw,by,bx);if(b.isEmptyObject(bz)){return this.each(e.complete,[false])}bz=b.extend({},bz);function bv(){if(e.queue===false){b._mark(this)}var bE=b.extend({},e),bK=this.nodeType===1,bI=bK&&b(this).is(":hidden"),bB,bF,bD,bJ,bH,bC,bG,bL,bA;bE.animatedProperties={};for(bD in bz){bB=b.camelCase(bD);if(bD!==bB){bz[bB]=bz[bD];delete bz[bD]}bF=bz[bB];if(b.isArray(bF)){bE.animatedProperties[bB]=bF[1];bF=bz[bB]=bF[0]}else{bE.animatedProperties[bB]=bE.specialEasing&&bE.specialEasing[bB]||bE.easing||"swing"}if(bF==="hide"&&bI||bF==="show"&&!bI){return bE.complete.call(this)}if(bK&&(bB==="height"||bB==="width")){bE.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY];if(b.css(this,"display")==="inline"&&b.css(this,"float")==="none"){if(!b.support.inlineBlockNeedsLayout||x(this.nodeName)==="inline"){this.style.display="inline-block"}else{this.style.zoom=1}}}}if(bE.overflow!=null){this.style.overflow="hidden"}for(bD in bz){bJ=new b.fx(this,bE,bD);bF=bz[bD];if(aB.test(bF)){bA=b._data(this,"toggle"+bD)||(bF==="toggle"?bI?"show":"hide":0);if(bA){b._data(this,"toggle"+bD,bA==="show"?"hide":"show");bJ[bA]()}else{bJ[bF]()}}else{bH=aT.exec(bF);bC=bJ.cur();if(bH){bG=parseFloat(bH[2]);bL=bH[3]||(b.cssNumber[bD]?"":"px");if(bL!=="px"){b.style(this,bD,(bG||1)+bL);bC=((bG||1)/bJ.cur())*bC;b.style(this,bD,bC+bL)}if(bH[1]){bG=((bH[1]==="-="?-1:1)*bG)+bC}bJ.custom(bC,bG,bL)}else{bJ.custom(bC,bF,"")}}}return true}return e.queue===false?this.each(bv):this.queue(e.queue,bv)},stop:function(bw,bv,e){if(typeof bw!=="string"){e=bv;bv=bw;bw=L}if(bv&&bw!==false){this.queue(bw||"fx",[])}return this.each(function(){var bx,by=false,bA=b.timers,bz=b._data(this);if(!e){b._unmark(true,this)}function bB(bE,bF,bD){var bC=bF[bD];b.removeData(bE,bD,true);bC.stop(e)}if(bw==null){for(bx in bz){if(bz[bx]&&bz[bx].stop&&bx.indexOf(".run")===bx.length-4){bB(this,bz,bx)}}}else{if(bz[bx=bw+".run"]&&bz[bx].stop){bB(this,bz,bx)}}for(bx=bA.length;bx--;){if(bA[bx].elem===this&&(bw==null||bA[bx].queue===bw)){if(e){bA[bx](true)}else{bA[bx].saveState()}by=true;bA.splice(bx,1)}}if(!(e&&by)){b.dequeue(this,bw)}})}});function bh(){setTimeout(at,0);return(a4=b.now())}function at(){a4=L}function a0(bv,e){var bw={};b.each(aH.concat.apply([],aH.slice(0,e)),function(){bw[this]=bv});return bw}b.each({slideDown:a0("show",1),slideUp:a0("hide",1),slideToggle:a0("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,bv){b.fn[e]=function(bw,by,bx){return this.animate(bv,bw,by,bx)}});b.extend({speed:function(bw,bx,bv){var e=bw&&typeof bw==="object"?b.extend({},bw):{complete:bv||!bv&&bx||b.isFunction(bw)&&bw,duration:bw,easing:bv&&bx||bx&&!b.isFunction(bx)&&bx};e.duration=b.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in b.fx.speeds?b.fx.speeds[e.duration]:b.fx.speeds._default;if(e.queue==null||e.queue===true){e.queue="fx"}e.old=e.complete;e.complete=function(by){if(b.isFunction(e.old)){e.old.call(this)}if(e.queue){b.dequeue(this,e.queue)}else{if(by!==false){b._unmark(this)}}};return e},easing:{linear:function(bw,bx,e,bv){return e+bv*bw},swing:function(bw,bx,e,bv){return((-Math.cos(bw*Math.PI)/2)+0.5)*bv+e}},timers:[],fx:function(bv,e,bw){this.options=e;this.elem=bv;this.prop=bw;e.orig=e.orig||{}}});b.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(b.fx.step[this.prop]||b.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var e,bv=b.css(this.elem,this.prop);return isNaN(e=parseFloat(bv))?!bv||bv==="auto"?0:bv:e},custom:function(bz,by,bx){var e=this,bw=b.fx;this.startTime=a4||bh();this.end=by;this.now=this.start=bz;this.pos=this.state=0;this.unit=bx||this.unit||(b.cssNumber[this.prop]?"":"px");function bv(bA){return e.step(bA)}bv.queue=this.options.queue;bv.elem=this.elem;bv.saveState=function(){if(e.options.hide&&b._data(e.elem,"fxshow"+e.prop)===L){b._data(e.elem,"fxshow"+e.prop,e.start)}};if(bv()&&b.timers.push(bv)&&!a3){a3=setInterval(bw.tick,bw.interval)}},show:function(){var e=b._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=e||b.style(this.elem,this.prop);this.options.show=true;if(e!==L){this.custom(this.cur(),e)}else{this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur())}b(this.elem).show()},hide:function(){this.options.orig[this.prop]=b._data(this.elem,"fxshow"+this.prop)||b.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(by){var bA,bB,bv,bx=a4||bh(),e=true,bz=this.elem,bw=this.options;if(by||bx>=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC]})}if(bw.hide){b(bz).hide()}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true)}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz)}}return false}else{if(bw.duration==Infinity){this.now=bx}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos)}this.update()}return true}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e<bv.length;e++){bw=bv[e];if(!bw()&&bv[e]===bw){bv.splice(e--,1)}}if(!bv.length){b.fx.stop()}},interval:13,stop:function(){clearInterval(a3);a3=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(e){b.style(e.elem,"opacity",e.now)},_default:function(e){if(e.elem.style&&e.elem.style[e.prop]!=null){e.elem.style[e.prop]=e.now+e.unit}else{e.elem[e.prop]=e.now}}}});b.each(["width","height"],function(e,bv){b.fx.step[bv]=function(bw){b.style(bw.elem,bv,Math.max(0,bw.now)+bw.unit)}});if(b.expr&&b.expr.filters){b.expr.filters.animated=function(e){return b.grep(b.timers,function(bv){return e===bv.elem}).length}}function x(bx){if(!Q[bx]){var e=av.body,bv=b("<"+bx+">").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!a8){a8=av.createElement("iframe");a8.frameBorder=a8.width=a8.height=0}e.appendChild(a8);if(!m||!a8.createElement){m=(a8.contentWindow||a8.contentDocument).document;m.write((av.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>");m.close()}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(a8)}Q[bx]=bw}return Q[bx]}var V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){b.fn.offset=function(bI){var by=this[0],bB;if(bI){return this.each(function(e){b.offset.setOffset(this,bI,e)})}if(!by||!by.ownerDocument){return null}if(by===by.ownerDocument.body){return b.offset.bodyOffset(by)}try{bB=by.getBoundingClientRect()}catch(bF){}var bH=by.ownerDocument,bw=bH.documentElement;if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0}}var bC=bH.body,bD=aK(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx}}}else{b.fn.offset=function(bF){var bz=this[0];if(bF){return this.each(function(bG){b.offset.setOffset(this,bF,bG)})}if(!bz||!bz.ownerDocument){return null}if(bz===bz.ownerDocument.body){return b.offset.bodyOffset(bz)}var bC,bw=bz.offsetParent,bv=bz,bE=bz.ownerDocument,bx=bE.documentElement,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}bv=bw;bw=bz.offsetParent}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}e=bC}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft)}return{top:bD,left:by}}}b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0}return{top:bw,left:bv}},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative"}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv)}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw}if(bG.left!=null){bD.left=(bG.left-bv.left)+by}if("using" in bG){bG.using.call(bx,bD)}else{bz.css(bD)}}};b.fn.extend({position:function(){if(!this[0]){return null}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent}return e})}});b.each(["Left","Top"],function(bv,e){var bw="scroll"+e;b.fn[bw]=function(bz){var bx,by;if(bz===L){bx=this[0];if(!bx){return null}by=aK(bx);return by?("pageXOffset" in by)?by[bv?"pageYOffset":"pageXOffset"]:b.support.boxModel&&by.document.documentElement[bw]||by.document.body[bw]:bx[bw]}return this.each(function(){by=aK(this);if(by){by.scrollTo(!bv?bz:b(by).scrollLeft(),bv?bz:b(by).scrollTop())}else{this[bw]=bz}})}});function aK(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}b.each(["Height","Width"],function(bv,e){var bw=e.toLowerCase();b.fn["inner"+e]=function(){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,"padding")):this[bw]():null};b.fn["outer"+e]=function(by){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,by?"margin":"border")):this[bw]():null};b.fn[bw]=function(bz){var bA=this[0];if(!bA){return bz==null?null:this}if(b.isFunction(bz)){return this.each(function(bE){var bD=b(this);bD[bw](bz.call(this,bE,bD[bw]()))})}if(b.isWindow(bA)){var bB=bA.document.documentElement["client"+e],bx=bA.document.body;return bA.document.compatMode==="CSS1Compat"&&bB||bx&&bx["client"+e]||bB}else{if(bA.nodeType===9){return Math.max(bA.documentElement["client"+e],bA.body["scroll"+e],bA.documentElement["scroll"+e],bA.body["offset"+e],bA.documentElement["offset"+e])}else{if(bz===L){var bC=b.css(bA,bw),by=parseFloat(bC);return b.isNumeric(by)?by:bC}else{return this.css(bw,typeof bz==="string"?bz:bz+"px")}}}}});bb.jQuery=bb.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b})}})(window);/*!
+ * jQuery UI 1.8.18
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI
+ */
+(function(a,d){a.ui=a.ui||{};if(a.ui.version){return}a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(e,f){return typeof e==="number"?this.each(function(){var g=this;setTimeout(function(){a(g).focus();if(f){f.call(g)}},e)}):this._focus.apply(this,arguments)},scrollParent:function(){var e;if((a.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){e=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(a.curCSS(this,"position",1))&&(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}else{e=this.parents().filter(function(){return(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!e.length?a(document):e},zIndex:function(h){if(h!==d){return this.css("zIndex",h)}if(this.length){var f=a(this[0]),e,g;while(f.length&&f[0]!==document){e=f.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){g=parseInt(f.css("zIndex"),10);if(!isNaN(g)&&g!==0){return g}}f=f.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(g,e){var f=e==="Width"?["Left","Right"]:["Top","Bottom"],h=e.toLowerCase(),k={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};function j(m,l,i,n){a.each(f,function(){l-=parseFloat(a.curCSS(m,"padding"+this,true))||0;if(i){l-=parseFloat(a.curCSS(m,"border"+this+"Width",true))||0}if(n){l-=parseFloat(a.curCSS(m,"margin"+this,true))||0}});return l}a.fn["inner"+e]=function(i){if(i===d){return k["inner"+e].call(this)}return this.each(function(){a(this).css(h,j(this,i)+"px")})};a.fn["outer"+e]=function(i,l){if(typeof i!=="number"){return k["outer"+e].call(this,i)}return this.each(function(){a(this).css(h,j(this,i,true,l)+"px")})}});function c(g,e){var j=g.nodeName.toLowerCase();if("area"===j){var i=g.parentNode,h=i.name,f;if(!g.href||!h||i.nodeName.toLowerCase()!=="map"){return false}f=a("img[usemap=#"+h+"]")[0];return !!f&&b(f)}return(/input|select|textarea|button|object/.test(j)?!g.disabled:"a"==j?g.href||e:e)&&b(g)}function b(e){return !a(e).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.extend(a.expr[":"],{data:function(g,f,e){return !!a.data(g,e[3])},focusable:function(e){return c(e,!isNaN(a.attr(e,"tabindex")))},tabbable:function(g){var e=a.attr(g,"tabindex"),f=isNaN(e);return(f||e>=0)&&c(g,!f)}});a(function(){var e=document.body,f=e.appendChild(f=document.createElement("div"));f.offsetHeight;a.extend(f.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=f.offsetHeight===100;a.support.selectstart="onselectstart" in f;e.removeChild(f).style.display="none"});a.extend(a.ui,{plugin:{add:function(f,g,j){var h=a.ui[f].prototype;for(var e in j){h.plugins[e]=h.plugins[e]||[];h.plugins[e].push([g,j[e]])}},call:function(e,g,f){var j=e.plugins[g];if(!j||!e.element[0].parentNode){return}for(var h=0;h<j.length;h++){if(e.options[j[h][0]]){j[h][1].apply(e.element,f)}}}},contains:function(f,e){return document.compareDocumentPosition?f.compareDocumentPosition(e)&16:f!==e&&f.contains(e)},hasScroll:function(h,f){if(a(h).css("overflow")==="hidden"){return false}var e=(f&&f==="left")?"scrollLeft":"scrollTop",g=false;if(h[e]>0){return true}h[e]=1;g=(h[e]>0);h[e]=0;return g},isOverAxis:function(f,e,g){return(f>e)&&(f<(e+g))},isOver:function(j,f,i,h,e,g){return a.ui.isOverAxis(j,i,e)&&a.ui.isOverAxis(f,h,g)}})})(jQuery);/*!
+ * jQuery UI Widget 1.8.18
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Widget
+ */
+(function(b,d){if(b.cleanData){var c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)}}else{var a=b.fn.remove;b.fn.remove=function(e,f){return this.each(function(){if(!f){if(!e||b.filter(e,[this]).length){b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(g){}})}}return a.call(b(this),e,f)})}}b.widget=function(f,h,e){var g=f.split(".")[0],j;f=f.split(".")[1];j=g+"-"+f;if(!e){e=h;h=b.Widget}b.expr[":"][j]=function(k){return !!b.data(k,f)};b[g]=b[g]||{};b[g][f]=function(k,l){if(arguments.length){this._createWidget(k,l)}};var i=new h();i.options=b.extend(true,{},i.options);b[g][f].prototype=b.extend(true,i,{namespace:g,widgetName:f,widgetEventPrefix:b[g][f].prototype.widgetEventPrefix||f,widgetBaseClass:j},e);b.widget.bridge(f,b[g][f])};b.widget.bridge=function(f,e){b.fn[f]=function(i){var g=typeof i==="string",h=Array.prototype.slice.call(arguments,1),j=this;i=!g&&h.length?b.extend.apply(null,[true,i].concat(h)):i;if(g&&i.charAt(0)==="_"){return j}if(g){this.each(function(){var k=b.data(this,f),l=k&&b.isFunction(k[i])?k[i].apply(k,h):k;if(l!==k&&l!==d){j=l;return false}})}else{this.each(function(){var k=b.data(this,f);if(k){k.option(i||{})._init()}else{b.data(this,f,new e(i,this))}})}return j}};b.Widget=function(e,f){if(arguments.length){this._createWidget(e,f)}};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(f,g){b.data(g,this.widgetName,this);this.element=b(g);this.options=b.extend(true,{},this.options,this._getCreateOptions(),f);var e=this;this.element.bind("remove."+this.widgetName,function(){e.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(f,g){var e=f;if(arguments.length===0){return b.extend({},this.options)}if(typeof f==="string"){if(g===d){return this.options[f]}e={};e[f]=g}this._setOptions(e);return this},_setOptions:function(f){var e=this;b.each(f,function(g,h){e._setOption(g,h)});return this},_setOption:function(e,f){this.options[e]=f;if(e==="disabled"){this.widget()[f?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",f)}return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(e,f,g){var j,i,h=this.options[e];g=g||{};f=b.Event(f);f.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase();f.target=this.element[0];i=f.originalEvent;if(i){for(j in i){if(!(j in f)){f[j]=i[j]}}}this.element.trigger(f,g);return !(b.isFunction(h)&&h.call(this.element[0],f,g)===false||f.isDefaultPrevented())}}})(jQuery);/*!
+ * jQuery UI Mouse 1.8.18
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Mouse
+ *
+ * Depends:
+ * jquery.ui.widget.js
+ */
+(function(b,c){var a=false;b(document).mouseup(function(d){a=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var d=this;this.element.bind("mousedown."+this.widgetName,function(e){return d._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===b.data(e.target,d.widgetName+".preventClickEvent")){b.removeData(e.target,d.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(f){if(a){return}(this._mouseStarted&&this._mouseUp(f));this._mouseDownEvent=f;var e=this,g=(f.which==1),d=(typeof this.options.cancel=="string"&&f.target.nodeName?b(f.target).closest(this.options.cancel).length:false);if(!g||d||!this._mouseCapture(f)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(f)&&this._mouseDelayMet(f)){this._mouseStarted=(this._mouseStart(f)!==false);if(!this._mouseStarted){f.preventDefault();return true}}if(true===b.data(f.target,this.widgetName+".preventClickEvent")){b.removeData(f.target,this.widgetName+".preventClickEvent")}this._mouseMoveDelegate=function(h){return e._mouseMove(h)};this._mouseUpDelegate=function(h){return e._mouseUp(h)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);f.preventDefault();a=true;return true},_mouseMove:function(d){if(b.browser.msie&&!(document.documentMode>=9)&&!d.button){return this._mouseUp(d)}if(this._mouseStarted){this._mouseDrag(d);return d.preventDefault()}if(this._mouseDistanceMet(d)&&this._mouseDelayMet(d)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,d)!==false);(this._mouseStarted?this._mouseDrag(d):this._mouseUp(d))}return !this._mouseStarted},_mouseUp:function(d){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;if(d.target==this._mouseDownEvent.target){b.data(d.target,this.widgetName+".preventClickEvent",true)}this._mouseStop(d)}return false},_mouseDistanceMet:function(d){return(Math.max(Math.abs(this._mouseDownEvent.pageX-d.pageX),Math.abs(this._mouseDownEvent.pageY-d.pageY))>=this.options.distance)},_mouseDelayMet:function(d){return this.mouseDelayMet},_mouseStart:function(d){},_mouseDrag:function(d){},_mouseStop:function(d){},_mouseCapture:function(d){return true}})})(jQuery);(function(c,d){c.widget("ui.resizable",c.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000},_create:function(){var f=this,k=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(k.aspectRatio),aspectRatio:k.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:k.helper||k.ghost||k.animate?k.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){this.element.wrap(c('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=k.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var l=this.handles.split(",");this.handles={};for(var g=0;g<l.length;g++){var j=c.trim(l[g]),e="ui-resizable-"+j;var h=c('<div class="ui-resizable-handle '+e+'"></div>');if(/sw|se|ne|nw/.test(j)){h.css({zIndex:++k.zIndex})}if("se"==j){h.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[j]=".ui-resizable-"+j;this.element.append(h)}}this._renderAxis=function(q){q=q||this.element;for(var n in this.handles){if(this.handles[n].constructor==String){this.handles[n]=c(this.handles[n],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=c(this.handles[n],this.element),p=0;p=/sw|ne|nw|se|n|s/.test(n)?o.outerHeight():o.outerWidth();var m=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");q.css(m,p);this._proportionallyResize()}if(!c(this.handles[n]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!f.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}f.axis=i&&i[1]?i[1]:"se"}});if(k.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){if(k.disabled){return}c(this).removeClass("ui-resizable-autohide");f._handles.show()},function(){if(k.disabled){return}if(!f.resizing){c(this).addClass("ui-resizable-autohide");f._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var e=function(g){c(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var f=this.element;f.after(this.originalElement.css({position:f.css("position"),width:f.outerWidth(),height:f.outerHeight(),top:f.css("top"),left:f.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(f){var g=false;for(var e in this.handles){if(c(this.handles[e])[0]==f.target){g=true}}return !this.options.disabled&&g},_mouseStart:function(g){var j=this.options,f=this.element.position(),e=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(e.is(".ui-draggable")||(/absolute/).test(e.css("position"))){e.css({position:"absolute",top:f.top,left:f.left})}this._renderProxy();var k=b(this.helper.css("left")),h=b(this.helper.css("top"));if(j.containment){k+=c(j.containment).scrollLeft()||0;h+=c(j.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:k,top:h};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:k,top:h};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:g.pageX,top:g.pageY};this.aspectRatio=(typeof j.aspectRatio=="number")?j.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var i=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",i=="auto"?this.axis+"-resize":i);e.addClass("ui-resizable-resizing");this._propagate("start",g);return true},_mouseDrag:function(e){var h=this.helper,g=this.options,m={},q=this,j=this.originalMousePosition,n=this.axis;var r=(e.pageX-j.left)||0,p=(e.pageY-j.top)||0;var i=this._change[n];if(!i){return false}var l=i.apply(this,[e,r,p]),k=c.browser.msie&&c.browser.version<7,f=this.sizeDiff;this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey){l=this._updateRatio(l,e)}l=this._respectSize(l,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(l);this._trigger("resize",e,this.ui());return false},_mouseStop:function(h){this.resizing=false;var i=this.options,m=this;if(this._helper){var g=this._proportionallyResizeElements,e=g.length&&(/textarea/i).test(g[0].nodeName),f=e&&c.ui.hasScroll(g[0],"left")?0:m.sizeDiff.height,k=e?0:m.sizeDiff.width;var n={width:(m.helper.width()-k),height:(m.helper.height()-f)},j=(parseInt(m.element.css("left"),10)+(m.position.left-m.originalPosition.left))||null,l=(parseInt(m.element.css("top"),10)+(m.position.top-m.originalPosition.top))||null;if(!i.animate){this.element.css(c.extend(n,{top:l,left:j}))}m.helper.height(m.size.height);m.helper.width(m.size.width);if(this._helper&&!i.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",h);if(this._helper){this.helper.remove()}return false},_updateVirtualBoundaries:function(g){var j=this.options,i,h,f,k,e;e={minWidth:a(j.minWidth)?j.minWidth:0,maxWidth:a(j.maxWidth)?j.maxWidth:Infinity,minHeight:a(j.minHeight)?j.minHeight:0,maxHeight:a(j.maxHeight)?j.maxHeight:Infinity};if(this._aspectRatio||g){i=e.minHeight*this.aspectRatio;f=e.minWidth/this.aspectRatio;h=e.maxHeight*this.aspectRatio;k=e.maxWidth/this.aspectRatio;if(i>e.minWidth){e.minWidth=i}if(f>e.minHeight){e.minHeight=f}if(h<e.maxWidth){e.maxWidth=h}if(k<e.maxHeight){e.maxHeight=k}}this._vBoundaries=e},_updateCache:function(e){var f=this.options;this.offset=this.helper.offset();if(a(e.left)){this.position.left=e.left}if(a(e.top)){this.position.top=e.top}if(a(e.height)){this.size.height=e.height}if(a(e.width)){this.size.width=e.width}},_updateRatio:function(h,g){var i=this.options,j=this.position,f=this.size,e=this.axis;if(a(h.height)){h.width=(h.height*this.aspectRatio)}else{if(a(h.width)){h.height=(h.width/this.aspectRatio)}}if(e=="sw"){h.left=j.left+(f.width-h.width);h.top=null}if(e=="nw"){h.top=j.top+(f.height-h.height);h.left=j.left+(f.width-h.width)}return h},_respectSize:function(l,g){var j=this.helper,i=this._vBoundaries,r=this._aspectRatio||g.shiftKey,q=this.axis,t=a(l.width)&&i.maxWidth&&(i.maxWidth<l.width),m=a(l.height)&&i.maxHeight&&(i.maxHeight<l.height),h=a(l.width)&&i.minWidth&&(i.minWidth>l.width),s=a(l.height)&&i.minHeight&&(i.minHeight>l.height);if(h){l.width=i.minWidth}if(s){l.height=i.minHeight}if(t){l.width=i.maxWidth}if(m){l.height=i.maxHeight}var f=this.originalPosition.left+this.originalSize.width,p=this.position.top+this.size.height;var k=/sw|nw|w/.test(q),e=/nw|ne|n/.test(q);if(h&&k){l.left=f-i.minWidth}if(t&&k){l.left=f-i.maxWidth}if(s&&e){l.top=p-i.minHeight}if(m&&e){l.top=p-i.maxHeight}var n=!l.width&&!l.height;if(n&&!l.left&&l.top){l.top=null}else{if(n&&!l.top&&l.left){l.left=null}}return l},_proportionallyResize:function(){var k=this.options;if(!this._proportionallyResizeElements.length){return}var g=this.helper||this.element;for(var f=0;f<this._proportionallyResizeElements.length;f++){var h=this._proportionallyResizeElements[f];if(!this.borderDif){var e=[h.css("borderTopWidth"),h.css("borderRightWidth"),h.css("borderBottomWidth"),h.css("borderLeftWidth")],j=[h.css("paddingTop"),h.css("paddingRight"),h.css("paddingBottom"),h.css("paddingLeft")];this.borderDif=c.map(e,function(l,n){var m=parseInt(l,10)||0,o=parseInt(j[n],10)||0;return m+o})}if(c.browser.msie&&!(!(c(g).is(":hidden")||c(g).parents(":hidden").length))){continue}h.css({height:(g.height()-this.borderDif[0]-this.borderDif[2])||0,width:(g.width()-this.borderDif[1]-this.borderDif[3])||0})}},_renderProxy:function(){var f=this.element,i=this.options;this.elementOffset=f.offset();if(this._helper){this.helper=this.helper||c('<div style="overflow:hidden;"></div>');var e=c.browser.msie&&c.browser.version<7,g=(e?1:0),h=(e?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++i.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(g,f,e){return{width:this.originalSize.width+f}},w:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{left:i.left+f,width:g.width-f}},n:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{top:i.top+e,height:g.height-e}},s:function(g,f,e){return{height:this.originalSize.height+e}},se:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},sw:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[g,f,e]))},ne:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},nw:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[g,f,e]))}},_propagate:function(f,e){c.ui.plugin.call(this,f,[e,this.ui()]);(f!="resize"&&this._trigger(f,e,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});c.extend(c.ui.resizable,{version:"1.8.18"});c.ui.plugin.add("resizable","alsoResize",{start:function(f,g){var e=c(this).data("resizable"),i=e.options;var h=function(j){c(j).each(function(){var k=c(this);k.data("resizable-alsoresize",{width:parseInt(k.width(),10),height:parseInt(k.height(),10),left:parseInt(k.css("left"),10),top:parseInt(k.css("top"),10)})})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.parentNode){if(i.alsoResize.length){i.alsoResize=i.alsoResize[0];h(i.alsoResize)}else{c.each(i.alsoResize,function(j){h(j)})}}else{h(i.alsoResize)}},resize:function(g,i){var f=c(this).data("resizable"),j=f.options,h=f.originalSize,l=f.originalPosition;var k={height:(f.size.height-h.height)||0,width:(f.size.width-h.width)||0,top:(f.position.top-l.top)||0,left:(f.position.left-l.left)||0},e=function(m,n){c(m).each(function(){var q=c(this),r=c(this).data("resizable-alsoresize"),p={},o=n&&n.length?n:q.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];c.each(o,function(s,u){var t=(r[u]||0)+(k[u]||0);if(t&&t>=0){p[u]=t||null}});q.css(p)})};if(typeof(j.alsoResize)=="object"&&!j.alsoResize.nodeType){c.each(j.alsoResize,function(m,n){e(m,n)})}else{e(j.alsoResize)}},stop:function(e,f){c(this).removeData("resizable-alsoresize")}});c.ui.plugin.add("resizable","animate",{stop:function(i,n){var p=c(this).data("resizable"),j=p.options;var h=p._proportionallyResizeElements,e=h.length&&(/textarea/i).test(h[0].nodeName),f=e&&c.ui.hasScroll(h[0],"left")?0:p.sizeDiff.height,l=e?0:p.sizeDiff.width;var g={width:(p.size.width-l),height:(p.size.height-f)},k=(parseInt(p.element.css("left"),10)+(p.position.left-p.originalPosition.left))||null,m=(parseInt(p.element.css("top"),10)+(p.position.top-p.originalPosition.top))||null;p.element.animate(c.extend(g,m&&k?{top:m,left:k}:{}),{duration:j.animateDuration,easing:j.animateEasing,step:function(){var o={width:parseInt(p.element.css("width"),10),height:parseInt(p.element.css("height"),10),top:parseInt(p.element.css("top"),10),left:parseInt(p.element.css("left"),10)};if(h&&h.length){c(h[0]).css({width:o.width,height:o.height})}p._updateCache(o);p._propagate("resize",i)}})}});c.ui.plugin.add("resizable","containment",{start:function(f,r){var t=c(this).data("resizable"),j=t.options,l=t.element;var g=j.containment,k=(g instanceof c)?g.get(0):(/parent/.test(g))?l.parent().get(0):g;if(!k){return}t.containerElement=c(k);if(/document/.test(g)||g==document){t.containerOffset={left:0,top:0};t.containerPosition={left:0,top:0};t.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var n=c(k),i=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){i[p]=b(n.css("padding"+o))});t.containerOffset=n.offset();t.containerPosition=n.position();t.containerSize={height:(n.innerHeight()-i[3]),width:(n.innerWidth()-i[1])};var q=t.containerOffset,e=t.containerSize.height,m=t.containerSize.width,h=(c.ui.hasScroll(k,"left")?k.scrollWidth:m),s=(c.ui.hasScroll(k)?k.scrollHeight:e);t.parentData={element:k,left:q.left,top:q.top,width:h,height:s}}},resize:function(g,q){var t=c(this).data("resizable"),i=t.options,f=t.containerSize,p=t.containerOffset,m=t.size,n=t.position,r=t._aspectRatio||g.shiftKey,e={top:0,left:0},h=t.containerElement;if(h[0]!=document&&(/static/).test(h.css("position"))){e=p}if(n.left<(t._helper?p.left:0)){t.size.width=t.size.width+(t._helper?(t.position.left-p.left):(t.position.left-e.left));if(r){t.size.height=t.size.width/i.aspectRatio}t.position.left=i.helper?p.left:0}if(n.top<(t._helper?p.top:0)){t.size.height=t.size.height+(t._helper?(t.position.top-p.top):t.position.top);if(r){t.size.width=t.size.height*i.aspectRatio}t.position.top=t._helper?p.top:0}t.offset.left=t.parentData.left+t.position.left;t.offset.top=t.parentData.top+t.position.top;var l=Math.abs((t._helper?t.offset.left-e.left:(t.offset.left-e.left))+t.sizeDiff.width),s=Math.abs((t._helper?t.offset.top-e.top:(t.offset.top-p.top))+t.sizeDiff.height);var k=t.containerElement.get(0)==t.element.parent().get(0),j=/relative|absolute/.test(t.containerElement.css("position"));if(k&&j){l-=t.parentData.left}if(l+t.size.width>=t.parentData.width){t.size.width=t.parentData.width-l;if(r){t.size.height=t.size.width/t.aspectRatio}}if(s+t.size.height>=t.parentData.height){t.size.height=t.parentData.height-s;if(r){t.size.width=t.size.height*t.aspectRatio}}},stop:function(f,n){var q=c(this).data("resizable"),g=q.options,l=q.position,m=q.containerOffset,e=q.containerPosition,i=q.containerElement;var j=c(q.helper),r=j.offset(),p=j.outerWidth()-q.sizeDiff.width,k=j.outerHeight()-q.sizeDiff.height;if(q._helper&&!g.animate&&(/relative/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}if(q._helper&&!g.animate&&(/static/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}}});c.ui.plugin.add("resizable","ghost",{start:function(g,h){var e=c(this).data("resizable"),i=e.options,f=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:"");e.ghost.appendTo(e.helper)},resize:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost){e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})}},stop:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost&&e.helper){e.helper.get(0).removeChild(e.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(e,m){var p=c(this).data("resizable"),h=p.options,k=p.size,i=p.originalSize,j=p.originalPosition,n=p.axis,l=h._aspectRatio||e.shiftKey;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var g=Math.round((k.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1),f=Math.round((k.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f}else{if(/^(ne)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f}else{if(/^(sw)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.left=j.left-g}else{p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f;p.position.left=j.left-g}}}}});var b=function(e){return parseInt(e,10)||0};var a=function(e){return !isNaN(parseInt(e,10))}})(jQuery);/*!
+ * jQuery hashchange event - v1.3 - 7/21/2010
+ * http://benalman.com/projects/jquery-hashchange-plugin/
+ *
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$('<iframe tabindex="-1" title="empty"/>').hide().one("load",function(){r||l(a());n()}).attr("src",r||"javascript:0").insertAfter("body")[0].contentWindow;h.onpropertychange=function(){try{if(event.propertyName==="title"){q.document.title=h.title}}catch(s){}}}};j.stop=k;o=function(){return a(q.location.href)};l=function(v,s){var u=q.document,t=$.fn[c].domain;if(v!==s){u.title=h.title;u.open();t&&u.write('<script>document.domain="'+t+'"<\/script>');u.close();q.location.hash=v}}})();return j})()})(jQuery,this);(function(c){var a=c.scrollTo=function(f,e,d){c(window).scrollTo(f,e,d)};a.defaults={axis:"xy",duration:parseFloat(c.fn.jquery)>=1.3?0:1};a.window=function(d){return c(window)._scrollable()};c.fn._scrollable=function(){return this.map(function(){var e=this,d=!e.nodeName||c.inArray(e.nodeName.toLowerCase(),["iframe","#document","html","body"])!=-1;if(!d){return e}var f=(e.contentWindow||e).document||e.ownerDocument||e;return c.browser.safari||f.compatMode=="BackCompat"?f.body:f.documentElement})};c.fn.scrollTo=function(f,e,d){if(typeof e=="object"){d=e;e=0}if(typeof d=="function"){d={onAfter:d}}if(f=="max"){f=9000000000}d=c.extend({},a.defaults,d);e=e||d.speed||d.duration;d.queue=d.queue&&d.axis.length>1;if(d.queue){e/=2}d.offset=b(d.offset);d.over=b(d.over);return this._scrollable().each(function(){var l=this,j=c(l),k=f,i,g={},m=j.is("html,body");switch(typeof k){case"number":case"string":if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(k)){k=b(k);break}k=c(k,this);case"object":if(k.is||k.style){i=(k=c(k)).offset()}}c.each(d.axis.split(""),function(q,r){var s=r=="x"?"Left":"Top",u=s.toLowerCase(),p="scroll"+s,o=l[p],n=a.max(l,r);if(i){g[p]=i[u]+(m?0:o-j.offset()[u]);if(d.margin){g[p]-=parseInt(k.css("margin"+s))||0;g[p]-=parseInt(k.css("border"+s+"Width"))||0}g[p]+=d.offset[u]||0;if(d.over[u]){g[p]+=k[r=="x"?"width":"height"]()*d.over[u]}}else{var t=k[u];g[p]=t.slice&&t.slice(-1)=="%"?parseFloat(t)/100*n:t}if(/^\d+$/.test(g[p])){g[p]=g[p]<=0?0:Math.min(g[p],n)}if(!q&&d.queue){if(o!=g[p]){h(d.onAfterFirst)}delete g[p]}});h(d.onAfter);function h(n){j.animate(g,e,d.easing,n&&function(){n.call(this,f,d)})}}).end()};a.max=function(j,i){var h=i=="x"?"Width":"Height",e="scroll"+h;if(!c(j).is("html,body")){return j[e]-c(j)[h.toLowerCase()]()}var g="client"+h,f=j.ownerDocument.documentElement,d=j.ownerDocument.body;return Math.max(f[e],d[e])-Math.min(f[g],d[g])};function b(d){return typeof d=="object"?d:{top:d,left:d}}})(jQuery);/*!
+ PowerTip - v1.2.0 - 2013-04-03
+ http://stevenbenner.github.com/jquery-powertip/
+ Copyright (c) 2013 Steven Benner (http://stevenbenner.com/).
+ Released under MIT license.
+ https://raw.github.com/stevenbenner/jquery-powertip/master/LICENSE.txt
+*/
+(function(a){if(typeof define==="function"&&define.amd){define(["jquery"],a)}else{a(jQuery)}}(function(k){var A=k(document),s=k(window),w=k("body");var n="displayController",e="hasActiveHover",d="forcedOpen",u="hasMouseMove",f="mouseOnToPopup",g="originalTitle",y="powertip",o="powertipjq",l="powertiptarget",E=180/Math.PI;var c={isTipOpen:false,isFixedTipOpen:false,isClosing:false,tipOpenImminent:false,activeHover:null,currentX:0,currentY:0,previousX:0,previousY:0,desyncTimeout:null,mouseTrackingActive:false,delayInProgress:false,windowWidth:0,windowHeight:0,scrollTop:0,scrollLeft:0};var p={none:0,top:1,bottom:2,left:4,right:8};k.fn.powerTip=function(F,N){if(!this.length){return this}if(k.type(F)==="string"&&k.powerTip[F]){return k.powerTip[F].call(this,this,N)}var O=k.extend({},k.fn.powerTip.defaults,F),G=new x(O);h();this.each(function M(){var R=k(this),Q=R.data(y),P=R.data(o),T=R.data(l),S;if(R.data(n)){k.powerTip.destroy(R)}S=R.attr("title");if(!Q&&!T&&!P&&S){R.data(y,S);R.data(g,S);R.removeAttr("title")}R.data(n,new t(R,O,G))});if(!O.manual){this.on({"mouseenter.powertip":function J(P){k.powerTip.show(this,P)},"mouseleave.powertip":function L(){k.powerTip.hide(this)},"focus.powertip":function K(){k.powerTip.show(this)},"blur.powertip":function H(){k.powerTip.hide(this,true)},"keydown.powertip":function I(P){if(P.keyCode===27){k.powerTip.hide(this,true)}}})}return this};k.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false};k.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};k.powerTip={show:function z(F,G){if(G){i(G);c.previousX=G.pageX;c.previousY=G.pageY;k(F).data(n).show()}else{k(F).first().data(n).show(true,true)}return F},reposition:function r(F){k(F).first().data(n).resetPosition();return F},hide:function D(G,F){if(G){k(G).first().data(n).hide(F)}else{if(c.activeHover){c.activeHover.data(n).hide(true)}}return G},destroy:function C(G){k(G).off(".powertip").each(function F(){var I=k(this),H=[g,n,e,d];if(I.data(g)){I.attr("title",I.data(g));H.push(y)}I.removeData(H)});return G}};k.powerTip.showTip=k.powerTip.show;k.powerTip.closeTip=k.powerTip.hide;function b(){var F=this;F.top="auto";F.left="auto";F.right="auto";F.bottom="auto";F.set=function(H,G){if(k.isNumeric(G)){F[H]=Math.round(G)}}}function t(K,N,F){var J=null;function L(P,Q){M();if(!K.data(e)){if(!P){c.tipOpenImminent=true;J=setTimeout(function O(){J=null;I()},N.intentPollInterval)}else{if(Q){K.data(d,true)}F.showTip(K)}}}function G(P){M();c.tipOpenImminent=false;if(K.data(e)){K.data(d,false);if(!P){c.delayInProgress=true;J=setTimeout(function O(){J=null;F.hideTip(K);c.delayInProgress=false},N.closeDelay)}else{F.hideTip(K)}}}function I(){var Q=Math.abs(c.previousX-c.currentX),O=Math.abs(c.previousY-c.currentY),P=Q+O;if(P<N.intentSensitivity){F.showTip(K)}else{c.previousX=c.currentX;c.previousY=c.currentY;L()}}function M(){J=clearTimeout(J);c.delayInProgress=false}function H(){F.resetPosition(K)}this.show=L;this.hide=G;this.cancel=M;this.resetPosition=H}function j(){function G(M,L,J,O,P){var K=L.split("-")[0],N=new b(),I;if(q(M)){I=H(M,K)}else{I=F(M,K)}switch(L){case"n":N.set("left",I.left-(J/2));N.set("bottom",c.windowHeight-I.top+P);break;case"e":N.set("left",I.left+P);N.set("top",I.top-(O/2));break;case"s":N.set("left",I.left-(J/2));N.set("top",I.top+P);break;case"w":N.set("top",I.top-(O/2));N.set("right",c.windowWidth-I.left+P);break;case"nw":N.set("bottom",c.windowHeight-I.top+P);N.set("right",c.windowWidth-I.left-20);break;case"nw-alt":N.set("left",I.left);N.set("bottom",c.windowHeight-I.top+P);break;case"ne":N.set("left",I.left-20);N.set("bottom",c.windowHeight-I.top+P);break;case"ne-alt":N.set("bottom",c.windowHeight-I.top+P);N.set("right",c.windowWidth-I.left);break;case"sw":N.set("top",I.top+P);N.set("right",c.windowWidth-I.left-20);break;case"sw-alt":N.set("left",I.left);N.set("top",I.top+P);break;case"se":N.set("left",I.left-20);N.set("top",I.top+P);break;case"se-alt":N.set("top",I.top+P);N.set("right",c.windowWidth-I.left);break}return N}function F(K,J){var O=K.offset(),N=K.outerWidth(),I=K.outerHeight(),M,L;switch(J){case"n":M=O.left+N/2;L=O.top;break;case"e":M=O.left+N;L=O.top+I/2;break;case"s":M=O.left+N/2;L=O.top+I;break;case"w":M=O.left;L=O.top+I/2;break;case"nw":M=O.left;L=O.top;break;case"ne":M=O.left+N;L=O.top;break;case"sw":M=O.left;L=O.top+I;break;case"se":M=O.left+N;L=O.top+I;break}return{top:L,left:M}}function H(O,K){var S=O.closest("svg")[0],N=O[0],W=S.createSVGPoint(),L=N.getBBox(),V=N.getScreenCTM(),M=L.width/2,Q=L.height/2,P=[],I=["nw","n","ne","e","se","s","sw","w"],U,X,R,T;function J(){P.push(W.matrixTransform(V))}W.x=L.x;W.y=L.y;J();W.x+=M;J();W.x+=M;J();W.y+=Q;J();W.y+=Q;J();W.x-=M;J();W.x-=M;J();W.y-=Q;J();if(P[0].y!==P[1].y||P[0].x!==P[7].x){X=Math.atan2(V.b,V.a)*E;R=Math.ceil(((X%360)-22.5)/45);if(R<1){R+=8}while(R--){I.push(I.shift())}}for(T=0;T<P.length;T++){if(I[T]===K){U=P[T];break}}return{top:U.y+c.scrollTop,left:U.x+c.scrollLeft}}this.compute=G}function x(Q){var P=new j(),O=k("#"+Q.popupId);if(O.length===0){O=k("<div/>",{id:Q.popupId});if(w.length===0){w=k("body")}w.append(O)}if(Q.followMouse){if(!O.data(u)){A.on("mousemove",M);s.on("scroll",M);O.data(u,true)}}if(Q.mouseOnToPopup){O.on({mouseenter:function L(){if(O.data(f)){if(c.activeHover){c.activeHover.data(n).cancel()}}},mouseleave:function N(){if(c.activeHover){c.activeHover.data(n).hide()}}})}function I(S){S.data(e,true);O.queue(function R(T){H(S);T()})}function H(S){var U;if(!S.data(e)){return}if(c.isTipOpen){if(!c.isClosing){K(c.activeHover)}O.delay(100).queue(function R(V){H(S);V()});return}S.trigger("powerTipPreRender");U=B(S);if(U){O.empty().append(U)}else{return}S.trigger("powerTipRender");c.activeHover=S;c.isTipOpen=true;O.data(f,Q.mouseOnToPopup);if(!Q.followMouse){G(S);c.isFixedTipOpen=true}else{M()}O.fadeIn(Q.fadeInTime,function T(){if(!c.desyncTimeout){c.desyncTimeout=setInterval(J,500)}S.trigger("powerTipOpen")})}function K(R){c.isClosing=true;c.activeHover=null;c.isTipOpen=false;c.desyncTimeout=clearInterval(c.desyncTimeout);R.data(e,false);R.data(d,false);O.fadeOut(Q.fadeOutTime,function S(){var T=new b();c.isClosing=false;c.isFixedTipOpen=false;O.removeClass();T.set("top",c.currentY+Q.offset);T.set("left",c.currentX+Q.offset);O.css(T);R.trigger("powerTipClose")})}function M(){if(!c.isFixedTipOpen&&(c.isTipOpen||(c.tipOpenImminent&&O.data(u)))){var R=O.outerWidth(),V=O.outerHeight(),U=new b(),S,T;U.set("top",c.currentY+Q.offset);U.set("left",c.currentX+Q.offset);S=m(U,R,V);if(S!==p.none){T=a(S);if(T===1){if(S===p.right){U.set("left",c.windowWidth-R)}else{if(S===p.bottom){U.set("top",c.scrollTop+c.windowHeight-V)}}}else{U.set("left",c.currentX-R-Q.offset);U.set("top",c.currentY-V-Q.offset)}}O.css(U)}}function G(S){var R,T;if(Q.smartPlacement){R=k.fn.powerTip.smartPlacementLists[Q.placement];k.each(R,function(U,W){var V=m(F(S,W),O.outerWidth(),O.outerHeight());T=W;if(V===p.none){return false}})}else{F(S,Q.placement);T=Q.placement}O.addClass(T)}function F(U,T){var R=0,S,W,V=new b();V.set("top",0);V.set("left",0);O.css(V);do{S=O.outerWidth();W=O.outerHeight();V=P.compute(U,T,S,W,Q.offset);O.css(V)}while(++R<=5&&(S!==O.outerWidth()||W!==O.outerHeight()));return V}function J(){var R=false;if(c.isTipOpen&&!c.isClosing&&!c.delayInProgress){if(c.activeHover.data(e)===false||c.activeHover.is(":disabled")){R=true}else{if(!v(c.activeHover)&&!c.activeHover.is(":focus")&&!c.activeHover.data(d)){if(O.data(f)){if(!v(O)){R=true}}else{R=true}}}if(R){K(c.activeHover)}}}this.showTip=I;this.hideTip=K;this.resetPosition=G}function q(F){return window.SVGElement&&F[0] instanceof SVGElement}function h(){if(!c.mouseTrackingActive){c.mouseTrackingActive=true;k(function H(){c.scrollLeft=s.scrollLeft();c.scrollTop=s.scrollTop();c.windowWidth=s.width();c.windowHeight=s.height()});A.on("mousemove",i);s.on({resize:function G(){c.windowWidth=s.width();c.windowHeight=s.height()},scroll:function F(){var I=s.scrollLeft(),J=s.scrollTop();if(I!==c.scrollLeft){c.currentX+=I-c.scrollLeft;c.scrollLeft=I}if(J!==c.scrollTop){c.currentY+=J-c.scrollTop;c.scrollTop=J}}})}}function i(F){c.currentX=F.pageX;c.currentY=F.pageY}function v(F){var H=F.offset(),J=F[0].getBoundingClientRect(),I=J.right-J.left,G=J.bottom-J.top;return c.currentX>=H.left&&c.currentX<=H.left+I&&c.currentY>=H.top&&c.currentY<=H.top+G}function B(I){var G=I.data(y),F=I.data(o),K=I.data(l),H,J;if(G){if(k.isFunction(G)){G=G.call(I[0])}J=G}else{if(F){if(k.isFunction(F)){F=F.call(I[0])}if(F.length>0){J=F.clone(true,true)}}else{if(K){H=k("#"+K);if(H.length>0){J=H.html()}}}}return J}function m(M,L,K){var G=c.scrollTop,J=c.scrollLeft,I=G+c.windowHeight,F=J+c.windowWidth,H=p.none;if(M.top<G||Math.abs(M.bottom-c.windowHeight)-K<G){H|=p.top}if(M.top+K>I||Math.abs(M.bottom-c.windowHeight)>I){H|=p.bottom}if(M.left<J||M.right+L>F){H|=p.left}if(M.left+L>F||M.right<J){H|=p.right}return H}function a(G){var F=0;while(G){G&=G-1;F++}return F}})); \ No newline at end of file
diff --git a/doc/html/nav_f.png b/doc/html/nav_f.png
new file mode 100644
index 0000000..72a58a5
--- /dev/null
+++ b/doc/html/nav_f.png
Binary files differ
diff --git a/doc/html/nav_g.png b/doc/html/nav_g.png
new file mode 100644
index 0000000..2093a23
--- /dev/null
+++ b/doc/html/nav_g.png
Binary files differ
diff --git a/doc/html/nav_h.png b/doc/html/nav_h.png
new file mode 100644
index 0000000..33389b1
--- /dev/null
+++ b/doc/html/nav_h.png
Binary files differ
diff --git a/doc/html/navtree.css b/doc/html/navtree.css
new file mode 100644
index 0000000..1a868b3
--- /dev/null
+++ b/doc/html/navtree.css
@@ -0,0 +1,143 @@
+#nav-tree .children_ul {
+ margin:0;
+ padding:4px;
+}
+
+#nav-tree ul {
+ list-style:none outside none;
+ margin:0px;
+ padding:0px;
+}
+
+#nav-tree li {
+ white-space:nowrap;
+ margin:0px;
+ padding:0px;
+}
+
+#nav-tree .plus {
+ margin:0px;
+}
+
+#nav-tree .selected {
+ background-image: url('tab_a.png');
+ background-repeat:repeat-x;
+ color: #fff;
+ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+}
+
+#nav-tree img {
+ margin:0px;
+ padding:0px;
+ border:0px;
+ vertical-align: middle;
+}
+
+#nav-tree a {
+ text-decoration:none;
+ padding:0px;
+ margin:0px;
+ outline:none;
+}
+
+#nav-tree .label {
+ margin:0px;
+ padding:0px;
+ font: 12px 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+}
+
+#nav-tree .label a {
+ padding:2px;
+}
+
+#nav-tree .selected a {
+ text-decoration:none;
+ color:#fff;
+}
+
+#nav-tree .children_ul {
+ margin:0px;
+ padding:0px;
+}
+
+#nav-tree .item {
+ margin:0px;
+ padding:0px;
+}
+
+#nav-tree {
+ padding: 0px 0px;
+ background-color: #FAFAFF;
+ font-size:14px;
+ overflow:auto;
+}
+
+#doc-content {
+ overflow:auto;
+ display:block;
+ padding:0px;
+ margin:0px;
+ -webkit-overflow-scrolling : touch; /* iOS 5+ */
+}
+
+#side-nav {
+ padding:0 6px 0 0;
+ margin: 0px;
+ display:block;
+ position: absolute;
+ left: 0px;
+ width: 250px;
+}
+
+.ui-resizable .ui-resizable-handle {
+ display:block;
+}
+
+.ui-resizable-e {
+ background:url("splitbar.png") repeat scroll right center transparent;
+ cursor:e-resize;
+ height:100%;
+ right:0;
+ top:0;
+ width:6px;
+}
+
+.ui-resizable-handle {
+ display:none;
+ font-size:0.1px;
+ position:absolute;
+ z-index:1;
+}
+
+#nav-tree-contents {
+ margin: 6px 0px 0px 0px;
+}
+
+#nav-tree {
+ background-image:url('nav_h.png');
+ background-repeat:repeat-x;
+ background-color: #F9FAFC;
+ -webkit-overflow-scrolling : touch; /* iOS 5+ */
+}
+
+#nav-sync {
+ position:absolute;
+ top:5px;
+ right:24px;
+ z-index:0;
+}
+
+#nav-sync img {
+ opacity:0.3;
+}
+
+#nav-sync img:hover {
+ opacity:0.9;
+}
+
+@media print
+{
+ #nav-tree { display: none; }
+ div.ui-resizable-handle { display: none; position: relative; }
+}
+
diff --git a/doc/html/navtree.js b/doc/html/navtree.js
new file mode 100644
index 0000000..9df45a7
--- /dev/null
+++ b/doc/html/navtree.js
@@ -0,0 +1,523 @@
+var navTreeSubIndices = new Array();
+
+function getData(varName)
+{
+ var i = varName.lastIndexOf('/');
+ var n = i>=0 ? varName.substring(i+1) : varName;
+ return eval(n.replace(/\-/g,'_'));
+}
+
+function stripPath(uri)
+{
+ return uri.substring(uri.lastIndexOf('/')+1);
+}
+
+function stripPath2(uri)
+{
+ var i = uri.lastIndexOf('/');
+ var s = uri.substring(i+1);
+ var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/);
+ return m ? uri.substring(i-6) : s;
+}
+
+function hashValue()
+{
+ return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,'');
+}
+
+function hashUrl()
+{
+ return '#'+hashValue();
+}
+
+function pathName()
+{
+ return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, '');
+}
+
+function localStorageSupported()
+{
+ try {
+ return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem;
+ }
+ catch(e) {
+ return false;
+ }
+}
+
+
+function storeLink(link)
+{
+ if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) {
+ window.localStorage.setItem('navpath',link);
+ }
+}
+
+function deleteLink()
+{
+ if (localStorageSupported()) {
+ window.localStorage.setItem('navpath','');
+ }
+}
+
+function cachedLink()
+{
+ if (localStorageSupported()) {
+ return window.localStorage.getItem('navpath');
+ } else {
+ return '';
+ }
+}
+
+function getScript(scriptName,func,show)
+{
+ var head = document.getElementsByTagName("head")[0];
+ var script = document.createElement('script');
+ script.id = scriptName;
+ script.type = 'text/javascript';
+ script.onload = func;
+ script.src = scriptName+'.js';
+ if ($.browser.msie && $.browser.version<=8) {
+ // script.onload does not work with older versions of IE
+ script.onreadystatechange = function() {
+ if (script.readyState=='complete' || script.readyState=='loaded') {
+ func(); if (show) showRoot();
+ }
+ }
+ }
+ head.appendChild(script);
+}
+
+function createIndent(o,domNode,node,level)
+{
+ var level=-1;
+ var n = node;
+ while (n.parentNode) { level++; n=n.parentNode; }
+ if (node.childrenData) {
+ var imgNode = document.createElement("img");
+ imgNode.style.paddingLeft=(16*level).toString()+'px';
+ imgNode.width = 16;
+ imgNode.height = 22;
+ imgNode.border = 0;
+ node.plus_img = imgNode;
+ node.expandToggle = document.createElement("a");
+ node.expandToggle.href = "javascript:void(0)";
+ node.expandToggle.onclick = function() {
+ if (node.expanded) {
+ $(node.getChildrenUL()).slideUp("fast");
+ node.plus_img.src = node.relpath+"arrowright.png";
+ node.expanded = false;
+ } else {
+ expandNode(o, node, false, false);
+ }
+ }
+ node.expandToggle.appendChild(imgNode);
+ domNode.appendChild(node.expandToggle);
+ imgNode.src = node.relpath+"arrowright.png";
+ } else {
+ var span = document.createElement("span");
+ span.style.display = 'inline-block';
+ span.style.width = 16*(level+1)+'px';
+ span.style.height = '22px';
+ span.innerHTML = '&#160;';
+ domNode.appendChild(span);
+ }
+}
+
+var animationInProgress = false;
+
+function gotoAnchor(anchor,aname,updateLocation)
+{
+ var pos, docContent = $('#doc-content');
+ var ancParent = $(anchor.parent());
+ if (ancParent.hasClass('memItemLeft') ||
+ ancParent.hasClass('fieldname') ||
+ ancParent.hasClass('fieldtype') ||
+ ancParent.is(':header'))
+ {
+ pos = ancParent.position().top;
+ } else if (anchor.position()) {
+ pos = anchor.position().top;
+ }
+ if (pos) {
+ var dist = Math.abs(Math.min(
+ pos-docContent.offset().top,
+ docContent[0].scrollHeight-
+ docContent.height()-docContent.scrollTop()));
+ animationInProgress=true;
+ docContent.animate({
+ scrollTop: pos + docContent.scrollTop() - docContent.offset().top
+ },Math.max(50,Math.min(500,dist)),function(){
+ if (updateLocation) window.location.href=aname;
+ animationInProgress=false;
+ });
+ }
+}
+
+function newNode(o, po, text, link, childrenData, lastNode)
+{
+ var node = new Object();
+ node.children = Array();
+ node.childrenData = childrenData;
+ node.depth = po.depth + 1;
+ node.relpath = po.relpath;
+ node.isLast = lastNode;
+
+ node.li = document.createElement("li");
+ po.getChildrenUL().appendChild(node.li);
+ node.parentNode = po;
+
+ node.itemDiv = document.createElement("div");
+ node.itemDiv.className = "item";
+
+ node.labelSpan = document.createElement("span");
+ node.labelSpan.className = "label";
+
+ createIndent(o,node.itemDiv,node,0);
+ node.itemDiv.appendChild(node.labelSpan);
+ node.li.appendChild(node.itemDiv);
+
+ var a = document.createElement("a");
+ node.labelSpan.appendChild(a);
+ node.label = document.createTextNode(text);
+ node.expanded = false;
+ a.appendChild(node.label);
+ if (link) {
+ var url;
+ if (link.substring(0,1)=='^') {
+ url = link.substring(1);
+ link = url;
+ } else {
+ url = node.relpath+link;
+ }
+ a.className = stripPath(link.replace('#',':'));
+ if (link.indexOf('#')!=-1) {
+ var aname = '#'+link.split('#')[1];
+ var srcPage = stripPath(pathName());
+ var targetPage = stripPath(link.split('#')[0]);
+ a.href = srcPage!=targetPage ? url : "javascript:void(0)";
+ a.onclick = function(){
+ storeLink(link);
+ if (!$(a).parent().parent().hasClass('selected'))
+ {
+ $('.item').removeClass('selected');
+ $('.item').removeAttr('id');
+ $(a).parent().parent().addClass('selected');
+ $(a).parent().parent().attr('id','selected');
+ }
+ var anchor = $(aname);
+ gotoAnchor(anchor,aname,true);
+ };
+ } else {
+ a.href = url;
+ a.onclick = function() { storeLink(link); }
+ }
+ } else {
+ if (childrenData != null)
+ {
+ a.className = "nolink";
+ a.href = "javascript:void(0)";
+ a.onclick = node.expandToggle.onclick;
+ }
+ }
+
+ node.childrenUL = null;
+ node.getChildrenUL = function() {
+ if (!node.childrenUL) {
+ node.childrenUL = document.createElement("ul");
+ node.childrenUL.className = "children_ul";
+ node.childrenUL.style.display = "none";
+ node.li.appendChild(node.childrenUL);
+ }
+ return node.childrenUL;
+ };
+
+ return node;
+}
+
+function showRoot()
+{
+ var headerHeight = $("#top").height();
+ var footerHeight = $("#nav-path").height();
+ var windowHeight = $(window).height() - headerHeight - footerHeight;
+ (function (){ // retry until we can scroll to the selected item
+ try {
+ var navtree=$('#nav-tree');
+ navtree.scrollTo('#selected',0,{offset:-windowHeight/2});
+ } catch (err) {
+ setTimeout(arguments.callee, 0);
+ }
+ })();
+}
+
+function expandNode(o, node, imm, showRoot)
+{
+ if (node.childrenData && !node.expanded) {
+ if (typeof(node.childrenData)==='string') {
+ var varName = node.childrenData;
+ getScript(node.relpath+varName,function(){
+ node.childrenData = getData(varName);
+ expandNode(o, node, imm, showRoot);
+ }, showRoot);
+ } else {
+ if (!node.childrenVisited) {
+ getNode(o, node);
+ } if (imm || ($.browser.msie && $.browser.version>8)) {
+ // somehow slideDown jumps to the start of tree for IE9 :-(
+ $(node.getChildrenUL()).show();
+ } else {
+ $(node.getChildrenUL()).slideDown("fast");
+ }
+ if (node.isLast) {
+ node.plus_img.src = node.relpath+"arrowdown.png";
+ } else {
+ node.plus_img.src = node.relpath+"arrowdown.png";
+ }
+ node.expanded = true;
+ }
+ }
+}
+
+function glowEffect(n,duration)
+{
+ n.addClass('glow').delay(duration).queue(function(next){
+ $(this).removeClass('glow');next();
+ });
+}
+
+function highlightAnchor()
+{
+ var aname = hashUrl();
+ var anchor = $(aname);
+ if (anchor.parent().attr('class')=='memItemLeft'){
+ var rows = $('.memberdecls tr[class$="'+hashValue()+'"]');
+ glowEffect(rows.children(),300); // member without details
+ } else if (anchor.parent().attr('class')=='fieldname'){
+ glowEffect(anchor.parent().parent(),1000); // enum value
+ } else if (anchor.parent().attr('class')=='fieldtype'){
+ glowEffect(anchor.parent().parent(),1000); // struct field
+ } else if (anchor.parent().is(":header")) {
+ glowEffect(anchor.parent(),1000); // section header
+ } else {
+ glowEffect(anchor.next(),1000); // normal member
+ }
+ gotoAnchor(anchor,aname,false);
+}
+
+function selectAndHighlight(hash,n)
+{
+ var a;
+ if (hash) {
+ var link=stripPath(pathName())+':'+hash.substring(1);
+ a=$('.item a[class$="'+link+'"]');
+ }
+ if (a && a.length) {
+ a.parent().parent().addClass('selected');
+ a.parent().parent().attr('id','selected');
+ highlightAnchor();
+ } else if (n) {
+ $(n.itemDiv).addClass('selected');
+ $(n.itemDiv).attr('id','selected');
+ }
+ if ($('#nav-tree-contents .item:first').hasClass('selected')) {
+ $('#nav-sync').css('top','30px');
+ } else {
+ $('#nav-sync').css('top','5px');
+ }
+ showRoot();
+}
+
+function showNode(o, node, index, hash)
+{
+ if (node && node.childrenData) {
+ if (typeof(node.childrenData)==='string') {
+ var varName = node.childrenData;
+ getScript(node.relpath+varName,function(){
+ node.childrenData = getData(varName);
+ showNode(o,node,index,hash);
+ },true);
+ } else {
+ if (!node.childrenVisited) {
+ getNode(o, node);
+ }
+ $(node.getChildrenUL()).css({'display':'block'});
+ node.plus_img.src = node.relpath+"arrowdown.png";
+ node.expanded = true;
+ var n = node.children[o.breadcrumbs[index]];
+ if (index+1<o.breadcrumbs.length) {
+ showNode(o,n,index+1,hash);
+ } else {
+ if (typeof(n.childrenData)==='string') {
+ var varName = n.childrenData;
+ getScript(n.relpath+varName,function(){
+ n.childrenData = getData(varName);
+ node.expanded=false;
+ showNode(o,node,index,hash); // retry with child node expanded
+ },true);
+ } else {
+ var rootBase = stripPath(o.toroot.replace(/\..+$/, ''));
+ if (rootBase=="index" || rootBase=="pages" || rootBase=="search") {
+ expandNode(o, n, true, true);
+ }
+ selectAndHighlight(hash,n);
+ }
+ }
+ }
+ } else {
+ selectAndHighlight(hash);
+ }
+}
+
+function removeToInsertLater(element) {
+ var parentNode = element.parentNode;
+ var nextSibling = element.nextSibling;
+ parentNode.removeChild(element);
+ return function() {
+ if (nextSibling) {
+ parentNode.insertBefore(element, nextSibling);
+ } else {
+ parentNode.appendChild(element);
+ }
+ };
+}
+
+function getNode(o, po)
+{
+ var insertFunction = removeToInsertLater(po.li);
+ po.childrenVisited = true;
+ var l = po.childrenData.length-1;
+ for (var i in po.childrenData) {
+ var nodeData = po.childrenData[i];
+ po.children[i] = newNode(o, po, nodeData[0], nodeData[1], nodeData[2],
+ i==l);
+ }
+ insertFunction();
+}
+
+function gotoNode(o,subIndex,root,hash,relpath)
+{
+ var nti = navTreeSubIndices[subIndex][root+hash];
+ o.breadcrumbs = $.extend(true, [], nti ? nti : navTreeSubIndices[subIndex][root]);
+ if (!o.breadcrumbs && root!=NAVTREE[0][1]) { // fallback: show index
+ navTo(o,NAVTREE[0][1],"",relpath);
+ $('.item').removeClass('selected');
+ $('.item').removeAttr('id');
+ }
+ if (o.breadcrumbs) {
+ o.breadcrumbs.unshift(0); // add 0 for root node
+ showNode(o, o.node, 0, hash);
+ }
+}
+
+function navTo(o,root,hash,relpath)
+{
+ var link = cachedLink();
+ if (link) {
+ var parts = link.split('#');
+ root = parts[0];
+ if (parts.length>1) hash = '#'+parts[1].replace(/[^\w\-]/g,'');
+ else hash='';
+ }
+ if (hash.match(/^#l\d+$/)) {
+ var anchor=$('a[name='+hash.substring(1)+']');
+ glowEffect(anchor.parent(),1000); // line number
+ hash=''; // strip line number anchors
+ }
+ var url=root+hash;
+ var i=-1;
+ while (NAVTREEINDEX[i+1]<=url) i++;
+ if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index
+ if (navTreeSubIndices[i]) {
+ gotoNode(o,i,root,hash,relpath)
+ } else {
+ getScript(relpath+'navtreeindex'+i,function(){
+ navTreeSubIndices[i] = eval('NAVTREEINDEX'+i);
+ if (navTreeSubIndices[i]) {
+ gotoNode(o,i,root,hash,relpath);
+ }
+ },true);
+ }
+}
+
+function showSyncOff(n,relpath)
+{
+ n.html('<img src="'+relpath+'sync_off.png" title="'+SYNCOFFMSG+'"/>');
+}
+
+function showSyncOn(n,relpath)
+{
+ n.html('<img src="'+relpath+'sync_on.png" title="'+SYNCONMSG+'"/>');
+}
+
+function toggleSyncButton(relpath)
+{
+ var navSync = $('#nav-sync');
+ if (navSync.hasClass('sync')) {
+ navSync.removeClass('sync');
+ showSyncOff(navSync,relpath);
+ storeLink(stripPath2(pathName())+hashUrl());
+ } else {
+ navSync.addClass('sync');
+ showSyncOn(navSync,relpath);
+ deleteLink();
+ }
+}
+
+function initNavTree(toroot,relpath)
+{
+ var o = new Object();
+ o.toroot = toroot;
+ o.node = new Object();
+ o.node.li = document.getElementById("nav-tree-contents");
+ o.node.childrenData = NAVTREE;
+ o.node.children = new Array();
+ o.node.childrenUL = document.createElement("ul");
+ o.node.getChildrenUL = function() { return o.node.childrenUL; };
+ o.node.li.appendChild(o.node.childrenUL);
+ o.node.depth = 0;
+ o.node.relpath = relpath;
+ o.node.expanded = false;
+ o.node.isLast = true;
+ o.node.plus_img = document.createElement("img");
+ o.node.plus_img.src = relpath+"arrowright.png";
+ o.node.plus_img.width = 16;
+ o.node.plus_img.height = 22;
+
+ if (localStorageSupported()) {
+ var navSync = $('#nav-sync');
+ if (cachedLink()) {
+ showSyncOff(navSync,relpath);
+ navSync.removeClass('sync');
+ } else {
+ showSyncOn(navSync,relpath);
+ }
+ navSync.click(function(){ toggleSyncButton(relpath); });
+ }
+
+ $(window).load(function(){
+ navTo(o,toroot,hashUrl(),relpath);
+ showRoot();
+ });
+
+ $(window).bind('hashchange', function(){
+ if (window.location.hash && window.location.hash.length>1){
+ var a;
+ if ($(location).attr('hash')){
+ var clslink=stripPath(pathName())+':'+hashValue();
+ a=$('.item a[class$="'+clslink.replace(/</g,'\\3c ')+'"]');
+ }
+ if (a==null || !$(a).parent().parent().hasClass('selected')){
+ $('.item').removeClass('selected');
+ $('.item').removeAttr('id');
+ }
+ var link=stripPath2(pathName());
+ navTo(o,link,hashUrl(),relpath);
+ } else if (!animationInProgress) {
+ $('#doc-content').scrollTop(0);
+ $('.item').removeClass('selected');
+ $('.item').removeAttr('id');
+ navTo(o,toroot,hashUrl(),relpath);
+ }
+ })
+}
+
diff --git a/doc/html/navtreedata.js b/doc/html/navtreedata.js
new file mode 100644
index 0000000..21efa41
--- /dev/null
+++ b/doc/html/navtreedata.js
@@ -0,0 +1,12 @@
+var NAVTREE =
+[
+ [ "NVIDIA Gameworks Volumetric Lighting", "index.html", ]
+];
+
+var NAVTREEINDEX =
+[
+"index.html"
+];
+
+var SYNCONMSG = 'click to disable panel synchronisation';
+var SYNCOFFMSG = 'click to enable panel synchronisation'; \ No newline at end of file
diff --git a/doc/html/navtreeindex0.js b/doc/html/navtreeindex0.js
new file mode 100644
index 0000000..9e75a21
--- /dev/null
+++ b/doc/html/navtreeindex0.js
@@ -0,0 +1,5 @@
+var NAVTREEINDEX0 =
+{
+"index.html":[],
+"pages.html":[]
+};
diff --git a/doc/html/open.png b/doc/html/open.png
new file mode 100644
index 0000000..30f75c7
--- /dev/null
+++ b/doc/html/open.png
Binary files differ
diff --git a/doc/html/resize.js b/doc/html/resize.js
new file mode 100644
index 0000000..2b86c36
--- /dev/null
+++ b/doc/html/resize.js
@@ -0,0 +1,97 @@
+var cookie_namespace = 'doxygen';
+var sidenav,navtree,content,header;
+
+function readCookie(cookie)
+{
+ var myCookie = cookie_namespace+"_"+cookie+"=";
+ if (document.cookie)
+ {
+ var index = document.cookie.indexOf(myCookie);
+ if (index != -1)
+ {
+ var valStart = index + myCookie.length;
+ var valEnd = document.cookie.indexOf(";", valStart);
+ if (valEnd == -1)
+ {
+ valEnd = document.cookie.length;
+ }
+ var val = document.cookie.substring(valStart, valEnd);
+ return val;
+ }
+ }
+ return 0;
+}
+
+function writeCookie(cookie, val, expiration)
+{
+ if (val==undefined) return;
+ if (expiration == null)
+ {
+ var date = new Date();
+ date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week
+ expiration = date.toGMTString();
+ }
+ document.cookie = cookie_namespace + "_" + cookie + "=" + val + "; expires=" + expiration+"; path=/";
+}
+
+function resizeWidth()
+{
+ var windowWidth = $(window).width() + "px";
+ var sidenavWidth = $(sidenav).outerWidth();
+ content.css({marginLeft:parseInt(sidenavWidth)+"px"});
+ writeCookie('width',sidenavWidth, null);
+}
+
+function restoreWidth(navWidth)
+{
+ var windowWidth = $(window).width() + "px";
+ content.css({marginLeft:parseInt(navWidth)+6+"px"});
+ sidenav.css({width:navWidth + "px"});
+}
+
+function resizeHeight()
+{
+ var headerHeight = header.outerHeight();
+ var footerHeight = footer.outerHeight();
+ var windowHeight = $(window).height() - headerHeight - footerHeight;
+ content.css({height:windowHeight + "px"});
+ navtree.css({height:windowHeight + "px"});
+ sidenav.css({height:windowHeight + "px"});
+}
+
+function initResizable()
+{
+ header = $("#top");
+ sidenav = $("#side-nav");
+ content = $("#doc-content");
+ navtree = $("#nav-tree");
+ footer = $("#nav-path");
+ $(".side-nav-resizable").resizable({resize: function(e, ui) { resizeWidth(); } });
+ $(window).resize(function() { resizeHeight(); });
+ var width = readCookie('width');
+ if (width) { restoreWidth(width); } else { resizeWidth(); }
+ resizeHeight();
+ var url = location.href;
+ var i=url.indexOf("#");
+ if (i>=0) window.location.hash=url.substr(i);
+ var _preventDefault = function(evt) { evt.preventDefault(); };
+ $("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault);
+ $(document).bind('touchmove',function(e){
+ var device = navigator.userAgent.toLowerCase();
+ var ios = device.match(/(iphone|ipod|ipad)/);
+ if (ios) {
+ try {
+ var target = e.target;
+ while (target) {
+ if ($(target).css('-webkit-overflow-scrolling')=='touch') return;
+ target = target.parentNode;
+ }
+ e.preventDefault();
+ } catch(err) {
+ e.preventDefault();
+ }
+ }
+ });
+}
+
+
diff --git a/doc/html/splitbar.png b/doc/html/splitbar.png
new file mode 100644
index 0000000..fe895f2
--- /dev/null
+++ b/doc/html/splitbar.png
Binary files differ
diff --git a/doc/html/sync_off.png b/doc/html/sync_off.png
new file mode 100644
index 0000000..3b443fc
--- /dev/null
+++ b/doc/html/sync_off.png
Binary files differ
diff --git a/doc/html/sync_on.png b/doc/html/sync_on.png
new file mode 100644
index 0000000..e08320f
--- /dev/null
+++ b/doc/html/sync_on.png
Binary files differ
diff --git a/doc/html/tab_a.png b/doc/html/tab_a.png
new file mode 100644
index 0000000..3b725c4
--- /dev/null
+++ b/doc/html/tab_a.png
Binary files differ
diff --git a/doc/html/tab_b.png b/doc/html/tab_b.png
new file mode 100644
index 0000000..e2b4a86
--- /dev/null
+++ b/doc/html/tab_b.png
Binary files differ
diff --git a/doc/html/tab_h.png b/doc/html/tab_h.png
new file mode 100644
index 0000000..fd5cb70
--- /dev/null
+++ b/doc/html/tab_h.png
Binary files differ
diff --git a/doc/html/tab_s.png b/doc/html/tab_s.png
new file mode 100644
index 0000000..ab478c9
--- /dev/null
+++ b/doc/html/tab_s.png
Binary files differ
diff --git a/doc/html/tabs.css b/doc/html/tabs.css
new file mode 100644
index 0000000..9cf578f
--- /dev/null
+++ b/doc/html/tabs.css
@@ -0,0 +1,60 @@
+.tabs, .tabs2, .tabs3 {
+ background-image: url('tab_b.png');
+ width: 100%;
+ z-index: 101;
+ font-size: 13px;
+ font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+}
+
+.tabs2 {
+ font-size: 10px;
+}
+.tabs3 {
+ font-size: 9px;
+}
+
+.tablist {
+ margin: 0;
+ padding: 0;
+ display: table;
+}
+
+.tablist li {
+ float: left;
+ display: table-cell;
+ background-image: url('tab_b.png');
+ line-height: 36px;
+ list-style: none;
+}
+
+.tablist a {
+ display: block;
+ padding: 0 20px;
+ font-weight: bold;
+ background-image:url('tab_s.png');
+ background-repeat:no-repeat;
+ background-position:right;
+ color: #283A5D;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ text-decoration: none;
+ outline: none;
+}
+
+.tabs3 .tablist a {
+ padding: 0 10px;
+}
+
+.tablist a:hover {
+ background-image: url('tab_h.png');
+ background-repeat:repeat-x;
+ color: #fff;
+ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+ text-decoration: none;
+}
+
+.tablist li.current a {
+ background-image: url('tab_a.png');
+ background-repeat:repeat-x;
+ color: #fff;
+ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+}
diff --git a/external/NvFoundation/1.1/doc/NvFoundation.chm b/external/NvFoundation/1.1/doc/NvFoundation.chm
new file mode 100644
index 0000000..ba680cb
--- /dev/null
+++ b/external/NvFoundation/1.1/doc/NvFoundation.chm
Binary files differ
diff --git a/external/NvFoundation/1.1/doc/ReadMe.txt b/external/NvFoundation/1.1/doc/ReadMe.txt
new file mode 100644
index 0000000..f0898a1
--- /dev/null
+++ b/external/NvFoundation/1.1/doc/ReadMe.txt
@@ -0,0 +1,8 @@
+The NvFoundation library defines just the most basic
+data types to be shared across all public interfaces.
+
+It defines basic types for integers, floats, vectors,
+matrices, and quaternions.
+
+It also defines basic interfaces for error reporting
+and memory allocation.
diff --git a/external/NvFoundation/1.1/doc/create_docs.cmd b/external/NvFoundation/1.1/doc/create_docs.cmd
new file mode 100644
index 0000000..f4227c5
--- /dev/null
+++ b/external/NvFoundation/1.1/doc/create_docs.cmd
@@ -0,0 +1,7 @@
+set DOXYGEN_DIR=..\..\..\..\..\BuildTools\doxygen-win\bin
+set HTMLHELP_DIR=..\..\..\..\..\BuildTools\HTMLHelpWorkshop
+
+%DOXYGEN_DIR%\doxygen.exe docs.doxyfile
+cd html
+..\%HTMLHELP_DIR%\hhc.exe index.hhp
+cd ..
diff --git a/external/NvFoundation/1.1/doc/docs.doxyfile b/external/NvFoundation/1.1/doc/docs.doxyfile
new file mode 100644
index 0000000..445d331
--- /dev/null
+++ b/external/NvFoundation/1.1/doc/docs.doxyfile
@@ -0,0 +1,10 @@
+# Doxyfile 1.5.8
+
+PROJECT_NAME = "NVIDIA(R) NvFoundation Reference"
+ENABLED_SECTIONS = PHYSICS_SDK_PAGES
+WARN_LOGFILE = NvFoundation.err
+INPUT = ../Include/
+GENERATE_HTMLHELP = YES
+HTML_OUTPUT = html/
+CHM_FILE = ../NvFoundation.chm
+TOC_EXPAND = YES
diff --git a/external/NvFoundation/1.1/include/Nv.h b/external/NvFoundation/1.1/include/Nv.h
new file mode 100644
index 0000000..83d85de
--- /dev/null
+++ b/external/NvFoundation/1.1/include/Nv.h
@@ -0,0 +1,89 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NV_H
+#define NV_NVFOUNDATION_NV_H
+
+/** \addtogroup foundation
+@{
+*/
+
+#include "NvSimpleTypes.h"
+
+/** files to always include */
+#include <string.h>
+#include <stdlib.h>
+
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+class NvAllocatorCallback;
+class NvErrorCallback;
+struct NvErrorCode;
+class NvAssertHandler;
+
+class NvInputStream;
+class NvInputData;
+class NvOutputStream;
+
+class NvVec2;
+class NvVec3;
+class NvVec4;
+class NvMat33;
+class NvMat44;
+class NvPlane;
+class NvQuat;
+class NvTransform;
+class NvBounds3;
+
+/** enum for empty constructor tag*/
+enum NvEMPTY
+{
+ NvEmpty
+};
+
+/** enum for zero constructor tag for vectors and matrices */
+enum NvZERO
+{
+ NvZero
+};
+
+/** enum for identity constructor flag for quaternions, transforms, and matrices */
+enum NvIDENTITY
+{
+ NvIdentity
+};
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NV_H
diff --git a/external/NvFoundation/1.1/include/NvAllocatorCallback.h b/external/NvFoundation/1.1/include/NvAllocatorCallback.h
new file mode 100644
index 0000000..1d1682d
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvAllocatorCallback.h
@@ -0,0 +1,95 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVALLOCATORCALLBACK_H
+#define NV_NVFOUNDATION_NVALLOCATORCALLBACK_H
+
+/** \addtogroup foundation
+@{
+*/
+
+#include "Nv.h"
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+
+/**
+\brief Abstract base class for an application defined memory allocator that can be used by the Nv library.
+
+\note The SDK state should not be modified from within any allocation/free function.
+
+<b>Threading:</b> All methods of this class should be thread safe as it can be called from the user thread
+or the physics processing thread(s).
+*/
+
+class NvAllocatorCallback
+{
+ public:
+ /**
+ \brief destructor
+ */
+ virtual ~NvAllocatorCallback()
+ {
+ }
+
+ /**
+ \brief Allocates size bytes of memory, which must be 16-byte aligned.
+
+ This method should never return NULL. If you run out of memory, then
+ you should terminate the app or take some other appropriate action.
+
+ <b>Threading:</b> This function should be thread safe as it can be called in the context of the user thread
+ and physics processing thread(s).
+
+ \param size Number of bytes to allocate.
+ \param typeName Name of the datatype that is being allocated
+ \param filename The source file which allocated the memory
+ \param line The source line which allocated the memory
+ \return The allocated block of memory.
+ */
+ virtual void* allocate(size_t size, const char* typeName, const char* filename, int line) = 0;
+
+ /**
+ \brief Frees memory previously allocated by allocate().
+
+ <b>Threading:</b> This function should be thread safe as it can be called in the context of the user thread
+ and physics processing thread(s).
+
+ \param ptr Memory to free.
+ */
+ virtual void deallocate(void* ptr) = 0;
+};
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVALLOCATORCALLBACK_H
diff --git a/external/NvFoundation/1.1/include/NvAssert.h b/external/NvFoundation/1.1/include/NvAssert.h
new file mode 100644
index 0000000..e2ccb95
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvAssert.h
@@ -0,0 +1,97 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVASSERT_H
+#define NV_NVFOUNDATION_NVASSERT_H
+
+/** \addtogroup foundation
+@{ */
+
+#include "Nv.h"
+
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+
+/* Base class to handle assert failures */
+class NvAssertHandler
+{
+ public:
+ virtual ~NvAssertHandler()
+ {
+ }
+ virtual void operator()(const char* exp, const char* file, int line, bool& ignore) = 0;
+};
+
+NV_FOUNDATION_API NvAssertHandler& NvGetAssertHandler();
+NV_FOUNDATION_API void NvSetAssertHandler(NvAssertHandler& handler);
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+#if !NV_ENABLE_ASSERTS
+#define NV_ASSERT(exp) ((void)0)
+#define NV_ALWAYS_ASSERT_MESSAGE(exp) ((void)0)
+#define NV_ASSERT_WITH_MESSAGE(condition, message) ((void)0)
+#elif NV_SPU
+#include "ps3/NvPS3Assert.h"
+#else
+#if NV_VC
+#define NV_CODE_ANALYSIS_ASSUME(exp) \
+ __analysis_assume(!!(exp)) // This macro will be used to get rid of analysis warning messages if a NV_ASSERT is used
+// to "guard" illegal mem access, for example.
+#else
+#define NV_CODE_ANALYSIS_ASSUME(exp)
+#endif
+#define NV_ASSERT(exp) \
+ { \
+ static bool _ignore = false; \
+ ((void)((!!(exp)) || (!_ignore && (nvidia::NvGetAssertHandler()(#exp, __FILE__, __LINE__, _ignore), false)))); \
+ NV_CODE_ANALYSIS_ASSUME(exp); \
+ }
+#define NV_ALWAYS_ASSERT_MESSAGE(exp) \
+ { \
+ static bool _ignore = false; \
+ if(!_ignore) \
+ nvidia::NvGetAssertHandler()(exp, __FILE__, __LINE__, _ignore); \
+ }
+#define NV_ASSERT_WITH_MESSAGE(exp, message) \
+ { \
+ static bool _ignore = false; \
+ ((void)((!!(exp)) || (!_ignore && (nvidia::NvGetAssertHandler()(message, __FILE__, __LINE__, _ignore), false)))); \
+ NV_CODE_ANALYSIS_ASSUME(exp); \
+ }
+#endif
+
+#define NV_ALWAYS_ASSERT() NV_ASSERT(0)
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVASSERT_H
diff --git a/external/NvFoundation/1.1/include/NvBounds3.h b/external/NvFoundation/1.1/include/NvBounds3.h
new file mode 100644
index 0000000..ea76169
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvBounds3.h
@@ -0,0 +1,480 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVBOUNDS3_H
+#define NV_NVFOUNDATION_NVBOUNDS3_H
+
+/** \addtogroup foundation
+@{
+*/
+
+#include "NvTransform.h"
+#include "NvMat33.h"
+
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+
+// maximum extents defined such that floating point exceptions are avoided for standard use cases
+#define NV_MAX_BOUNDS_EXTENTS (NV_MAX_REAL * 0.25f)
+
+/**
+\brief Class representing 3D range or axis aligned bounding box.
+
+Stored as minimum and maximum extent corners. Alternate representation
+would be center and dimensions.
+May be empty or nonempty. For nonempty bounds, minimum <= maximum has to hold for all axes.
+Empty bounds have to be represented as minimum = NV_MAX_BOUNDS_EXTENTS and maximum = -NV_MAX_BOUNDS_EXTENTS for all
+axes.
+All other representations are invalid and the behavior is undefined.
+*/
+class NvBounds3
+{
+ public:
+ /**
+ \brief Default constructor, not performing any initialization for performance reason.
+ \remark Use empty() function below to construct empty bounds.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvBounds3()
+ {
+ }
+
+ /**
+ \brief Construct from two bounding points
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvBounds3(const NvVec3& minimum, const NvVec3& maximum);
+
+ /**
+ \brief Return empty bounds.
+ */
+ static NV_CUDA_CALLABLE NV_FORCE_INLINE NvBounds3 empty();
+
+ /**
+ \brief returns the AABB containing v0 and v1.
+ \param v0 first point included in the AABB.
+ \param v1 second point included in the AABB.
+ */
+ static NV_CUDA_CALLABLE NV_FORCE_INLINE NvBounds3 boundsOfPoints(const NvVec3& v0, const NvVec3& v1);
+
+ /**
+ \brief returns the AABB from center and extents vectors.
+ \param center Center vector
+ \param extent Extents vector
+ */
+ static NV_CUDA_CALLABLE NV_FORCE_INLINE NvBounds3 centerExtents(const NvVec3& center, const NvVec3& extent);
+
+ /**
+ \brief Construct from center, extent, and (not necessarily orthogonal) basis
+ */
+ static NV_CUDA_CALLABLE NV_INLINE NvBounds3
+ basisExtent(const NvVec3& center, const NvMat33& basis, const NvVec3& extent);
+
+ /**
+ \brief Construct from pose and extent
+ */
+ static NV_CUDA_CALLABLE NV_INLINE NvBounds3 poseExtent(const NvTransform& pose, const NvVec3& extent);
+
+ /**
+ \brief gets the transformed bounds of the passed AABB (resulting in a bigger AABB).
+
+ This version is safe to call for empty bounds.
+
+ \param[in] matrix Transform to apply, can contain scaling as well
+ \param[in] bounds The bounds to transform.
+ */
+ static NV_CUDA_CALLABLE NV_INLINE NvBounds3 transformSafe(const NvMat33& matrix, const NvBounds3& bounds);
+
+ /**
+ \brief gets the transformed bounds of the passed AABB (resulting in a bigger AABB).
+
+ Calling this method for empty bounds leads to undefined behavior. Use #transformSafe() instead.
+
+ \param[in] matrix Transform to apply, can contain scaling as well
+ \param[in] bounds The bounds to transform.
+ */
+ static NV_CUDA_CALLABLE NV_INLINE NvBounds3 transformFast(const NvMat33& matrix, const NvBounds3& bounds);
+
+ /**
+ \brief gets the transformed bounds of the passed AABB (resulting in a bigger AABB).
+
+ This version is safe to call for empty bounds.
+
+ \param[in] transform Transform to apply, can contain scaling as well
+ \param[in] bounds The bounds to transform.
+ */
+ static NV_CUDA_CALLABLE NV_INLINE NvBounds3 transformSafe(const NvTransform& transform, const NvBounds3& bounds);
+
+ /**
+ \brief gets the transformed bounds of the passed AABB (resulting in a bigger AABB).
+
+ Calling this method for empty bounds leads to undefined behavior. Use #transformSafe() instead.
+
+ \param[in] transform Transform to apply, can contain scaling as well
+ \param[in] bounds The bounds to transform.
+ */
+ static NV_CUDA_CALLABLE NV_INLINE NvBounds3 transformFast(const NvTransform& transform, const NvBounds3& bounds);
+
+ /**
+ \brief Sets empty to true
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE void setEmpty();
+
+ /**
+ \brief Sets the bounds to maximum size [-NV_MAX_BOUNDS_EXTENTS, NV_MAX_BOUNDS_EXTENTS].
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE void setMaximal();
+
+ /**
+ \brief expands the volume to include v
+ \param v Point to expand to.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE void include(const NvVec3& v);
+
+ /**
+ \brief expands the volume to include b.
+ \param b Bounds to perform union with.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE void include(const NvBounds3& b);
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool isEmpty() const;
+
+ /**
+ \brief indicates whether the intersection of this and b is empty or not.
+ \param b Bounds to test for intersection.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool intersects(const NvBounds3& b) const;
+
+ /**
+ \brief computes the 1D-intersection between two AABBs, on a given axis.
+ \param a the other AABB
+ \param axis the axis (0, 1, 2)
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool intersects1D(const NvBounds3& a, uint32_t axis) const;
+
+ /**
+ \brief indicates if these bounds contain v.
+ \param v Point to test against bounds.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool contains(const NvVec3& v) const;
+
+ /**
+ \brief checks a box is inside another box.
+ \param box the other AABB
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool isInside(const NvBounds3& box) const;
+
+ /**
+ \brief returns the center of this axis aligned box.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 getCenter() const;
+
+ /**
+ \brief get component of the box's center along a given axis
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float getCenter(uint32_t axis) const;
+
+ /**
+ \brief get component of the box's extents along a given axis
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float getExtents(uint32_t axis) const;
+
+ /**
+ \brief returns the dimensions (width/height/depth) of this axis aligned box.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 getDimensions() const;
+
+ /**
+ \brief returns the extents, which are half of the width/height/depth.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 getExtents() const;
+
+ /**
+ \brief scales the AABB.
+
+ This version is safe to call for empty bounds.
+
+ \param scale Factor to scale AABB by.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE void scaleSafe(float scale);
+
+ /**
+ \brief scales the AABB.
+
+ Calling this method for empty bounds leads to undefined behavior. Use #scaleSafe() instead.
+
+ \param scale Factor to scale AABB by.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE void scaleFast(float scale);
+
+ /**
+ fattens the AABB in all 3 dimensions by the given distance.
+
+ This version is safe to call for empty bounds.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE void fattenSafe(float distance);
+
+ /**
+ fattens the AABB in all 3 dimensions by the given distance.
+
+ Calling this method for empty bounds leads to undefined behavior. Use #fattenSafe() instead.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE void fattenFast(float distance);
+
+ /**
+ checks that the AABB values are not NaN
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool isFinite() const;
+
+ /**
+ checks that the AABB values describe a valid configuration.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool isValid() const;
+
+ NvVec3 minimum, maximum;
+};
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE NvBounds3::NvBounds3(const NvVec3& minimum_, const NvVec3& maximum_)
+: minimum(minimum_), maximum(maximum_)
+{
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE NvBounds3 NvBounds3::empty()
+{
+ return NvBounds3(NvVec3(NV_MAX_BOUNDS_EXTENTS), NvVec3(-NV_MAX_BOUNDS_EXTENTS));
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE bool NvBounds3::isFinite() const
+{
+ return minimum.isFinite() && maximum.isFinite();
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE NvBounds3 NvBounds3::boundsOfPoints(const NvVec3& v0, const NvVec3& v1)
+{
+ return NvBounds3(v0.minimum(v1), v0.maximum(v1));
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE NvBounds3 NvBounds3::centerExtents(const NvVec3& center, const NvVec3& extent)
+{
+ return NvBounds3(center - extent, center + extent);
+}
+
+NV_CUDA_CALLABLE NV_INLINE NvBounds3
+NvBounds3::basisExtent(const NvVec3& center, const NvMat33& basis, const NvVec3& extent)
+{
+ // extended basis vectors
+ NvVec3 c0 = basis.column0 * extent.x;
+ NvVec3 c1 = basis.column1 * extent.y;
+ NvVec3 c2 = basis.column2 * extent.z;
+
+ NvVec3 w;
+ // find combination of base vectors that produces max. distance for each component = sum of abs()
+ w.x = NvAbs(c0.x) + NvAbs(c1.x) + NvAbs(c2.x);
+ w.y = NvAbs(c0.y) + NvAbs(c1.y) + NvAbs(c2.y);
+ w.z = NvAbs(c0.z) + NvAbs(c1.z) + NvAbs(c2.z);
+
+ return NvBounds3(center - w, center + w);
+}
+
+NV_CUDA_CALLABLE NV_INLINE NvBounds3 NvBounds3::poseExtent(const NvTransform& pose, const NvVec3& extent)
+{
+ return basisExtent(pose.p, NvMat33(pose.q), extent);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE void NvBounds3::setEmpty()
+{
+ minimum = NvVec3(NV_MAX_BOUNDS_EXTENTS);
+ maximum = NvVec3(-NV_MAX_BOUNDS_EXTENTS);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE void NvBounds3::setMaximal()
+{
+ minimum = NvVec3(-NV_MAX_BOUNDS_EXTENTS);
+ maximum = NvVec3(NV_MAX_BOUNDS_EXTENTS);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE void NvBounds3::include(const NvVec3& v)
+{
+ NV_ASSERT(isValid());
+ minimum = minimum.minimum(v);
+ maximum = maximum.maximum(v);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE void NvBounds3::include(const NvBounds3& b)
+{
+ NV_ASSERT(isValid());
+ minimum = minimum.minimum(b.minimum);
+ maximum = maximum.maximum(b.maximum);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE bool NvBounds3::isEmpty() const
+{
+ NV_ASSERT(isValid());
+ return minimum.x > maximum.x;
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE bool NvBounds3::intersects(const NvBounds3& b) const
+{
+ NV_ASSERT(isValid() && b.isValid());
+ return !(b.minimum.x > maximum.x || minimum.x > b.maximum.x || b.minimum.y > maximum.y || minimum.y > b.maximum.y ||
+ b.minimum.z > maximum.z || minimum.z > b.maximum.z);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE bool NvBounds3::intersects1D(const NvBounds3& a, uint32_t axis) const
+{
+ NV_ASSERT(isValid() && a.isValid());
+ return maximum[axis] >= a.minimum[axis] && a.maximum[axis] >= minimum[axis];
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE bool NvBounds3::contains(const NvVec3& v) const
+{
+ NV_ASSERT(isValid());
+
+ return !(v.x < minimum.x || v.x > maximum.x || v.y < minimum.y || v.y > maximum.y || v.z < minimum.z ||
+ v.z > maximum.z);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE bool NvBounds3::isInside(const NvBounds3& box) const
+{
+ NV_ASSERT(isValid() && box.isValid());
+ if(box.minimum.x > minimum.x)
+ return false;
+ if(box.minimum.y > minimum.y)
+ return false;
+ if(box.minimum.z > minimum.z)
+ return false;
+ if(box.maximum.x < maximum.x)
+ return false;
+ if(box.maximum.y < maximum.y)
+ return false;
+ if(box.maximum.z < maximum.z)
+ return false;
+ return true;
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 NvBounds3::getCenter() const
+{
+ NV_ASSERT(isValid());
+ return (minimum + maximum) * 0.5f;
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvBounds3::getCenter(uint32_t axis) const
+{
+ NV_ASSERT(isValid());
+ return (minimum[axis] + maximum[axis]) * 0.5f;
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvBounds3::getExtents(uint32_t axis) const
+{
+ NV_ASSERT(isValid());
+ return (maximum[axis] - minimum[axis]) * 0.5f;
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 NvBounds3::getDimensions() const
+{
+ NV_ASSERT(isValid());
+ return maximum - minimum;
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 NvBounds3::getExtents() const
+{
+ NV_ASSERT(isValid());
+ return getDimensions() * 0.5f;
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE void NvBounds3::scaleSafe(float scale)
+{
+ NV_ASSERT(isValid());
+ if(!isEmpty())
+ scaleFast(scale);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE void NvBounds3::scaleFast(float scale)
+{
+ NV_ASSERT(isValid());
+ *this = centerExtents(getCenter(), getExtents() * scale);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE void NvBounds3::fattenSafe(float distance)
+{
+ NV_ASSERT(isValid());
+ if(!isEmpty())
+ fattenFast(distance);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE void NvBounds3::fattenFast(float distance)
+{
+ NV_ASSERT(isValid());
+ minimum.x -= distance;
+ minimum.y -= distance;
+ minimum.z -= distance;
+
+ maximum.x += distance;
+ maximum.y += distance;
+ maximum.z += distance;
+}
+
+NV_CUDA_CALLABLE NV_INLINE NvBounds3 NvBounds3::transformSafe(const NvMat33& matrix, const NvBounds3& bounds)
+{
+ NV_ASSERT(bounds.isValid());
+ return !bounds.isEmpty() ? transformFast(matrix, bounds) : bounds;
+}
+
+NV_CUDA_CALLABLE NV_INLINE NvBounds3 NvBounds3::transformFast(const NvMat33& matrix, const NvBounds3& bounds)
+{
+ NV_ASSERT(bounds.isValid());
+ return NvBounds3::basisExtent(matrix * bounds.getCenter(), matrix, bounds.getExtents());
+}
+
+NV_CUDA_CALLABLE NV_INLINE NvBounds3 NvBounds3::transformSafe(const NvTransform& transform, const NvBounds3& bounds)
+{
+ NV_ASSERT(bounds.isValid());
+ return !bounds.isEmpty() ? transformFast(transform, bounds) : bounds;
+}
+
+NV_CUDA_CALLABLE NV_INLINE NvBounds3 NvBounds3::transformFast(const NvTransform& transform, const NvBounds3& bounds)
+{
+ NV_ASSERT(bounds.isValid());
+ return NvBounds3::basisExtent(transform.transform(bounds.getCenter()), NvMat33(transform.q), bounds.getExtents());
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE bool NvBounds3::isValid() const
+{
+ return (isFinite() && (((minimum.x <= maximum.x) && (minimum.y <= maximum.y) && (minimum.z <= maximum.z)) ||
+ ((minimum.x == NV_MAX_BOUNDS_EXTENTS) && (minimum.y == NV_MAX_BOUNDS_EXTENTS) &&
+ (minimum.z == NV_MAX_BOUNDS_EXTENTS) && (maximum.x == -NV_MAX_BOUNDS_EXTENTS) &&
+ (maximum.y == -NV_MAX_BOUNDS_EXTENTS) && (maximum.z == -NV_MAX_BOUNDS_EXTENTS))));
+}
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVBOUNDS3_H
diff --git a/external/NvFoundation/1.1/include/NvCTypes.h b/external/NvFoundation/1.1/include/NvCTypes.h
new file mode 100644
index 0000000..fd83c18
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvCTypes.h
@@ -0,0 +1,124 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2013 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_C_TYPES_H
+#define NV_C_TYPES_H
+
+#include "NvPreprocessor.h"
+#ifdef _MSC_VER
+#ifndef _INTPTR
+#define _INTPTR 0
+#endif
+#endif
+#include <stdint.h>
+
+/** C type for 2-float vectors */
+typedef struct
+{
+ float x, y;
+} NvcVec2;
+
+/** C type for 3-float vectors */
+typedef struct
+{
+ float x, y, z;
+} NvcVec3;
+
+/** C type for 4-float vectors */
+typedef struct
+{
+ float x, y, z, w;
+} NvcVec4;
+
+/** C type for quaternions */
+typedef struct
+{
+ float x, y, z, w;
+} NvcQuat;
+
+/** C type for transforms */
+typedef struct
+{
+ NvcQuat q;
+ NvcVec3 p;
+} NvcTransform;
+
+/** C type for 3x3 matrices */
+typedef struct
+{
+ NvcVec3 column0, column1, column2, column3;
+} NvcMat34;
+
+/** C type for 3x3 matrices */
+typedef struct
+{
+ NvcVec3 column0, column1, column2;
+} NvcMat33;
+
+/** C type for 4x4 matrices */
+typedef struct
+{
+ NvcVec4 column0, column1, column2, column3;
+} NvcMat44;
+
+/** C type for 3d bounding box */
+typedef struct
+{
+ NvcVec3 minimum;
+ NvcVec3 maximum;
+} NvcBounds3;
+
+/** C type for a plane */
+typedef struct
+{
+ NvcVec3 n;
+ float d;
+} NvcPlane;
+
+/** C type for 2-integer vectors */
+typedef struct
+{
+ int32_t x, y;
+} NvcVec2i;
+
+/** C type for 3-integer vectors */
+typedef struct
+{
+ int32_t x, y, z;
+} NvcVec3i;
+
+/** C type for 4-integer vectors */
+typedef struct
+{
+ int32_t x, y, z, w;
+} NvcVec4i;
+
+/** @} */
+
+#endif // NV_C_TYPES_H
diff --git a/external/NvFoundation/1.1/include/NvErrorCallback.h b/external/NvFoundation/1.1/include/NvErrorCallback.h
new file mode 100644
index 0000000..d9f23e8
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvErrorCallback.h
@@ -0,0 +1,73 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVERRORCALLBACK_H
+#define NV_NVFOUNDATION_NVERRORCALLBACK_H
+
+/** \addtogroup foundation
+@{
+*/
+
+#include "NvErrors.h"
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+
+/**
+\brief User defined interface class. Used by the library to emit debug information.
+
+\note The SDK state should not be modified from within any error reporting functions.
+
+<b>Threading:</b> The SDK sequences its calls to the output stream using a mutex, so the class need not
+be implemented in a thread-safe manner if the SDK is the only client.
+*/
+class NvErrorCallback
+{
+ public:
+ virtual ~NvErrorCallback()
+ {
+ }
+
+ /**
+ \brief Reports an error code.
+ \param code Error code, see #NvErrorCode
+ \param message Message to display.
+ \param file File error occured in.
+ \param line Line number error occured on.
+ */
+ virtual void reportError(NvErrorCode::Enum code, const char* message, const char* file, int line) = 0;
+};
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVERRORCALLBACK_H
diff --git a/external/NvFoundation/1.1/include/NvErrors.h b/external/NvFoundation/1.1/include/NvErrors.h
new file mode 100644
index 0000000..043c525
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvErrors.h
@@ -0,0 +1,93 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVERRORS_H
+#define NV_NVFOUNDATION_NVERRORS_H
+/** \addtogroup foundation
+@{
+*/
+
+#include "Nv.h"
+
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+
+/**
+\brief Error codes
+
+These error codes are passed to #NvErrorCallback
+
+@see NvErrorCallback
+*/
+
+struct NvErrorCode
+{
+ enum Enum
+ {
+ eNO_ERROR = 0,
+
+ //! \brief An informational message.
+ eDEBUG_INFO = 1,
+
+ //! \brief a warning message for the user to help with debugging
+ eDEBUG_WARNING = 2,
+
+ //! \brief method called with invalid parameter(s)
+ eINVALID_PARAMETER = 4,
+
+ //! \brief method was called at a time when an operation is not possible
+ eINVALID_OPERATION = 8,
+
+ //! \brief method failed to allocate some memory
+ eOUT_OF_MEMORY = 16,
+
+ /** \brief The library failed for some reason.
+ Possibly you have passed invalid values like NaNs, which are not checked for.
+ */
+ eINTERNAL_ERROR = 32,
+
+ //! \brief An unrecoverable error, execution should be halted and log output flushed
+ eABORT = 64,
+
+ //! \brief The SDK has determined that an operation may result in poor performance.
+ ePERF_WARNING = 128,
+
+ //! \brief A bit mask for including all errors
+ eMASK_ALL = -1
+ };
+};
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVERRORS_H
diff --git a/external/NvFoundation/1.1/include/NvFlags.h b/external/NvFoundation/1.1/include/NvFlags.h
new file mode 100644
index 0000000..b2ec31c
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvFlags.h
@@ -0,0 +1,375 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVFLAGS_H
+#define NV_NVFOUNDATION_NVFLAGS_H
+
+/** \addtogroup foundation
+ @{
+*/
+
+#include "Nv.h"
+
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+/**
+\brief Container for bitfield flag variables associated with a specific enum type.
+
+This allows for type safe manipulation for bitfields.
+
+<h3>Example</h3>
+ // enum that defines each bit...
+ struct MyEnum
+ {
+ enum Enum
+ {
+ eMAN = 1,
+ eBEAR = 2,
+ ePIG = 4,
+ };
+ };
+
+ // implements some convenient global operators.
+ NV_FLAGS_OPERATORS(MyEnum::Enum, uint8_t);
+
+ NvFlags<MyEnum::Enum, uint8_t> myFlags;
+ myFlags |= MyEnum::eMAN;
+ myFlags |= MyEnum::eBEAR | MyEnum::ePIG;
+ if(myFlags & MyEnum::eBEAR)
+ {
+ doSomething();
+ }
+*/
+
+template <typename enumtype, typename storagetype = uint32_t>
+class NvFlags
+{
+ public:
+ typedef storagetype InternalType;
+
+ NV_INLINE explicit NvFlags(const NvEMPTY)
+ {
+ }
+ NV_INLINE NvFlags(void);
+ NV_INLINE NvFlags(enumtype e);
+ NV_INLINE NvFlags(const NvFlags<enumtype, storagetype>& f);
+ NV_INLINE explicit NvFlags(storagetype b);
+
+ NV_INLINE bool isSet(enumtype e) const;
+ NV_INLINE NvFlags<enumtype, storagetype>& set(enumtype e);
+ NV_INLINE bool operator==(enumtype e) const;
+ NV_INLINE bool operator==(const NvFlags<enumtype, storagetype>& f) const;
+ NV_INLINE bool operator==(bool b) const;
+ NV_INLINE bool operator!=(enumtype e) const;
+ NV_INLINE bool operator!=(const NvFlags<enumtype, storagetype>& f) const;
+
+ NV_INLINE NvFlags<enumtype, storagetype>& operator=(const NvFlags<enumtype, storagetype>& f);
+ NV_INLINE NvFlags<enumtype, storagetype>& operator=(enumtype e);
+
+ NV_INLINE NvFlags<enumtype, storagetype>& operator|=(enumtype e);
+ NV_INLINE NvFlags<enumtype, storagetype>& operator|=(const NvFlags<enumtype, storagetype>& f);
+ NV_INLINE NvFlags<enumtype, storagetype> operator|(enumtype e) const;
+ NV_INLINE NvFlags<enumtype, storagetype> operator|(const NvFlags<enumtype, storagetype>& f) const;
+
+ NV_INLINE NvFlags<enumtype, storagetype>& operator&=(enumtype e);
+ NV_INLINE NvFlags<enumtype, storagetype>& operator&=(const NvFlags<enumtype, storagetype>& f);
+ NV_INLINE NvFlags<enumtype, storagetype> operator&(enumtype e) const;
+ NV_INLINE NvFlags<enumtype, storagetype> operator&(const NvFlags<enumtype, storagetype>& f) const;
+
+ NV_INLINE NvFlags<enumtype, storagetype>& operator^=(enumtype e);
+ NV_INLINE NvFlags<enumtype, storagetype>& operator^=(const NvFlags<enumtype, storagetype>& f);
+ NV_INLINE NvFlags<enumtype, storagetype> operator^(enumtype e) const;
+ NV_INLINE NvFlags<enumtype, storagetype> operator^(const NvFlags<enumtype, storagetype>& f) const;
+
+ NV_INLINE NvFlags<enumtype, storagetype> operator~(void) const;
+
+ NV_INLINE operator bool(void) const;
+ NV_INLINE operator uint8_t(void) const;
+ NV_INLINE operator uint16_t(void) const;
+ NV_INLINE operator uint32_t(void) const;
+
+ NV_INLINE void clear(enumtype e);
+
+ public:
+ friend NV_INLINE NvFlags<enumtype, storagetype> operator&(enumtype a, NvFlags<enumtype, storagetype>& b)
+ {
+ NvFlags<enumtype, storagetype> out;
+ out.mBits = a & b.mBits;
+ return out;
+ }
+
+ private:
+ storagetype mBits;
+};
+
+#define NV_FLAGS_OPERATORS(enumtype, storagetype) \
+ NV_INLINE NvFlags<enumtype, storagetype> operator|(enumtype a, enumtype b) \
+ { \
+ NvFlags<enumtype, storagetype> r(a); \
+ r |= b; \
+ return r; \
+ } \
+ NV_INLINE NvFlags<enumtype, storagetype> operator&(enumtype a, enumtype b) \
+ { \
+ NvFlags<enumtype, storagetype> r(a); \
+ r &= b; \
+ return r; \
+ } \
+ NV_INLINE NvFlags<enumtype, storagetype> operator~(enumtype a) \
+ { \
+ return ~NvFlags<enumtype, storagetype>(a); \
+ }
+
+#define NV_FLAGS_TYPEDEF(x, y) \
+ typedef NvFlags<x::Enum, y> x##s; \
+ NV_FLAGS_OPERATORS(x::Enum, y)
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>::NvFlags(void)
+{
+ mBits = 0;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>::NvFlags(enumtype e)
+{
+ mBits = static_cast<storagetype>(e);
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>::NvFlags(const NvFlags<enumtype, storagetype>& f)
+{
+ mBits = f.mBits;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>::NvFlags(storagetype b)
+{
+ mBits = b;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE bool NvFlags<enumtype, storagetype>::isSet(enumtype e) const
+{
+ return (mBits & static_cast<storagetype>(e)) == static_cast<storagetype>(e);
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>& NvFlags<enumtype, storagetype>::set(enumtype e)
+{
+ mBits = static_cast<storagetype>(e);
+ return *this;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE bool NvFlags<enumtype, storagetype>::operator==(enumtype e) const
+{
+ return mBits == static_cast<storagetype>(e);
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE bool NvFlags<enumtype, storagetype>::operator==(const NvFlags<enumtype, storagetype>& f) const
+{
+ return mBits == f.mBits;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE bool NvFlags<enumtype, storagetype>::operator==(bool b) const
+{
+ return bool(*this) == b;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE bool NvFlags<enumtype, storagetype>::operator!=(enumtype e) const
+{
+ return mBits != static_cast<storagetype>(e);
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE bool NvFlags<enumtype, storagetype>::operator!=(const NvFlags<enumtype, storagetype>& f) const
+{
+ return mBits != f.mBits;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>& NvFlags<enumtype, storagetype>::operator=(enumtype e)
+{
+ mBits = static_cast<storagetype>(e);
+ return *this;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>& NvFlags<enumtype, storagetype>::operator=(const NvFlags<enumtype, storagetype>& f)
+{
+ mBits = f.mBits;
+ return *this;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>& NvFlags<enumtype, storagetype>::operator|=(enumtype e)
+{
+ mBits |= static_cast<storagetype>(e);
+ return *this;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>& NvFlags<enumtype, storagetype>::
+operator|=(const NvFlags<enumtype, storagetype>& f)
+{
+ mBits |= f.mBits;
+ return *this;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype> NvFlags<enumtype, storagetype>::operator|(enumtype e) const
+{
+ NvFlags<enumtype, storagetype> out(*this);
+ out |= e;
+ return out;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype> NvFlags<enumtype, storagetype>::
+operator|(const NvFlags<enumtype, storagetype>& f) const
+{
+ NvFlags<enumtype, storagetype> out(*this);
+ out |= f;
+ return out;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>& NvFlags<enumtype, storagetype>::operator&=(enumtype e)
+{
+ mBits &= static_cast<storagetype>(e);
+ return *this;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>& NvFlags<enumtype, storagetype>::
+operator&=(const NvFlags<enumtype, storagetype>& f)
+{
+ mBits &= f.mBits;
+ return *this;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype> NvFlags<enumtype, storagetype>::operator&(enumtype e) const
+{
+ NvFlags<enumtype, storagetype> out = *this;
+ out.mBits &= static_cast<storagetype>(e);
+ return out;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype> NvFlags<enumtype, storagetype>::
+operator&(const NvFlags<enumtype, storagetype>& f) const
+{
+ NvFlags<enumtype, storagetype> out = *this;
+ out.mBits &= f.mBits;
+ return out;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>& NvFlags<enumtype, storagetype>::operator^=(enumtype e)
+{
+ mBits ^= static_cast<storagetype>(e);
+ return *this;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>& NvFlags<enumtype, storagetype>::
+operator^=(const NvFlags<enumtype, storagetype>& f)
+{
+ mBits ^= f.mBits;
+ return *this;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype> NvFlags<enumtype, storagetype>::operator^(enumtype e) const
+{
+ NvFlags<enumtype, storagetype> out = *this;
+ out.mBits ^= static_cast<storagetype>(e);
+ return out;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype> NvFlags<enumtype, storagetype>::
+operator^(const NvFlags<enumtype, storagetype>& f) const
+{
+ NvFlags<enumtype, storagetype> out = *this;
+ out.mBits ^= f.mBits;
+ return out;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype> NvFlags<enumtype, storagetype>::operator~(void) const
+{
+ NvFlags<enumtype, storagetype> out;
+ out.mBits = storagetype(~mBits);
+ return out;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>::operator bool(void) const
+{
+ return mBits ? true : false;
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>::operator uint8_t(void) const
+{
+ return static_cast<uint8_t>(mBits);
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>::operator uint16_t(void) const
+{
+ return static_cast<uint16_t>(mBits);
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE NvFlags<enumtype, storagetype>::operator uint32_t(void) const
+{
+ return static_cast<uint32_t>(mBits);
+}
+
+template <typename enumtype, typename storagetype>
+NV_INLINE void NvFlags<enumtype, storagetype>::clear(enumtype e)
+{
+ mBits &= ~static_cast<storagetype>(e);
+}
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVFLAGS_H
diff --git a/external/NvFoundation/1.1/include/NvFoundationInterface.h b/external/NvFoundation/1.1/include/NvFoundationInterface.h
new file mode 100644
index 0000000..40678fb
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvFoundationInterface.h
@@ -0,0 +1,37 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2013 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_FOUNDATION_INTERFACE_H
+#define NV_FOUNDATION_INTERFACE_H
+
+#include "NvErrorCallback.h"
+#include "NvAllocatorCallback.h"
+#include "NvAssert.h"
+
+#endif // NV_FOUNDATION_INTERFACE_H
diff --git a/external/NvFoundation/1.1/include/NvFoundationMath.h b/external/NvFoundation/1.1/include/NvFoundationMath.h
new file mode 100644
index 0000000..04c83f6
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvFoundationMath.h
@@ -0,0 +1,42 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2013 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_FOUNDATION_MATH_H
+#define NV_FOUNDATION_MATH_H
+
+#include "NvVec2.h"
+#include "NvVec3.h"
+#include "NvVec4.h"
+#include "NvMat33.h"
+#include "NvMat44.h"
+#include "NvTransform.h"
+#include "NvQuat.h"
+#include "NvBounds3.h"
+
+#endif // NV_FOUNDATION_H
diff --git a/external/NvFoundation/1.1/include/NvIO.h b/external/NvFoundation/1.1/include/NvIO.h
new file mode 100644
index 0000000..51796fd
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvIO.h
@@ -0,0 +1,138 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVIO_H
+#define NV_NVFOUNDATION_NVIO_H
+
+/** \addtogroup common
+ @{
+*/
+
+#include "NvSimpleTypes.h"
+
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+
+/**
+\brief Input stream class for I/O.
+
+The user needs to supply a NvInputStream implementation to a number of methods to allow the SDK to read data.
+*/
+
+class NvInputStream
+{
+ public:
+ /**
+ \brief read from the stream. The number of bytes read may be less than the number requested.
+
+ \param[in] dest the destination address to which the data will be read
+ \param[in] count the number of bytes requested
+
+ \return the number of bytes read from the stream.
+ */
+
+ virtual uint32_t read(void* dest, uint32_t count) = 0;
+
+ virtual ~NvInputStream()
+ {
+ }
+};
+
+/**
+\brief Input data class for I/O which provides random read access.
+
+The user needs to supply a NvInputData implementation to a number of methods to allow the SDK to read data.
+*/
+
+class NvInputData : public NvInputStream
+{
+ public:
+ /**
+ \brief return the length of the input data
+
+ \return size in bytes of the input data
+ */
+
+ virtual uint32_t getLength() const = 0;
+
+ /**
+ \brief seek to the given offset from the start of the data.
+
+ \param[in] offset the offset to seek to. If greater than the length of the data, this call is equivalent to
+ seek(length);
+ */
+
+ virtual void seek(uint32_t offset) = 0;
+
+ /**
+ \brief return the current offset from the start of the data
+
+ \return the offset to seek to.
+ */
+
+ virtual uint32_t tell() const = 0;
+
+ virtual ~NvInputData()
+ {
+ }
+};
+
+/**
+\brief Output stream class for I/O.
+
+The user needs to supply a NvOutputStream implementation to a number of methods to allow the SDK to write data.
+*/
+
+class NvOutputStream
+{
+ public:
+ /**
+ \brief write to the stream. The number of bytes written may be less than the number sent.
+
+ \param[in] src the destination address from which the data will be written
+ \param[in] count the number of bytes to be written
+
+ \return the number of bytes written to the stream by this call.
+ */
+
+ virtual uint32_t write(const void* src, uint32_t count) = 0;
+
+ virtual ~NvOutputStream()
+ {
+ }
+};
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVIO_H
diff --git a/external/NvFoundation/1.1/include/NvIntrinsics.h b/external/NvFoundation/1.1/include/NvIntrinsics.h
new file mode 100644
index 0000000..b093224
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvIntrinsics.h
@@ -0,0 +1,53 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVINTRINSICS_H
+#define NV_NVFOUNDATION_NVINTRINSICS_H
+
+#include "NvPreprocessor.h"
+
+#if NV_WINDOWS_FAMILY
+#include "windows/NvWindowsIntrinsics.h"
+#elif NV_X360
+#include "xbox360/NvXbox360Intrinsics.h"
+#elif(NV_LINUX || NV_ANDROID || NV_APPLE_FAMILY || NV_PS4)
+#include "unix/NvUnixIntrinsics.h"
+#elif NV_PS3
+#include "ps3/NvPS3Intrinsics.h"
+#elif NV_PSP2
+#include "psp2/NvPSP2Intrinsics.h"
+#elif NV_WIIU
+#include "wiiu/NvWiiUIntrinsics.h"
+#elif NV_XBOXONE
+#include "XboxOne/NvXboxOneIntrinsics.h"
+#else
+#error "Platform not supported!"
+#endif
+
+#endif // #ifndef NV_NVFOUNDATION_NVINTRINSICS_H
diff --git a/external/NvFoundation/1.1/include/NvMat33.h b/external/NvFoundation/1.1/include/NvMat33.h
new file mode 100644
index 0000000..b0a43fd
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvMat33.h
@@ -0,0 +1,392 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVMAT33_H
+#define NV_NVFOUNDATION_NVMAT33_H
+/** \addtogroup foundation
+@{
+*/
+
+#include "NvVec3.h"
+#include "NvQuat.h"
+
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+/*!
+\brief 3x3 matrix class
+
+Some clarifications, as there have been much confusion about matrix formats etc in the past.
+
+Short:
+- Matrix have base vectors in columns (vectors are column matrices, 3x1 matrices).
+- Matrix is physically stored in column major format
+- Matrices are concaternated from left
+
+Long:
+Given three base vectors a, b and c the matrix is stored as
+
+|a.x b.x c.x|
+|a.y b.y c.y|
+|a.z b.z c.z|
+
+Vectors are treated as columns, so the vector v is
+
+|x|
+|y|
+|z|
+
+And matrices are applied _before_ the vector (pre-multiplication)
+v' = M*v
+
+|x'| |a.x b.x c.x| |x| |a.x*x + b.x*y + c.x*z|
+|y'| = |a.y b.y c.y| * |y| = |a.y*x + b.y*y + c.y*z|
+|z'| |a.z b.z c.z| |z| |a.z*x + b.z*y + c.z*z|
+
+
+Physical storage and indexing:
+To be compatible with popular 3d rendering APIs (read D3d and OpenGL)
+the physical indexing is
+
+|0 3 6|
+|1 4 7|
+|2 5 8|
+
+index = column*3 + row
+
+which in C++ translates to M[column][row]
+
+The mathematical indexing is M_row,column and this is what is used for _-notation
+so _12 is 1st row, second column and operator(row, column)!
+
+*/
+class NvMat33
+{
+ public:
+ //! Default constructor
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvMat33()
+ {
+ }
+
+ //! identity constructor
+ NV_CUDA_CALLABLE NV_INLINE NvMat33(NvIDENTITY r)
+ : column0(1.0f, 0.0f, 0.0f), column1(0.0f, 1.0f, 0.0f), column2(0.0f, 0.0f, 1.0f)
+ {
+ NV_UNUSED(r);
+ }
+
+ //! zero constructor
+ NV_CUDA_CALLABLE NV_INLINE NvMat33(NvZERO r) : column0(0.0f), column1(0.0f), column2(0.0f)
+ {
+ NV_UNUSED(r);
+ }
+
+ //! Construct from three base vectors
+ NV_CUDA_CALLABLE NvMat33(const NvVec3& col0, const NvVec3& col1, const NvVec3& col2)
+ : column0(col0), column1(col1), column2(col2)
+ {
+ }
+
+ //! constructor from a scalar, which generates a multiple of the identity matrix
+ explicit NV_CUDA_CALLABLE NV_INLINE NvMat33(float r)
+ : column0(r, 0.0f, 0.0f), column1(0.0f, r, 0.0f), column2(0.0f, 0.0f, r)
+ {
+ }
+
+ //! Construct from float[9]
+ explicit NV_CUDA_CALLABLE NV_INLINE NvMat33(float values[])
+ : column0(values[0], values[1], values[2])
+ , column1(values[3], values[4], values[5])
+ , column2(values[6], values[7], values[8])
+ {
+ }
+
+ //! Construct from a quaternion
+ explicit NV_CUDA_CALLABLE NV_FORCE_INLINE NvMat33(const NvQuat& q)
+ {
+ const float x = q.x;
+ const float y = q.y;
+ const float z = q.z;
+ const float w = q.w;
+
+ const float x2 = x + x;
+ const float y2 = y + y;
+ const float z2 = z + z;
+
+ const float xx = x2 * x;
+ const float yy = y2 * y;
+ const float zz = z2 * z;
+
+ const float xy = x2 * y;
+ const float xz = x2 * z;
+ const float xw = x2 * w;
+
+ const float yz = y2 * z;
+ const float yw = y2 * w;
+ const float zw = z2 * w;
+
+ column0 = NvVec3(1.0f - yy - zz, xy + zw, xz - yw);
+ column1 = NvVec3(xy - zw, 1.0f - xx - zz, yz + xw);
+ column2 = NvVec3(xz + yw, yz - xw, 1.0f - xx - yy);
+ }
+
+ //! Copy constructor
+ NV_CUDA_CALLABLE NV_INLINE NvMat33(const NvMat33& other)
+ : column0(other.column0), column1(other.column1), column2(other.column2)
+ {
+ }
+
+ //! Assignment operator
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvMat33& operator=(const NvMat33& other)
+ {
+ column0 = other.column0;
+ column1 = other.column1;
+ column2 = other.column2;
+ return *this;
+ }
+
+ //! Construct from diagonal, off-diagonals are zero.
+ NV_CUDA_CALLABLE NV_INLINE static NvMat33 createDiagonal(const NvVec3& d)
+ {
+ return NvMat33(NvVec3(d.x, 0.0f, 0.0f), NvVec3(0.0f, d.y, 0.0f), NvVec3(0.0f, 0.0f, d.z));
+ }
+
+ /**
+ \brief returns true if the two matrices are exactly equal
+ */
+ NV_CUDA_CALLABLE NV_INLINE bool operator==(const NvMat33& m) const
+ {
+ return column0 == m.column0 && column1 == m.column1 && column2 == m.column2;
+ }
+
+ //! Get transposed matrix
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvMat33 getTranspose() const
+ {
+ const NvVec3 v0(column0.x, column1.x, column2.x);
+ const NvVec3 v1(column0.y, column1.y, column2.y);
+ const NvVec3 v2(column0.z, column1.z, column2.z);
+
+ return NvMat33(v0, v1, v2);
+ }
+
+ //! Get the real inverse
+ NV_CUDA_CALLABLE NV_INLINE NvMat33 getInverse() const
+ {
+ const float det = getDeterminant();
+ NvMat33 inverse;
+
+ if(det != 0)
+ {
+ const float invDet = 1.0f / det;
+
+ inverse.column0.x = invDet * (column1.y * column2.z - column2.y * column1.z);
+ inverse.column0.y = invDet * -(column0.y * column2.z - column2.y * column0.z);
+ inverse.column0.z = invDet * (column0.y * column1.z - column0.z * column1.y);
+
+ inverse.column1.x = invDet * -(column1.x * column2.z - column1.z * column2.x);
+ inverse.column1.y = invDet * (column0.x * column2.z - column0.z * column2.x);
+ inverse.column1.z = invDet * -(column0.x * column1.z - column0.z * column1.x);
+
+ inverse.column2.x = invDet * (column1.x * column2.y - column1.y * column2.x);
+ inverse.column2.y = invDet * -(column0.x * column2.y - column0.y * column2.x);
+ inverse.column2.z = invDet * (column0.x * column1.y - column1.x * column0.y);
+
+ return inverse;
+ }
+ else
+ {
+ return NvMat33(NvIdentity);
+ }
+ }
+
+ //! Get determinant
+ NV_CUDA_CALLABLE NV_INLINE float getDeterminant() const
+ {
+ return column0.dot(column1.cross(column2));
+ }
+
+ //! Unary minus
+ NV_CUDA_CALLABLE NV_INLINE NvMat33 operator-() const
+ {
+ return NvMat33(-column0, -column1, -column2);
+ }
+
+ //! Add
+ NV_CUDA_CALLABLE NV_INLINE NvMat33 operator+(const NvMat33& other) const
+ {
+ return NvMat33(column0 + other.column0, column1 + other.column1, column2 + other.column2);
+ }
+
+ //! Subtract
+ NV_CUDA_CALLABLE NV_INLINE NvMat33 operator-(const NvMat33& other) const
+ {
+ return NvMat33(column0 - other.column0, column1 - other.column1, column2 - other.column2);
+ }
+
+ //! Scalar multiplication
+ NV_CUDA_CALLABLE NV_INLINE NvMat33 operator*(float scalar) const
+ {
+ return NvMat33(column0 * scalar, column1 * scalar, column2 * scalar);
+ }
+
+ friend NvMat33 operator*(float, const NvMat33&);
+
+ //! Matrix vector multiplication (returns 'this->transform(vec)')
+ NV_CUDA_CALLABLE NV_INLINE NvVec3 operator*(const NvVec3& vec) const
+ {
+ return transform(vec);
+ }
+
+ // a <op>= b operators
+
+ //! Matrix multiplication
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvMat33 operator*(const NvMat33& other) const
+ {
+ // Rows from this <dot> columns from other
+ // column0 = transform(other.column0) etc
+ return NvMat33(transform(other.column0), transform(other.column1), transform(other.column2));
+ }
+
+ //! Equals-add
+ NV_CUDA_CALLABLE NV_INLINE NvMat33& operator+=(const NvMat33& other)
+ {
+ column0 += other.column0;
+ column1 += other.column1;
+ column2 += other.column2;
+ return *this;
+ }
+
+ //! Equals-sub
+ NV_CUDA_CALLABLE NV_INLINE NvMat33& operator-=(const NvMat33& other)
+ {
+ column0 -= other.column0;
+ column1 -= other.column1;
+ column2 -= other.column2;
+ return *this;
+ }
+
+ //! Equals scalar multiplication
+ NV_CUDA_CALLABLE NV_INLINE NvMat33& operator*=(float scalar)
+ {
+ column0 *= scalar;
+ column1 *= scalar;
+ column2 *= scalar;
+ return *this;
+ }
+
+ //! Equals matrix multiplication
+ NV_CUDA_CALLABLE NV_INLINE NvMat33& operator*=(const NvMat33& other)
+ {
+ *this = *this * other;
+ return *this;
+ }
+
+ //! Element access, mathematical way!
+ NV_DEPRECATED NV_CUDA_CALLABLE NV_FORCE_INLINE float operator()(unsigned int row, unsigned int col) const
+ {
+ return (*this)[col][row];
+ }
+
+ //! Element access, mathematical way!
+ NV_DEPRECATED NV_CUDA_CALLABLE NV_FORCE_INLINE float& operator()(unsigned int row, unsigned int col)
+ {
+ return (*this)[col][row];
+ }
+
+ // Transform etc
+
+ //! Transform vector by matrix, equal to v' = M*v
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 transform(const NvVec3& other) const
+ {
+ return column0 * other.x + column1 * other.y + column2 * other.z;
+ }
+
+ //! Transform vector by matrix transpose, v' = M^t*v
+ NV_CUDA_CALLABLE NV_INLINE NvVec3 transformTranspose(const NvVec3& other) const
+ {
+ return NvVec3(column0.dot(other), column1.dot(other), column2.dot(other));
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE const float* front() const
+ {
+ return &column0.x;
+ }
+
+ NV_DEPRECATED NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3& operator[](unsigned int num)
+ {
+ return (&column0)[num];
+ }
+ NV_DEPRECATED NV_CUDA_CALLABLE NV_FORCE_INLINE const NvVec3& operator[](unsigned int num) const
+ {
+ return (&column0)[num];
+ }
+
+ // Data, see above for format!
+
+ NvVec3 column0, column1, column2; // the three base vectors
+};
+
+// implementation from NvQuat.h
+NV_CUDA_CALLABLE NV_INLINE NvQuat::NvQuat(const NvMat33& m)
+{
+ if (m.column2.z < 0)
+ {
+ if (m.column0.x > m.column1.y)
+ {
+ float t = 1 + m.column0.x - m.column1.y - m.column2.z;
+ *this = NvQuat(t, m.column0.y + m.column1.x, m.column2.x + m.column0.z, m.column1.z - m.column2.y) * (0.5f / NvSqrt(t));
+ }
+ else
+ {
+ float t = 1 - m.column0.x + m.column1.y - m.column2.z;
+ *this = NvQuat(m.column0.y + m.column1.x, t, m.column1.z + m.column2.y, m.column2.x - m.column0.z) * (0.5f / NvSqrt(t));
+ }
+ }
+ else
+ {
+ if (m.column0.x < -m.column1.y)
+ {
+ float t = 1 - m.column0.x - m.column1.y + m.column2.z;
+ *this = NvQuat(m.column2.x + m.column0.z, m.column1.z + m.column2.y, t, m.column0.y - m.column1.x) * (0.5f / NvSqrt(t));
+ }
+ else
+ {
+ float t = 1 + m.column0.x + m.column1.y + m.column2.z;
+ *this = NvQuat(m.column1.z - m.column2.y, m.column2.x - m.column0.z, m.column0.y - m.column1.x, t) * (0.5f / NvSqrt(t));
+ }
+ }
+}
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVMAT33_H
diff --git a/external/NvFoundation/1.1/include/NvMat44.h b/external/NvFoundation/1.1/include/NvMat44.h
new file mode 100644
index 0000000..3519d95
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvMat44.h
@@ -0,0 +1,376 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVMAT44_H
+#define NV_NVFOUNDATION_NVMAT44_H
+/** \addtogroup foundation
+@{
+*/
+
+#include "NvQuat.h"
+#include "NvVec4.h"
+#include "NvMat33.h"
+#include "NvTransform.h"
+
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+
+/*!
+\brief 4x4 matrix class
+
+This class is layout-compatible with D3D and OpenGL matrices. More notes on layout are given in the NvMat33
+
+@see NvMat33 NvTransform
+*/
+
+class NvMat44
+{
+ public:
+ //! Default constructor
+ NV_CUDA_CALLABLE NV_INLINE NvMat44()
+ {
+ }
+
+ //! identity constructor
+ NV_CUDA_CALLABLE NV_INLINE NvMat44(NvIDENTITY r)
+ : column0(1.0f, 0.0f, 0.0f, 0.0f)
+ , column1(0.0f, 1.0f, 0.0f, 0.0f)
+ , column2(0.0f, 0.0f, 1.0f, 0.0f)
+ , column3(0.0f, 0.0f, 0.0f, 1.0f)
+ {
+ NV_UNUSED(r);
+ }
+
+ //! zero constructor
+ NV_CUDA_CALLABLE NV_INLINE NvMat44(NvZERO r) : column0(NvZero), column1(NvZero), column2(NvZero), column3(NvZero)
+ {
+ NV_UNUSED(r);
+ }
+
+ //! Construct from four 4-vectors
+ NV_CUDA_CALLABLE NvMat44(const NvVec4& col0, const NvVec4& col1, const NvVec4& col2, const NvVec4& col3)
+ : column0(col0), column1(col1), column2(col2), column3(col3)
+ {
+ }
+
+ //! constructor that generates a multiple of the identity matrix
+ explicit NV_CUDA_CALLABLE NV_INLINE NvMat44(float r)
+ : column0(r, 0.0f, 0.0f, 0.0f)
+ , column1(0.0f, r, 0.0f, 0.0f)
+ , column2(0.0f, 0.0f, r, 0.0f)
+ , column3(0.0f, 0.0f, 0.0f, r)
+ {
+ }
+
+ //! Construct from three base vectors and a translation
+ NV_CUDA_CALLABLE NvMat44(const NvVec3& col0, const NvVec3& col1, const NvVec3& col2, const NvVec3& col3)
+ : column0(col0, 0), column1(col1, 0), column2(col2, 0), column3(col3, 1.0f)
+ {
+ }
+
+ //! Construct from float[16]
+ explicit NV_CUDA_CALLABLE NV_INLINE NvMat44(float values[])
+ : column0(values[0], values[1], values[2], values[3])
+ , column1(values[4], values[5], values[6], values[7])
+ , column2(values[8], values[9], values[10], values[11])
+ , column3(values[12], values[13], values[14], values[15])
+ {
+ }
+
+ //! Construct from a quaternion
+ explicit NV_CUDA_CALLABLE NV_INLINE NvMat44(const NvQuat& q)
+ {
+ const float x = q.x;
+ const float y = q.y;
+ const float z = q.z;
+ const float w = q.w;
+
+ const float x2 = x + x;
+ const float y2 = y + y;
+ const float z2 = z + z;
+
+ const float xx = x2 * x;
+ const float yy = y2 * y;
+ const float zz = z2 * z;
+
+ const float xy = x2 * y;
+ const float xz = x2 * z;
+ const float xw = x2 * w;
+
+ const float yz = y2 * z;
+ const float yw = y2 * w;
+ const float zw = z2 * w;
+
+ column0 = NvVec4(1.0f - yy - zz, xy + zw, xz - yw, 0.0f);
+ column1 = NvVec4(xy - zw, 1.0f - xx - zz, yz + xw, 0.0f);
+ column2 = NvVec4(xz + yw, yz - xw, 1.0f - xx - yy, 0.0f);
+ column3 = NvVec4(0.0f, 0.0f, 0.0f, 1.0f);
+ }
+
+ //! Construct from a diagonal vector
+ explicit NV_CUDA_CALLABLE NV_INLINE NvMat44(const NvVec4& diagonal)
+ : column0(diagonal.x, 0.0f, 0.0f, 0.0f)
+ , column1(0.0f, diagonal.y, 0.0f, 0.0f)
+ , column2(0.0f, 0.0f, diagonal.z, 0.0f)
+ , column3(0.0f, 0.0f, 0.0f, diagonal.w)
+ {
+ }
+
+ //! Construct from Mat33 and a translation
+ NV_CUDA_CALLABLE NvMat44(const NvMat33& axes, const NvVec3& position)
+ : column0(axes.column0, 0.0f), column1(axes.column1, 0.0f), column2(axes.column2, 0.0f), column3(position, 1.0f)
+ {
+ }
+
+ NV_CUDA_CALLABLE NvMat44(const NvTransform& t)
+ {
+ *this = NvMat44(NvMat33(t.q), t.p);
+ }
+
+ /**
+ \brief returns true if the two matrices are exactly equal
+ */
+ NV_CUDA_CALLABLE NV_INLINE bool operator==(const NvMat44& m) const
+ {
+ return column0 == m.column0 && column1 == m.column1 && column2 == m.column2 && column3 == m.column3;
+ }
+
+ //! Copy constructor
+ NV_CUDA_CALLABLE NV_INLINE NvMat44(const NvMat44& other)
+ : column0(other.column0), column1(other.column1), column2(other.column2), column3(other.column3)
+ {
+ }
+
+ //! Assignment operator
+ NV_CUDA_CALLABLE NV_INLINE const NvMat44& operator=(const NvMat44& other)
+ {
+ column0 = other.column0;
+ column1 = other.column1;
+ column2 = other.column2;
+ column3 = other.column3;
+ return *this;
+ }
+
+ //! Get transposed matrix
+ NV_CUDA_CALLABLE NV_INLINE NvMat44 getTranspose() const
+ {
+ return NvMat44(
+ NvVec4(column0.x, column1.x, column2.x, column3.x), NvVec4(column0.y, column1.y, column2.y, column3.y),
+ NvVec4(column0.z, column1.z, column2.z, column3.z), NvVec4(column0.w, column1.w, column2.w, column3.w));
+ }
+
+ //! Unary minus
+ NV_CUDA_CALLABLE NV_INLINE NvMat44 operator-() const
+ {
+ return NvMat44(-column0, -column1, -column2, -column3);
+ }
+
+ //! Add
+ NV_CUDA_CALLABLE NV_INLINE NvMat44 operator+(const NvMat44& other) const
+ {
+ return NvMat44(column0 + other.column0, column1 + other.column1, column2 + other.column2,
+ column3 + other.column3);
+ }
+
+ //! Subtract
+ NV_CUDA_CALLABLE NV_INLINE NvMat44 operator-(const NvMat44& other) const
+ {
+ return NvMat44(column0 - other.column0, column1 - other.column1, column2 - other.column2,
+ column3 - other.column3);
+ }
+
+ //! Scalar multiplication
+ NV_CUDA_CALLABLE NV_INLINE NvMat44 operator*(float scalar) const
+ {
+ return NvMat44(column0 * scalar, column1 * scalar, column2 * scalar, column3 * scalar);
+ }
+
+ friend NvMat44 operator*(float, const NvMat44&);
+
+ //! Matrix multiplication
+ NV_CUDA_CALLABLE NV_INLINE NvMat44 operator*(const NvMat44& other) const
+ {
+ // Rows from this <dot> columns from other
+ // column0 = transform(other.column0) etc
+ return NvMat44(transform(other.column0), transform(other.column1), transform(other.column2),
+ transform(other.column3));
+ }
+
+ // a <op>= b operators
+
+ //! Equals-add
+ NV_CUDA_CALLABLE NV_INLINE NvMat44& operator+=(const NvMat44& other)
+ {
+ column0 += other.column0;
+ column1 += other.column1;
+ column2 += other.column2;
+ column3 += other.column3;
+ return *this;
+ }
+
+ //! Equals-sub
+ NV_CUDA_CALLABLE NV_INLINE NvMat44& operator-=(const NvMat44& other)
+ {
+ column0 -= other.column0;
+ column1 -= other.column1;
+ column2 -= other.column2;
+ column3 -= other.column3;
+ return *this;
+ }
+
+ //! Equals scalar multiplication
+ NV_CUDA_CALLABLE NV_INLINE NvMat44& operator*=(float scalar)
+ {
+ column0 *= scalar;
+ column1 *= scalar;
+ column2 *= scalar;
+ column3 *= scalar;
+ return *this;
+ }
+
+ //! Equals matrix multiplication
+ NV_CUDA_CALLABLE NV_INLINE NvMat44& operator*=(const NvMat44& other)
+ {
+ *this = *this * other;
+ return *this;
+ }
+
+ //! Element access, mathematical way!
+ NV_DEPRECATED NV_CUDA_CALLABLE NV_FORCE_INLINE float operator()(unsigned int row, unsigned int col) const
+ {
+ return (*this)[col][row];
+ }
+
+ //! Element access, mathematical way!
+ NV_DEPRECATED NV_CUDA_CALLABLE NV_FORCE_INLINE float& operator()(unsigned int row, unsigned int col)
+ {
+ return (*this)[col][row];
+ }
+
+ //! Transform vector by matrix, equal to v' = M*v
+ NV_CUDA_CALLABLE NV_INLINE NvVec4 transform(const NvVec4& other) const
+ {
+ return column0 * other.x + column1 * other.y + column2 * other.z + column3 * other.w;
+ }
+
+ //! Transform vector by matrix, equal to v' = M*v
+ NV_CUDA_CALLABLE NV_INLINE NvVec3 transform(const NvVec3& other) const
+ {
+ return transform(NvVec4(other, 1.0f)).getXYZ();
+ }
+
+ //! Rotate vector by matrix, equal to v' = M*v
+ NV_CUDA_CALLABLE NV_INLINE const NvVec4 rotate(const NvVec4& other) const
+ {
+ return column0 * other.x + column1 * other.y + column2 * other.z; // + column3*0;
+ }
+
+ //! Rotate vector by matrix, equal to v' = M*v
+ NV_CUDA_CALLABLE NV_INLINE const NvVec3 rotate(const NvVec3& other) const
+ {
+ return rotate(NvVec4(other, 1.0f)).getXYZ();
+ }
+
+ NV_CUDA_CALLABLE NV_INLINE NvVec3 getBasis(int num) const
+ {
+ NV_ASSERT(num >= 0 && num < 3);
+ return (&column0)[num].getXYZ();
+ }
+
+ NV_CUDA_CALLABLE NV_INLINE NvVec3 getPosition() const
+ {
+ return column3.getXYZ();
+ }
+
+ NV_CUDA_CALLABLE NV_INLINE void setPosition(const NvVec3& position)
+ {
+ column3.x = position.x;
+ column3.y = position.y;
+ column3.z = position.z;
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE const float* front() const
+ {
+ return &column0.x;
+ }
+
+ NV_DEPRECATED NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec4& operator[](unsigned int num)
+ {
+ return (&column0)[num];
+ }
+ NV_DEPRECATED NV_CUDA_CALLABLE NV_FORCE_INLINE const NvVec4& operator[](unsigned int num) const
+ {
+ return (&column0)[num];
+ }
+
+ NV_CUDA_CALLABLE NV_INLINE void scale(const NvVec4& p)
+ {
+ column0 *= p.x;
+ column1 *= p.y;
+ column2 *= p.z;
+ column3 *= p.w;
+ }
+
+ NV_CUDA_CALLABLE NV_INLINE NvMat44 inverseRT(void) const
+ {
+ NvVec3 r0(column0.x, column1.x, column2.x), r1(column0.y, column1.y, column2.y),
+ r2(column0.z, column1.z, column2.z);
+
+ return NvMat44(r0, r1, r2, -(r0 * column3.x + r1 * column3.y + r2 * column3.z));
+ }
+
+ NV_CUDA_CALLABLE NV_INLINE bool isFinite() const
+ {
+ return column0.isFinite() && column1.isFinite() && column2.isFinite() && column3.isFinite();
+ }
+
+ // Data, see above for format!
+
+ NvVec4 column0, column1, column2, column3; // the four base vectors
+};
+
+// implementation from NvTransform.h
+NV_CUDA_CALLABLE NV_FORCE_INLINE NvTransform::NvTransform(const NvMat44& m)
+{
+ NvVec3 column0 = NvVec3(m.column0.x, m.column0.y, m.column0.z);
+ NvVec3 column1 = NvVec3(m.column1.x, m.column1.y, m.column1.z);
+ NvVec3 column2 = NvVec3(m.column2.x, m.column2.y, m.column2.z);
+
+ q = NvQuat(NvMat33(column0, column1, column2));
+ p = NvVec3(m.column3.x, m.column3.y, m.column3.z);
+}
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVMAT44_H
diff --git a/external/NvFoundation/1.1/include/NvMath.h b/external/NvFoundation/1.1/include/NvMath.h
new file mode 100644
index 0000000..2dda45a
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvMath.h
@@ -0,0 +1,338 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVMATH_H
+#define NV_NVFOUNDATION_NVMATH_H
+
+/** \addtogroup foundation
+@{
+*/
+
+#include "NvPreprocessor.h"
+
+#if NV_VC
+#pragma warning(push)
+#pragma warning(disable : 4985) // 'symbol name': attributes not present on previous declaration
+#endif
+#include <math.h>
+#if NV_VC
+#pragma warning(pop)
+#endif
+
+#include <float.h>
+#include "NvIntrinsics.h"
+#include "NvAssert.h"
+
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+
+// constants
+static const float NvPi = float(3.141592653589793);
+static const float NvHalfPi = float(1.57079632679489661923);
+static const float NvTwoPi = float(6.28318530717958647692);
+static const float NvInvPi = float(0.31830988618379067154);
+static const float NvInvTwoPi = float(0.15915494309189533577);
+static const float NvPiDivTwo = float(1.57079632679489661923);
+static const float NvPiDivFour = float(0.78539816339744830962);
+
+/**
+\brief The return value is the greater of the two specified values.
+*/
+template <class T>
+NV_CUDA_CALLABLE NV_FORCE_INLINE T NvMax(T a, T b)
+{
+ return a < b ? b : a;
+}
+
+//! overload for float to use fsel on xbox
+template <>
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvMax(float a, float b)
+{
+ return intrinsics::selectMax(a, b);
+}
+
+/**
+\brief The return value is the lesser of the two specified values.
+*/
+template <class T>
+NV_CUDA_CALLABLE NV_FORCE_INLINE T NvMin(T a, T b)
+{
+ return a < b ? a : b;
+}
+
+template <>
+//! overload for float to use fsel on xbox
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvMin(float a, float b)
+{
+ return intrinsics::selectMin(a, b);
+}
+
+/*
+Many of these are just implemented as NV_CUDA_CALLABLE NV_FORCE_INLINE calls to the C lib right now,
+but later we could replace some of them with some approximations or more
+clever stuff.
+*/
+
+/**
+\brief abs returns the absolute value of its argument.
+*/
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvAbs(float a)
+{
+ return intrinsics::abs(a);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE bool NvEquals(float a, float b, float eps)
+{
+ return (NvAbs(a - b) < eps);
+}
+
+/**
+\brief abs returns the absolute value of its argument.
+*/
+NV_CUDA_CALLABLE NV_FORCE_INLINE double NvAbs(double a)
+{
+ return ::fabs(a);
+}
+
+/**
+\brief abs returns the absolute value of its argument.
+*/
+NV_CUDA_CALLABLE NV_FORCE_INLINE int32_t NvAbs(int32_t a)
+{
+ return ::abs(a);
+}
+
+/**
+\brief Clamps v to the range [hi,lo]
+*/
+template <class T>
+NV_CUDA_CALLABLE NV_FORCE_INLINE T NvClamp(T v, T lo, T hi)
+{
+ NV_ASSERT(lo <= hi);
+ return NvMin(hi, NvMax(lo, v));
+}
+
+//! \brief Square root.
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvSqrt(float a)
+{
+ return intrinsics::sqrt(a);
+}
+
+//! \brief Square root.
+NV_CUDA_CALLABLE NV_FORCE_INLINE double NvSqrt(double a)
+{
+ return ::sqrt(a);
+}
+
+//! \brief reciprocal square root.
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvRecipSqrt(float a)
+{
+ return intrinsics::recipSqrt(a);
+}
+
+//! \brief reciprocal square root.
+NV_CUDA_CALLABLE NV_FORCE_INLINE double NvRecipSqrt(double a)
+{
+ return 1 / ::sqrt(a);
+}
+
+//! trigonometry -- all angles are in radians.
+
+//! \brief Sine of an angle ( <b>Unit:</b> Radians )
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvSin(float a)
+{
+ return intrinsics::sin(a);
+}
+
+//! \brief Sine of an angle ( <b>Unit:</b> Radians )
+NV_CUDA_CALLABLE NV_FORCE_INLINE double NvSin(double a)
+{
+ return ::sin(a);
+}
+
+//! \brief Cosine of an angle (<b>Unit:</b> Radians)
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvCos(float a)
+{
+ return intrinsics::cos(a);
+}
+
+//! \brief Cosine of an angle (<b>Unit:</b> Radians)
+NV_CUDA_CALLABLE NV_FORCE_INLINE double NvCos(double a)
+{
+ return ::cos(a);
+}
+
+/**
+\brief Tangent of an angle.
+<b>Unit:</b> Radians
+*/
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvTan(float a)
+{
+ return ::tanf(a);
+}
+
+/**
+\brief Tangent of an angle.
+<b>Unit:</b> Radians
+*/
+NV_CUDA_CALLABLE NV_FORCE_INLINE double NvTan(double a)
+{
+ return ::tan(a);
+}
+
+/**
+\brief Arcsine.
+Returns angle between -PI/2 and PI/2 in radians
+<b>Unit:</b> Radians
+*/
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvAsin(float f)
+{
+ return ::asinf(NvClamp(f, -1.0f, 1.0f));
+}
+
+/**
+\brief Arcsine.
+Returns angle between -PI/2 and PI/2 in radians
+<b>Unit:</b> Radians
+*/
+NV_CUDA_CALLABLE NV_FORCE_INLINE double NvAsin(double f)
+{
+ return ::asin(NvClamp(f, -1.0, 1.0));
+}
+
+/**
+\brief Arccosine.
+Returns angle between 0 and PI in radians
+<b>Unit:</b> Radians
+*/
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvAcos(float f)
+{
+ return ::acosf(NvClamp(f, -1.0f, 1.0f));
+}
+
+/**
+\brief Arccosine.
+Returns angle between 0 and PI in radians
+<b>Unit:</b> Radians
+*/
+NV_CUDA_CALLABLE NV_FORCE_INLINE double NvAcos(double f)
+{
+ return ::acos(NvClamp(f, -1.0, 1.0));
+}
+
+/**
+\brief ArcTangent.
+Returns angle between -PI/2 and PI/2 in radians
+<b>Unit:</b> Radians
+*/
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvAtan(float a)
+{
+ return ::atanf(a);
+}
+
+/**
+\brief ArcTangent.
+Returns angle between -PI/2 and PI/2 in radians
+<b>Unit:</b> Radians
+*/
+NV_CUDA_CALLABLE NV_FORCE_INLINE double NvAtan(double a)
+{
+ return ::atan(a);
+}
+
+/**
+\brief Arctangent of (x/y) with correct sign.
+Returns angle between -PI and PI in radians
+<b>Unit:</b> Radians
+*/
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvAtan2(float x, float y)
+{
+ return ::atan2f(x, y);
+}
+
+/**
+\brief Arctangent of (x/y) with correct sign.
+Returns angle between -PI and PI in radians
+<b>Unit:</b> Radians
+*/
+NV_CUDA_CALLABLE NV_FORCE_INLINE double NvAtan2(double x, double y)
+{
+ return ::atan2(x, y);
+}
+
+//! \brief returns true if the passed number is a finite floating point number as opposed to INF, NAN, etc.
+NV_CUDA_CALLABLE NV_FORCE_INLINE bool NvIsFinite(float f)
+{
+ return intrinsics::isFinite(f);
+}
+
+//! \brief returns true if the passed number is a finite floating point number as opposed to INF, NAN, etc.
+NV_CUDA_CALLABLE NV_FORCE_INLINE bool NvIsFinite(double f)
+{
+ return intrinsics::isFinite(f);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvFloor(float a)
+{
+ return ::floorf(a);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvExp(float a)
+{
+ return ::expf(a);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvCeil(float a)
+{
+ return ::ceilf(a);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvSign(float a)
+{
+ return nvidia::intrinsics::sign(a);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvPow(float x, float y)
+{
+ return ::powf(x, y);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE float NvLog(float x)
+{
+ return ::logf(x);
+}
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVMATH_H
diff --git a/external/NvFoundation/1.1/include/NvPlane.h b/external/NvFoundation/1.1/include/NvPlane.h
new file mode 100644
index 0000000..c61dfa9
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvPlane.h
@@ -0,0 +1,145 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVPLANE_H
+#define NV_NVFOUNDATION_NVPLANE_H
+
+/** \addtogroup foundation
+@{
+*/
+
+#include "NvMath.h"
+#include "NvVec3.h"
+
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+
+/**
+\brief Representation of a plane.
+
+ Plane equation used: n.dot(v) + d = 0
+*/
+class NvPlane
+{
+ public:
+ /**
+ \brief Constructor
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvPlane()
+ {
+ }
+
+ /**
+ \brief Constructor from a normal and a distance
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvPlane(float nx, float ny, float nz, float distance) : n(nx, ny, nz), d(distance)
+ {
+ }
+
+ /**
+ \brief Constructor from a normal and a distance
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvPlane(const NvVec3& normal, float distance) : n(normal), d(distance)
+ {
+ }
+
+ /**
+ \brief Constructor from a point on the plane and a normal
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvPlane(const NvVec3& point, const NvVec3& normal)
+ : n(normal), d(-point.dot(n)) // p satisfies normal.dot(p) + d = 0
+ {
+ }
+
+ /**
+ \brief Constructor from three points
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvPlane(const NvVec3& p0, const NvVec3& p1, const NvVec3& p2)
+ {
+ n = (p1 - p0).cross(p2 - p0).getNormalized();
+ d = -p0.dot(n);
+ }
+
+ /**
+ \brief returns true if the two planes are exactly equal
+ */
+ NV_CUDA_CALLABLE NV_INLINE bool operator==(const NvPlane& p) const
+ {
+ return n == p.n && d == p.d;
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float distance(const NvVec3& p) const
+ {
+ return p.dot(n) + d;
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool contains(const NvVec3& p) const
+ {
+ return NvAbs(distance(p)) < (1.0e-7f);
+ }
+
+ /**
+ \brief projects p into the plane
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 project(const NvVec3& p) const
+ {
+ return p - n * distance(p);
+ }
+
+ /**
+ \brief find an arbitrary point in the plane
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 pointInPlane() const
+ {
+ return -n * d;
+ }
+
+ /**
+ \brief equivalent plane with unit normal
+ */
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE void normalize()
+ {
+ float denom = 1.0f / n.magnitude();
+ n *= denom;
+ d *= denom;
+ }
+
+ NvVec3 n; //!< The normal to the plane
+ float d; //!< The distance from the origin
+};
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVPLANE_H
diff --git a/external/NvFoundation/1.1/include/NvPreprocessor.h b/external/NvFoundation/1.1/include/NvPreprocessor.h
new file mode 100644
index 0000000..8913106
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvPreprocessor.h
@@ -0,0 +1,540 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVPREPROCESSOR_H
+#define NV_NVFOUNDATION_NVPREPROCESSOR_H
+
+#include <stddef.h>
+
+/** \addtogroup foundation
+ @{
+*/
+
+/*
+The following preprocessor identifiers specify compiler, OS, and architecture.
+All definitions have a value of 1 or 0, use '#if' instead of '#ifdef'.
+*/
+
+/**
+Compiler defines, see http://sourceforge.net/p/predef/wiki/Compilers/
+*/
+#if defined(_MSC_VER)
+#if _MSC_VER >= 1900
+#define NV_VC 14
+#elif _MSC_VER >= 1800
+#define NV_VC 12
+#elif _MSC_VER >= 1700
+#define NV_VC 11
+#elif _MSC_VER >= 1600
+#define NV_VC 10
+#elif _MSC_VER >= 1500
+#define NV_VC 9
+#else
+#error "Unknown VC version"
+#endif
+#elif defined(__clang__)
+#define NV_CLANG 1
+#elif defined(__SNC__)
+#define NV_SNC 1
+#elif defined(__ghs__)
+#define NV_GHS 1
+#elif defined(__GNUC__) // note: __clang__, __SNC__, or __ghs__ imply __GNUC__
+#define NV_GCC 1
+#else
+#error "Unknown compiler"
+#endif
+
+/**
+Operating system defines, see http://sourceforge.net/p/predef/wiki/OperatingSystems/
+*/
+#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_PARTITION_APP
+#define NV_WINRT 1 // Windows Runtime, either on Windows RT or Windows 8
+#elif defined(XBOXONE)
+#define NV_XBOXONE 1
+#elif defined(_WIN64) // note: XBOXONE implies _WIN64
+#define NV_WIN64 1
+#elif defined(_M_PPC)
+#define NV_X360 1
+#elif defined(_WIN32) // note: _M_PPC implies _WIN32
+#define NV_WIN32 1
+#elif defined(__ANDROID__)
+#define NV_ANDROID 1
+#elif defined(__linux__) // note: __ANDROID__ implies __linux__
+#define NV_LINUX 1
+#elif defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
+#define NV_IOS 1
+#elif defined(__APPLE__)
+#define NV_OSX 1
+#elif defined(__CELLOS_LV2__)
+#define NV_PS3 1
+#elif defined(__ORBIS__)
+#define NV_PS4 1
+#elif defined(__SNC__) && defined(__arm__)
+#define NV_PSP2 1
+#elif defined(__ghs__)
+#define NV_WIIU 1
+#else
+#error "Unknown operating system"
+#endif
+
+/**
+Architecture defines, see http://sourceforge.net/p/predef/wiki/Architectures/
+*/
+#if defined(__x86_64__) || defined(_M_X64) // ps4 compiler defines _M_X64 without value
+#define NV_X64 1
+#elif defined(__i386__) || defined(_M_IX86)
+#define NV_X86 1
+#elif defined(__arm64__) || defined(__aarch64__)
+#define NV_A64 1
+#elif defined(__arm__) || defined(_M_ARM)
+#define NV_ARM 1
+#elif defined(__SPU__)
+#define NV_SPU 1
+#elif defined(__ppc__) || defined(_M_PPC) || defined(__CELLOS_LV2__)
+#define NV_PPC 1
+#else
+#error "Unknown architecture"
+#endif
+
+/**
+SIMD defines
+*/
+#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
+#define NV_SSE2 1
+#endif
+#if defined(_M_ARM) || defined(__ARM_NEON__)
+#define NV_NEON 1
+#endif
+#if defined(_M_PPC) || defined(__CELLOS_LV2__)
+#define NV_VMX 1
+#endif
+
+/**
+define anything not defined on this platform to 0
+*/
+#ifndef NV_VC
+#define NV_VC 0
+#endif
+#ifndef NV_CLANG
+#define NV_CLANG 0
+#endif
+#ifndef NV_SNC
+#define NV_SNC 0
+#endif
+#ifndef NV_GHS
+#define NV_GHS 0
+#endif
+#ifndef NV_GCC
+#define NV_GCC 0
+#endif
+#ifndef NV_WINRT
+#define NV_WINRT 0
+#endif
+#ifndef NV_XBOXONE
+#define NV_XBOXONE 0
+#endif
+#ifndef NV_WIN64
+#define NV_WIN64 0
+#endif
+#ifndef NV_X360
+#define NV_X360 0
+#endif
+#ifndef NV_WIN32
+#define NV_WIN32 0
+#endif
+#ifndef NV_ANDROID
+#define NV_ANDROID 0
+#endif
+#ifndef NV_LINUX
+#define NV_LINUX 0
+#endif
+#ifndef NV_IOS
+#define NV_IOS 0
+#endif
+#ifndef NV_OSX
+#define NV_OSX 0
+#endif
+#ifndef NV_PS3
+#define NV_PS3 0
+#endif
+#ifndef NV_PS4
+#define NV_PS4 0
+#endif
+#ifndef NV_PSP2
+#define NV_PSP2 0
+#endif
+#ifndef NV_WIIU
+#define NV_WIIU 0
+#endif
+#ifndef NV_X64
+#define NV_X64 0
+#endif
+#ifndef NV_X86
+#define NV_X86 0
+#endif
+#ifndef NV_A64
+#define NV_A64 0
+#endif
+#ifndef NV_ARM
+#define NV_ARM 0
+#endif
+#ifndef NV_SPU
+#define NV_SPU 0
+#endif
+#ifndef NV_PPC
+#define NV_PPC 0
+#endif
+#ifndef NV_SSE2
+#define NV_SSE2 0
+#endif
+#ifndef NV_NEON
+#define NV_NEON 0
+#endif
+#ifndef NV_VMX
+#define NV_VMX 0
+#endif
+
+/*
+define anything not defined through the command line to 0
+*/
+#ifndef NV_DEBUG
+#define NV_DEBUG 0
+#endif
+#ifndef NV_CHECKED
+#define NV_CHECKED 0
+#endif
+#ifndef NV_PROFILE
+#define NV_PROFILE 0
+#endif
+#ifndef NV_NVTX
+#define NV_NVTX 0
+#endif
+#ifndef NV_DOXYGEN
+#define NV_DOXYGEN 0
+#endif
+
+/**
+family shortcuts
+*/
+// compiler
+#define NV_GCC_FAMILY (NV_CLANG || NV_SNC || NV_GHS || NV_GCC)
+// os
+#define NV_WINDOWS_FAMILY (NV_WINRT || NV_WIN32 || NV_WIN64)
+#define NV_MICROSOFT_FAMILY (NV_XBOXONE || NV_X360 || NV_WINDOWS_FAMILY)
+#define NV_LINUX_FAMILY (NV_LINUX || NV_ANDROID)
+#define NV_APPLE_FAMILY (NV_IOS || NV_OSX) // equivalent to #if __APPLE__
+#define NV_UNIX_FAMILY (NV_LINUX_FAMILY || NV_APPLE_FAMILY) // shortcut for unix/posix platforms
+// architecture
+#define NV_INTEL_FAMILY (NV_X64 || NV_X86)
+#define NV_ARM_FAMILY (NV_ARM || NV_A64)
+#define NV_P64_FAMILY (NV_X64 || NV_A64) // shortcut for 64-bit architectures
+
+// shortcut for PS3 PPU
+#define NV_PPU (NV_PS3&& NV_PPC)
+
+/**
+Assert macro
+*/
+#ifndef NV_ENABLE_ASSERTS
+#if NV_DEBUG && !defined(__CUDACC__)
+#define NV_ENABLE_ASSERTS 1
+#else
+#define NV_ENABLE_ASSERTS 0
+#endif
+#endif
+
+/**
+DLL export macros
+*/
+#ifndef NV_C_EXPORT
+#if NV_WINDOWS_FAMILY || NV_LINUX
+#define NV_C_EXPORT extern "C"
+#else
+#define NV_C_EXPORT
+#endif
+#endif
+
+#if NV_UNIX_FAMILY&& __GNUC__ >= 4
+#define NV_UNIX_EXPORT __attribute__((visibility("default")))
+#else
+#define NV_UNIX_EXPORT
+#endif
+
+#if NV_WINDOWS_FAMILY
+#define NV_DLL_EXPORT __declspec(dllexport)
+#define NV_DLL_IMPORT __declspec(dllimport)
+#else
+#define NV_DLL_EXPORT NV_UNIX_EXPORT
+#define NV_DLL_IMPORT
+#endif
+
+/**
+Define API function declaration
+
+NV_FOUNDATION_DLL=1 - used by the DLL library (PhysXCommon) to export the API
+NV_FOUNDATION_DLL=0 - for windows configurations where the NV_FOUNDATION_API is linked through standard static linking
+no definition - this will allow DLLs and libraries to use the exported API from PhysXCommon
+
+*/
+
+#if NV_WINDOWS_FAMILY && !NV_ARM_FAMILY || NV_WINRT
+#ifndef NV_FOUNDATION_DLL
+#define NV_FOUNDATION_API NV_DLL_IMPORT
+#elif NV_FOUNDATION_DLL
+#define NV_FOUNDATION_API NV_DLL_EXPORT
+#endif
+#elif NV_UNIX_FAMILY
+#ifdef NV_FOUNDATION_DLL
+#define NV_FOUNDATION_API NV_UNIX_EXPORT
+#endif
+#endif
+
+#ifndef NV_FOUNDATION_API
+#define NV_FOUNDATION_API
+#endif
+
+/**
+Calling convention
+*/
+#ifndef NV_CALL_CONV
+#if NV_MICROSOFT_FAMILY
+#define NV_CALL_CONV __cdecl
+#else
+#define NV_CALL_CONV
+#endif
+#endif
+
+/**
+Pack macros - disabled on SPU because they are not supported
+*/
+#if NV_VC
+#define NV_PUSH_PACK_DEFAULT __pragma(pack(push, 8))
+#define NV_POP_PACK __pragma(pack(pop))
+#elif NV_GCC_FAMILY && !NV_SPU
+#define NV_PUSH_PACK_DEFAULT _Pragma("pack(push, 8)")
+#define NV_POP_PACK _Pragma("pack(pop)")
+#else
+#define NV_PUSH_PACK_DEFAULT
+#define NV_POP_PACK
+#endif
+
+/**
+Inline macro
+*/
+#define NV_INLINE inline
+#if NV_MICROSOFT_FAMILY
+#pragma inline_depth(255)
+#endif
+
+/**
+Force inline macro
+*/
+#if NV_VC
+#define NV_FORCE_INLINE __forceinline
+#elif NV_LINUX // Workaround; Fedora Core 3 do not agree with force inline and NvcPool
+#define NV_FORCE_INLINE inline
+#elif NV_GCC_FAMILY
+#define NV_FORCE_INLINE inline __attribute__((always_inline))
+#else
+#define NV_FORCE_INLINE inline
+#endif
+
+/**
+Noinline macro
+*/
+#if NV_MICROSOFT_FAMILY
+#define NV_NOINLINE __declspec(noinline)
+#elif NV_GCC_FAMILY
+#define NV_NOINLINE __attribute__((noinline))
+#else
+#define NV_NOINLINE
+#endif
+
+/**
+Restrict macro
+*/
+#if defined(__CUDACC__)
+#define NV_RESTRICT __restrict__
+#else
+#define NV_RESTRICT __restrict
+#endif
+
+/**
+Noalias macro
+*/
+#if NV_MICROSOFT_FAMILY
+#define NV_NOALIAS __declspec(noalias)
+#else
+#define NV_NOALIAS
+#endif
+
+/**
+Alignment macros
+
+NV_ALIGN_PREFIX and NV_ALIGN_SUFFIX can be used for type alignment instead of aligning individual variables as follows:
+NV_ALIGN_PREFIX(16)
+struct A {
+...
+} NV_ALIGN_SUFFIX(16);
+This declaration style is parsed correctly by Visual Assist.
+
+*/
+#ifndef NV_ALIGN
+#if NV_MICROSOFT_FAMILY
+#define NV_ALIGN(alignment, decl) __declspec(align(alignment)) decl
+#define NV_ALIGN_PREFIX(alignment) __declspec(align(alignment))
+#define NV_ALIGN_SUFFIX(alignment)
+#elif NV_GCC_FAMILY
+#define NV_ALIGN(alignment, decl) decl __attribute__((aligned(alignment)))
+#define NV_ALIGN_PREFIX(alignment)
+#define NV_ALIGN_SUFFIX(alignment) __attribute__((aligned(alignment)))
+#else
+#define NV_ALIGN(alignment, decl)
+#define NV_ALIGN_PREFIX(alignment)
+#define NV_ALIGN_SUFFIX(alignment)
+#endif
+#endif
+
+/**
+Deprecated macro
+- To deprecate a function: Place NV_DEPRECATED at the start of the function header (leftmost word).
+- To deprecate a 'typedef', a 'struct' or a 'class': Place NV_DEPRECATED directly after the keywords ('typdef',
+'struct', 'class').
+
+Use these macro definitions to create warnings for deprecated functions
+#define NV_DEPRECATED __declspec(deprecated) // Microsoft
+#define NV_DEPRECATED __attribute__((deprecated())) // GCC
+*/
+#define NV_DEPRECATED
+
+/**
+General defines
+*/
+
+// static assert
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
+#define NV_COMPILE_TIME_ASSERT(exp) typedef char NvCompileTimeAssert_Dummy[(exp) ? 1 : -1] __attribute__((unused))
+#else
+#define NV_COMPILE_TIME_ASSERT(exp) typedef char NvCompileTimeAssert_Dummy[(exp) ? 1 : -1]
+#endif
+
+#if NV_GCC_FAMILY && !NV_SNC && !NV_GHS
+#define NV_OFFSET_OF(X, Y) __builtin_offsetof(X, Y)
+#else
+#define NV_OFFSET_OF(X, Y) offsetof(X, Y)
+#endif
+
+#define NV_OFFSETOF_BASE 0x100 // casting the null ptr takes a special-case code path, which we don't want
+#define NV_OFFSET_OF_RT(Class, Member) \
+ (reinterpret_cast<size_t>(&reinterpret_cast<Class*>(NV_OFFSETOF_BASE)->Member) - size_t(NV_OFFSETOF_BASE))
+
+// check that exactly one of NDEBUG and _DEBUG is defined
+#if !defined(NDEBUG) ^ defined(_DEBUG)
+#error Exactly one of NDEBUG and _DEBUG needs to be defined!
+#endif
+
+// make sure NV_CHECKED is defined in all _DEBUG configurations as well
+#if !defined(NV_CHECKED) && defined(NV_DEBUG)
+#error NV_CHECKED must be defined when NV_DEBUG is defined
+#endif
+
+#ifdef __CUDACC__
+#define NV_CUDA_CALLABLE __host__ __device__
+#else
+#define NV_CUDA_CALLABLE
+#endif
+
+// avoid unreferenced parameter warning
+// preferred solution: omit the parameter's name from the declaration
+template <class T>
+NV_CUDA_CALLABLE NV_INLINE void NV_UNUSED(T const&)
+{
+}
+
+// Ensure that the application hasn't tweaked the pack value to less than 8, which would break
+// matching between the API headers and the binaries
+// This assert works on win32/win64/360/ps3, but may need further specialization on other platforms.
+// Some GCC compilers need the compiler flag -malign-double to be set.
+// Apparently the apple-clang-llvm compiler doesn't support malign-double.
+#if NV_PS4 || NV_APPLE_FAMILY
+struct NvPackValidation
+{
+ char _;
+ long a;
+};
+#elif NV_ANDROID
+struct NvPackValidation
+{
+ char _;
+ double a;
+};
+#else
+struct NvPackValidation
+{
+ char _;
+ long long a;
+};
+#endif
+#if !NV_APPLE_FAMILY
+NV_COMPILE_TIME_ASSERT(NV_OFFSET_OF(NvPackValidation, a) == 8);
+#endif
+
+// use in a cpp file to suppress LNK4221
+#if NV_VC
+#define NV_DUMMY_SYMBOL \
+ namespace \
+ { \
+ char NvDummySymbol; \
+ }
+#else
+#define NV_DUMMY_SYMBOL
+#endif
+
+#if NV_GCC_FAMILY && !NV_GHS
+#define NV_WEAK_SYMBOL __attribute__((weak)) // this is to support SIMD constant merging in template specialization
+#else
+#define NV_WEAK_SYMBOL
+#endif
+
+// Macro for avoiding default assignment and copy, because doing this by inheritance can increase class size on some
+// platforms.
+#define NV_NOCOPY(Class) \
+ \
+protected: \
+ Class(const Class&); \
+ Class& operator=(const Class&);
+
+#define NV_STRINGIZE_HELPER(X) #X
+#define NV_STRINGIZE(X) NV_STRINGIZE_HELPER(X)
+
+#define NV_CONCAT_HELPER(X, Y) X##Y
+#define NV_CONCAT(X, Y) NV_CONCAT_HELPER(X, Y)
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVPREPROCESSOR_H
diff --git a/external/NvFoundation/1.1/include/NvProfiler.h b/external/NvFoundation/1.1/include/NvProfiler.h
new file mode 100644
index 0000000..67a4c81
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvProfiler.h
@@ -0,0 +1,219 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+
+#ifndef NV_PROFILER_H
+#define NV_PROFILER_H
+
+#include <NvSimpleTypes.h>
+
+namespace nvidia
+{
+ class NvProfilerCallback;
+ namespace shdfnd
+ {
+ NV_FOUNDATION_API NvProfilerCallback *getProfilerCallback();
+ NV_FOUNDATION_API void setProfilerCallback(NvProfilerCallback *profiler);
+ }
+}
+
+
+namespace nvidia
+{
+
+struct NvProfileTypes
+{
+ enum Enum
+ {
+ eNORMAL = 0, //!< ordinary profile zone, starts and ends in same thread
+ eSTALL = 1, //!< thread is busy but can't progress (example: spin-lock)
+ eIDLE = 2, //!< thread is idle (example: waiting for event)
+ eDETACHED = 3, //!< zone crosses thread boundary
+ eLOCK = 4, //!< thread tries to acquire a lock, reports result on zoneEnd()
+ eLOCK_SUCCESS = 5, //!< locking mutex succeded, to be passed to zoneEnd()
+ eLOCK_FAILED = 6, //!< locking mutex failed, to be passed to zoneEnd()
+ eLOCK_TIMEOUT = 7 //!< locking mutex timed out, to be passed to zoneEnd()
+ };
+};
+
+struct NvProfileContext
+{
+ enum Enum
+ {
+ eNONE = 0 //!< value for no specific profile context. \see NvProfilerCallback::zoneAt
+ };
+};
+
+
+/**
+\brief The pure virtual callback interface for general purpose instrumentation and profiling of GameWorks modules as well as applications
+*/
+class NvProfilerCallback
+{
+public:
+
+ /**************************************************************************************************************************
+ Instrumented profiling events
+ ***************************************************************************************************************************/
+
+ /**
+ \brief Mark the beginning of a nested profile block
+ \param eventName Event name. Must be a persistent const char *
+ \param type What type this zone is (i.e. normal, cross thread, lock, etc.). eLOCK_* should not be used here.
+ \param contextId the context id of this zone. Zones with the same id belong to the same group. 0 is used for no specific group.
+ \param filename The source code filename where this profile event begins
+ \param lineno The source code line number where this profile event begins
+ */
+ virtual void zoneStart(const char* eventName, NvProfileTypes::Enum type, uint64_t contextId, const char *filename, int lineno) = 0;
+
+ /**
+ \brief Mark the end of a nested profile block
+ \param eventName The name of the zone ending, must match the corresponding name passed with 'zoneStart'. Must be a persistent const char *
+ \param type What type this zone is (i.e. normal, cross thread, lock, etc.). Should match the value passed to zoneStart, except if eLOCK was passed to zoneStart. In this case, type should be one of eLOCK_*.
+ \param contextId The context of this zone. Should match the value passed to zoneStart.
+ \note eventName plus contextId can be used to uniquely match up start and end of a zone.
+ */
+ virtual void zoneEnd(const char *eventName, NvProfileTypes::Enum type, uint64_t contextId) = 0;
+
+ /**************************************************************************************************************************
+ TimeSpan events; profiling events not associated with any specific thread.
+ ***************************************************************************************************************************/
+
+ /**
+ \brief Return current time
+ This function is called to calibrate the start and end times passed to zoneAt().
+ */
+ virtual uint64_t getTime() = 0;
+
+ /**
+ \brief Send a discrete zone of data with manually recorded time stamps
+ \param start The timestamp and the start of the span
+ \param end The timestamp at the end of the span
+ \param name The name of this event. Must be a persistent const char *
+ \param type What type this zone is (i.e. normal, cross thread, lock, etc.). eLOCK or eLOCK_* should not be used here.
+ \param contextId The context id for this event
+ \param filename The source code filename where this zone is being sent from
+ \param linenumber The source code line number where this zone is being sent from
+ */
+ virtual void zoneAt(uint64_t start, uint64_t end, const char* name, NvProfileTypes::Enum type, uint64_t contextId, const char* filename, int linenumber) = 0;
+
+ /**************************************************************************************************************************
+ Bundled CUDA warp profile events
+ ***************************************************************************************************************************/
+
+ /**
+ \brief Bundled profiling data relating to CUDA warps
+ */
+ struct WarpProfileEvent
+ {
+ uint16_t block;
+ uint8_t warp;
+ uint8_t mpId;
+ uint8_t hwWarpId;
+ uint8_t userDataCfg;
+ uint16_t eventId;
+ uint32_t startTime;
+ uint32_t endTime;
+ };
+
+ /**
+ \brief Converts a string into a unique 16 bit integer value; used when sending CUDA kernel warp data.
+ \param str The source string
+ \return Returns the unique id associated with this string which can later be passed via the WarpProfileEvent structure
+ */
+ virtual uint16_t getStringID(const char *str) = 0;
+
+ /**
+ \brief Defines the format version number for the kernel warp data struct
+ */
+ static const uint32_t CurrentCUDABufferFormat = 1;
+
+ /**
+ \brief Send a CUDA profile buffer. We assume the submit time is almost exactly the end time of the batch.
+ We then work backwards, using the batchRuntimeInMilliseconds in order to get the original time
+ of the batch. The buffer format is described in GPUProfile.h.
+
+ \param batchRuntimeInMilliseconds The batch runtime in milliseconds, see cuEventElapsedTime.
+ \param cudaData An opaque pointer to the buffer of cuda data.
+ \param eventCount number of events
+ \param bufferVersion Version of the format of the cuda data.
+ */
+ virtual void CUDAProfileBuffer( float batchRuntimeInMilliseconds, const WarpProfileEvent* cudaData, uint32_t eventCount, uint32_t bufferVersion = CurrentCUDABufferFormat ) = 0;
+
+ protected:
+ virtual ~NvProfilerCallback(void) {}
+};
+
+class NvProfileScoped
+{
+public:
+ NV_FORCE_INLINE NvProfileScoped(const char *eventName, NvProfileTypes::Enum type, uint64_t contextId, const char *fileName, int lineno)
+ : mCallback(nvidia::shdfnd::getProfilerCallback())
+ {
+ if ( mCallback )
+ {
+ mEventName = eventName;
+ mType = type;
+ mContextId = contextId;
+ mCallback->zoneStart(mEventName, mType, mContextId, fileName, lineno);
+ }
+ }
+ ~NvProfileScoped(void)
+ {
+ if ( mCallback )
+ {
+ mCallback->zoneEnd(mEventName, mType, mContextId);
+ }
+ }
+ nvidia::NvProfilerCallback *mCallback;
+ const char *mEventName;
+ NvProfileTypes::Enum mType;
+ uint64_t mContextId;
+};
+
+
+
+} // end of NVIDIA namespace
+
+
+
+#if NV_DEBUG || NV_CHECKED || NV_PROFILE
+
+#define NV_PROFILE_ZONE(x,y) nvidia::NvProfileScoped NV_CONCAT(_scoped,__LINE__)(x,nvidia::NvProfileTypes::eNORMAL,y,__FILE__,__LINE__)
+#define NV_PROFILE_START_CROSSTHREAD(x,y) if ( nvidia::shdfnd::getProfilerCallback() ) nvidia::shdfnd::getProfilerCallback()->zoneStart(x,nvidia::NvProfileTypes::eDETACHED,y,__FILE__,__LINE__)
+#define NV_PROFILE_STOP_CROSSTHREAD(x,y) if ( nvidia::shdfnd::getProfilerCallback() ) nvidia::shdfnd::getProfilerCallback()->zoneEnd(x,nvidia::NvProfileTypes::eDETACHED,y)
+
+#else
+
+#define NV_PROFILE_ZONE(x,y)
+#define NV_PROFILE_START_CROSSTHREAD(x,y)
+#define NV_PROFILE_STOP_CROSSTHREAD(x,y)
+
+#endif
+
+#define NV_PROFILE_POINTER_TO_U64( pointer ) static_cast<uint64_t>(reinterpret_cast<size_t>(pointer))
+
+#endif
diff --git a/external/NvFoundation/1.1/include/NvQuat.h b/external/NvFoundation/1.1/include/NvQuat.h
new file mode 100644
index 0000000..54f83cc
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvQuat.h
@@ -0,0 +1,398 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVQUAT_H
+#define NV_NVFOUNDATION_NVQUAT_H
+
+/** \addtogroup foundation
+@{
+*/
+
+#include "NvVec3.h"
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+
+/**
+\brief This is a quaternion class. For more information on quaternion mathematics
+consult a mathematics source on complex numbers.
+
+*/
+
+class NvQuat
+{
+ public:
+ /**
+ \brief Default constructor, does not do any initialization.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvQuat()
+ {
+ }
+
+ //! identity constructor
+ NV_CUDA_CALLABLE NV_INLINE NvQuat(NvIDENTITY r) : x(0.0f), y(0.0f), z(0.0f), w(1.0f)
+ {
+ NV_UNUSED(r);
+ }
+
+ /**
+ \brief Constructor from a scalar: sets the real part w to the scalar value, and the imaginary parts (x,y,z) to zero
+ */
+ explicit NV_CUDA_CALLABLE NV_FORCE_INLINE NvQuat(float r) : x(0.0f), y(0.0f), z(0.0f), w(r)
+ {
+ }
+
+ /**
+ \brief Constructor. Take note of the order of the elements!
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvQuat(float nx, float ny, float nz, float nw) : x(nx), y(ny), z(nz), w(nw)
+ {
+ }
+
+ /**
+ \brief Creates from angle-axis representation.
+
+ Axis must be normalized!
+
+ Angle is in radians!
+
+ <b>Unit:</b> Radians
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvQuat(float angleRadians, const NvVec3& unitAxis)
+ {
+ NV_ASSERT(NvAbs(1.0f - unitAxis.magnitude()) < 1e-3f);
+ const float a = angleRadians * 0.5f;
+ const float s = NvSin(a);
+ w = NvCos(a);
+ x = unitAxis.x * s;
+ y = unitAxis.y * s;
+ z = unitAxis.z * s;
+ }
+
+ /**
+ \brief Copy ctor.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvQuat(const NvQuat& v) : x(v.x), y(v.y), z(v.z), w(v.w)
+ {
+ }
+
+ /**
+ \brief Creates from orientation matrix.
+
+ \param[in] m Rotation matrix to extract quaternion from.
+ */
+ NV_CUDA_CALLABLE NV_INLINE explicit NvQuat(const NvMat33& m); /* defined in NvMat33.h */
+
+ /**
+ \brief returns true if all elements are finite (not NAN or INF, etc.)
+ */
+ NV_CUDA_CALLABLE bool isFinite() const
+ {
+ return NvIsFinite(x) && NvIsFinite(y) && NvIsFinite(z) && NvIsFinite(w);
+ }
+
+ /**
+ \brief returns true if finite and magnitude is close to unit
+ */
+
+ NV_CUDA_CALLABLE bool isUnit() const
+ {
+ const float unitTolerance = 1e-4f;
+ return isFinite() && NvAbs(magnitude() - 1) < unitTolerance;
+ }
+
+ /**
+ \brief returns true if finite and magnitude is reasonably close to unit to allow for some accumulation of error vs
+ isValid
+ */
+
+ NV_CUDA_CALLABLE bool isSane() const
+ {
+ const float unitTolerance = 1e-2f;
+ return isFinite() && NvAbs(magnitude() - 1) < unitTolerance;
+ }
+
+ /**
+ \brief returns true if the two quaternions are exactly equal
+ */
+ NV_CUDA_CALLABLE NV_INLINE bool operator==(const NvQuat& q) const
+ {
+ return x == q.x && y == q.y && z == q.z && w == q.w;
+ }
+
+ /**
+ \brief converts this quaternion to angle-axis representation
+ */
+
+ NV_CUDA_CALLABLE NV_INLINE void toRadiansAndUnitAxis(float& angle, NvVec3& axis) const
+ {
+ const float quatEpsilon = 1.0e-8f;
+ const float s2 = x * x + y * y + z * z;
+ if(s2 < quatEpsilon * quatEpsilon) // can't extract a sensible axis
+ {
+ angle = 0.0f;
+ axis = NvVec3(1.0f, 0.0f, 0.0f);
+ }
+ else
+ {
+ const float s = NvRecipSqrt(s2);
+ axis = NvVec3(x, y, z) * s;
+ angle = NvAbs(w) < quatEpsilon ? NvPi : NvAtan2(s2 * s, w) * 2.0f;
+ }
+ }
+
+ /**
+ \brief Gets the angle between this quat and the identity quaternion.
+
+ <b>Unit:</b> Radians
+ */
+ NV_CUDA_CALLABLE NV_INLINE float getAngle() const
+ {
+ return NvAcos(w) * 2.0f;
+ }
+
+ /**
+ \brief Gets the angle between this quat and the argument
+
+ <b>Unit:</b> Radians
+ */
+ NV_CUDA_CALLABLE NV_INLINE float getAngle(const NvQuat& q) const
+ {
+ return NvAcos(dot(q)) * 2.0f;
+ }
+
+ /**
+ \brief This is the squared 4D vector length, should be 1 for unit quaternions.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float magnitudeSquared() const
+ {
+ return x * x + y * y + z * z + w * w;
+ }
+
+ /**
+ \brief returns the scalar product of this and other.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float dot(const NvQuat& v) const
+ {
+ return x * v.x + y * v.y + z * v.z + w * v.w;
+ }
+
+ NV_CUDA_CALLABLE NV_INLINE NvQuat getNormalized() const
+ {
+ const float s = 1.0f / magnitude();
+ return NvQuat(x * s, y * s, z * s, w * s);
+ }
+
+ NV_CUDA_CALLABLE NV_INLINE float magnitude() const
+ {
+ return NvSqrt(magnitudeSquared());
+ }
+
+ // modifiers:
+ /**
+ \brief maps to the closest unit quaternion.
+ */
+ NV_CUDA_CALLABLE NV_INLINE float normalize() // convert this NvQuat to a unit quaternion
+ {
+ const float mag = magnitude();
+ if(mag != 0.0f)
+ {
+ const float imag = 1.0f / mag;
+
+ x *= imag;
+ y *= imag;
+ z *= imag;
+ w *= imag;
+ }
+ return mag;
+ }
+
+ /*
+ \brief returns the conjugate.
+
+ \note for unit quaternions, this is the inverse.
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvQuat getConjugate() const
+ {
+ return NvQuat(-x, -y, -z, w);
+ }
+
+ /*
+ \brief returns imaginary part.
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec3 getImaginaryPart() const
+ {
+ return NvVec3(x, y, z);
+ }
+
+ /** brief computes rotation of x-axis */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 getBasisVector0() const
+ {
+ const float x2 = x * 2.0f;
+ const float w2 = w * 2.0f;
+ return NvVec3((w * w2) - 1.0f + x * x2, (z * w2) + y * x2, (-y * w2) + z * x2);
+ }
+
+ /** brief computes rotation of y-axis */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 getBasisVector1() const
+ {
+ const float y2 = y * 2.0f;
+ const float w2 = w * 2.0f;
+ return NvVec3((-z * w2) + x * y2, (w * w2) - 1.0f + y * y2, (x * w2) + z * y2);
+ }
+
+ /** brief computes rotation of z-axis */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 getBasisVector2() const
+ {
+ const float z2 = z * 2.0f;
+ const float w2 = w * 2.0f;
+ return NvVec3((y * w2) + x * z2, (-x * w2) + y * z2, (w * w2) - 1.0f + z * z2);
+ }
+
+ /**
+ rotates passed vec by this (assumed unitary)
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE const NvVec3 rotate(const NvVec3& v) const
+ {
+ const float vx = 2.0f * v.x;
+ const float vy = 2.0f * v.y;
+ const float vz = 2.0f * v.z;
+ const float w2 = w * w - 0.5f;
+ const float dot2 = (x * vx + y * vy + z * vz);
+ return NvVec3((vx * w2 + (y * vz - z * vy) * w + x * dot2), (vy * w2 + (z * vx - x * vz) * w + y * dot2),
+ (vz * w2 + (x * vy - y * vx) * w + z * dot2));
+ }
+
+ /**
+ inverse rotates passed vec by this (assumed unitary)
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE const NvVec3 rotateInv(const NvVec3& v) const
+ {
+ const float vx = 2.0f * v.x;
+ const float vy = 2.0f * v.y;
+ const float vz = 2.0f * v.z;
+ const float w2 = w * w - 0.5f;
+ const float dot2 = (x * vx + y * vy + z * vz);
+ return NvVec3((vx * w2 - (y * vz - z * vy) * w + x * dot2), (vy * w2 - (z * vx - x * vz) * w + y * dot2),
+ (vz * w2 - (x * vy - y * vx) * w + z * dot2));
+ }
+
+ /**
+ \brief Assignment operator
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvQuat& operator=(const NvQuat& p)
+ {
+ x = p.x;
+ y = p.y;
+ z = p.z;
+ w = p.w;
+ return *this;
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvQuat& operator*=(const NvQuat& q)
+ {
+ const float tx = w * q.x + q.w * x + y * q.z - q.y * z;
+ const float ty = w * q.y + q.w * y + z * q.x - q.z * x;
+ const float tz = w * q.z + q.w * z + x * q.y - q.x * y;
+
+ w = w * q.w - q.x * x - y * q.y - q.z * z;
+ x = tx;
+ y = ty;
+ z = tz;
+
+ return *this;
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvQuat& operator+=(const NvQuat& q)
+ {
+ x += q.x;
+ y += q.y;
+ z += q.z;
+ w += q.w;
+ return *this;
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvQuat& operator-=(const NvQuat& q)
+ {
+ x -= q.x;
+ y -= q.y;
+ z -= q.z;
+ w -= q.w;
+ return *this;
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvQuat& operator*=(const float s)
+ {
+ x *= s;
+ y *= s;
+ z *= s;
+ w *= s;
+ return *this;
+ }
+
+ /** quaternion multiplication */
+ NV_CUDA_CALLABLE NV_INLINE NvQuat operator*(const NvQuat& q) const
+ {
+ return NvQuat(w * q.x + q.w * x + y * q.z - q.y * z, w * q.y + q.w * y + z * q.x - q.z * x,
+ w * q.z + q.w * z + x * q.y - q.x * y, w * q.w - x * q.x - y * q.y - z * q.z);
+ }
+
+ /** quaternion addition */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvQuat operator+(const NvQuat& q) const
+ {
+ return NvQuat(x + q.x, y + q.y, z + q.z, w + q.w);
+ }
+
+ /** quaternion subtraction */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvQuat operator-() const
+ {
+ return NvQuat(-x, -y, -z, -w);
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvQuat operator-(const NvQuat& q) const
+ {
+ return NvQuat(x - q.x, y - q.y, z - q.z, w - q.w);
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvQuat operator*(float r) const
+ {
+ return NvQuat(x * r, y * r, z * r, w * r);
+ }
+
+ /** the quaternion elements */
+ float x, y, z, w;
+};
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVQUAT_H
diff --git a/external/NvFoundation/1.1/include/NvSimpleTypes.h b/external/NvFoundation/1.1/include/NvSimpleTypes.h
new file mode 100644
index 0000000..8041ceb
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvSimpleTypes.h
@@ -0,0 +1,72 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVSIMPLETYPES_H
+#define NV_NVFOUNDATION_NVSIMPLETYPES_H
+
+/** \addtogroup foundation
+ @{
+*/
+
+// Platform specific types:
+// Design note: Its OK to use int for general loop variables and temps.
+
+#include "NvPreprocessor.h"
+#if NV_VC
+#pragma warning(push)
+#pragma warning(disable : 4668) // suppressing warning generated by Microsoft Visual Studio when including this standard
+// header
+#endif
+
+#if NV_LINUX
+#define __STDC_LIMIT_MACROS
+#endif
+
+#include <stdint.h>
+#if NV_VC
+#pragma warning(pop)
+#endif
+// Type ranges
+
+// These are here because we sometimes have non-IEEE compliant platforms to deal with.
+// Removal is under consideration (issue GWSD-34)
+
+#define NV_MAX_F32 3.4028234663852885981170418348452e+38F
+// maximum possible float value
+#define NV_MAX_F64 DBL_MAX // maximum possible double value
+
+#define NV_EPS_F32 FLT_EPSILON // maximum relative error of float rounding
+#define NV_EPS_F64 DBL_EPSILON // maximum relative error of double rounding
+
+#define NV_MAX_REAL NV_MAX_F32
+#define NV_EPS_REAL NV_EPS_F32
+#define NV_NORMALIZATION_EPSILON float(1e-20f)
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVSIMPLETYPES_H
diff --git a/external/NvFoundation/1.1/include/NvTransform.h b/external/NvFoundation/1.1/include/NvTransform.h
new file mode 100644
index 0000000..e15cd08
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvTransform.h
@@ -0,0 +1,215 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVTRANSFORM_H
+#define NV_NVFOUNDATION_NVTRANSFORM_H
+/** \addtogroup foundation
+ @{
+*/
+
+#include "NvQuat.h"
+#include "NvPlane.h"
+
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+
+/*!
+\brief class representing a rigid euclidean transform as a quaternion and a vector
+*/
+
+class NvTransform
+{
+ public:
+ NvQuat q;
+ NvVec3 p;
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvTransform()
+ {
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE explicit NvTransform(const NvVec3& position) : q(NvIdentity), p(position)
+ {
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE explicit NvTransform(NvIDENTITY r) : q(NvIdentity), p(NvZero)
+ {
+ NV_UNUSED(r);
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE explicit NvTransform(const NvQuat& orientation) : q(orientation), p(0)
+ {
+ NV_ASSERT(orientation.isSane());
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvTransform(float x, float y, float z, NvQuat aQ = NvQuat(NvIdentity))
+ : q(aQ), p(x, y, z)
+ {
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvTransform(const NvVec3& p0, const NvQuat& q0) : q(q0), p(p0)
+ {
+ NV_ASSERT(q0.isSane());
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE explicit NvTransform(const NvMat44& m); // defined in NvMat44.h
+
+ /**
+ \brief returns true if the two transforms are exactly equal
+ */
+ NV_CUDA_CALLABLE NV_INLINE bool operator==(const NvTransform& t) const
+ {
+ return p == t.p && q == t.q;
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvTransform operator*(const NvTransform& x) const
+ {
+ NV_ASSERT(x.isSane());
+ return transform(x);
+ }
+
+ //! Equals matrix multiplication
+ NV_CUDA_CALLABLE NV_INLINE NvTransform& operator*=(NvTransform& other)
+ {
+ *this = *this * other;
+ return *this;
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvTransform getInverse() const
+ {
+ NV_ASSERT(isFinite());
+ return NvTransform(q.rotateInv(-p), q.getConjugate());
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 transform(const NvVec3& input) const
+ {
+ NV_ASSERT(isFinite());
+ return q.rotate(input) + p;
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 transformInv(const NvVec3& input) const
+ {
+ NV_ASSERT(isFinite());
+ return q.rotateInv(input - p);
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 rotate(const NvVec3& input) const
+ {
+ NV_ASSERT(isFinite());
+ return q.rotate(input);
+ }
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 rotateInv(const NvVec3& input) const
+ {
+ NV_ASSERT(isFinite());
+ return q.rotateInv(input);
+ }
+
+ //! Transform transform to parent (returns compound transform: first src, then *this)
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvTransform transform(const NvTransform& src) const
+ {
+ NV_ASSERT(src.isSane());
+ NV_ASSERT(isSane());
+ // src = [srct, srcr] -> [r*srct + t, r*srcr]
+ return NvTransform(q.rotate(src.p) + p, q * src.q);
+ }
+
+ /**
+ \brief returns true if finite and q is a unit quaternion
+ */
+
+ NV_CUDA_CALLABLE bool isValid() const
+ {
+ return p.isFinite() && q.isFinite() && q.isUnit();
+ }
+
+ /**
+ \brief returns true if finite and quat magnitude is reasonably close to unit to allow for some accumulation of error
+ vs isValid
+ */
+
+ NV_CUDA_CALLABLE bool isSane() const
+ {
+ return isFinite() && q.isSane();
+ }
+
+ /**
+ \brief returns true if all elems are finite (not NAN or INF, etc.)
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool isFinite() const
+ {
+ return p.isFinite() && q.isFinite();
+ }
+
+ //! Transform transform from parent (returns compound transform: first src, then this->inverse)
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvTransform transformInv(const NvTransform& src) const
+ {
+ NV_ASSERT(src.isSane());
+ NV_ASSERT(isFinite());
+ // src = [srct, srcr] -> [r^-1*(srct-t), r^-1*srcr]
+ NvQuat qinv = q.getConjugate();
+ return NvTransform(qinv.rotate(src.p - p), qinv * src.q);
+ }
+
+ /**
+ \brief transform plane
+ */
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvPlane transform(const NvPlane& plane) const
+ {
+ NvVec3 transformedNormal = rotate(plane.n);
+ return NvPlane(transformedNormal, plane.d - p.dot(transformedNormal));
+ }
+
+ /**
+ \brief inverse-transform plane
+ */
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvPlane inverseTransform(const NvPlane& plane) const
+ {
+ NvVec3 transformedNormal = rotateInv(plane.n);
+ return NvPlane(transformedNormal, plane.d + p.dot(plane.n));
+ }
+
+ /**
+ \brief return a normalized transform (i.e. one in which the quaternion has unit magnitude)
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvTransform getNormalized() const
+ {
+ return NvTransform(p, q.getNormalized());
+ }
+};
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVTRANSFORM_H
diff --git a/external/NvFoundation/1.1/include/NvVec2.h b/external/NvFoundation/1.1/include/NvVec2.h
new file mode 100644
index 0000000..49d502e
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvVec2.h
@@ -0,0 +1,347 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVVEC2_H
+#define NV_NVFOUNDATION_NVVEC2_H
+
+/** \addtogroup foundation
+@{
+*/
+
+#include "NvMath.h"
+
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+
+/**
+\brief 2 Element vector class.
+
+This is a 2-dimensional vector class with public data members.
+*/
+class NvVec2
+{
+ public:
+ /**
+ \brief default constructor leaves data uninitialized.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2()
+ {
+ }
+
+ /**
+ \brief zero constructor.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2(NvZERO r) : x(0.0f), y(0.0f)
+ {
+ NV_UNUSED(r);
+ }
+
+ /**
+ \brief Assigns scalar parameter to all elements.
+
+ Useful to initialize to zero or one.
+
+ \param[in] a Value to assign to elements.
+ */
+ explicit NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2(float a) : x(a), y(a)
+ {
+ }
+
+ /**
+ \brief Initializes from 2 scalar parameters.
+
+ \param[in] nx Value to initialize X component.
+ \param[in] ny Value to initialize Y component.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2(float nx, float ny) : x(nx), y(ny)
+ {
+ }
+
+ /**
+ \brief Copy ctor.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2(const NvVec2& v) : x(v.x), y(v.y)
+ {
+ }
+
+ // Operators
+
+ /**
+ \brief Assignment operator
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2& operator=(const NvVec2& p)
+ {
+ x = p.x;
+ y = p.y;
+ return *this;
+ }
+
+ /**
+ \brief element access
+ */
+ NV_DEPRECATED NV_CUDA_CALLABLE NV_FORCE_INLINE float& operator[](int index)
+ {
+ NV_ASSERT(index >= 0 && index <= 1);
+
+ return reinterpret_cast<float*>(this)[index];
+ }
+
+ /**
+ \brief element access
+ */
+ NV_DEPRECATED NV_CUDA_CALLABLE NV_FORCE_INLINE const float& operator[](int index) const
+ {
+ NV_ASSERT(index >= 0 && index <= 1);
+
+ return reinterpret_cast<const float*>(this)[index];
+ }
+
+ /**
+ \brief returns true if the two vectors are exactly equal.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool operator==(const NvVec2& v) const
+ {
+ return x == v.x && y == v.y;
+ }
+
+ /**
+ \brief returns true if the two vectors are not exactly equal.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool operator!=(const NvVec2& v) const
+ {
+ return x != v.x || y != v.y;
+ }
+
+ /**
+ \brief tests for exact zero vector
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool isZero() const
+ {
+ return x == 0.0f && y == 0.0f;
+ }
+
+ /**
+ \brief returns true if all 2 elems of the vector are finite (not NAN or INF, etc.)
+ */
+ NV_CUDA_CALLABLE NV_INLINE bool isFinite() const
+ {
+ return NvIsFinite(x) && NvIsFinite(y);
+ }
+
+ /**
+ \brief is normalized - used by API parameter validation
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool isNormalized() const
+ {
+ const float unitTolerance = 1e-4f;
+ return isFinite() && NvAbs(magnitude() - 1) < unitTolerance;
+ }
+
+ /**
+ \brief returns the squared magnitude
+
+ Avoids calling NvSqrt()!
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float magnitudeSquared() const
+ {
+ return x * x + y * y;
+ }
+
+ /**
+ \brief returns the magnitude
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float magnitude() const
+ {
+ return NvSqrt(magnitudeSquared());
+ }
+
+ /**
+ \brief negation
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2 operator-() const
+ {
+ return NvVec2(-x, -y);
+ }
+
+ /**
+ \brief vector addition
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2 operator+(const NvVec2& v) const
+ {
+ return NvVec2(x + v.x, y + v.y);
+ }
+
+ /**
+ \brief vector difference
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2 operator-(const NvVec2& v) const
+ {
+ return NvVec2(x - v.x, y - v.y);
+ }
+
+ /**
+ \brief scalar post-multiplication
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2 operator*(float f) const
+ {
+ return NvVec2(x * f, y * f);
+ }
+
+ /**
+ \brief scalar division
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2 operator/(float f) const
+ {
+ f = 1.0f / f; // PT: inconsistent notation with operator /=
+ return NvVec2(x * f, y * f);
+ }
+
+ /**
+ \brief vector addition
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2& operator+=(const NvVec2& v)
+ {
+ x += v.x;
+ y += v.y;
+ return *this;
+ }
+
+ /**
+ \brief vector difference
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2& operator-=(const NvVec2& v)
+ {
+ x -= v.x;
+ y -= v.y;
+ return *this;
+ }
+
+ /**
+ \brief scalar multiplication
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2& operator*=(float f)
+ {
+ x *= f;
+ y *= f;
+ return *this;
+ }
+ /**
+ \brief scalar division
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2& operator/=(float f)
+ {
+ f = 1.0f / f; // PT: inconsistent notation with operator /
+ x *= f;
+ y *= f;
+ return *this;
+ }
+
+ /**
+ \brief returns the scalar product of this and other.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float dot(const NvVec2& v) const
+ {
+ return x * v.x + y * v.y;
+ }
+
+ /** return a unit vector */
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2 getNormalized() const
+ {
+ const float m = magnitudeSquared();
+ return m > 0.0f ? *this * NvRecipSqrt(m) : NvVec2(0, 0);
+ }
+
+ /**
+ \brief normalizes the vector in place
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float normalize()
+ {
+ const float m = magnitude();
+ if(m > 0.0f)
+ *this /= m;
+ return m;
+ }
+
+ /**
+ \brief a[i] * b[i], for all i.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2 multiply(const NvVec2& a) const
+ {
+ return NvVec2(x * a.x, y * a.y);
+ }
+
+ /**
+ \brief element-wise minimum
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2 minimum(const NvVec2& v) const
+ {
+ return NvVec2(NvMin(x, v.x), NvMin(y, v.y));
+ }
+
+ /**
+ \brief returns MIN(x, y);
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float minElement() const
+ {
+ return NvMin(x, y);
+ }
+
+ /**
+ \brief element-wise maximum
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec2 maximum(const NvVec2& v) const
+ {
+ return NvVec2(NvMax(x, v.x), NvMax(y, v.y));
+ }
+
+ /**
+ \brief returns MAX(x, y);
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float maxElement() const
+ {
+ return NvMax(x, y);
+ }
+
+ float x, y;
+};
+
+NV_CUDA_CALLABLE static NV_FORCE_INLINE NvVec2 operator*(float f, const NvVec2& v)
+{
+ return NvVec2(f * v.x, f * v.y);
+}
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVVEC2_H
diff --git a/external/NvFoundation/1.1/include/NvVec3.h b/external/NvFoundation/1.1/include/NvVec3.h
new file mode 100644
index 0000000..137fb8b
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvVec3.h
@@ -0,0 +1,393 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVVEC3_H
+#define NV_NVFOUNDATION_NVVEC3_H
+
+/** \addtogroup foundation
+@{
+*/
+
+#include "NvMath.h"
+
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+
+/**
+\brief 3 Element vector class.
+
+This is a 3-dimensional vector class with public data members.
+*/
+class NvVec3
+{
+ public:
+ /**
+ \brief default constructor leaves data uninitialized.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3()
+ {
+ }
+
+ /**
+ \brief zero constructor.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3(NvZERO r) : x(0.0f), y(0.0f), z(0.0f)
+ {
+ NV_UNUSED(r);
+ }
+
+ /**
+ \brief Assigns scalar parameter to all elements.
+
+ Useful to initialize to zero or one.
+
+ \param[in] a Value to assign to elements.
+ */
+ explicit NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3(float a) : x(a), y(a), z(a)
+ {
+ }
+
+ /**
+ \brief Initializes from 3 scalar parameters.
+
+ \param[in] nx Value to initialize X component.
+ \param[in] ny Value to initialize Y component.
+ \param[in] nz Value to initialize Z component.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3(float nx, float ny, float nz) : x(nx), y(ny), z(nz)
+ {
+ }
+
+ /**
+ \brief Copy ctor.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3(const NvVec3& v) : x(v.x), y(v.y), z(v.z)
+ {
+ }
+
+ // Operators
+
+ /**
+ \brief Assignment operator
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3& operator=(const NvVec3& p)
+ {
+ x = p.x;
+ y = p.y;
+ z = p.z;
+ return *this;
+ }
+
+ /**
+ \brief element access
+ */
+ NV_DEPRECATED NV_CUDA_CALLABLE NV_FORCE_INLINE float& operator[](unsigned int index)
+ {
+ NV_ASSERT(index <= 2);
+
+ return reinterpret_cast<float*>(this)[index];
+ }
+
+ /**
+ \brief element access
+ */
+ NV_DEPRECATED NV_CUDA_CALLABLE NV_FORCE_INLINE const float& operator[](unsigned int index) const
+ {
+ NV_ASSERT(index <= 2);
+
+ return reinterpret_cast<const float*>(this)[index];
+ }
+ /**
+ \brief returns true if the two vectors are exactly equal.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool operator==(const NvVec3& v) const
+ {
+ return x == v.x && y == v.y && z == v.z;
+ }
+
+ /**
+ \brief returns true if the two vectors are not exactly equal.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool operator!=(const NvVec3& v) const
+ {
+ return x != v.x || y != v.y || z != v.z;
+ }
+
+ /**
+ \brief tests for exact zero vector
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool isZero() const
+ {
+ return x == 0.0f && y == 0.0f && z == 0.0f;
+ }
+
+ /**
+ \brief returns true if all 3 elems of the vector are finite (not NAN or INF, etc.)
+ */
+ NV_CUDA_CALLABLE NV_INLINE bool isFinite() const
+ {
+ return NvIsFinite(x) && NvIsFinite(y) && NvIsFinite(z);
+ }
+
+ /**
+ \brief is normalized - used by API parameter validation
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE bool isNormalized() const
+ {
+ const float unitTolerance = 1e-4f;
+ return isFinite() && NvAbs(magnitude() - 1) < unitTolerance;
+ }
+
+ /**
+ \brief returns the squared magnitude
+
+ Avoids calling NvSqrt()!
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float magnitudeSquared() const
+ {
+ return x * x + y * y + z * z;
+ }
+
+ /**
+ \brief returns the magnitude
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float magnitude() const
+ {
+ return NvSqrt(magnitudeSquared());
+ }
+
+ /**
+ \brief negation
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 operator-() const
+ {
+ return NvVec3(-x, -y, -z);
+ }
+
+ /**
+ \brief vector addition
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 operator+(const NvVec3& v) const
+ {
+ return NvVec3(x + v.x, y + v.y, z + v.z);
+ }
+
+ /**
+ \brief vector difference
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 operator-(const NvVec3& v) const
+ {
+ return NvVec3(x - v.x, y - v.y, z - v.z);
+ }
+
+ /**
+ \brief scalar post-multiplication
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 operator*(float f) const
+ {
+ return NvVec3(x * f, y * f, z * f);
+ }
+
+ /**
+ \brief scalar division
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 operator/(float f) const
+ {
+ f = 1.0f / f;
+ return NvVec3(x * f, y * f, z * f);
+ }
+
+ /**
+ \brief vector addition
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3& operator+=(const NvVec3& v)
+ {
+ x += v.x;
+ y += v.y;
+ z += v.z;
+ return *this;
+ }
+
+ /**
+ \brief vector difference
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3& operator-=(const NvVec3& v)
+ {
+ x -= v.x;
+ y -= v.y;
+ z -= v.z;
+ return *this;
+ }
+
+ /**
+ \brief scalar multiplication
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3& operator*=(float f)
+ {
+ x *= f;
+ y *= f;
+ z *= f;
+ return *this;
+ }
+ /**
+ \brief scalar division
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3& operator/=(float f)
+ {
+ f = 1.0f / f;
+ x *= f;
+ y *= f;
+ z *= f;
+ return *this;
+ }
+
+ /**
+ \brief returns the scalar product of this and other.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float dot(const NvVec3& v) const
+ {
+ return x * v.x + y * v.y + z * v.z;
+ }
+
+ /**
+ \brief cross product
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 cross(const NvVec3& v) const
+ {
+ return NvVec3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
+ }
+
+ /** return a unit vector */
+
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 getNormalized() const
+ {
+ const float m = magnitudeSquared();
+ return m > 0.0f ? *this * NvRecipSqrt(m) : NvVec3(0, 0, 0);
+ }
+
+ /**
+ \brief normalizes the vector in place
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float normalize()
+ {
+ const float m = magnitude();
+ if(m > 0.0f)
+ *this /= m;
+ return m;
+ }
+
+ /**
+ \brief normalizes the vector in place. Does nothing if vector magnitude is under NV_NORMALIZATION_EPSILON.
+ Returns vector magnitude if >= NV_NORMALIZATION_EPSILON and 0.0f otherwise.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float normalizeSafe()
+ {
+ const float mag = magnitude();
+ if(mag < NV_NORMALIZATION_EPSILON)
+ return 0.0f;
+ *this *= 1.0f / mag;
+ return mag;
+ }
+
+ /**
+ \brief normalizes the vector in place. Asserts if vector magnitude is under NV_NORMALIZATION_EPSILON.
+ returns vector magnitude.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float normalizeFast()
+ {
+ const float mag = magnitude();
+ NV_ASSERT(mag >= NV_NORMALIZATION_EPSILON);
+ *this *= 1.0f / mag;
+ return mag;
+ }
+
+ /**
+ \brief a[i] * b[i], for all i.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 multiply(const NvVec3& a) const
+ {
+ return NvVec3(x * a.x, y * a.y, z * a.z);
+ }
+
+ /**
+ \brief element-wise minimum
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 minimum(const NvVec3& v) const
+ {
+ return NvVec3(NvMin(x, v.x), NvMin(y, v.y), NvMin(z, v.z));
+ }
+
+ /**
+ \brief returns MIN(x, y, z);
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float minElement() const
+ {
+ return NvMin(x, NvMin(y, z));
+ }
+
+ /**
+ \brief element-wise maximum
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 maximum(const NvVec3& v) const
+ {
+ return NvVec3(NvMax(x, v.x), NvMax(y, v.y), NvMax(z, v.z));
+ }
+
+ /**
+ \brief returns MAX(x, y, z);
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE float maxElement() const
+ {
+ return NvMax(x, NvMax(y, z));
+ }
+
+ /**
+ \brief returns absolute values of components;
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec3 abs() const
+ {
+ return NvVec3(NvAbs(x), NvAbs(y), NvAbs(z));
+ }
+
+ float x, y, z;
+};
+
+NV_CUDA_CALLABLE static NV_FORCE_INLINE NvVec3 operator*(float f, const NvVec3& v)
+{
+ return NvVec3(f * v.x, f * v.y, f * v.z);
+}
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVVEC3_H
diff --git a/external/NvFoundation/1.1/include/NvVec4.h b/external/NvFoundation/1.1/include/NvVec4.h
new file mode 100644
index 0000000..6eaf10b
--- /dev/null
+++ b/external/NvFoundation/1.1/include/NvVec4.h
@@ -0,0 +1,376 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_NVFOUNDATION_NVVEC4_H
+#define NV_NVFOUNDATION_NVVEC4_H
+/** \addtogroup foundation
+@{
+*/
+#include "NvMath.h"
+#include "NvVec3.h"
+#include "NvAssert.h"
+
+/**
+\brief 4 Element vector class.
+
+This is a 4-dimensional vector class with public data members.
+*/
+#if !NV_DOXYGEN
+namespace nvidia
+{
+#endif
+
+class NvVec4
+{
+ public:
+ /**
+ \brief default constructor leaves data uninitialized.
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec4()
+ {
+ }
+
+ /**
+ \brief zero constructor.
+ */
+ NV_CUDA_CALLABLE NV_FORCE_INLINE NvVec4(NvZERO r) : x(0.0f), y(0.0f), z(0.0f), w(0.0f)
+ {
+ NV_UNUSED(r);
+ }
+
+ /**
+ \brief Assigns scalar parameter to all elements.
+
+ Useful to initialize to zero or one.
+
+ \param[in] a Value to assign to elements.
+ */
+ explicit NV_CUDA_CALLABLE NV_INLINE NvVec4(float a) : x(a), y(a), z(a), w(a)
+ {
+ }
+
+ /**
+ \brief Initializes from 3 scalar parameters.
+
+ \param[in] nx Value to initialize X component.
+ \param[in] ny Value to initialize Y component.
+ \param[in] nz Value to initialize Z component.
+ \param[in] nw Value to initialize W component.
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec4(float nx, float ny, float nz, float nw) : x(nx), y(ny), z(nz), w(nw)
+ {
+ }
+
+ /**
+ \brief Initializes from 3 scalar parameters.
+
+ \param[in] v Value to initialize the X, Y, and Z components.
+ \param[in] nw Value to initialize W component.
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec4(const NvVec3& v, float nw) : x(v.x), y(v.y), z(v.z), w(nw)
+ {
+ }
+
+ /**
+ \brief Initializes from an array of scalar parameters.
+
+ \param[in] v Value to initialize with.
+ */
+ explicit NV_CUDA_CALLABLE NV_INLINE NvVec4(const float v[]) : x(v[0]), y(v[1]), z(v[2]), w(v[3])
+ {
+ }
+
+ /**
+ \brief Copy ctor.
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec4(const NvVec4& v) : x(v.x), y(v.y), z(v.z), w(v.w)
+ {
+ }
+
+ // Operators
+
+ /**
+ \brief Assignment operator
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec4& operator=(const NvVec4& p)
+ {
+ x = p.x;
+ y = p.y;
+ z = p.z;
+ w = p.w;
+ return *this;
+ }
+
+ /**
+ \brief element access
+ */
+ NV_DEPRECATED NV_CUDA_CALLABLE NV_INLINE float& operator[](unsigned int index)
+ {
+ NV_ASSERT(index <= 3);
+
+ return reinterpret_cast<float*>(this)[index];
+ }
+
+ /**
+ \brief element access
+ */
+ NV_DEPRECATED NV_CUDA_CALLABLE NV_INLINE const float& operator[](unsigned int index) const
+ {
+ NV_ASSERT(index <= 3);
+
+ return reinterpret_cast<const float*>(this)[index];
+ }
+
+ /**
+ \brief returns true if the two vectors are exactly equal.
+ */
+ NV_CUDA_CALLABLE NV_INLINE bool operator==(const NvVec4& v) const
+ {
+ return x == v.x && y == v.y && z == v.z && w == v.w;
+ }
+
+ /**
+ \brief returns true if the two vectors are not exactly equal.
+ */
+ NV_CUDA_CALLABLE NV_INLINE bool operator!=(const NvVec4& v) const
+ {
+ return x != v.x || y != v.y || z != v.z || w != v.w;
+ }
+
+ /**
+ \brief tests for exact zero vector
+ */
+ NV_CUDA_CALLABLE NV_INLINE bool isZero() const
+ {
+ return x == 0 && y == 0 && z == 0 && w == 0;
+ }
+
+ /**
+ \brief returns true if all 3 elems of the vector are finite (not NAN or INF, etc.)
+ */
+ NV_CUDA_CALLABLE NV_INLINE bool isFinite() const
+ {
+ return NvIsFinite(x) && NvIsFinite(y) && NvIsFinite(z) && NvIsFinite(w);
+ }
+
+ /**
+ \brief is normalized - used by API parameter validation
+ */
+ NV_CUDA_CALLABLE NV_INLINE bool isNormalized() const
+ {
+ const float unitTolerance = 1e-4f;
+ return isFinite() && NvAbs(magnitude() - 1) < unitTolerance;
+ }
+
+ /**
+ \brief returns the squared magnitude
+
+ Avoids calling NvSqrt()!
+ */
+ NV_CUDA_CALLABLE NV_INLINE float magnitudeSquared() const
+ {
+ return x * x + y * y + z * z + w * w;
+ }
+
+ /**
+ \brief returns the magnitude
+ */
+ NV_CUDA_CALLABLE NV_INLINE float magnitude() const
+ {
+ return NvSqrt(magnitudeSquared());
+ }
+
+ /**
+ \brief negation
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec4 operator-() const
+ {
+ return NvVec4(-x, -y, -z, -w);
+ }
+
+ /**
+ \brief vector addition
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec4 operator+(const NvVec4& v) const
+ {
+ return NvVec4(x + v.x, y + v.y, z + v.z, w + v.w);
+ }
+
+ /**
+ \brief vector difference
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec4 operator-(const NvVec4& v) const
+ {
+ return NvVec4(x - v.x, y - v.y, z - v.z, w - v.w);
+ }
+
+ /**
+ \brief scalar post-multiplication
+ */
+
+ NV_CUDA_CALLABLE NV_INLINE NvVec4 operator*(float f) const
+ {
+ return NvVec4(x * f, y * f, z * f, w * f);
+ }
+
+ /**
+ \brief scalar division
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec4 operator/(float f) const
+ {
+ f = 1.0f / f;
+ return NvVec4(x * f, y * f, z * f, w * f);
+ }
+
+ /**
+ \brief vector addition
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec4& operator+=(const NvVec4& v)
+ {
+ x += v.x;
+ y += v.y;
+ z += v.z;
+ w += v.w;
+ return *this;
+ }
+
+ /**
+ \brief vector difference
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec4& operator-=(const NvVec4& v)
+ {
+ x -= v.x;
+ y -= v.y;
+ z -= v.z;
+ w -= v.w;
+ return *this;
+ }
+
+ /**
+ \brief scalar multiplication
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec4& operator*=(float f)
+ {
+ x *= f;
+ y *= f;
+ z *= f;
+ w *= f;
+ return *this;
+ }
+ /**
+ \brief scalar division
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec4& operator/=(float f)
+ {
+ f = 1.0f / f;
+ x *= f;
+ y *= f;
+ z *= f;
+ w *= f;
+ return *this;
+ }
+
+ /**
+ \brief returns the scalar product of this and other.
+ */
+ NV_CUDA_CALLABLE NV_INLINE float dot(const NvVec4& v) const
+ {
+ return x * v.x + y * v.y + z * v.z + w * v.w;
+ }
+
+ /** return a unit vector */
+
+ NV_CUDA_CALLABLE NV_INLINE NvVec4 getNormalized() const
+ {
+ float m = magnitudeSquared();
+ return m > 0.0f ? *this * NvRecipSqrt(m) : NvVec4(0, 0, 0, 0);
+ }
+
+ /**
+ \brief normalizes the vector in place
+ */
+ NV_CUDA_CALLABLE NV_INLINE float normalize()
+ {
+ float m = magnitude();
+ if(m > 0.0f)
+ *this /= m;
+ return m;
+ }
+
+ /**
+ \brief a[i] * b[i], for all i.
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec4 multiply(const NvVec4& a) const
+ {
+ return NvVec4(x * a.x, y * a.y, z * a.z, w * a.w);
+ }
+
+ /**
+ \brief element-wise minimum
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec4 minimum(const NvVec4& v) const
+ {
+ return NvVec4(NvMin(x, v.x), NvMin(y, v.y), NvMin(z, v.z), NvMin(w, v.w));
+ }
+
+ /**
+ \brief element-wise maximum
+ */
+ NV_CUDA_CALLABLE NV_INLINE NvVec4 maximum(const NvVec4& v) const
+ {
+ return NvVec4(NvMax(x, v.x), NvMax(y, v.y), NvMax(z, v.z), NvMax(w, v.w));
+ }
+
+ NV_CUDA_CALLABLE NV_INLINE NvVec3 getXYZ() const
+ {
+ return NvVec3(x, y, z);
+ }
+
+ /**
+ \brief set vector elements to zero
+ */
+ NV_CUDA_CALLABLE NV_INLINE void setZero()
+ {
+ x = y = z = w = 0.0f;
+ }
+
+ float x, y, z, w;
+};
+
+NV_CUDA_CALLABLE static NV_INLINE NvVec4 operator*(float f, const NvVec4& v)
+{
+ return NvVec4(f * v.x, f * v.y, f * v.z, f * v.w);
+}
+
+#if !NV_DOXYGEN
+} // namespace nvidia
+#endif
+
+/** @} */
+#endif // #ifndef NV_NVFOUNDATION_NVVEC4_H
diff --git a/external/NvFoundation/1.1/include/ps3/NvPS3Assert.h b/external/NvFoundation/1.1/include/ps3/NvPS3Assert.h
new file mode 100644
index 0000000..52240b9
--- /dev/null
+++ b/external/NvFoundation/1.1/include/ps3/NvPS3Assert.h
@@ -0,0 +1,55 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+// SCE CONFIDENTIAL
+// Copyright (C) Sony Computer Entertainment Inc.
+// All Rights Reserved.
+
+#ifndef NV_PS3_NVPS3ASSERT_H
+#define NV_PS3_NVPS3ASSERT_H
+
+#include <NvFoundation/NvPreprocessor.h>
+
+#ifdef NV_SPU
+#include "spu_printf.h"
+
+namespace nvidia
+{
+NV_INLINE void NvPs3Assert(const char* exp, const char* file, int line)
+{
+ spu_printf("SPU: Assertion failed! exp %s \n, line %d \n, file %s \n ", exp, line, file);
+ __builtin_snpause();
+}
+}
+
+#define NV_ASSERT(exp) ((void)(!!(exp) || (nvidia::NvPs3Assert(#exp, __FILE__, __LINE__), false)))
+#define NV_ALWAYS_ASSERT_MESSAGE(exp) nvidia::NvPs3Assert(exp, __FILE__, __LINE__)
+#define NV_ASSERT_WITH_MESSAGE(exp, message) \
+ ((void)(!!(exp) || (nvidia::NvPs3Assert(message, __FILE__, __LINE__), false)))
+#endif // NV_SPU
+#endif // #ifndef NV_PS3_NVPS3ASSERT_H
diff --git a/external/NvFoundation/1.1/include/ps3/NvPS3Error.h b/external/NvFoundation/1.1/include/ps3/NvPS3Error.h
new file mode 100644
index 0000000..6f06da3
--- /dev/null
+++ b/external/NvFoundation/1.1/include/ps3/NvPS3Error.h
@@ -0,0 +1,51 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+// dsequeira: I expect these have to be inlined on SPU, elsewhere they shouldn't be.
+
+#ifndef NV_PS3_NVPS3ERROR_H
+#define NV_PS3_NVPS3ERROR_H
+
+#include <NvFoundation/NvPreprocessor.h>
+
+#if defined(__CELLOS_LV2__) && defined(__SPU__)
+#include <spu_printf.h>
+
+NV_FORCE_INLINE void NvcOutputDebugString(const char* str)
+{
+ spu_printf(str);
+}
+
+NV_FORCE_INLINE void reportError(const char* error)
+{
+ spu_printf("Internal error: %s: \n", error);
+ NV_ASSERT(0);
+}
+#endif
+
+#endif // #ifndef NV_PS3_NVPS3ERROR_H
diff --git a/external/NvFoundation/1.1/include/ps3/NvPS3Intrinsics.h b/external/NvFoundation/1.1/include/ps3/NvPS3Intrinsics.h
new file mode 100644
index 0000000..dbef32a
--- /dev/null
+++ b/external/NvFoundation/1.1/include/ps3/NvPS3Intrinsics.h
@@ -0,0 +1,219 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+#ifndef NV_PS3_NVPS3INTRINSICS_H
+#define NV_PS3_NVPS3INTRINSICS_H
+
+#include "Nv.h"
+#include "NvAssert.h"
+
+#if !NV_PS3
+#error "This file should only be included by ps3 builds!!"
+#endif
+
+#include <math.h>
+#ifdef __SPU__
+#include "spu_intrinsics.h"
+#else
+#include "ppu_intrinsics.h"
+#endif
+
+namespace nvidia
+{
+namespace intrinsics
+{
+//! \brief platform-specific absolute value
+NV_FORCE_INLINE float abs(float a)
+{
+ return ::fabsf(a);
+}
+
+//! \brief platform-specific select float
+#ifdef __SPU__
+NV_FORCE_INLINE float fsel(float a, float b, float c)
+{
+ return (a >= 0 ? b : c);
+}
+#else
+NV_FORCE_INLINE float fsel(float a, float b, float c)
+{
+ return __fsels(a, b, c);
+}
+#endif
+
+//! \brief platform-specific sign
+#ifdef __SPU__
+NV_FORCE_INLINE float sign(float a)
+{
+ return (a >= 0 ? 1.0f : -1.0f);
+}
+#else
+NV_FORCE_INLINE float sign(float a)
+{
+ return __fsels(a, 1.0f, -1.0f);
+}
+#endif
+
+//! \brief platform-specific reciprocal
+NV_FORCE_INLINE float recip(float a)
+{
+ return 1.0f / a;
+}
+
+//! \brief platform-specific reciprocal estimate
+#if defined(__SPU__) || !defined(_PPU_INTRINSICS_GCC_H)
+NV_FORCE_INLINE float recipFast(float a)
+{
+ return 1.0f / a;
+}
+#else
+NV_FORCE_INLINE float recipFast(float a)
+{
+ return __fres(a);
+}
+#endif
+
+//! \brief platform-specific square root
+NV_FORCE_INLINE float sqrt(float a)
+{
+ return ::sqrtf(a);
+}
+
+//! \brief platform-specific reciprocal square root
+NV_FORCE_INLINE float recipSqrt(float a)
+{
+ return 1.0f / ::sqrtf(a);
+}
+
+//! \brief platform-specific reciprocal square root estimate
+#ifdef __SPU__
+NV_FORCE_INLINE float recipSqrtFast(float a)
+{
+ return 1.0f / ::sqrtf(a);
+}
+#else
+NV_FORCE_INLINE float recipSqrtFast(float a)
+{
+ return float(__frsqrte(a));
+}
+#endif
+
+//! \brief platform-specific sine
+NV_FORCE_INLINE float sin(float a)
+{
+ return ::sinf(a);
+}
+
+//! \brief platform-specific cosine
+NV_FORCE_INLINE float cos(float a)
+{
+ return ::cosf(a);
+}
+
+//! \brief platform-specific minimum
+#ifdef __SPU__
+NV_FORCE_INLINE float selectMin(float a, float b)
+{
+ return (a >= b ? b : a);
+}
+#else
+NV_FORCE_INLINE float selectMin(float a, float b)
+{
+ return __fsels(a - b, b, a);
+}
+#endif
+
+//! \brief platform-specific maximum
+#ifdef __SPU__
+NV_FORCE_INLINE float selectMax(float a, float b)
+{
+ return (a >= b ? a : b);
+}
+#else
+NV_FORCE_INLINE float selectMax(float a, float b)
+{
+ return __fsels(a - b, a, b);
+}
+#endif
+//! \brief platform-specific finiteness check (not INF or NAN)
+NV_FORCE_INLINE bool isFinite(float a)
+{
+ return !isnan(a) && !isinf(a);
+}
+
+//! \brief platform-specific finiteness check (not INF or NAN)
+NV_FORCE_INLINE bool isFinite(double a)
+{
+ return !isnan(a) && !isinf(a);
+}
+
+/*!
+Sets \c count bytes starting at \c dst to zero.
+*/
+NV_FORCE_INLINE void* memZero(void* NV_RESTRICT dest, uint32_t count)
+{
+ return memset(dest, 0, count);
+}
+
+/*!
+Sets \c count bytes starting at \c dst to \c c.
+*/
+NV_FORCE_INLINE void* memSet(void* NV_RESTRICT dest, int32_t c, uint32_t count)
+{
+ return memset(dest, c, count);
+}
+
+/*!
+Copies \c count bytes from \c src to \c dst. User memMove if regions overlap.
+*/
+NV_FORCE_INLINE void* memCopy(void* NV_RESTRICT dest, const void* NV_RESTRICT src, uint32_t count)
+{
+ return memcpy(dest, src, count);
+}
+
+/*!
+Copies \c count bytes from \c src to \c dst. Supports overlapping regions.
+*/
+NV_FORCE_INLINE void* memMove(void* NV_RESTRICT dest, const void* NV_RESTRICT src, uint32_t count)
+{
+ return memmove(dest, src, count);
+}
+
+/*!
+Set 128B to zero starting at \c dst+offset. Must be aligned.
+*/
+NV_FORCE_INLINE void memZero128(void* NV_RESTRICT dest, uint32_t offset = 0)
+{
+ NV_ASSERT(((size_t(dest) + offset) & 0x7f) == 0);
+ memSet((char*)dest + offset, 0, 128);
+}
+
+} // namespace intrinsics
+} // namespace nvidia
+
+#endif // #ifndef NV_PS3_NVPS3INTRINSICS_H
diff --git a/external/NvFoundation/1.1/include/psp2/NvPSP2Intrinsics.h b/external/NvFoundation/1.1/include/psp2/NvPSP2Intrinsics.h
new file mode 100644
index 0000000..b61a800
--- /dev/null
+++ b/external/NvFoundation/1.1/include/psp2/NvPSP2Intrinsics.h
@@ -0,0 +1,180 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_PSP2_NVPSP2INTRINSICS_H
+#define NV_PSP2_NVPSP2INTRINSICS_H
+
+#include "Nv.h"
+#include "NvAssert.h"
+
+#if !NV_PSP2
+#error "This file should only be included by psp2 builds!!"
+#endif
+
+#include <math.h>
+#include <float.h>
+
+namespace nvidia
+{
+namespace intrinsics
+{
+//! \brief platform-specific absolute value
+NV_FORCE_INLINE float abs(float a)
+{
+ return ::fabs(a);
+}
+
+//! \brief platform-specific select float
+NV_FORCE_INLINE float fsel(float a, float b, float c)
+{
+ return (a >= 0.0f) ? b : c;
+}
+
+//! \brief platform-specific sign
+NV_FORCE_INLINE float sign(float a)
+{
+ return (a >= 0.0f) ? 1.0f : -1.0f;
+}
+
+//! \brief platform-specific reciprocal
+NV_FORCE_INLINE float recip(float a)
+{
+ return 1.0f / a;
+}
+
+//! \brief platform-specific reciprocal estimate
+NV_FORCE_INLINE float recipFast(float a)
+{
+ return 1.0f / a;
+}
+
+//! \brief platform-specific square root
+NV_FORCE_INLINE float sqrt(float a)
+{
+ return ::sqrtf(a);
+}
+
+//! \brief platform-specific reciprocal square root
+NV_FORCE_INLINE float recipSqrt(float a)
+{
+ return 1.0f / ::sqrtf(a);
+}
+
+NV_FORCE_INLINE float recipSqrtFast(float a)
+{
+ return 1.0f / ::sqrtf(a);
+}
+
+//! \brief platform-specific sine
+NV_FORCE_INLINE float sin(float a)
+{
+ return ::sinf(a);
+}
+
+//! \brief platform-specific cosine
+NV_FORCE_INLINE float cos(float a)
+{
+ return ::cosf(a);
+}
+
+//! \brief platform-specific minimum
+NV_FORCE_INLINE float selectMin(float a, float b)
+{
+ return a < b ? a : b;
+}
+
+//! \brief platform-specific maximum
+NV_FORCE_INLINE float selectMax(float a, float b)
+{
+ return a > b ? a : b;
+}
+
+//! \brief platform-specific float floor
+NV_FORCE_INLINE float floor(float a)
+{
+ return floor(a);
+}
+
+//! \brief platform-specific finiteness check (not INF or NAN)
+NV_FORCE_INLINE bool isFinite(float a)
+{
+ return isfinite(a);
+}
+
+//! \brief platform-specific finiteness check (not INF or NAN)
+NV_FORCE_INLINE bool isFinite(double a)
+{
+ return isfinite(a);
+}
+
+/*!
+Sets \c count bytes starting at \c dst to zero.
+*/
+NV_FORCE_INLINE void* memZero(void* NV_RESTRICT dest, uint32_t count)
+{
+ return memset(dest, 0, count);
+}
+
+/*!
+Sets \c count bytes starting at \c dst to \c c.
+*/
+NV_FORCE_INLINE void* memSet(void* NV_RESTRICT dest, int32_t c, uint32_t count)
+{
+ return memset(dest, c, count);
+}
+
+/*!
+Copies \c count bytes from \c src to \c dst. User memMove if regions overlap.
+*/
+NV_FORCE_INLINE void* memCopy(void* NV_RESTRICT dest, const void* NV_RESTRICT src, uint32_t count)
+{
+ return memcpy(dest, src, count);
+}
+
+/*!
+Copies \c count bytes from \c src to \c dst. Supports overlapping regions.
+*/
+NV_FORCE_INLINE void* memMove(void* NV_RESTRICT dest, const void* NV_RESTRICT src, uint32_t count)
+{
+ return memmove(dest, src, count);
+}
+
+/*!
+Set 128B to zero starting at \c dst+offset. Must be aligned.
+*/
+NV_FORCE_INLINE void memZero128(void* NV_RESTRICT dest, uint32_t offset = 0)
+{
+ NV_ASSERT(((size_t(dest) + offset) & 0x7f) == 0);
+ memSet((char*)dest + offset, 0, 128);
+}
+
+} // namespace intrinsics
+} // namespace nvidia
+
+#endif // #ifndef NV_PSP2_NVPSP2INTRINSICS_H
diff --git a/external/NvFoundation/1.1/include/unix/NvUnixIntrinsics.h b/external/NvFoundation/1.1/include/unix/NvUnixIntrinsics.h
new file mode 100644
index 0000000..4230c83
--- /dev/null
+++ b/external/NvFoundation/1.1/include/unix/NvUnixIntrinsics.h
@@ -0,0 +1,174 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_UNIX_NVUNIXINTRINSICS_H
+#define NV_UNIX_NVUNIXINTRINSICS_H
+
+#include "Nv.h"
+#include "NvAssert.h"
+
+#if !(NV_LINUX || NV_ANDROID || NV_PS4 || NV_APPLE_FAMILY)
+#error "This file should only be included by Unix builds!!"
+#endif
+
+#include <math.h>
+#include <float.h>
+
+namespace nvidia
+{
+namespace intrinsics
+{
+//! \brief platform-specific absolute value
+NV_CUDA_CALLABLE NV_FORCE_INLINE float abs(float a)
+{
+ return ::fabsf(a);
+}
+
+//! \brief platform-specific select float
+NV_CUDA_CALLABLE NV_FORCE_INLINE float fsel(float a, float b, float c)
+{
+ return (a >= 0.0f) ? b : c;
+}
+
+//! \brief platform-specific sign
+NV_CUDA_CALLABLE NV_FORCE_INLINE float sign(float a)
+{
+ return (a >= 0.0f) ? 1.0f : -1.0f;
+}
+
+//! \brief platform-specific reciprocal
+NV_CUDA_CALLABLE NV_FORCE_INLINE float recip(float a)
+{
+ return 1.0f / a;
+}
+
+//! \brief platform-specific reciprocal estimate
+NV_CUDA_CALLABLE NV_FORCE_INLINE float recipFast(float a)
+{
+ return 1.0f / a;
+}
+
+//! \brief platform-specific square root
+NV_CUDA_CALLABLE NV_FORCE_INLINE float sqrt(float a)
+{
+ return ::sqrtf(a);
+}
+
+//! \brief platform-specific reciprocal square root
+NV_CUDA_CALLABLE NV_FORCE_INLINE float recipSqrt(float a)
+{
+ return 1.0f / ::sqrtf(a);
+}
+
+NV_CUDA_CALLABLE NV_FORCE_INLINE float recipSqrtFast(float a)
+{
+ return 1.0f / ::sqrtf(a);
+}
+
+//! \brief platform-specific sine
+NV_CUDA_CALLABLE NV_FORCE_INLINE float sin(float a)
+{
+ return ::sinf(a);
+}
+
+//! \brief platform-specific cosine
+NV_CUDA_CALLABLE NV_FORCE_INLINE float cos(float a)
+{
+ return ::cosf(a);
+}
+
+//! \brief platform-specific minimum
+NV_CUDA_CALLABLE NV_FORCE_INLINE float selectMin(float a, float b)
+{
+ return a < b ? a : b;
+}
+
+//! \brief platform-specific maximum
+NV_CUDA_CALLABLE NV_FORCE_INLINE float selectMax(float a, float b)
+{
+ return a > b ? a : b;
+}
+
+//! \brief platform-specific finiteness check (not INF or NAN)
+NV_CUDA_CALLABLE NV_FORCE_INLINE bool isFinite(float a)
+{
+ return !!isfinite(a);
+}
+
+//! \brief platform-specific finiteness check (not INF or NAN)
+NV_CUDA_CALLABLE NV_FORCE_INLINE bool isFinite(double a)
+{
+ return !!isfinite(a);
+}
+
+/*!
+Sets \c count bytes starting at \c dst to zero.
+*/
+NV_FORCE_INLINE void* memZero(void* NV_RESTRICT dest, uint32_t count)
+{
+ return memset(dest, 0, count);
+}
+
+/*!
+Sets \c count bytes starting at \c dst to \c c.
+*/
+NV_FORCE_INLINE void* memSet(void* NV_RESTRICT dest, int32_t c, uint32_t count)
+{
+ return memset(dest, c, count);
+}
+
+/*!
+Copies \c count bytes from \c src to \c dst. User memMove if regions overlap.
+*/
+NV_FORCE_INLINE void* memCopy(void* NV_RESTRICT dest, const void* NV_RESTRICT src, uint32_t count)
+{
+ return memcpy(dest, src, count);
+}
+
+/*!
+Copies \c count bytes from \c src to \c dst. Supports overlapping regions.
+*/
+NV_FORCE_INLINE void* memMove(void* NV_RESTRICT dest, const void* NV_RESTRICT src, uint32_t count)
+{
+ return memmove(dest, src, count);
+}
+
+/*!
+Set 128B to zero starting at \c dst+offset. Must be aligned.
+*/
+NV_FORCE_INLINE void memZero128(void* NV_RESTRICT dest, uint32_t offset = 0)
+{
+ NV_ASSERT(((size_t(dest) + offset) & 0x7f) == 0);
+ memSet(reinterpret_cast<char * NV_RESTRICT>(dest) + offset, 0, 128);
+}
+
+} // namespace intrinsics
+} // namespace nvidia
+
+#endif // #ifndef NV_UNIX_NVUNIXINTRINSICS_H
diff --git a/external/NvFoundation/1.1/include/wiiu/NvWiiUIntrinsics.h b/external/NvFoundation/1.1/include/wiiu/NvWiiUIntrinsics.h
new file mode 100644
index 0000000..f50213b
--- /dev/null
+++ b/external/NvFoundation/1.1/include/wiiu/NvWiiUIntrinsics.h
@@ -0,0 +1,179 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_WIIU_NVWIIUINTRINSICS_H
+#define NV_WIIU_NVWIIUINTRINSICS_H
+
+#include "Nv.h"
+#include "NvAssert.h"
+
+#if !NV_WIIU
+#error "This file should only be included by Wii U builds!!"
+#endif
+
+#include <math.h>
+#include <ppc_ghs.h>
+
+namespace nvidia
+{
+namespace intrinsics
+{
+//! \brief platform-specific absolute value
+NV_FORCE_INLINE float abs(float a)
+{
+ return __fabsf(a);
+}
+
+//! \brief platform-specific select float
+NV_FORCE_INLINE float fsel(float a, float b, float c)
+{
+ return __FSELF(a, b, c);
+}
+
+//! \brief platform-specific sign
+NV_FORCE_INLINE float sign(float a)
+{
+ return __FSELF(a, 1.0f, -1.0f);
+}
+
+//! \brief platform-specific reciprocal
+NV_FORCE_INLINE float recip(float a)
+{
+ return 1.0f / a;
+}
+
+//! \brief platform-specific reciprocal estimate
+NV_FORCE_INLINE float recipFast(float a)
+{
+ return __FRES(a);
+} // note: resolution of less than 1/4000
+
+//! \brief platform-specific square root
+NV_FORCE_INLINE float sqrt(float a)
+{
+ return ::sqrtf(a);
+}
+
+//! \brief platform-specific reciprocal square root
+NV_FORCE_INLINE float recipSqrt(float a)
+{
+ return 1.0f / ::sqrtf(a);
+}
+
+NV_FORCE_INLINE float recipSqrtFast(float a)
+{
+ return __FRSQRTEF(a);
+} // note: resolution of less than 1/4000
+
+//! \brief platform-specific sine
+NV_FORCE_INLINE float sin(float a)
+{
+ return ::sinf(a);
+}
+
+//! \brief platform-specific cosine
+NV_FORCE_INLINE float cos(float a)
+{
+ return ::cosf(a);
+}
+
+//! \brief platform-specific minimum
+NV_FORCE_INLINE float selectMin(float a, float b)
+{
+ return __FSELF(a - b, b, a);
+}
+
+//! \brief platform-specific maximum
+NV_FORCE_INLINE float selectMax(float a, float b)
+{
+ return __FSELF(a - b, a, b);
+}
+
+//! \brief platform-specific finiteness check (not INF or NAN)
+NV_FORCE_INLINE bool isFinite(float a)
+{
+ return isfinite(a);
+}
+
+//! \brief platform-specific finiteness check (not INF or NAN)
+NV_FORCE_INLINE bool isFinite(double a)
+{
+ return isfinite(a);
+}
+
+/*!
+Sets \c count bytes starting at \c dst to zero.
+*/
+NV_FORCE_INLINE void* memZero(void* NV_RESTRICT dest, uint32_t count)
+{
+ return memset(dest, 0, count);
+}
+
+/*!
+Sets \c count bytes starting at \c dst to \c c.
+*/
+NV_FORCE_INLINE void* memSet(void* NV_RESTRICT dest, int32_t c, uint32_t count)
+{
+ return memset(dest, c, count);
+}
+
+/*!
+Copies \c count bytes from \c src to \c dst. User memMove if regions overlap.
+*/
+NV_FORCE_INLINE void* memCopy(void* NV_RESTRICT dest, const void* NV_RESTRICT src, uint32_t count)
+{
+ return memcpy(dest, src, count);
+}
+
+/*!
+Copies \c count bytes from \c src to \c dst. Supports overlapping regions.
+*/
+NV_FORCE_INLINE void* memMove(void* NV_RESTRICT dest, const void* NV_RESTRICT src, uint32_t count)
+{
+ return memmove(dest, src, count); // could try OSBlockMove() in <cafe/os.h>
+}
+
+/*!
+Set 128B to zero starting at \c dst+offset. Must be aligned.
+*/
+NV_FORCE_INLINE void memZero128(void* NV_RESTRICT dest, uint32_t offset = 0)
+{
+ NV_UNUSED(offset);
+ NV_ASSERT(((size_t(dest) + offset) & 0x7f) == 0);
+
+ __DCBZ(dest, 0);
+ __DCBZ(dest, 32);
+ __DCBZ(dest, 64);
+ __DCBZ(dest, 96);
+}
+
+} // namespace intrinsics
+} // namespace nvidia
+
+#endif // #ifndef NV_WIIU_NVWIIUINTRINSICS_H
diff --git a/external/NvFoundation/1.1/include/windows/NvWindowsIntrinsics.h b/external/NvFoundation/1.1/include/windows/NvWindowsIntrinsics.h
new file mode 100644
index 0000000..e5ab4bb
--- /dev/null
+++ b/external/NvFoundation/1.1/include/windows/NvWindowsIntrinsics.h
@@ -0,0 +1,188 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_WINDOWS_NVWINDOWSINTRINSICS_H
+#define NV_WINDOWS_NVWINDOWSINTRINSICS_H
+
+#include "Nv.h"
+#include "NvAssert.h"
+
+#if !NV_WINDOWS_FAMILY
+#error "This file should only be included by Windows or WIN8ARM builds!!"
+#endif
+
+#include <math.h>
+#include <float.h>
+
+#if !NV_DOXYGEN
+namespace nvidia
+{
+namespace intrinsics
+{
+#endif
+
+//! \brief platform-specific absolute value
+NV_CUDA_CALLABLE NV_FORCE_INLINE float abs(float a)
+{
+ return ::fabsf(a);
+}
+
+//! \brief platform-specific select float
+NV_CUDA_CALLABLE NV_FORCE_INLINE float fsel(float a, float b, float c)
+{
+ return (a >= 0.0f) ? b : c;
+}
+
+//! \brief platform-specific sign
+NV_CUDA_CALLABLE NV_FORCE_INLINE float sign(float a)
+{
+ return (a >= 0.0f) ? 1.0f : -1.0f;
+}
+
+//! \brief platform-specific reciprocal
+NV_CUDA_CALLABLE NV_FORCE_INLINE float recip(float a)
+{
+ return 1.0f / a;
+}
+
+//! \brief platform-specific reciprocal estimate
+NV_CUDA_CALLABLE NV_FORCE_INLINE float recipFast(float a)
+{
+ return 1.0f / a;
+}
+
+//! \brief platform-specific square root
+NV_CUDA_CALLABLE NV_FORCE_INLINE float sqrt(float a)
+{
+ return ::sqrtf(a);
+}
+
+//! \brief platform-specific reciprocal square root
+NV_CUDA_CALLABLE NV_FORCE_INLINE float recipSqrt(float a)
+{
+ return 1.0f / ::sqrtf(a);
+}
+
+//! \brief platform-specific reciprocal square root estimate
+NV_CUDA_CALLABLE NV_FORCE_INLINE float recipSqrtFast(float a)
+{
+ return 1.0f / ::sqrtf(a);
+}
+
+//! \brief platform-specific sine
+NV_CUDA_CALLABLE NV_FORCE_INLINE float sin(float a)
+{
+ return ::sinf(a);
+}
+
+//! \brief platform-specific cosine
+NV_CUDA_CALLABLE NV_FORCE_INLINE float cos(float a)
+{
+ return ::cosf(a);
+}
+
+//! \brief platform-specific minimum
+NV_CUDA_CALLABLE NV_FORCE_INLINE float selectMin(float a, float b)
+{
+ return a < b ? a : b;
+}
+
+//! \brief platform-specific maximum
+NV_CUDA_CALLABLE NV_FORCE_INLINE float selectMax(float a, float b)
+{
+ return a > b ? a : b;
+}
+
+//! \brief platform-specific finiteness check (not INF or NAN)
+NV_CUDA_CALLABLE NV_FORCE_INLINE bool isFinite(float a)
+{
+#ifdef __CUDACC__
+ return !!isfinite(a);
+#else
+ return (0 == ((_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF) & _fpclass(a)));
+#endif
+}
+
+//! \brief platform-specific finiteness check (not INF or NAN)
+NV_CUDA_CALLABLE NV_FORCE_INLINE bool isFinite(double a)
+{
+#ifdef __CUDACC__
+ return !!isfinite(a);
+#else
+ return (0 == ((_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF) & _fpclass(a)));
+#endif
+}
+
+/*!
+Sets \c count bytes starting at \c dst to zero.
+*/
+NV_FORCE_INLINE void* memZero(void* NV_RESTRICT dest, uint32_t count)
+{
+ return memset(dest, 0, count);
+}
+
+/*!
+Sets \c count bytes starting at \c dst to \c c.
+*/
+NV_FORCE_INLINE void* memSet(void* NV_RESTRICT dest, int32_t c, uint32_t count)
+{
+ return memset(dest, c, count);
+}
+
+/*!
+Copies \c count bytes from \c src to \c dst. User memMove if regions overlap.
+*/
+NV_FORCE_INLINE void* memCopy(void* NV_RESTRICT dest, const void* NV_RESTRICT src, uint32_t count)
+{
+ return memcpy(dest, src, count);
+}
+
+/*!
+Copies \c count bytes from \c src to \c dst. Supports overlapping regions.
+*/
+NV_FORCE_INLINE void* memMove(void* NV_RESTRICT dest, const void* NV_RESTRICT src, uint32_t count)
+{
+ return memmove(dest, src, count);
+}
+
+/*!
+Set 128B to zero starting at \c dst+offset. Must be aligned.
+*/
+NV_FORCE_INLINE void memZero128(void* NV_RESTRICT dest, uint32_t offset = 0)
+{
+ NV_ASSERT(((size_t(dest) + offset) & 0x7f) == 0);
+ memSet((char * NV_RESTRICT)dest + offset, 0, 128);
+}
+
+#if !NV_DOXYGEN
+} // namespace intrinsics
+} // namespace nvidia
+#endif
+
+#endif // #ifndef NV_WINDOWS_NVWINDOWSINTRINSICS_H
diff --git a/external/NvFoundation/1.1/include/xbox360/NvXbox360Intrinsics.h b/external/NvFoundation/1.1/include/xbox360/NvXbox360Intrinsics.h
new file mode 100644
index 0000000..8cee763
--- /dev/null
+++ b/external/NvFoundation/1.1/include/xbox360/NvXbox360Intrinsics.h
@@ -0,0 +1,189 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+#ifndef NV_XBOX360_NVXBOX360INTRINSICS_H
+#define NV_XBOX360_NVXBOX360INTRINSICS_H
+
+#include "Nv.h"
+#include "NvAssert.h"
+
+#if !NV_X360
+#error "This file should only be included by xbox builds!!"
+#endif
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
+#ifndef XM_NO_OPERATOR_OVERLOADS
+#define XM_NO_OPERATOR_OVERLOADS
+#endif
+
+#pragma warning(push)
+// 'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives'
+// enumerator 'identifier' in switch of enum 'enumeration' is not handled
+#pragma warning(disable : 4061 4062 4668 4365)
+#include <xtl.h>
+#pragma warning(pop)
+
+#include <PPCIntrinsics.h>
+#include <math.h>
+#include <float.h>
+
+namespace nvidia
+{
+namespace intrinsics
+{
+//! \brief platform-specific absolute value
+NV_FORCE_INLINE float abs(float a)
+{
+ return __fabs(a);
+}
+
+//! \brief platform-specific select float
+NV_FORCE_INLINE float fsel(float a, float b, float c)
+{
+ return __fself(a, b, c);
+}
+
+//! \brief platform-specific sign
+NV_FORCE_INLINE float sign(float a)
+{
+ return __fself(a, 1.0f, -1.0f);
+}
+
+//! \brief platform-specific reciprocal
+NV_FORCE_INLINE float recip(float a)
+{
+ return 1.0f / (a);
+}
+
+//! \brief platform-specific reciprocal estimate
+NV_FORCE_INLINE float recipFast(float a)
+{
+ return __fres(a);
+}
+
+//! \brief platform-specific square root
+NV_FORCE_INLINE float sqrt(float a)
+{
+ return __fsqrts(a);
+}
+
+//! \brief platform-specific reciprocal square root
+NV_FORCE_INLINE float recipSqrt(float a)
+{
+ return recip(__fsqrts(a));
+}
+
+//! \brief platform-specific reciprocal square root estimate
+NV_FORCE_INLINE float recipSqrtFast(float a)
+{
+ return float(__frsqrte(a));
+}
+
+//! \brief platform-specific sine
+NV_FORCE_INLINE float sin(float a)
+{
+ return ::sinf(a);
+}
+
+//! \brief platform-specific cosine
+NV_FORCE_INLINE float cos(float a)
+{
+ return ::cosf(a);
+}
+
+//! \brief platform-specific minimum
+NV_FORCE_INLINE float selectMin(float a, float b)
+{
+ return __fself(a - b, b, a);
+}
+
+//! \brief platform-specific maximum
+NV_FORCE_INLINE float selectMax(float a, float b)
+{
+ return __fself(a - b, a, b);
+}
+
+//! \brief platform-specific finiteness check (not INF or NAN)
+NV_FORCE_INLINE bool isFinite(float a)
+{
+ return 0 == ((_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF) & _fpclass(a));
+}
+
+//! \brief platform-specific finiteness check (not INF or NAN)
+NV_FORCE_INLINE bool isFinite(double a)
+{
+ return 0 == ((_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF) & _fpclass(a));
+}
+
+/*!
+Sets \c count bytes starting at \c dst to zero.
+*/
+NV_FORCE_INLINE void* memZero(void* NV_RESTRICT dest, uint32_t count)
+{
+ return XMemSet(dest, 0, count);
+}
+
+/*!
+Sets \c count bytes starting at \c dst to \c c.
+*/
+NV_FORCE_INLINE void* memSet(void* NV_RESTRICT dest, int32_t c, uint32_t count)
+{
+ return XMemSet(dest, c, count);
+}
+
+/*!
+Copies \c count bytes from \c src to \c dst. User memMove if regions overlap.
+*/
+NV_FORCE_INLINE void* memCopy(void* NV_RESTRICT dest, const void* NV_RESTRICT src, uint32_t count)
+{
+ return XMemCpy(dest, src, count);
+}
+
+/*!
+Copies \c count bytes from \c src to \c dst. Supports overlapping regions.
+*/
+NV_FORCE_INLINE void* memMove(void* NV_RESTRICT dest, const void* NV_RESTRICT src, uint32_t count)
+{
+ return memmove(dest, src, count);
+}
+
+/*!
+Set 128B to zero starting at \c dst+offset. Must be aligned.
+*/
+NV_FORCE_INLINE void memZero128(void* NV_RESTRICT dest, uint32_t offset = 0)
+{
+ NV_ASSERT(((size_t(dest) + offset) & 0x7f) == 0);
+ __dcbz128((int)offset, dest);
+}
+
+} // namespace intrinsics
+} // namespace nvidia
+#endif // #ifndef NV_XBOX360_NVXBOX360INTRINSICS_H
diff --git a/external/NvFoundation/1.1/include/xboxone/NvXboxOneIntrinsics.h b/external/NvFoundation/1.1/include/xboxone/NvXboxOneIntrinsics.h
new file mode 100644
index 0000000..ae58981
--- /dev/null
+++ b/external/NvFoundation/1.1/include/xboxone/NvXboxOneIntrinsics.h
@@ -0,0 +1,188 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, 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. 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 (c) 2008-2014 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef NV_XBOXONE_NVXBOXONEINTRINSICS_H
+#define NV_XBOXONE_NVXBOXONEINTRINSICS_H
+
+#include "Nv.h"
+#include "NvAssert.h"
+
+#if !NV_XBOXONE
+#error "This file should only be included by XboxOne builds!!"
+#endif
+
+#include <math.h>
+#include <float.h>
+
+#if !NV_DOXYGEN
+namespace nvidia
+{
+namespace intrinsics
+{
+#endif
+
+//! \brief platform-specific absolute value
+NV_FORCE_INLINE float abs(float a)
+{
+ return ::fabs(a);
+}
+
+//! \brief platform-specific select float
+NV_FORCE_INLINE float fsel(float a, float b, float c)
+{
+ return (a >= 0.0f) ? b : c;
+}
+
+//! \brief platform-specific sign
+NV_FORCE_INLINE float sign(float a)
+{
+ return (a >= 0.0f) ? 1.0f : -1.0f;
+}
+
+//! \brief platform-specific reciprocal
+NV_FORCE_INLINE float recip(float a)
+{
+ return 1.0f / a;
+}
+
+//! \brief platform-specific reciprocal estimate
+NV_FORCE_INLINE float recipFast(float a)
+{
+ return 1.0f / a;
+}
+
+//! \brief platform-specific square root
+NV_FORCE_INLINE float sqrt(float a)
+{
+ return ::sqrtf(a);
+}
+
+//! \brief platform-specific reciprocal square root
+NV_FORCE_INLINE float recipSqrt(float a)
+{
+ return 1.0f / ::sqrtf(a);
+}
+
+//! \brief platform-specific reciprocal square root estimate
+NV_FORCE_INLINE float recipSqrtFast(float a)
+{
+ return 1.0f / ::sqrtf(a);
+}
+
+//! \brief platform-specific sine
+NV_FORCE_INLINE float sin(float a)
+{
+ return ::sinf(a);
+}
+
+//! \brief platform-specific cosine
+NV_FORCE_INLINE float cos(float a)
+{
+ return ::cosf(a);
+}
+
+//! \brief platform-specific minimum
+NV_FORCE_INLINE float selectMin(float a, float b)
+{
+ return a < b ? a : b;
+}
+
+//! \brief platform-specific maximum
+NV_FORCE_INLINE float selectMax(float a, float b)
+{
+ return a > b ? a : b;
+}
+
+//! \brief platform-specific finiteness check (not INF or NAN)
+NV_FORCE_INLINE bool isFinite(float a)
+{
+#ifdef __CUDACC__
+ return isfinite(a) ? true : false;
+#else
+ return (0 == ((_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF) & _fpclass(a)));
+#endif
+}
+
+//! \brief platform-specific finiteness check (not INF or NAN)
+NV_FORCE_INLINE bool isFinite(double a)
+{
+#ifdef __CUDACC__
+ return isfinite(a) ? true : false;
+#else
+ return (0 == ((_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF) & _fpclass(a)));
+#endif
+}
+
+/*!
+Sets \c count bytes starting at \c dst to zero.
+*/
+NV_FORCE_INLINE void* memZero(void* NV_RESTRICT dest, uint32_t count)
+{
+ return memset(dest, 0, count);
+}
+
+/*!
+Sets \c count bytes starting at \c dst to \c c.
+*/
+NV_FORCE_INLINE void* memSet(void* NV_RESTRICT dest, int32_t c, uint32_t count)
+{
+ return memset(dest, c, count);
+}
+
+/*!
+Copies \c count bytes from \c src to \c dst. User memMove if regions overlap.
+*/
+NV_FORCE_INLINE void* memCopy(void* NV_RESTRICT dest, const void* NV_RESTRICT src, uint32_t count)
+{
+ return memcpy(dest, src, count);
+}
+
+/*!
+Copies \c count bytes from \c src to \c dst. Supports overlapping regions.
+*/
+NV_FORCE_INLINE void* memMove(void* NV_RESTRICT dest, const void* NV_RESTRICT src, uint32_t count)
+{
+ return memmove(dest, src, count);
+}
+
+/*!
+Set 128B to zero starting at \c dst+offset. Must be aligned.
+*/
+NV_FORCE_INLINE void memZero128(void* NV_RESTRICT dest, uint32_t offset = 0)
+{
+ NV_ASSERT(((size_t(dest) + offset) & 0x7f) == 0);
+ memSet((char * NV_RESTRICT)dest + offset, 0, 128);
+}
+
+#if !NV_DOXYGEN
+} // namespace intrinsics
+} // namespace nvidia
+#endif
+
+#endif // #ifndef NV_XBOXONE_NVXBOXONEINTRINSICS_H
diff --git a/include/Nv/VolumetricLighting/NvVolumetricLighting.h b/include/Nv/VolumetricLighting/NvVolumetricLighting.h
new file mode 100644
index 0000000..91a11f7
--- /dev/null
+++ b/include/Nv/VolumetricLighting/NvVolumetricLighting.h
@@ -0,0 +1,511 @@
+// 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 (c) 2003 - 2016 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.
+//
+
+
+/*==============================================================================
+ NvVolumetricLighting.h
+================================================================================
+
+NVIDIA Volumetric Lighting
+-----------------------------------------
+Gameworks Volumetric Lighting provides dynamic, physically-based light
+scattering based on application-provided media properties and existing
+shadowing information.
+
+ENGINEERING CONTACT
+Nathan Hoobler (NVIDIA Devtech)
+
+==============================================================================*/
+#ifndef NVVOLUMETRICLIGHTING_H
+#define NVVOLUMETRICLIGHTING_H
+////////////////////////////////////////////////////////////////////////////////
+
+/*==============================================================================
+NvFoundation Includes
+==============================================================================*/
+
+#include <Nv.h>
+#include <NvPreprocessor.h>
+#include <NvCTypes.h>
+
+/*==============================================================================
+Forward Declarations
+==============================================================================*/
+
+#if defined(NV_PLATFORM_D3D11)
+struct ID3D11Device;
+struct ID3D11DeviceContext;
+struct ID3D11RenderTargetView;
+struct ID3D11DepthStencilView;
+struct ID3D11ShaderResourceView;
+#endif
+
+// [Add other platforms here]
+
+////////////////////////////////////////////////////////////////////////////////
+#if (!NV_DOXYGEN)
+namespace Nv {
+using namespace nvidia;
+namespace VolumetricLighting {
+#endif
+////////////////////////////////////////////////////////////////////////////////
+
+/*==============================================================================
+ Library Version
+==============================================================================*/
+
+//! Describes the library version
+struct VersionDesc
+{
+ uint32_t Major; //!< Major version of the product, changed manually with every product release with a large new feature set. API refactoring. Breaks backwards compatibility
+ uint32_t Minor; //!< Minor version of the product, changed manually with every minor product release containing some features. Minor API changes
+ uint32_t Build; //!< Very minor version of the product, mostly for bug fixing. No API changes, serialization compatible.
+ uint32_t Revision; //!< Latest Perforce revision of the codebase used for this build.
+};
+
+//! Current library version number
+const VersionDesc LIBRARY_VERSION={1,0,0,0/*VERSIONCHANGELISTREPLACETOKEN*/};
+
+/*==============================================================================
+ Platform-dependent wrappers
+==============================================================================*/
+
+//! Rendering context information for platform
+union PlatformRenderCtx
+{
+#if defined(NV_PLATFORM_D3D11)
+ ID3D11DeviceContext* d3d11;
+ PlatformRenderCtx(ID3D11DeviceContext* x) : d3d11(x){};
+ operator ID3D11DeviceContext*() { return d3d11; }
+#endif
+ // [Add other platforms here]
+};
+
+//! Render target information for platform
+union PlatformRenderTarget
+{
+#if defined(NV_PLATFORM_D3D11)
+ ID3D11RenderTargetView* d3d11;
+ PlatformRenderTarget(ID3D11RenderTargetView* x) : d3d11(x){};
+ operator ID3D11RenderTargetView*() { return d3d11; }
+#endif
+ // [Add other platforms here]
+};
+
+//! Depth-Stencil target information for platform
+union PlatformDepthStencilTarget
+{
+#if defined(NV_PLATFORM_D3D11)
+ ID3D11DepthStencilView* d3d11;
+ PlatformDepthStencilTarget(ID3D11DepthStencilView* x) : d3d11(x){};
+ operator ID3D11DepthStencilView*() { return d3d11; }
+#endif
+ // [Add other platforms here]
+};
+
+//! Surface shader resource information for platform
+union PlatformShaderResource
+{
+#if defined(NV_PLATFORM_D3D11)
+ ID3D11ShaderResourceView* d3d11;
+ PlatformShaderResource(ID3D11ShaderResourceView* x) : d3d11(x){};
+ operator ID3D11ShaderResourceView*() { return d3d11; }
+#endif
+ // [Add other platforms here]
+};
+
+/*==============================================================================
+ API Types and Enums
+==============================================================================*/
+
+//! Context used for an instance of the library used for rendering
+typedef void * Context;
+
+//! Return codes returned by library API functions
+enum class Status
+{
+ OK = 0, //!< Success
+ FAIL = -1, //!< Unspecified Failure
+ INVALID_VERSION = -2, //!< Mismatch between header and dll
+ UNINITIALIZED = -3, //!< API call made before the library has been properly initialized
+ UNIMPLEMENTED = -4, //!< Call not implemented for platform
+ INVALID_PARAMETER = -5, //!< One or more invalid parameters
+ UNSUPPORTED_DEVICE = -6, //!< Device doesn't support necessary features
+ RESOURCE_FAILURE = -7, //!< Failed to allocate a resource
+ API_ERROR = -8, //!< The platform API returned an error to the library
+};
+
+//! Platform/API IDs
+enum class PlatformName
+{
+ UNKNOWN = -1,
+ #if defined(NV_PLATFORM_D3D11)
+ D3D11, //!< Direct3D 11
+ #endif
+ // [Add other platforms here]
+ COUNT
+};
+
+//! Debug mode constants (bit flags)
+enum class DebugFlags
+{
+ NONE = 0x00000000, //!< No debug visualizations
+ WIREFRAME = 0x00000001, //!< Render volume as wireframe
+ NO_BLENDING = 0x00000002 //!< Don't blend scene into output
+};
+
+//! Specifies the godrays buffer resolution relative to framebuffer
+enum class DownsampleMode
+{
+ UNKNOWN = -1,
+ FULL, //!< Same resolution as framebuffer
+ HALF, //!< Half dimensions of framebuffer (1x downsample)
+ QUARTER, //!< Quarter dimensions of framebuffer (2x downsample)
+ COUNT
+};
+
+//! Specifies the godrays buffer sample rate
+enum class MultisampleMode
+{
+ UNKNOWN = -1,
+ SINGLE, //!< Single-sample
+ MSAA2, //!< 2x MSAA
+ MSAA4, //!< 4x MSAA
+ COUNT
+};
+
+enum class FilterMode
+{
+ UNKNOWN = -1,
+ NONE, //!< No post-processing filter
+ TEMPORAL, //!< Temporal AA on post-process output
+};
+
+//! Phase function to use for this media term
+enum class PhaseFunctionType
+{
+ UNKNOWN = -1,
+ ISOTROPIC, //!< Isotropic scattering (equivalent to HG with 0 eccentricity, but more efficient)
+ RAYLEIGH, //!< Rayleigh scattering term (air/small molecules)
+ HENYEYGREENSTEIN, //!< Scattering term with variable anisotropy
+ MIE_HAZY, //!< Slightly forward-scattering
+ MIE_MURKY, //!< Densely forward-scattering
+ COUNT
+};
+
+//! Specifies the geometric mapping of the shadow map
+enum class ShadowMapLayout
+{
+ UNKNOWN = -1,
+ SIMPLE, //!< Simple frustum depth texture
+ CASCADE_ATLAS, //!< Multiple depth views combined into one texture
+ CASCADE_ARRAY, //!< Multiple depth views as texture array slices
+ PARABOLOID, //!< Depth mapped using paraboloid warping
+ COUNT
+};
+
+//! Specifies the encoding of shadow map samples
+enum class ShadowMapFormat
+{
+ UNKNOWN = -1,
+ DEPTH, //!< Simple depth-buffer output
+ COUNT
+};
+
+//! Specifies the class of light source
+enum class LightType
+{
+ UNKNOWN = -1,
+ DIRECTIONAL, //!< Simple analytic directional light (like the sun)
+ SPOTLIGHT, //!< Spotlight with frustum shadow map and angular falloff
+ OMNI, //!< Omni-directional local light source
+ COUNT
+};
+
+//! Specifies the type of distance attenuation applied to the light
+enum class AttenuationMode
+{
+ UNKNOWN = -1,
+ NONE, //!< No attenuation
+ POLYNOMIAL, //!< f(x) = 1-(A+Bx+Cx^2)
+ INV_POLYNOMIAL, //!< f(x) = 1/(A+Bx+Cx^2)+D
+ COUNT
+};
+
+//! Specifies the type of angular falloff to apply to the spotlight
+enum class SpotlightFalloffMode
+{
+ UNKNOWN = -1,
+ NONE, //!< No falloff (constant brightness across cone cross-section)
+ FIXED, //!< A_fixed(vL, vP) = (dot(vL, vP) - theta_max)/(1 - theta_max)
+ CUSTOM, //!< A_custom(vL, vP) = (A_fixed(vL, vP))^n
+ COUNT
+};
+
+//! Amount of tessellation to use
+enum class TessellationQuality
+{
+ UNKNOWN = -1,
+ LOW, //!< Low amount of tessellation (16x)
+ MEDIUM, //!< Medium amount of tessellation (32x)
+ HIGH, //!< High amount of tessellation (64x)
+ COUNT
+};
+
+//! Quality of upsampling
+enum class UpsampleQuality
+{
+ UNKNOWN = -1,
+ POINT, //!< Point sampling (no filter)
+ BILINEAR, //!< Bilinear Filtering
+ BILATERAL, //!< Bilateral Filtering (using depth)
+ COUNT
+};
+
+//! Platform-specific parameters
+struct PlatformDesc
+{
+ PlatformName platform; //!< Platform identifier
+ union
+ {
+ #if defined(NV_PLATFORM_D3D11) || defined(GFSDK_PLATFORM_DURANGO)
+ struct
+ {
+ ID3D11Device *pDevice; //!< D3D11 Device to use for context
+ } d3d11;
+ #endif
+ // [Add other platforms here]
+ };
+};
+
+//! Context description
+struct ContextDesc
+{
+ struct
+ {
+ uint32_t uWidth; //!< Width of output/depth surface
+ uint32_t uHeight; //!< Height of output/depth surface
+ uint32_t uSamples; //!< Sample rate of output/depth surface
+ } framebuffer;
+ DownsampleMode eDownsampleMode; //!< Target resolution of internal buffer
+ MultisampleMode eInternalSampleMode; //!< Target sample rate of internal buffer
+ FilterMode eFilterMode; //!< Type of filtering to do on the output
+};
+
+//! Viewer Camera/Framebuffer Description
+struct ViewerDesc
+{
+ NvcMat44 mProj; //!< Camera projection transform
+ NvcMat44 mViewProj; //!< Camera view-proj transform
+ NvcVec3 vEyePosition; //!< Camera position in world-space
+ uint32_t uViewportWidth; //!< Viewport Width (may differ from framebuffer)
+ uint32_t uViewportHeight; //!< Viewport Height (may differ from framebuffer)
+};
+
+//! Describes one component of the phase function
+struct PhaseTerm
+{
+ PhaseFunctionType ePhaseFunc; //!< Phase function this term uses
+ NvcVec3 vDensity; //!< Optical density in [R,G,B]
+ float fEccentricity; //!< Degree/direction of anisotropy (-1, 1) (HG only)
+};
+
+//! Maximum number of phase terms in a medium
+const uint32_t MAX_PHASE_TERMS = 4;
+
+//! Volume Medium Description
+struct MediumDesc
+{
+ NvcVec3 vAbsorption; //!< Absorpsive component of the medium
+ uint32_t uNumPhaseTerms; //!< Number of valid phase terms
+
+ //! Phase term definitions
+ PhaseTerm PhaseTerms[MAX_PHASE_TERMS];
+
+};
+
+//! Describes an individual slice in a shadow map cascade
+struct ShadowMapElementDesc
+{
+ NvcMat44 mViewProj; //!< View-Proj transform for cascade
+ uint32_t uOffsetX; //!< X-offset within texture
+ uint32_t uOffsetY; //!< Y-offset within texture
+ uint32_t uWidth; //!< Footprint width within texture
+ uint32_t uHeight; //!< Footprint height within texture
+ uint32_t mArrayIndex; //!< Texture array index for this element (if used)
+};
+
+//! Maximum number of sub-elements in a shadow map set
+const uint32_t MAX_SHADOWMAP_ELEMENTS = 4;
+
+//! Shadow Map Structural Description
+struct ShadowMapDesc
+{
+ ShadowMapLayout eType; //!< Shadow map structure type
+ uint32_t uWidth; //!< Shadow map texture width
+ uint32_t uHeight; //!< Shadow map texture height
+ uint32_t uElementCount; //!< Number of sub-elements in the shadow map
+
+ //! Individual cascade descriptions
+ ShadowMapElementDesc Elements[MAX_SHADOWMAP_ELEMENTS];
+};
+
+//! Light Source Description
+struct LightDesc
+{
+ LightType eType; //!< Type of light source
+ NvcMat44 mLightToWorld; //!< Light clip-space to world-space transform
+ NvcVec3 vIntensity; //!< Color of light
+ union
+ {
+ //! LightType = Directional
+ struct {
+ NvcVec3 vDirection; //!< Normalized light direction
+ } Directional;
+
+ //! LightType = Spotlight
+ struct {
+ NvcVec3 vDirection; //!< Normalized light direction
+ NvcVec3 vPosition; //!< Light position in world-space
+ float fZNear; //!< World-space distance to near view plane
+ float fZFar; //!< World-space distance to far view plane
+ SpotlightFalloffMode eFalloffMode; //!< Equation to use for angular falloff
+ float fFalloff_CosTheta; //!< Spotlight falloff angle
+ float fFalloff_Power; //!< Spotlight power
+ AttenuationMode eAttenuationMode; //!< Light falloff equation
+ float fAttenuationFactors[4]; //!< Factors in the attenuation equation
+ } Spotlight;
+
+ //! LightType = Omni
+ struct {
+ NvcVec3 vPosition; //!< Light position in world-space
+ float fZNear; //!< World-space distance to near view plane
+ float fZFar; //!< World-space distance to far view plane
+ AttenuationMode eAttenuationMode; //!< Light falloff equation
+ float fAttenuationFactors[4]; //!< Factors in the attenuation equation
+ } Omni;
+ };
+};
+
+//! Parameters for Volume Generation
+struct VolumeDesc
+{
+ float fTargetRayResolution; //!< Target minimum ray width in pixels
+ uint32_t uMaxMeshResolution; //!< Maximum geometric resolution of the mesh. Accounts for requested tessellation quality.
+ float fDepthBias; //!< Amount to bias ray geometry depth
+ TessellationQuality eTessQuality; //!< Quality level of tessellation to use
+};
+
+//! Post-Processing Behavior Description
+struct PostprocessDesc
+{
+ NvcMat44 mUnjitteredViewProj; //!< Camera view projection without jitter
+ float fTemporalFactor; //!< Weight of pixel history smoothing (0.0 for off)
+ float fFilterThreshold; //!< Threshold of frame movement to use temporal history
+ UpsampleQuality eUpsampleQuality; //!< Quality of upsampling to use
+ NvcVec3 vFogLight; //!< Light to use as "faked" multiscattering
+ float fMultiscatter; //<! strength of faked multiscatter effect
+ bool bDoFog; //!< Apply fogging based on scattering
+ bool bIgnoreSkyFog; //!< Ignore depth values of (1.0f) for fogging
+ float fBlendfactor; //!< Blend factor to use for compositing
+
+};
+
+/*==============================================================================
+ API Definition
+==============================================================================*/
+
+#define NV_VOLUMETRICLIGHTING_API(r) NV_DLL_EXPORT r NV_CALL_CONV
+
+//! Load the library and initialize global state
+NV_VOLUMETRICLIGHTING_API(Status) OpenLibrary(
+ NvAllocatorCallback * allocator = nullptr, //!< (opt) Memory management handler for library
+ NvAssertHandler * assert_handler = nullptr, //!< (opt) Assertion handler for library
+ const VersionDesc & link_version = LIBRARY_VERSION //!< Requested library version (do not set)
+ );
+
+//! Release the library and resources, and uninitialize all global state
+NV_VOLUMETRICLIGHTING_API(Status) CloseLibrary();
+
+//! Create a new rendering interface
+NV_VOLUMETRICLIGHTING_API(Status) CreateContext(
+ Context & out_ctx, //!< Pointer to contain newly created context
+ const PlatformDesc * pPlatformDesc, //!< Platform-specific data
+ const ContextDesc * pContextDesc //!< Context description
+ );
+
+//! Release the context and any associated resources
+NV_VOLUMETRICLIGHTING_API(Status) ReleaseContext(
+ Context & ctx //!< Library context to release
+ );
+
+//! Begin accumulation of lighting volumes for a view
+NV_VOLUMETRICLIGHTING_API(Status) BeginAccumulation(
+ Context ctx, //!< Library context to operate on
+ PlatformRenderCtx renderCtx, //!< Context to use for rendering
+ PlatformShaderResource sceneDepth, //!< Scene Depth-Buffer
+ ViewerDesc const* pViewerDesc, //!< Description of camera space
+ MediumDesc const* pMediumDesc, //!< Description of medium
+ DebugFlags debugFlags = DebugFlags::NONE //!< Debug flags to apply for this pass
+ );
+
+//! Add a lighting volume to the accumulated results
+NV_VOLUMETRICLIGHTING_API(Status) RenderVolume(
+ Context ctx, //!< Library context to operate on
+ PlatformRenderCtx renderCtx, //!< Context to use for rendering
+ PlatformShaderResource shadowMap, //!< Shadow map resource
+ ShadowMapDesc const* pShadowMapDesc, //!< Shadow map layout description
+ LightDesc const* pLightDesc, //!< Light source description
+ VolumeDesc const* pVolumeDesc //!< Parameters for volume generation
+ );
+
+//! Finish accumulation of lighting volumes
+NV_VOLUMETRICLIGHTING_API(Status) EndAccumulation(
+ Context ctx, //!< Library context to operate on
+ PlatformRenderCtx renderCtx //!< Context to use for rendering
+ );
+
+//! Resolve the results and composite into the provided scene
+NV_VOLUMETRICLIGHTING_API(Status) ApplyLighting(
+ Context ctx, //!< Library context to operate on
+ PlatformRenderCtx renderCtx, //!< Context to use for rendering
+ PlatformRenderTarget sceneTarget, //!< Render target to composite into
+ PlatformShaderResource sceneDepth, //!< Depth buffer for scene
+ PostprocessDesc const* pPostprocessDesc //!< Options for how to perform the resolve and composite
+ );
+
+////////////////////////////////////////////////////////////////////////////////
+#if (!NV_DOXYGEN)
+}; /*namespace VolumetricLighting*/
+namespace Vl = VolumetricLighting;
+}; /*namespace Nv*/
+namespace NvVl = Nv::VolumetricLighting;
+#endif
+////////////////////////////////////////////////////////////////////////////////
+#endif // NVVOLUMETRICLIGHTING_H
diff --git a/lib/win64/NvVolumetricLighting.win64.lib b/lib/win64/NvVolumetricLighting.win64.lib
new file mode 100644
index 0000000..4997687
--- /dev/null
+++ b/lib/win64/NvVolumetricLighting.win64.lib
Binary files differ
diff --git a/redist/win64/NvVolumetricLighting.win64.dll b/redist/win64/NvVolumetricLighting.win64.dll
new file mode 100644
index 0000000..0f3aff4
--- /dev/null
+++ b/redist/win64/NvVolumetricLighting.win64.dll
Binary files differ
diff --git a/redist/win64/NvVolumetricLighting.win64.dll.pdb b/redist/win64/NvVolumetricLighting.win64.dll.pdb
new file mode 100644
index 0000000..b673aff
--- /dev/null
+++ b/redist/win64/NvVolumetricLighting.win64.dll.pdb
Binary files differ
diff --git a/samples/VolumetricLightingTest/common.h b/samples/VolumetricLightingTest/common.h
new file mode 100644
index 0000000..3b214ca
--- /dev/null
+++ b/samples/VolumetricLightingTest/common.h
@@ -0,0 +1,264 @@
+// 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 (c) 2003 - 2016 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 COMMON_H
+#define COMMON_H
+////////////////////////////////////////////////////////////////////////////////
+
+#include <NvPreprocessor.h>
+#include <NvAssert.h>
+#include <NvIntrinsics.h>
+#include <NvMath.h>
+#include <NvFoundationMath.h>
+#include <NvCTypes.h>
+
+namespace Nv
+{
+ using namespace nvidia;
+} // namespace Nv
+
+/*==============================================================================
+ GFSDK Conversion stubs
+==============================================================================*/
+
+NV_FORCE_INLINE NvcVec2 NVtoNVC(const Nv::NvVec2 & rhs)
+{
+ return *reinterpret_cast<const NvcVec2 *>(&rhs);
+}
+
+NV_FORCE_INLINE NvcVec3 NVtoNVC(const Nv::NvVec3 & rhs)
+{
+ return *reinterpret_cast<const NvcVec3 *>(&rhs);
+}
+
+NV_FORCE_INLINE NvcVec4 NVtoNVC(const Nv::NvVec4 & rhs)
+{
+ return *reinterpret_cast<const NvcVec4 *>(&rhs);
+}
+
+NV_FORCE_INLINE NvcMat44 NVtoNVC(const Nv::NvMat44 & rhs)
+{
+ return *reinterpret_cast<const NvcMat44 *>(&rhs);
+}
+
+
+NV_FORCE_INLINE Nv::NvMat44 PerspectiveProjLH(float fov, float aspect, float zn, float zf)
+{
+ Nv::NvMat44 p(Nv::NvZero);
+ float cot_fov = Nv::intrinsics::cos(fov) / Nv::intrinsics::sin(fov);
+ p(0, 0) = cot_fov / aspect;
+ p(1, 1) = cot_fov;
+ p(2, 2) = zf / (zf - zn);
+ p(2, 3) = -zn * zf / (zf - zn);
+ p(3, 2) = 1.0;
+ return p;
+}
+
+NV_FORCE_INLINE Nv::NvMat44 OrthographicProjLH(float width, float height, float zn, float zf)
+{
+ Nv::NvMat44 p(Nv::NvZero);
+ p(0, 0) = 2.0f / width;
+ p(1, 1) = 2.0f / height;
+ p(2, 2) = 1 / (zf - zn);
+ p(2, 3) = zn / (zf - zn);
+ p(3, 3) = 1.0f;
+ return p;
+}
+
+NV_FORCE_INLINE Nv::NvMat44 LookAtTransform(const Nv::NvVec3 & eye, const Nv::NvVec3 & at, const Nv::NvVec3 & up)
+{
+ Nv::NvVec3 zaxis = at - eye;
+ zaxis.normalize();
+ Nv::NvVec3 xaxis = up.cross(zaxis);
+ xaxis.normalize();
+ Nv::NvVec3 yaxis = zaxis.cross(xaxis);
+ return Nv::NvMat44(
+ Nv::NvVec4(xaxis.x, yaxis.x, zaxis.x, 0),
+ Nv::NvVec4(xaxis.y, yaxis.y, zaxis.y, 0),
+ Nv::NvVec4(xaxis.z, yaxis.z, zaxis.z, 0),
+ Nv::NvVec4(-xaxis.dot(eye), -yaxis.dot(eye), -zaxis.dot(eye), 1));
+}
+
+NV_FORCE_INLINE Nv::NvMat44 Inverse(const Nv::NvMat44 & in)
+{
+ const float * m = in.front();
+ float inv[16];
+ float det;
+ int i;
+
+ inv[0] = m[5] * m[10] * m[15] -
+ m[5] * m[11] * m[14] -
+ m[9] * m[6] * m[15] +
+ m[9] * m[7] * m[14] +
+ m[13] * m[6] * m[11] -
+ m[13] * m[7] * m[10];
+
+ inv[4] = -m[4] * m[10] * m[15] +
+ m[4] * m[11] * m[14] +
+ m[8] * m[6] * m[15] -
+ m[8] * m[7] * m[14] -
+ m[12] * m[6] * m[11] +
+ m[12] * m[7] * m[10];
+
+ inv[8] = m[4] * m[9] * m[15] -
+ m[4] * m[11] * m[13] -
+ m[8] * m[5] * m[15] +
+ m[8] * m[7] * m[13] +
+ m[12] * m[5] * m[11] -
+ m[12] * m[7] * m[9];
+
+ inv[12] = -m[4] * m[9] * m[14] +
+ m[4] * m[10] * m[13] +
+ m[8] * m[5] * m[14] -
+ m[8] * m[6] * m[13] -
+ m[12] * m[5] * m[10] +
+ m[12] * m[6] * m[9];
+
+ inv[1] = -m[1] * m[10] * m[15] +
+ m[1] * m[11] * m[14] +
+ m[9] * m[2] * m[15] -
+ m[9] * m[3] * m[14] -
+ m[13] * m[2] * m[11] +
+ m[13] * m[3] * m[10];
+
+ inv[5] = m[0] * m[10] * m[15] -
+ m[0] * m[11] * m[14] -
+ m[8] * m[2] * m[15] +
+ m[8] * m[3] * m[14] +
+ m[12] * m[2] * m[11] -
+ m[12] * m[3] * m[10];
+
+ inv[9] = -m[0] * m[9] * m[15] +
+ m[0] * m[11] * m[13] +
+ m[8] * m[1] * m[15] -
+ m[8] * m[3] * m[13] -
+ m[12] * m[1] * m[11] +
+ m[12] * m[3] * m[9];
+
+ inv[13] = m[0] * m[9] * m[14] -
+ m[0] * m[10] * m[13] -
+ m[8] * m[1] * m[14] +
+ m[8] * m[2] * m[13] +
+ m[12] * m[1] * m[10] -
+ m[12] * m[2] * m[9];
+
+ inv[2] = m[1] * m[6] * m[15] -
+ m[1] * m[7] * m[14] -
+ m[5] * m[2] * m[15] +
+ m[5] * m[3] * m[14] +
+ m[13] * m[2] * m[7] -
+ m[13] * m[3] * m[6];
+
+ inv[6] = -m[0] * m[6] * m[15] +
+ m[0] * m[7] * m[14] +
+ m[4] * m[2] * m[15] -
+ m[4] * m[3] * m[14] -
+ m[12] * m[2] * m[7] +
+ m[12] * m[3] * m[6];
+
+ inv[10] = m[0] * m[5] * m[15] -
+ m[0] * m[7] * m[13] -
+ m[4] * m[1] * m[15] +
+ m[4] * m[3] * m[13] +
+ m[12] * m[1] * m[7] -
+ m[12] * m[3] * m[5];
+
+ inv[14] = -m[0] * m[5] * m[14] +
+ m[0] * m[6] * m[13] +
+ m[4] * m[1] * m[14] -
+ m[4] * m[2] * m[13] -
+ m[12] * m[1] * m[6] +
+ m[12] * m[2] * m[5];
+
+ inv[3] = -m[1] * m[6] * m[11] +
+ m[1] * m[7] * m[10] +
+ m[5] * m[2] * m[11] -
+ m[5] * m[3] * m[10] -
+ m[9] * m[2] * m[7] +
+ m[9] * m[3] * m[6];
+
+ inv[7] = m[0] * m[6] * m[11] -
+ m[0] * m[7] * m[10] -
+ m[4] * m[2] * m[11] +
+ m[4] * m[3] * m[10] +
+ m[8] * m[2] * m[7] -
+ m[8] * m[3] * m[6];
+
+ inv[11] = -m[0] * m[5] * m[11] +
+ m[0] * m[7] * m[9] +
+ m[4] * m[1] * m[11] -
+ m[4] * m[3] * m[9] -
+ m[8] * m[1] * m[7] +
+ m[8] * m[3] * m[5];
+
+ inv[15] = m[0] * m[5] * m[10] -
+ m[0] * m[6] * m[9] -
+ m[4] * m[1] * m[10] +
+ m[4] * m[2] * m[9] +
+ m[8] * m[1] * m[6] -
+ m[8] * m[2] * m[5];
+
+ det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
+
+ if (det == 0)
+ return Nv::NvMat44(Nv::NvZero);
+
+ det = 1.0f / det;
+
+ for (i = 0; i < 16; i++)
+ inv[i] = inv[i] * det;
+
+ return Nv::NvMat44(inv);
+}
+/*==============================================================================
+ Helper Macros
+==============================================================================*/
+
+#ifdef _DEBUG
+# include <stdio.h>
+# include <assert.h>
+# if defined(WIN31) || defined(WIN63)
+# define LOG(fmt, ...) { char debug_string[1024]; _snprintf_c(debug_string, 1024, fmt, ##__VA_ARGS__); OutputDebugStringA(debug_string); }
+# define ASSERT_LOG(test, msg, ...) if (!(test)) { LOG(msg "\n", ##__VA_ARGS__); DebugBreak(); }
+# else
+# define LOG(fmt, ...) printf(fmt, ##__VA_ARGS__)
+# define ASSERT_LOG(test, msg, ...) if (!(test)) { LOG(msg, ##__VA_ARGS__); abort(); }
+# endif
+#else
+# define LOG(fmt, ...)
+# define ASSERT_LOG(test, msg, ...)
+#endif
+
+#define VALIDATE(r, e) if (FAILED(r)) { LOG("Call Failure: %u\n", r); return e; };
+#define SIZE_OF_ARRAY(a) (sizeof(a)/sizeof(a[0]))
+#define SAFE_DELETE(x) if((x) != nullptr) {delete (x); (x)=nullptr;}
+#define SAFE_RELEASE(x) if((x) != nullptr) {(x)->Release(); (x)=nullptr;}
+#define SAFE_RELEASE_ARRAY(x) for (unsigned _sr_count=0; _sr_count<SIZE_OF_ARRAY(x); ++_sr_count) {if((x)[_sr_count] != nullptr) {((IUnknown *)(x)[_sr_count])->Release(); (x)[_sr_count]=nullptr;}}
+#define SAFE_DELETE_ARRAY(x) if (x != nullptr) {SAFE_RELEASE_ARRAY(x); delete[] x; x=nullptr;}
+
+#endif // COMMON_H
diff --git a/samples/VolumetricLightingTest/d3d11/DeviceManager.cpp b/samples/VolumetricLightingTest/d3d11/DeviceManager.cpp
new file mode 100644
index 0000000..122da86
--- /dev/null
+++ b/samples/VolumetricLightingTest/d3d11/DeviceManager.cpp
@@ -0,0 +1,609 @@
+// TAGRELEASE: PUBLIC
+#include "common.h"
+
+#include "DeviceManager.h"
+#include <WinUser.h>
+#include <Windows.h>
+
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }
+#endif
+
+#define WINDOW_CLASS_NAME L"NvDX11"
+
+#define WINDOW_STYLE_NORMAL (WS_OVERLAPPEDWINDOW | WS_VISIBLE)
+#define WINDOW_STYLE_FULLSCREEN (WS_POPUP | WS_SYSMENU | WS_VISIBLE)
+
+// A singleton, sort of... To pass the events from WindowProc to the object.
+DeviceManager* g_DeviceManagerInstance = NULL;
+
+LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if(g_DeviceManagerInstance)
+ return g_DeviceManagerInstance->MsgProc(hWnd, uMsg, wParam, lParam);
+ else
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+
+HRESULT
+DeviceManager::CreateWindowDeviceAndSwapChain(const DeviceCreationParameters& params, LPWSTR title)
+{
+ g_DeviceManagerInstance = this;
+ m_WindowTitle = title;
+
+ HINSTANCE hInstance = GetModuleHandle(NULL);
+ WNDCLASSEX windowClass = { sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, WindowProc,
+ 0L, 0L, hInstance, NULL, NULL, NULL, NULL, WINDOW_CLASS_NAME, NULL };
+
+ RegisterClassEx(&windowClass);
+
+ UINT windowStyle = params.startFullscreen
+ ? WINDOW_STYLE_FULLSCREEN
+ : params.startMaximized
+ ? (WINDOW_STYLE_NORMAL | WS_MAXIMIZE)
+ : WINDOW_STYLE_NORMAL;
+
+ RECT rect = { 0, 0, params.backBufferWidth, params.backBufferHeight };
+ AdjustWindowRect(&rect, windowStyle, FALSE);
+
+ m_hWnd = CreateWindowEx(
+ 0,
+ WINDOW_CLASS_NAME,
+ title,
+ windowStyle,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ GetDesktopWindow(),
+ NULL,
+ hInstance,
+ NULL
+ );
+
+ if(!m_hWnd)
+ {
+#ifdef DEBUG
+ DWORD errorCode = GetLastError();
+ printf("CreateWindowEx error code = 0x%x\n", errorCode);
+#endif
+
+ MessageBox(NULL, L"Cannot create window", m_WindowTitle.c_str(), MB_OK | MB_ICONERROR);
+ return E_FAIL;
+ }
+
+ UpdateWindow(m_hWnd);
+
+ HRESULT hr = E_FAIL;
+
+ RECT clientRect;
+ GetClientRect(m_hWnd, &clientRect);
+ UINT width = clientRect.right - clientRect.left;
+ UINT height = clientRect.bottom - clientRect.top;
+
+ ZeroMemory(&m_SwapChainDesc, sizeof(m_SwapChainDesc));
+ m_SwapChainDesc.BufferCount = params.swapChainBufferCount;
+ m_SwapChainDesc.BufferDesc.Width = width;
+ m_SwapChainDesc.BufferDesc.Height = height;
+ m_SwapChainDesc.BufferDesc.Format = params.swapChainFormat;
+ m_SwapChainDesc.BufferDesc.RefreshRate.Numerator = params.refreshRate;
+ m_SwapChainDesc.BufferDesc.RefreshRate.Denominator = 0;
+ m_SwapChainDesc.BufferUsage = params.swapChainUsage;
+ m_SwapChainDesc.OutputWindow = m_hWnd;
+ m_SwapChainDesc.SampleDesc.Count = params.swapChainSampleCount;
+ m_SwapChainDesc.SampleDesc.Quality = 0;
+ m_SwapChainDesc.Windowed = !params.startFullscreen;
+ m_SwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
+
+ hr = D3D11CreateDeviceAndSwapChain(
+ NULL, // pAdapter
+ params.driverType, // DriverType
+ NULL, // Software
+ params.createDeviceFlags, // Flags
+ &params.featureLevel, // pFeatureLevels
+ 1, // FeatureLevels
+ D3D11_SDK_VERSION, // SDKVersion
+ &m_SwapChainDesc, // pSwapChainDesc
+ &m_SwapChain, // ppSwapChain
+ &m_Device, // ppDevice
+ NULL, // pFeatureLevel
+ &m_ImmediateContext // ppImmediateContext
+ );
+
+ if(FAILED(hr))
+ return hr;
+
+ m_DepthStencilDesc.ArraySize = 1;
+ m_DepthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+ m_DepthStencilDesc.CPUAccessFlags = 0;
+ m_DepthStencilDesc.Format = params.depthStencilFormat;
+ m_DepthStencilDesc.Width = width;
+ m_DepthStencilDesc.Height = height;
+ m_DepthStencilDesc.MipLevels = 1;
+ m_DepthStencilDesc.MiscFlags = 0;
+ m_DepthStencilDesc.SampleDesc.Count = params.swapChainSampleCount;
+ m_DepthStencilDesc.SampleDesc.Quality = 0;
+ m_DepthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
+
+ hr = CreateRenderTargetAndDepthStencil();
+
+ if(FAILED(hr))
+ return hr;
+
+ DeviceCreated();
+ BackBufferResized();
+
+ return S_OK;
+}
+
+void
+DeviceManager::Shutdown()
+{
+ if(m_SwapChain && GetWindowState() == kWindowFullscreen)
+ m_SwapChain->SetFullscreenState(false, NULL);
+
+ DeviceDestroyed();
+
+ SAFE_RELEASE(m_BackBufferRTV);
+ SAFE_RELEASE(m_DepthStencilDSV);
+ SAFE_RELEASE(m_DepthStencilBuffer);
+
+ g_DeviceManagerInstance = NULL;
+ SAFE_RELEASE(m_SwapChain);
+ SAFE_RELEASE(m_Device);
+
+ if(m_hWnd)
+ {
+ DestroyWindow(m_hWnd);
+ m_hWnd = NULL;
+ }
+}
+
+HRESULT
+DeviceManager::CreateRenderTargetAndDepthStencil()
+{
+ HRESULT hr;
+
+ ID3D11Texture2D *backBuffer = NULL;
+ hr = m_SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBuffer);
+ if (FAILED(hr))
+ return hr;
+
+ hr = m_Device->CreateRenderTargetView(backBuffer, NULL, &m_BackBufferRTV);
+ backBuffer->Release();
+ if (FAILED(hr))
+ return hr;
+
+ if(m_DepthStencilDesc.Format != DXGI_FORMAT_UNKNOWN)
+ {
+ hr = m_Device->CreateTexture2D(&m_DepthStencilDesc, NULL, &m_DepthStencilBuffer);
+ if (FAILED(hr))
+ return hr;
+
+ hr = m_Device->CreateDepthStencilView(m_DepthStencilBuffer, NULL, &m_DepthStencilDSV);
+ if (FAILED(hr))
+ return hr;
+ }
+
+ return S_OK;
+}
+
+void
+DeviceManager::MessageLoop()
+{
+ MSG msg = {0};
+
+ LARGE_INTEGER perfFreq, previousTime;
+ QueryPerformanceFrequency(&perfFreq);
+ QueryPerformanceCounter(&previousTime);
+
+ while (WM_QUIT != msg.message)
+ {
+ if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ else
+ {
+ LARGE_INTEGER newTime;
+ QueryPerformanceCounter(&newTime);
+
+ double elapsedSeconds = (m_FixedFrameInterval >= 0)
+ ? m_FixedFrameInterval
+ : (double)(newTime.QuadPart - previousTime.QuadPart) / (double)perfFreq.QuadPart;
+
+ if(m_SwapChain && GetWindowState() != kWindowMinimized)
+ {
+ Animate(elapsedSeconds);
+ Render();
+ m_SwapChain->Present(m_SyncInterval, 0);
+ Sleep(0);
+ }
+ else
+ {
+ // Release CPU resources when idle
+ Sleep(1);
+ }
+
+ {
+ m_vFrameTimes.push_back(elapsedSeconds);
+ double timeSum = 0;
+ for(auto it = m_vFrameTimes.begin(); it != m_vFrameTimes.end(); it++)
+ timeSum += *it;
+
+ if(timeSum > m_AverageTimeUpdateInterval)
+ {
+ m_AverageFrameTime = timeSum / (double)m_vFrameTimes.size();
+ m_vFrameTimes.clear();
+ }
+ }
+
+ previousTime = newTime;
+ }
+ }
+}
+
+LRESULT
+DeviceManager::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch(uMsg)
+ {
+ case WM_DESTROY:
+ case WM_CLOSE:
+ PostQuitMessage(0);
+ return 0;
+
+ case WM_SYSKEYDOWN:
+ if(wParam == VK_F4)
+ {
+ PostQuitMessage(0);
+ return 0;
+ }
+ break;
+
+ case WM_SIZE:
+ // Ignore the WM_SIZE event if there is no device,
+ // or if the window has been minimized (size == 0),
+ // or if it has been restored to the previous size
+ if (m_Device
+ && (lParam != 0)
+ && (LOWORD(lParam) != m_SwapChainDesc.BufferDesc.Width || HIWORD(lParam) != m_SwapChainDesc.BufferDesc.Height))
+ {
+ ID3D11RenderTargetView *nullRTV = NULL;
+ m_ImmediateContext->OMSetRenderTargets(1, &nullRTV, NULL);
+ SAFE_RELEASE(m_BackBufferRTV);
+ SAFE_RELEASE(m_DepthStencilDSV);
+ SAFE_RELEASE(m_DepthStencilBuffer);
+
+ if (m_SwapChain)
+ {
+ // Resize the swap chain
+ m_SwapChainDesc.BufferDesc.Width = LOWORD(lParam);
+ m_SwapChainDesc.BufferDesc.Height = HIWORD(lParam);
+ m_SwapChain->ResizeBuffers(m_SwapChainDesc.BufferCount, m_SwapChainDesc.BufferDesc.Width,
+ m_SwapChainDesc.BufferDesc.Height, m_SwapChainDesc.BufferDesc.Format,
+ m_SwapChainDesc.Flags);
+
+ m_DepthStencilDesc.Width = LOWORD(lParam);
+ m_DepthStencilDesc.Height = HIWORD(lParam);
+
+ CreateRenderTargetAndDepthStencil();
+
+ BackBufferResized();
+ }
+ }
+ }
+
+ if( uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST ||
+ uMsg >= WM_KEYFIRST && uMsg <= WM_KEYLAST )
+ {
+ // processing messages front-to-back
+ for(auto it = m_vControllers.begin(); it != m_vControllers.end(); it++)
+ {
+ if((*it)->IsEnabled())
+ {
+ // for kb/mouse messages, 0 means the message has been handled
+ if(0 == (*it)->MsgProc(hWnd, uMsg, wParam, lParam))
+ return 0;
+ }
+ }
+ }
+
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+void
+DeviceManager::Render()
+{
+ D3D11_VIEWPORT viewport = { 0.0f, 0.0f, (float)m_SwapChainDesc.BufferDesc.Width, (float)m_SwapChainDesc.BufferDesc.Height, 0.0f, 1.0f };
+
+ // rendering back-to-front
+ for(auto it = m_vControllers.rbegin(); it != m_vControllers.rend(); it++)
+ {
+ if((*it)->IsEnabled())
+ {
+ m_ImmediateContext->OMSetRenderTargets(1, &m_BackBufferRTV, m_DepthStencilDSV);
+ m_ImmediateContext->RSSetViewports(1, &viewport);
+
+ (*it)->Render(m_Device, m_ImmediateContext, m_BackBufferRTV, m_DepthStencilDSV);
+ }
+ }
+
+ m_ImmediateContext->OMSetRenderTargets(0, NULL, NULL);
+}
+
+void
+DeviceManager::Animate(double fElapsedTimeSeconds)
+{
+ for(auto it = m_vControllers.begin(); it != m_vControllers.end(); it++)
+ {
+ if((*it)->IsEnabled())
+ {
+ (*it)->Animate(fElapsedTimeSeconds);
+ }
+ }
+}
+
+void
+DeviceManager::DeviceCreated()
+{
+ for(auto it = m_vControllers.begin(); it != m_vControllers.end(); it++)
+ {
+ (*it)->DeviceCreated(m_Device);
+ }
+}
+
+void
+DeviceManager::DeviceDestroyed()
+{
+ for(auto it = m_vControllers.begin(); it != m_vControllers.end(); it++)
+ {
+ (*it)->DeviceDestroyed();
+ }
+}
+
+void
+DeviceManager::BackBufferResized()
+{
+ if(m_SwapChain == NULL)
+ return;
+
+ DXGI_SURFACE_DESC backSD;
+ backSD.Format = m_SwapChainDesc.BufferDesc.Format;
+ backSD.Width = m_SwapChainDesc.BufferDesc.Width;
+ backSD.Height = m_SwapChainDesc.BufferDesc.Height;
+ backSD.SampleDesc = m_SwapChainDesc.SampleDesc;
+
+ for(auto it = m_vControllers.begin(); it != m_vControllers.end(); it++)
+ {
+ (*it)->BackBufferResized(m_Device, &backSD);
+ }
+}
+
+HRESULT
+DeviceManager::ChangeBackBufferFormat(DXGI_FORMAT format, UINT sampleCount)
+{
+ HRESULT hr = E_FAIL;
+
+ if((format == DXGI_FORMAT_UNKNOWN || format == m_SwapChainDesc.BufferDesc.Format) &&
+ (sampleCount == 0 || sampleCount == m_SwapChainDesc.SampleDesc.Count))
+ return S_FALSE;
+
+ if(m_Device)
+ {
+ bool fullscreen = (GetWindowState() == kWindowFullscreen);
+ if(fullscreen)
+ m_SwapChain->SetFullscreenState(false, NULL);
+
+ IDXGISwapChain* newSwapChain = NULL;
+ DXGI_SWAP_CHAIN_DESC newSwapChainDesc = m_SwapChainDesc;
+
+ if(format != DXGI_FORMAT_UNKNOWN)
+ newSwapChainDesc.BufferDesc.Format = format;
+ if(sampleCount != 0)
+ newSwapChainDesc.SampleDesc.Count = sampleCount;
+
+ IDXGIAdapter* pDXGIAdapter = GetDXGIAdapter();
+
+ IDXGIFactory* pDXGIFactory = NULL;
+ pDXGIAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&pDXGIFactory));
+
+ hr = pDXGIFactory->CreateSwapChain(m_Device, &newSwapChainDesc, &newSwapChain);
+
+ pDXGIFactory->Release();
+ pDXGIAdapter->Release();
+
+ if (FAILED(hr))
+ {
+ if(fullscreen)
+ m_SwapChain->SetFullscreenState(true, NULL);
+
+ return hr;
+ }
+
+ SAFE_RELEASE(m_BackBufferRTV);
+ SAFE_RELEASE(m_SwapChain);
+ SAFE_RELEASE(m_DepthStencilBuffer);
+ SAFE_RELEASE(m_DepthStencilDSV);
+
+ m_SwapChain = newSwapChain;
+ m_SwapChainDesc = newSwapChainDesc;
+
+ m_DepthStencilDesc.SampleDesc.Count = sampleCount;
+
+ if(fullscreen)
+ m_SwapChain->SetFullscreenState(true, NULL);
+
+ CreateRenderTargetAndDepthStencil();
+ BackBufferResized();
+ }
+
+ return S_OK;
+}
+
+void
+DeviceManager::AddControllerToFront(IVisualController* pController)
+{
+ m_vControllers.remove(pController);
+ m_vControllers.push_front(pController);
+}
+
+void
+DeviceManager::AddControllerToBack(IVisualController* pController)
+{
+ m_vControllers.remove(pController);
+ m_vControllers.push_back(pController);
+}
+
+void
+DeviceManager::RemoveController(IVisualController* pController)
+{
+ m_vControllers.remove(pController);
+}
+
+HRESULT
+DeviceManager::ResizeWindow(int width, int height)
+{
+ if(m_SwapChain == NULL)
+ return E_FAIL;
+
+ RECT rect;
+ GetWindowRect(m_hWnd, &rect);
+
+ ShowWindow(m_hWnd, SW_RESTORE);
+
+ if(!MoveWindow(m_hWnd, rect.left, rect.top, width, height, true))
+ return E_FAIL;
+
+ // No need to call m_SwapChain->ResizeBackBuffer because MoveWindow will send WM_SIZE, which calls that function.
+
+ return S_OK;
+}
+
+HRESULT
+DeviceManager::EnterFullscreenMode(int width, int height)
+{
+ if(m_SwapChain == NULL)
+ return E_FAIL;
+
+ if(GetWindowState() == kWindowFullscreen)
+ return S_FALSE;
+
+ if(width <= 0 || height <= 0)
+ {
+ width = m_SwapChainDesc.BufferDesc.Width;
+ height = m_SwapChainDesc.BufferDesc.Height;
+ }
+
+ SetWindowLong(m_hWnd, GWL_STYLE, WINDOW_STYLE_FULLSCREEN);
+ MoveWindow(m_hWnd, 0, 0, width, height, true);
+
+ HRESULT hr = m_SwapChain->SetFullscreenState(true, NULL);
+
+ if(FAILED(hr))
+ {
+ SetWindowLong(m_hWnd, GWL_STYLE, WINDOW_STYLE_NORMAL);
+ return hr;
+ }
+
+ UpdateWindow(m_hWnd);
+ m_SwapChain->GetDesc(&m_SwapChainDesc);
+
+ return S_OK;
+}
+
+HRESULT
+DeviceManager::LeaveFullscreenMode(int windowWidth, int windowHeight)
+{
+ if(m_SwapChain == NULL)
+ return E_FAIL;
+
+ if(GetWindowState() != kWindowFullscreen)
+ return S_FALSE;
+
+ HRESULT hr = m_SwapChain->SetFullscreenState(false, NULL);
+ if(FAILED(hr)) return hr;
+
+ SetWindowLong(m_hWnd, GWL_STYLE, WINDOW_STYLE_NORMAL);
+
+ if(windowWidth <= 0 || windowHeight <= 0)
+ {
+ windowWidth = m_SwapChainDesc.BufferDesc.Width;
+ windowHeight = m_SwapChainDesc.BufferDesc.Height;
+ }
+
+ RECT rect = { 0, 0, windowWidth, windowHeight };
+ AdjustWindowRect(&rect, WINDOW_STYLE_NORMAL, FALSE);
+ MoveWindow(m_hWnd, 0, 0, rect.right - rect.left, rect.bottom - rect.top, true);
+ UpdateWindow(m_hWnd);
+
+ m_SwapChain->GetDesc(&m_SwapChainDesc);
+
+ return S_OK;
+}
+
+HRESULT
+DeviceManager::ToggleFullscreen()
+{
+ if(GetWindowState() == kWindowFullscreen)
+ return LeaveFullscreenMode();
+ else
+ return EnterFullscreenMode();
+}
+
+DeviceManager::WindowState
+DeviceManager::GetWindowState()
+{
+ if(m_SwapChain && !m_SwapChainDesc.Windowed)
+ return kWindowFullscreen;
+
+ if(m_hWnd == INVALID_HANDLE_VALUE)
+ return kWindowNone;
+
+ if(IsZoomed(m_hWnd))
+ return kWindowMaximized;
+
+ if(IsIconic(m_hWnd))
+ return kWindowMinimized;
+
+ return kWindowNormal;
+}
+
+HRESULT
+DeviceManager::GetDisplayResolution(int& width, int& height)
+{
+ if(m_hWnd != INVALID_HANDLE_VALUE)
+ {
+ HMONITOR monitor = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTOPRIMARY);
+ MONITORINFO info;
+ info.cbSize = sizeof(MONITORINFO);
+
+ if(GetMonitorInfo(monitor, &info))
+ {
+ width = info.rcMonitor.right - info.rcMonitor.left;
+ height = info.rcMonitor.bottom - info.rcMonitor.top;
+ return S_OK;
+ }
+ }
+
+ return E_FAIL;
+}
+
+IDXGIAdapter*
+DeviceManager::GetDXGIAdapter()
+{
+ if(!m_Device)
+ return NULL;
+
+ IDXGIDevice* pDXGIDevice = NULL;
+ m_Device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&pDXGIDevice));
+
+ IDXGIAdapter* pDXGIAdapter = NULL;
+ pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&pDXGIAdapter));
+
+ pDXGIDevice->Release();
+
+ return pDXGIAdapter;
+}
diff --git a/samples/VolumetricLightingTest/d3d11/DeviceManager.h b/samples/VolumetricLightingTest/d3d11/DeviceManager.h
new file mode 100644
index 0000000..4bd164a
--- /dev/null
+++ b/samples/VolumetricLightingTest/d3d11/DeviceManager.h
@@ -0,0 +1,148 @@
+// TAGRELEASE: PUBLIC
+
+#pragma once
+#include <Windows.h>
+#include <DXGI.h>
+#include <D3D11.h>
+#include <list>
+
+
+struct DeviceCreationParameters
+{
+ bool startMaximized;
+ bool startFullscreen;
+ int backBufferWidth;
+ int backBufferHeight;
+ int refreshRate;
+ int swapChainBufferCount;
+ DXGI_FORMAT swapChainFormat;
+ DXGI_FORMAT depthStencilFormat;
+ DXGI_USAGE swapChainUsage;
+ int swapChainSampleCount;
+ UINT createDeviceFlags;
+ D3D_DRIVER_TYPE driverType;
+ D3D_FEATURE_LEVEL featureLevel;
+
+ DeviceCreationParameters()
+ : startMaximized(false)
+ , startFullscreen(false)
+ , backBufferWidth(1280)
+ , backBufferHeight(720)
+ , refreshRate(0)
+ , swapChainBufferCount(1)
+ , swapChainFormat(DXGI_FORMAT_R8G8B8A8_UNORM)
+ , depthStencilFormat(DXGI_FORMAT_D24_UNORM_S8_UINT)
+ , swapChainUsage(DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT)
+ , swapChainSampleCount(1)
+ , createDeviceFlags(0)
+ , driverType(D3D_DRIVER_TYPE_HARDWARE)
+ , featureLevel(D3D_FEATURE_LEVEL_11_0)
+ { }
+};
+
+#pragma warning(push)
+#pragma warning(disable: 4100) // unreferenced formal parameter
+class IVisualController
+{
+private:
+ bool m_Enabled;
+public:
+ IVisualController() : m_Enabled(true) { }
+
+ virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return 1; }
+ virtual void Render(ID3D11Device* pDevice, ID3D11DeviceContext* pDeviceContext, ID3D11RenderTargetView* pRTV, ID3D11DepthStencilView* pDSV) { }
+ virtual void Animate(double fElapsedTimeSeconds) { }
+ virtual HRESULT DeviceCreated(ID3D11Device* pDevice) { return S_OK; }
+ virtual void DeviceDestroyed() { }
+ virtual void BackBufferResized(ID3D11Device* pDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc) { }
+
+ virtual void EnableController() { m_Enabled = true; }
+ virtual void DisableController() { m_Enabled = false; }
+ virtual bool IsEnabled() { return m_Enabled; }
+};
+#pragma warning(pop)
+
+class DeviceManager
+{
+public:
+ enum WindowState
+ {
+ kWindowNone,
+ kWindowNormal,
+ kWindowMinimized,
+ kWindowMaximized,
+ kWindowFullscreen
+ };
+
+protected:
+ ID3D11Device* m_Device;
+ ID3D11DeviceContext* m_ImmediateContext;
+ IDXGISwapChain* m_SwapChain;
+ ID3D11RenderTargetView* m_BackBufferRTV;
+ ID3D11Texture2D* m_DepthStencilBuffer;
+ ID3D11DepthStencilView* m_DepthStencilDSV;
+ DXGI_SWAP_CHAIN_DESC m_SwapChainDesc;
+ D3D11_TEXTURE2D_DESC m_DepthStencilDesc;
+ HWND m_hWnd;
+ std::list<IVisualController*> m_vControllers;
+ std::wstring m_WindowTitle;
+ double m_FixedFrameInterval;
+ UINT m_SyncInterval;
+ std::list<double> m_vFrameTimes;
+ double m_AverageFrameTime;
+ double m_AverageTimeUpdateInterval;
+private:
+ HRESULT CreateRenderTargetAndDepthStencil();
+public:
+
+ DeviceManager()
+ : m_Device(NULL)
+ , m_ImmediateContext(NULL)
+ , m_SwapChain(NULL)
+ , m_BackBufferRTV(NULL)
+ , m_DepthStencilBuffer(NULL)
+ , m_DepthStencilDSV(NULL)
+ , m_hWnd(NULL)
+ , m_WindowTitle(L"")
+ , m_FixedFrameInterval(-1)
+ , m_SyncInterval(0)
+ , m_AverageFrameTime(0)
+ , m_AverageTimeUpdateInterval(0.5)
+ { }
+
+ virtual ~DeviceManager()
+ { Shutdown(); }
+
+ virtual HRESULT CreateWindowDeviceAndSwapChain(const DeviceCreationParameters& params, LPWSTR windowTitle);
+ virtual HRESULT ChangeBackBufferFormat(DXGI_FORMAT format, UINT sampleCount);
+ virtual HRESULT ResizeWindow(int width, int height);
+ virtual HRESULT EnterFullscreenMode(int width = 0, int height = 0);
+ virtual HRESULT LeaveFullscreenMode(int windowWidth = 0, int windowHeight = 0);
+ virtual HRESULT ToggleFullscreen();
+
+ virtual void Shutdown();
+ virtual void MessageLoop();
+ virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual void Render();
+ virtual void Animate(double fElapsedTimeSeconds);
+ virtual void DeviceCreated();
+ virtual void DeviceDestroyed();
+ virtual void BackBufferResized();
+
+ void AddControllerToFront(IVisualController* pController);
+ void AddControllerToBack(IVisualController* pController);
+ void RemoveController(IVisualController* pController);
+
+ void SetFixedFrameInterval(double seconds) { m_FixedFrameInterval = seconds; }
+ void DisableFixedFrameInterval() { m_FixedFrameInterval = -1; }
+
+ HWND GetHWND() { return m_hWnd; }
+ ID3D11Device* GetDevice() { return m_Device; }
+ WindowState GetWindowState();
+ bool GetVsyncEnabled() { return m_SyncInterval > 0; }
+ void SetVsyncEnabled(bool enabled) { m_SyncInterval = enabled ? 1 : 0; }
+ HRESULT GetDisplayResolution(int& width, int& height);
+ IDXGIAdapter* GetDXGIAdapter();
+ double GetAverageFrameTime() { return m_AverageFrameTime; }
+ void SetAverageTimeUpdateInterval(double value) { m_AverageTimeUpdateInterval = value; }
+};
diff --git a/samples/VolumetricLightingTest/d3d11/compiled_shaders_d3d11.cpp b/samples/VolumetricLightingTest/d3d11/compiled_shaders_d3d11.cpp
new file mode 100644
index 0000000..43f2e5d
--- /dev/null
+++ b/samples/VolumetricLightingTest/d3d11/compiled_shaders_d3d11.cpp
@@ -0,0 +1,36 @@
+// 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 (c) 2003 - 2016 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 <stdint.h>
+namespace d3d11 { namespace shaders {
+ #include <shaders/post_PS.mux.bytecode>
+ #include <shaders/quad_VS.mux.bytecode>
+ #include <shaders/scene_VS.mux.bytecode>
+ #include <shaders/scene_GS.mux.bytecode>
+ #include <shaders/scene_PS.mux.bytecode>
+}; /* namespace shaders */ }; /* namespace d3d11 */
diff --git a/samples/VolumetricLightingTest/d3d11/compiled_shaders_d3d11.h b/samples/VolumetricLightingTest/d3d11/compiled_shaders_d3d11.h
new file mode 100644
index 0000000..2488d61
--- /dev/null
+++ b/samples/VolumetricLightingTest/d3d11/compiled_shaders_d3d11.h
@@ -0,0 +1,45 @@
+// 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 (c) 2003 - 2016 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 COMPILED_SHADERS_D3D11_H
+#define COMPILED_SHADERS_D3D11_H
+////////////////////////////////////////////////////////////////////////////////
+#include <stdint.h>
+namespace d3d11 { namespace shaders {
+ #include <shaders/post_PS.mux.h>
+ #include <shaders/quad_VS.mux.h>
+ #include <shaders/scene_VS.mux.h>
+ #include <shaders/scene_GS.mux.h>
+ #include <shaders/scene_PS.mux.h>
+}; /* namespace shaders */ }; /* namespace d3d11 */
+// We use the namespaces to avoid conflicts if supporting multiple APIs
+// but they aren't needed wherever these would be included.
+using namespace d3d11;
+using namespace shaders;
+////////////////////////////////////////////////////////////////////////////////
+#endif // COMPILED_SHADERS_D3D11_H
diff --git a/samples/VolumetricLightingTest/d3d11/d3d11_main.cpp b/samples/VolumetricLightingTest/d3d11/d3d11_main.cpp
new file mode 100644
index 0000000..308d025
--- /dev/null
+++ b/samples/VolumetricLightingTest/d3d11/d3d11_main.cpp
@@ -0,0 +1,478 @@
+// 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 (c) 2003 - 2016 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.h"
+
+#include "compiled_shaders_d3d11.h"
+#include "DeviceManager.h"
+#include "d3d11_util.h"
+#include "scene.h"
+
+#include <Nv/VolumetricLighting/NvVolumetricLighting.h>
+#include <d3d11.h>
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Control rendering of the scene
+#define LOAD_SHADERS(x) LoadShaders(device, ##x##::permutation_code, ##x##::permutation_length, shaders::##x##::PERMUTATION_ENTRY_COUNT, shaders.##x)
+
+class SceneController : public IVisualController
+{
+private:
+ Scene * pScene_;
+ DeviceManager * pManager_;
+
+ uint32_t framebufferWidth_;
+ uint32_t framebufferHeight_;
+
+ // Resources used by the scene
+
+ ConstantBuffer <Scene::ViewCB> * pViewCB_;
+ ConstantBuffer <Scene::ObjectCB> * pObjectCB_;
+ ConstantBuffer <Scene::LightCB> * pLightCB_;
+
+ RenderTarget * pSceneRT_;
+ DepthTarget * pSceneDepth_;
+ DepthTarget * pShadowMap_;
+ DepthTarget * pParaboloidShadowMap_;
+
+ ID3D11SamplerState * ss_shadowmap_;
+ ID3D11RasterizerState * rs_render_;
+ ID3D11BlendState * bs_no_color_;
+ ID3D11DepthStencilState * ds_shadowmap_;
+
+ struct
+ {
+ ID3D11PixelShader ** post_PS;
+ ID3D11VertexShader ** quad_VS;
+ ID3D11VertexShader ** scene_VS;
+ ID3D11GeometryShader ** scene_GS;
+ ID3D11PixelShader ** scene_PS;
+ } shaders;
+
+ // GWVL Platform-specific info
+ Nv::Vl::PlatformDesc platformDesc_;
+
+public:
+
+ SceneController(Scene * pScene, DeviceManager * pManager)
+ {
+ pScene_ = pScene;
+ pManager_ = pManager;
+ }
+
+ virtual HRESULT DeviceCreated(ID3D11Device* device)
+ {
+ Nv::Vl::OpenLibrary();
+
+ // Shaders
+ LOAD_SHADERS(post_PS);
+ LOAD_SHADERS(quad_VS);
+ LOAD_SHADERS(scene_VS);
+ LOAD_SHADERS(scene_GS);
+ LOAD_SHADERS(scene_PS);
+
+ // Constant Buffers
+ pViewCB_ = ConstantBuffer<Scene::ViewCB>::Create(device);
+ pObjectCB_ = ConstantBuffer<Scene::ObjectCB>::Create(device);
+ pLightCB_ = ConstantBuffer<Scene::LightCB>::Create(device);
+
+ // Textures
+ pSceneRT_ = nullptr;
+ pSceneDepth_ = nullptr;
+ pShadowMap_ = DepthTarget::Create(device, Scene::SHADOWMAP_RESOLUTION, Scene::SHADOWMAP_RESOLUTION, 1, DXGI_FORMAT_D16_UNORM, 1, "Simple Shadow Map");
+ pParaboloidShadowMap_ = DepthTarget::Create(device, Scene::SHADOWMAP_RESOLUTION, Scene::SHADOWMAP_RESOLUTION, 1, DXGI_FORMAT_D16_UNORM, 2, "Dual-Paraboloid Shadow Map");
+
+ // Shadowmap Sampler
+ {
+ CD3D11_SAMPLER_DESC desc((CD3D11_DEFAULT()));
+ desc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
+ desc.ComparisonFunc = D3D11_COMPARISON_LESS;
+ device->CreateSamplerState(&desc, &ss_shadowmap_);
+ }
+ // No color output blend-state
+ {
+ CD3D11_BLEND_DESC desc((CD3D11_DEFAULT()));
+ desc.RenderTarget[0].RenderTargetWriteMask = 0x00000000;
+ device->CreateBlendState(&desc, &bs_no_color_);
+ }
+ {
+ CD3D11_RASTERIZER_DESC rsDesc((CD3D11_DEFAULT()));
+ rsDesc.CullMode = D3D11_CULL_NONE;
+ device->CreateRasterizerState(&rsDesc, &rs_render_);
+ }
+ {
+ CD3D11_DEPTH_STENCIL_DESC dsDesc((CD3D11_DEFAULT()));
+ device->CreateDepthStencilState(&dsDesc, &ds_shadowmap_);
+ }
+ // Initialize GWVL settings info
+ {
+ platformDesc_.platform = Nv::Vl::PlatformName::D3D11;
+ platformDesc_.d3d11.pDevice = device;
+ }
+
+ return S_OK;
+ }
+
+ virtual void DeviceDestroyed()
+ {
+ // Release resources
+ SAFE_RELEASE(ss_shadowmap_);
+ SAFE_RELEASE(bs_no_color_);
+ SAFE_RELEASE(rs_render_);
+ SAFE_RELEASE(ds_shadowmap_);
+ SAFE_DELETE(pViewCB_);
+ SAFE_DELETE(pObjectCB_);
+ SAFE_DELETE(pLightCB_);
+ SAFE_DELETE(pSceneRT_);
+ SAFE_DELETE(pSceneDepth_);
+ SAFE_DELETE(pShadowMap_);
+ SAFE_DELETE(pParaboloidShadowMap_);
+ SAFE_DELETE_ARRAY(shaders.post_PS);
+ SAFE_DELETE_ARRAY(shaders.quad_VS);
+ SAFE_DELETE_ARRAY(shaders.scene_VS);
+ SAFE_DELETE_ARRAY(shaders.scene_GS);
+ SAFE_DELETE_ARRAY(shaders.scene_PS);
+
+ pScene_->Release();
+ Nv::Vl::CloseLibrary();
+ }
+
+ virtual void BackBufferResized(ID3D11Device* device, const DXGI_SURFACE_DESC* surface_desc)
+ {
+ framebufferWidth_ = surface_desc->Width;
+ framebufferHeight_ = surface_desc->Height;
+
+ // Create back-buffer sized resources
+ SAFE_DELETE(pSceneRT_);
+ SAFE_DELETE(pSceneDepth_);
+ pSceneRT_ = RenderTarget::Create(device, framebufferWidth_, framebufferHeight_, surface_desc->SampleDesc.Count, DXGI_FORMAT_R16G16B16A16_FLOAT, "Scene Render Target");
+ pSceneDepth_ = DepthTarget::Create(device, framebufferWidth_, framebufferHeight_, surface_desc->SampleDesc.Count, DXGI_FORMAT_D24_UNORM_S8_UINT, 1, "Scene Depth");
+
+ // Update the context desc and (re-)create the context
+ pScene_->updateFramebuffer(framebufferWidth_, framebufferHeight_, surface_desc->SampleDesc.Count);
+ }
+
+ virtual void Render(ID3D11Device*, ID3D11DeviceContext* ctx, ID3D11RenderTargetView* pFramebuffer_RTV, ID3D11DepthStencilView*)
+ {
+ NV_PERFEVENT(ctx, "Render Frame");
+ if (!pScene_->isCtxValid())
+ {
+ pScene_->createCtx(&platformDesc_);
+ }
+
+ float clear_color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+ ctx->ClearRenderTargetView( pSceneRT_->getRTV(), clear_color);
+ ctx->ClearDepthStencilView(pSceneDepth_->getDSV(), D3D11_CLEAR_DEPTH, 1.0, 0);
+
+ ID3D11Buffer * CBs[] = {
+ pViewCB_->getCB(),
+ pObjectCB_->getCB(),
+ pLightCB_->getCB()
+ };
+
+ auto RenderScene = [=]()
+ {
+ NV_PERFEVENT(ctx, "Draw Scene Geometry");
+ const float scene_range[] = { -6, -3, 3, 6 };
+ for (auto x : scene_range)
+ {
+ for (auto y : scene_range)
+ {
+ for (auto z : scene_range)
+ {
+ Scene::ObjectCB * pObject = this->pObjectCB_->Map(ctx);
+ pScene_->setupObjectCB(pObject, Nv::NvVec3(x, y, z));
+ this->pObjectCB_->Unmap(ctx);
+
+ ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ ctx->IASetVertexBuffers(0,0,nullptr, nullptr,nullptr);
+ ctx->IASetInputLayout(nullptr);
+ ctx->IASetIndexBuffer(nullptr, DXGI_FORMAT_R16_UINT, 0);
+ ctx->Draw(36, 0);
+ }
+ }
+ }
+ };
+
+ //----------------------------------------------------------------------
+ // Render the light's shadow map
+ {
+ NV_PERFEVENT(ctx, "Render Shadow Map");
+ {
+ Scene::ViewCB * pView = pViewCB_->Map(ctx);
+ pScene_->setupLightViewCB(pView);
+ pViewCB_->Unmap(ctx);
+ }
+
+ ctx->ClearState();
+ CD3D11_VIEWPORT shadowmap_viewport;
+ shadowmap_viewport.TopLeftX = 0;
+ shadowmap_viewport.TopLeftY = 0;
+ shadowmap_viewport.Width = static_cast<float>(Scene::SHADOWMAP_RESOLUTION);
+ shadowmap_viewport.Height = static_cast<float>(Scene::SHADOWMAP_RESOLUTION);
+ shadowmap_viewport.MinDepth = 0.0f;
+ shadowmap_viewport.MaxDepth = 1.0f;
+ ctx->RSSetState(rs_render_);
+ ctx->VSSetShader(shaders.scene_VS[scene_VS::SINGLE], nullptr, 0);
+ ctx->VSSetConstantBuffers(0, 3, CBs);
+ if (pScene_->getLightMode() == Scene::eLightMode::OMNI)
+ {
+ ctx->ClearDepthStencilView(pParaboloidShadowMap_->getDSV(), D3D11_CLEAR_DEPTH, 1.0, 0);
+ ctx->OMSetRenderTargets(0, nullptr, pParaboloidShadowMap_->getDSV());
+ CD3D11_VIEWPORT dual_viewports[] = { shadowmap_viewport, shadowmap_viewport };
+ ctx->RSSetViewports(2, dual_viewports);
+ ctx->GSSetShader(shaders.scene_GS[scene_GS::SINGLE], nullptr, 0);
+ ctx->GSSetConstantBuffers(0, 3, CBs);
+ }
+ else
+ {
+ ctx->ClearDepthStencilView(pShadowMap_->getDSV(), D3D11_CLEAR_DEPTH, 1.0, 0);
+ ctx->OMSetRenderTargets(0, nullptr, pShadowMap_->getDSV());
+ ctx->RSSetViewports(1, &shadowmap_viewport);
+ }
+ ctx->PSSetShader(nullptr, nullptr, 0);
+ ctx->OMSetBlendState(bs_no_color_, nullptr, 0xFFFFFFFF);
+ ctx->OMSetDepthStencilState(ds_shadowmap_, 0xFF);
+ RenderScene();
+ }
+ ID3D11ShaderResourceView * shadowmap_srv = (pScene_->getLightMode() == Scene::eLightMode::OMNI) ? pParaboloidShadowMap_->getSRV() : pShadowMap_->getSRV();
+
+ //----------------------------------------------------------------------
+ // Render the scene
+ {
+ NV_PERFEVENT(ctx, "Render Main Scene");
+ {
+ Scene::ViewCB * pView = pViewCB_->Map(ctx);
+ Scene::LightCB * pLight = pLightCB_->Map(ctx);
+ pScene_->setupSceneCBs(pView, pLight);
+ pViewCB_->Unmap(ctx);
+ pLightCB_->Unmap(ctx);
+ }
+
+ ctx->ClearState();
+ CD3D11_VIEWPORT scene_viewport;
+ scene_viewport.TopLeftX = 0.0f;
+ scene_viewport.TopLeftY = 0.f;
+ scene_viewport.Width = static_cast<float>(framebufferWidth_);
+ scene_viewport.Height = static_cast<float>(framebufferHeight_);
+ scene_viewport.MinDepth = 0.0f;
+ scene_viewport.MaxDepth = 1.0f;
+ ctx->RSSetViewports(1, &scene_viewport);
+ ctx->RSSetState(rs_render_);
+ ctx->VSSetShader(shaders.scene_VS[scene_VS::SINGLE], nullptr, 0);
+ ctx->VSSetConstantBuffers(0, 3, CBs);
+ ctx->GSSetShader(nullptr, nullptr, 0);
+ scene_PS::Desc ps_desc;
+ switch (pScene_->getLightMode())
+ {
+ default:
+ case Scene::eLightMode::DIRECTIONAL:
+ ps_desc.flags.LIGHTMODE = scene_PS::LIGHTMODE_DIRECTIONAL;
+ break;
+
+ case Scene::eLightMode::SPOTLIGHT:
+ ps_desc.flags.LIGHTMODE = scene_PS::LIGHTMODE_SPOTLIGHT;
+ break;
+
+ case Scene::eLightMode::OMNI:
+ ps_desc.flags.LIGHTMODE = scene_PS::LIGHTMODE_OMNI;
+ break;
+ }
+ ctx->PSSetShader(shaders.scene_PS[ps_desc], nullptr, 0);
+ ctx->PSSetConstantBuffers(0, 3, CBs);
+ ID3D11ShaderResourceView * SRVs[] = { shadowmap_srv };
+ ctx->PSSetShaderResources(0, 1, SRVs);
+ ctx->PSSetSamplers(0, 1, &ss_shadowmap_);
+ ID3D11RenderTargetView * RTVs[] = { pSceneRT_->getRTV() };
+ ctx->OMSetRenderTargets(1, RTVs, pSceneDepth_->getDSV());
+ RenderScene();
+ }
+
+ //----------------------------------------------------------------------
+ // Render the volumetric lighting
+ {
+ NV_PERFEVENT(ctx, "Volumetric Lighting");
+ ctx->ClearState();
+ pScene_->beginAccumulation(ctx, pSceneDepth_->getSRV());
+ pScene_->renderVolume(ctx, shadowmap_srv);
+ pScene_->endAccumulation(ctx);
+ pScene_->applyLighting(ctx, pSceneRT_->getRTV(), pSceneDepth_->getSRV());
+ }
+
+ //----------------------------------------------------------------------
+ // Tonemap to output
+ {
+ NV_PERFEVENT(ctx, "Postprocess");
+ ctx->ClearState();
+ CD3D11_VIEWPORT scene_viewport;
+ scene_viewport.TopLeftX = 0.0f;
+ scene_viewport.TopLeftY = 0.f;
+ scene_viewport.Width = static_cast<float>(framebufferWidth_);
+ scene_viewport.Height = static_cast<float>(framebufferHeight_);
+ scene_viewport.MinDepth = 0.0f;
+ scene_viewport.MaxDepth = 1.0f;
+ ctx->RSSetViewports(1, &scene_viewport);
+ ctx->RSSetState(rs_render_);
+ ID3D11RenderTargetView * RTVs[] = { pFramebuffer_RTV };
+ ctx->OMSetRenderTargets(1, RTVs, nullptr);
+ ctx->VSSetShader(shaders.quad_VS[quad_VS::SINGLE], nullptr, 0);
+ ctx->PSSetShader(shaders.post_PS[post_PS::SINGLE], nullptr, 0);
+ ID3D11ShaderResourceView * SRVs[] = { pSceneRT_->getSRV() };
+ ctx->PSSetShaderResources(0, 1, SRVs);
+ ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ ctx->IASetVertexBuffers(0, 0, nullptr, nullptr, nullptr);
+ ctx->IASetInputLayout(nullptr);
+ ctx->IASetIndexBuffer(nullptr, DXGI_FORMAT_R16_UINT, 0);
+ ctx->Draw(3, 0);
+ }
+ }
+
+ virtual void Animate(double fElapsedTimeSeconds)
+ {
+ pScene_->animate((float)fElapsedTimeSeconds);
+ }
+
+ virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ hWnd; uMsg; wParam; lParam;
+ switch (uMsg)
+ {
+ case WM_KEYDOWN:
+ switch (wParam)
+ {
+ case VK_ESCAPE:
+ PostQuitMessage(0);
+ break;
+
+ case VK_F1:
+ pScene_->setDebugMode(Nv::Vl::DebugFlags::NONE);
+ break;
+
+ case VK_F2:
+ pScene_->setDebugMode(Nv::Vl::DebugFlags::NO_BLENDING);
+ break;
+
+ case VK_F3:
+ pScene_->setDebugMode(Nv::Vl::DebugFlags::WIREFRAME);
+ break;
+
+ case VK_F4:
+ pManager_->ToggleFullscreen();
+ break;
+
+ case VK_SPACE:
+ pScene_->togglePause();
+ break;
+
+ case 0x44: // D key - toggle downsample mode
+ pScene_->toggleDownsampleMode();
+ break;
+
+ case 0x46: // F key - toggle fog
+ pScene_->toggleFog();
+ break;
+
+ case 0x4C: // L key - toggle light type
+ pScene_->toggleLightMode();
+ break;
+
+ case 0x4D: // M key - toggle MSAA mode
+ pScene_->toggleMsaaMode();
+ break;
+
+ case 0x4F: // O key - toggle light intensity
+ pScene_->toggleMediumType();
+ break;
+
+ case 0x50: // P key - toggle light intensity
+ pScene_->toggleIntensity();
+ break;
+
+ case 0x54: // T key - toggle temporal filtering
+ pScene_->toggleFiltering();
+ break;
+
+ case 0x55: // U key - toggle upsample mode
+ pScene_->toggleUpsampleMode();
+ break;
+
+ case 0x56: // V key - toggle view mode
+ pScene_->toggleViewpoint();
+ break;
+ }
+ return 0;
+ }
+ return 1;
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Entry point to the program. Initializes everything and goes into a message processing
+// loop. Idle time is used to render the scene.
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+int main_D3D11(Scene * pScene)
+{
+ // Enable run-time memory check for debug builds.
+#if (NV_CHECKED)
+ _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
+
+ AllocConsole();
+ freopen("CONIN$", "r",stdin);
+ freopen("CONOUT$", "w",stdout);
+ freopen("CONOUT$", "w",stderr);
+#endif
+
+ DeviceManager * device_manager = new DeviceManager();
+
+ auto scene_controller = SceneController(pScene, device_manager);
+ device_manager->AddControllerToFront(&scene_controller);
+
+ DeviceCreationParameters deviceParams;
+ deviceParams.swapChainFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
+ deviceParams.swapChainSampleCount = 4;
+ deviceParams.startFullscreen = false;
+ deviceParams.backBufferWidth = 1920;
+ deviceParams.backBufferHeight = 1080;
+#if (NV_CHECKED)
+ deviceParams.createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
+#endif
+
+ if(FAILED(device_manager->CreateWindowDeviceAndSwapChain(deviceParams, L"Gameworks Volumetric Lighting Unit Test")))
+ {
+ MessageBox(nullptr, L"Cannot initialize the D3D11 device with the requested parameters", L"Error", MB_OK | MB_ICONERROR);
+ return 1;
+ }
+ // Loop
+ device_manager->MessageLoop();
+ // Shutdown and exit
+ device_manager->Shutdown();
+ delete device_manager;
+
+ return 0;
+}
diff --git a/samples/VolumetricLightingTest/d3d11/d3d11_util.cpp b/samples/VolumetricLightingTest/d3d11/d3d11_util.cpp
new file mode 100644
index 0000000..4226fdb
--- /dev/null
+++ b/samples/VolumetricLightingTest/d3d11/d3d11_util.cpp
@@ -0,0 +1,347 @@
+// 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 (c) 2003 - 2016 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.h"
+#include "d3d11_util.h"
+#include <d3d11.h>
+
+/*==============================================================================
+ Overloaded functions to make shader compilation simpler
+==============================================================================*/
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11VertexShader ** out_shader)
+ { return device->CreateVertexShader(data, length, nullptr, out_shader); }
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11HullShader ** out_shader)
+ { return device->CreateHullShader(data, length, nullptr, out_shader); }
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11DomainShader ** out_shader)
+ { return device->CreateDomainShader(data, length, nullptr, out_shader); }
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11GeometryShader ** out_shader)
+ { return device->CreateGeometryShader(data, length, nullptr, out_shader); }
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11PixelShader ** out_shader)
+ { return device->CreatePixelShader(data, length, nullptr, out_shader); }
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11ComputeShader ** out_shader)
+ { return device->CreateComputeShader(data, length, nullptr, out_shader); }
+/*==============================================================================
+ Texture resource management helpers
+==============================================================================*/
+
+//------------------------------------------------------------------------------
+ShaderResource::ShaderResource(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11UnorderedAccessView * uav)
+{
+ resource_ = resource;
+ srv_ = srv;
+ uav_ = uav;
+}
+
+ShaderResource::~ShaderResource()
+{
+ SAFE_RELEASE(resource_);
+ SAFE_RELEASE(srv_);
+ SAFE_RELEASE(uav_);
+}
+
+//------------------------------------------------------------------------------
+RenderTarget * RenderTarget::Create(ID3D11Device * device, UINT width, UINT height, UINT samples, DXGI_FORMAT format, const char * debug_name)
+{
+ ID3D11Texture2D * tex = nullptr;
+ ID3D11ShaderResourceView * srv = nullptr;
+ ID3D11RenderTargetView * rtv = nullptr;
+ ID3D11UnorderedAccessView * uav = nullptr;
+
+ CD3D11_TEXTURE2D_DESC texDesc;
+ texDesc.ArraySize = 1;
+ texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
+ if (samples == 1)
+ texDesc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
+ texDesc.CPUAccessFlags = 0;
+ texDesc.Format = format;
+ texDesc.Width = width;
+ texDesc.Height = height;
+ texDesc.MipLevels = 1;
+ texDesc.MiscFlags = 0;
+ if (samples > 1)
+ {
+ texDesc.SampleDesc.Count = samples;
+ texDesc.SampleDesc.Quality = 0;//static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN);
+ }
+ else
+ {
+ texDesc.SampleDesc.Count = 1;
+ texDesc.SampleDesc.Quality = 0;
+ }
+ texDesc.Usage = D3D11_USAGE_DEFAULT;
+ device->CreateTexture2D(&texDesc, nullptr, &tex);
+ if (tex == nullptr)
+ {
+ return nullptr;
+ }
+
+ CD3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = texDesc.Format;
+ if (samples > 1)
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
+ }
+ else
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Texture2D.MostDetailedMip = 0;
+ srvDesc.Texture2D.MipLevels = 1;
+ }
+ device->CreateShaderResourceView(tex, &srvDesc, &srv);
+ if (srv == nullptr)
+ {
+ tex->Release();
+ return nullptr;
+ }
+
+ CD3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = texDesc.Format;
+ if (samples > 1)
+ {
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
+ }
+ else
+ {
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = 0;
+ }
+ device->CreateRenderTargetView(tex, &rtvDesc, &rtv);
+ if (rtv == nullptr)
+ {
+ tex->Release();
+ srv->Release();
+ return nullptr;
+ }
+
+ if (samples == 1)
+ {
+ CD3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
+ uavDesc.Format = texDesc.Format;
+ uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
+ uavDesc.Texture2D.MipSlice = 0;
+ device->CreateUnorderedAccessView(tex, &uavDesc, &uav);
+ if (uav == nullptr)
+ {
+ tex->Release();
+ srv->Release();
+ rtv->Release();
+ return nullptr;
+ }
+ }
+#if (NV_DEBUG || NV_PROFILE)
+ if (debug_name)
+ {
+ tex->SetPrivateData(WKPDID_D3DDebugObjectName, (UINT)strlen(debug_name), debug_name);
+ }
+#else
+ debug_name;
+#endif
+ return new RenderTarget(tex, srv, rtv, uav);
+}
+
+RenderTarget::RenderTarget(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11RenderTargetView * rtv, ID3D11UnorderedAccessView * uav)
+ : ShaderResource(resource, srv, uav)
+{
+ rtv_ = rtv;
+}
+
+RenderTarget::~RenderTarget()
+{
+ SAFE_RELEASE(rtv_);
+}
+
+//------------------------------------------------------------------------------
+DepthTarget * DepthTarget::Create(ID3D11Device * device, UINT width, UINT height, UINT samples, DXGI_FORMAT format, uint32_t slices, char * debug_name)
+{
+ ID3D11Texture2D * tex = nullptr;
+ ID3D11ShaderResourceView * srv = nullptr;
+ ID3D11DepthStencilView * dsv = nullptr;
+ ID3D11DepthStencilView * dsv_ro = nullptr;
+
+ DXGI_FORMAT tex_format;
+ DXGI_FORMAT srv_format;
+ DXGI_FORMAT dsv_format;
+ switch (format)
+ {
+ case DXGI_FORMAT_D32_FLOAT:
+ tex_format = DXGI_FORMAT_R32_TYPELESS;
+ srv_format = DXGI_FORMAT_R32_FLOAT;
+ dsv_format = DXGI_FORMAT_D32_FLOAT;
+ break;
+
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ tex_format = DXGI_FORMAT_R24G8_TYPELESS;
+ srv_format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
+ dsv_format = DXGI_FORMAT_D24_UNORM_S8_UINT;
+ break;
+
+ case DXGI_FORMAT_D16_UNORM:
+ tex_format = DXGI_FORMAT_R16_TYPELESS;
+ srv_format = DXGI_FORMAT_R16_UNORM;
+ dsv_format = DXGI_FORMAT_D16_UNORM;
+ break;
+
+ default:
+ return nullptr;
+ }
+
+ CD3D11_TEXTURE2D_DESC texDesc;
+ texDesc.ArraySize = slices;
+ texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL;
+ texDesc.CPUAccessFlags = 0;
+ texDesc.Format = tex_format;
+ texDesc.Width = width;
+ texDesc.Height = height;
+ texDesc.MipLevels = 1;
+ texDesc.MiscFlags = 0;
+ if (samples > 1)
+ {
+ texDesc.SampleDesc.Count = samples;
+ texDesc.SampleDesc.Quality = 0;//static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN);
+ }
+ else
+ {
+ texDesc.SampleDesc.Count = 1;
+ texDesc.SampleDesc.Quality = 0;
+ }
+ texDesc.Usage = D3D11_USAGE_DEFAULT;
+ device->CreateTexture2D(&texDesc, nullptr, &tex);
+ if (tex == nullptr)
+ {
+ return nullptr;
+ }
+
+ CD3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = srv_format;
+ if (slices == 1)
+ {
+ if (samples > 1)
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
+ }
+ else
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Texture2D.MostDetailedMip = 0;
+ srvDesc.Texture2D.MipLevels = 1;
+ }
+ }
+ else
+ {
+ if (samples > 1)
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
+ srvDesc.Texture2DMSArray.FirstArraySlice = 0;
+ srvDesc.Texture2DMSArray.ArraySize = slices;
+ }
+ else
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+ srvDesc.Texture2DArray.MostDetailedMip = 0;
+ srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.FirstArraySlice = 0;
+ srvDesc.Texture2DArray.ArraySize = slices;
+ }
+ }
+ device->CreateShaderResourceView(tex, &srvDesc, &srv);
+
+ if (srv == nullptr)
+ {
+ tex->Release();
+ return nullptr;
+ }
+
+ CD3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Flags = 0;
+ dsvDesc.Format = dsv_format;
+ if (slices == 1)
+ {
+ if (samples > 1)
+ {
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
+ }
+ else
+ {
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+ dsvDesc.Texture2D.MipSlice = 0;
+ }
+ }
+ else
+ {
+ if (samples > 1)
+ {
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY;
+ dsvDesc.Texture2DMSArray.FirstArraySlice = 0;
+ dsvDesc.Texture2DMSArray.ArraySize = slices;
+ }
+ else
+ {
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
+ dsvDesc.Texture2DArray.MipSlice = 0;
+ dsvDesc.Texture2DArray.FirstArraySlice = 0;
+ dsvDesc.Texture2DArray.ArraySize = slices;
+ }
+ }
+
+ device->CreateDepthStencilView(tex, &dsvDesc, &dsv);
+ dsvDesc.Flags |= D3D11_DSV_READ_ONLY_DEPTH;
+ if (dsv_format == DXGI_FORMAT_D24_UNORM_S8_UINT)
+ dsvDesc.Flags |= D3D11_DSV_READ_ONLY_STENCIL;
+ device->CreateDepthStencilView(tex, &dsvDesc, &dsv_ro);
+ if (dsv == nullptr || dsv_ro == nullptr)
+ {
+ tex->Release();
+ srv->Release();
+ return nullptr;
+ }
+
+#if (NV_DEBUG || NV_PROFILE)
+ if (debug_name)
+ {
+ tex->SetPrivateData(WKPDID_D3DDebugObjectName, (UINT)strlen(debug_name), debug_name);
+ }
+#else
+ debug_name;
+#endif
+
+ return new DepthTarget(tex, srv, dsv, dsv_ro, nullptr);
+}
+
+DepthTarget::DepthTarget(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11DepthStencilView * dsv, ID3D11DepthStencilView * readonly_dsv, ID3D11UnorderedAccessView * uav)
+ : ShaderResource(resource, srv, uav)
+{
+ dsv_ = dsv;
+ readonly_dsv_ = readonly_dsv;
+}
+
+DepthTarget::~DepthTarget()
+{
+ SAFE_RELEASE(dsv_);
+ SAFE_RELEASE(readonly_dsv_);
+}
+
diff --git a/samples/VolumetricLightingTest/d3d11/d3d11_util.h b/samples/VolumetricLightingTest/d3d11/d3d11_util.h
new file mode 100644
index 0000000..e9322cf
--- /dev/null
+++ b/samples/VolumetricLightingTest/d3d11/d3d11_util.h
@@ -0,0 +1,234 @@
+// 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 (c) 2003 - 2016 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 D3D11_UTIL_H
+#define D3D11_UTIL_H
+////////////////////////////////////////////////////////////////////////////////
+#include "common.h"
+
+#include <d3d11.h>
+#include <d3d11_1.h>
+
+#pragma warning( disable: 4127 )
+
+////////////////////////////////////////////////////////////////////////////////
+/*==============================================================================
+ Overloaded functions to make shader compilation simpler
+==============================================================================*/
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11VertexShader ** out_shader);
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11HullShader ** out_shader);
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11DomainShader ** out_shader);
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11GeometryShader ** out_shader);
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11PixelShader ** out_shader);
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11ComputeShader ** out_shader);
+
+
+template <class T>
+NV_FORCE_INLINE HRESULT LoadShaders(ID3D11Device * device, const void ** shader_codes, const uint32_t * shader_lengths, UINT count, T ** &out_shaders)
+{
+ HRESULT hr = S_OK;
+ out_shaders = new T*[count];
+ for (UINT i = 0; i < count; ++i)
+ {
+ const void * code = shader_codes[i];
+ uint32_t length = shader_lengths[i];
+ if (code == nullptr)
+ {
+ out_shaders[i] = nullptr;
+ continue;
+ }
+ hr = CompileShader(device, code, length, &out_shaders[i]);
+ ASSERT_LOG(hr == S_OK, "Failure loading shader");
+ if (FAILED(hr))
+ break;
+ }
+ return hr;
+}
+
+/*==============================================================================
+ Perf Events
+==============================================================================*/
+
+class ScopedPerfEvent
+{
+public:
+ ScopedPerfEvent(ID3D11DeviceContext * ctx, const wchar_t * msg)
+ {
+ ctx->QueryInterface(IID_ID3DUserDefinedAnnotation, reinterpret_cast<void **>(&pPerf));
+ if (pPerf)
+ {
+ pPerf->BeginEvent(msg);
+ }
+ }
+
+ ~ScopedPerfEvent()
+ {
+ if (pPerf)
+ {
+ pPerf->EndEvent();
+ SAFE_RELEASE(pPerf);
+ }
+ };
+
+private:
+ ScopedPerfEvent() : pPerf(nullptr) {};
+ ID3DUserDefinedAnnotation * pPerf;
+};
+
+#if (NV_PROFILE)
+# define NV_PERFEVENT(c, t) ScopedPerfEvent perfevent_##__COUNTER__##(c, L##t)
+# define NV_PERFEVENT_BEGIN(c, t) { \
+ ID3DUserDefinedAnnotation * pPerf_##__COUNTER__ ; \
+ c->QueryInterface(IID_ID3DUserDefinedAnnotation, reinterpret_cast<void **>(&pPerf_##__COUNTER__##)); \
+ if (pPerf_##__COUNTER__##) { pPerf_##__COUNTER__##->BeginEvent(L##t); pPerf_##__COUNTER__##->Release(); } }
+# define NV_PERFEVENT_END(c) { \
+ ID3DUserDefinedAnnotation * pPerf_##__COUNTER__ ; \
+ c->QueryInterface(IID_ID3DUserDefinedAnnotation, reinterpret_cast<void **>(&pPerf_##__COUNTER__##)); \
+ if (pPerf_##__COUNTER__##) { pPerf_##__COUNTER__##->EndEvent(); pPerf_##__COUNTER__##->Release(); } }
+#else
+# define NV_PERFEVENT(c, t)
+# define NV_PERFEVENT_BEGIN(c, t)
+# define NV_PERFEVENT_END(c)
+#endif
+
+/*==============================================================================
+ Constant buffer management
+==============================================================================*/
+
+template <class T>
+class ConstantBuffer
+{
+public:
+ static ConstantBuffer<T> * Create(ID3D11Device * device)
+ {
+ HRESULT hr;
+ ID3D11Buffer * cb = nullptr;
+
+ static_assert((sizeof(T) % 16) == 0, "Constant buffer size must be 16-byte aligned");
+
+ CD3D11_BUFFER_DESC cbDesc;
+ cbDesc.ByteWidth = sizeof(T);
+ cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ cbDesc.Usage = D3D11_USAGE_DYNAMIC;
+ cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ cbDesc.MiscFlags = 0;
+ cbDesc.StructureByteStride = 1;
+ hr = device->CreateBuffer(&cbDesc, nullptr, &cb);
+ if (cb == nullptr)
+ return nullptr;
+ return new ConstantBuffer<T>(cb);
+ }
+
+ ConstantBuffer(ID3D11Buffer * b)
+ {
+ buffer_ = b;
+ }
+
+ ~ConstantBuffer()
+ {
+ SAFE_RELEASE(buffer_);
+ }
+
+ T * Map(ID3D11DeviceContext * ctx)
+ {
+ HRESULT hr;
+ D3D11_MAPPED_SUBRESOURCE data;
+ hr = ctx->Map(buffer_, 0, D3D11_MAP_WRITE_DISCARD, 0, &data);
+ return static_cast<T*>(data.pData);
+ }
+
+ void Unmap(ID3D11DeviceContext * ctx)
+ {
+ ctx->Unmap(buffer_, 0);
+ }
+
+ ID3D11Buffer * getCB() { return buffer_; }
+
+private:
+ ConstantBuffer() {};
+
+ ID3D11Buffer *buffer_;
+};
+
+/*==============================================================================
+ Texture resource management helpers
+==============================================================================*/
+
+//------------------------------------------------------------------------------
+class ShaderResource
+{
+public:
+ ShaderResource(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11UnorderedAccessView * uav);
+ ~ShaderResource();
+
+ ID3D11Resource * getResource() { return resource_; }
+ ID3D11ShaderResourceView * getSRV() { return srv_; }
+ ID3D11UnorderedAccessView * getUAV() { return uav_; }
+
+protected:
+ ShaderResource() {};
+
+ ID3D11Resource * resource_;
+ ID3D11ShaderResourceView * srv_;
+ ID3D11UnorderedAccessView * uav_;
+};
+
+//------------------------------------------------------------------------------
+class RenderTarget : public ShaderResource
+{
+public:
+ static RenderTarget * Create(ID3D11Device * device, UINT width, UINT height, UINT samples, DXGI_FORMAT format, const char * debug_name=nullptr);
+ RenderTarget(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11RenderTargetView * rtv, ID3D11UnorderedAccessView * uav);
+ ~RenderTarget();
+
+ ID3D11RenderTargetView * getRTV() { return rtv_; }
+
+protected:
+ RenderTarget() {};
+ ID3D11RenderTargetView * rtv_;
+};
+
+//------------------------------------------------------------------------------
+class DepthTarget : public ShaderResource
+{
+public:
+ static DepthTarget * Create(ID3D11Device * device, UINT width, UINT height, UINT samples, DXGI_FORMAT format, uint32_t slices=1, char * debug_name=nullptr);
+ DepthTarget(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11DepthStencilView * dsv, ID3D11DepthStencilView * readonly_dsv, ID3D11UnorderedAccessView * uav);
+ ~DepthTarget();
+
+ ID3D11DepthStencilView * getDSV() { return dsv_; }
+ ID3D11DepthStencilView * getReadOnlyDSV() { return readonly_dsv_; }
+
+protected:
+ DepthTarget() {};
+ ID3D11DepthStencilView * dsv_;
+ ID3D11DepthStencilView * readonly_dsv_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+#endif // D3D11_UTIL_H \ No newline at end of file
diff --git a/samples/VolumetricLightingTest/main.cpp b/samples/VolumetricLightingTest/main.cpp
new file mode 100644
index 0000000..94d299f
--- /dev/null
+++ b/samples/VolumetricLightingTest/main.cpp
@@ -0,0 +1,68 @@
+// 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 (c) 2003 - 2016 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.h"
+#include "scene.h"
+
+#include <Nv/VolumetricLighting/NvVolumetricLighting.h>
+
+#if (NV_WIN32 || NV_WIN64)
+#include <windows.h>
+
+int main_D3D11(Scene * pScene);
+#endif
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Common entrypoint
+
+#if (NV_WIN32 || NV_WIN64)
+int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
+{
+ (void)hInstance;
+ (void)hPrevInstance;
+ (void)lpCmdLine;
+ (void)nCmdShow;
+
+ SetProcessDPIAware();
+#else
+int main(int argc, char ** argv)
+{
+ (void)argc;
+ (void)argv;
+#endif
+
+ // Common setup
+ Scene scene;
+
+ // Call into platform-specific implementation
+#if (NV_WIN32 || NV_WIN64)
+ return main_D3D11(&scene);
+#else
+ return -1;
+#endif
+};
diff --git a/samples/VolumetricLightingTest/scene.cpp b/samples/VolumetricLightingTest/scene.cpp
new file mode 100644
index 0000000..574baa2
--- /dev/null
+++ b/samples/VolumetricLightingTest/scene.cpp
@@ -0,0 +1,609 @@
+// 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 (c) 2003 - 2016 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.h"
+#include "scene.h"
+
+#include <Nv/VolumetricLighting/NvVolumetricLighting.h>
+
+////////////////////////////////////////////////////////////////////////////////
+const uint32_t Scene::SHADOWMAP_RESOLUTION = 1024;
+const float Scene::LIGHT_RANGE = 50.0f;
+const float Scene::SPOTLIGHT_FALLOFF_ANGLE = Nv::NvPi / 4.0f;
+const float Scene::SPOTLIGHT_FALLOFF_POWER = 1.0f;
+
+Scene::Scene()
+{
+ gwvlctx_ = nullptr;
+
+ isCtxValid_ = false;
+ debugMode_ = Nv::Vl::DebugFlags::NONE;
+ isPaused_ = false;
+
+ viewpoint_ = 0;
+ lightPower_ = 0;
+ mediumType_ = 0;
+ lightMode_ = eLightMode::SPOTLIGHT;
+
+ sceneTransform_ = Nv::NvMat44(Nv::NvIdentity);
+ lightTransform_ = Nv::NvMat44(Nv::NvIdentity);
+
+ //--------------------------------------------------------------------------
+ // Default context settings
+ contextDesc_.framebuffer.uWidth = 0;
+ contextDesc_.framebuffer.uHeight = 0;
+ contextDesc_.framebuffer.uSamples = 0;
+ contextDesc_.eDownsampleMode = Nv::Vl::DownsampleMode::FULL;
+ contextDesc_.eInternalSampleMode = Nv::Vl::MultisampleMode::SINGLE;
+ contextDesc_.eFilterMode = Nv::Vl::FilterMode::NONE;
+
+ //--------------------------------------------------------------------------
+ // Default post-process settings
+ postprocessDesc_.bDoFog = true;
+ postprocessDesc_.bIgnoreSkyFog = false;
+ postprocessDesc_.eUpsampleQuality = Nv::Vl::UpsampleQuality::BILINEAR;
+ postprocessDesc_.fBlendfactor = 1.0f;
+ postprocessDesc_.fTemporalFactor = 0.95f;
+ postprocessDesc_.fFilterThreshold = 0.20f;
+}
+
+void Scene::Release()
+{
+ if (gwvlctx_) Nv::Vl::ReleaseContext(gwvlctx_);
+ isCtxValid_ = false;
+}
+
+bool Scene::isCtxValid()
+{
+ return isCtxValid_;
+}
+
+void Scene::invalidateCtx()
+{
+ isCtxValid_ = false;
+}
+
+void Scene::createCtx(const Nv::Vl::PlatformDesc * platform)
+{
+ // Assumes platformDesc and contextDesc have been updated
+ if (gwvlctx_) Nv::Vl::ReleaseContext(gwvlctx_);
+ Nv::Vl::Status gwvl_status = Nv::Vl::CreateContext(gwvlctx_, platform, &contextDesc_);
+ ASSERT_LOG(gwvl_status == Nv::Vl::Status::OK, "GWVL Error: %d", gwvl_status);
+ gwvl_status;
+ isCtxValid_ = true;
+}
+
+void Scene::updateFramebuffer(uint32_t w, uint32_t h, uint32_t s)
+{
+ contextDesc_.framebuffer.uWidth = w;
+ contextDesc_.framebuffer.uHeight = h;
+ contextDesc_.framebuffer.uSamples = s;
+ invalidateCtx();
+}
+
+void Scene::setDebugMode(Nv::Vl::DebugFlags d)
+{
+ debugMode_ = d;
+}
+
+void Scene::togglePause()
+{
+ isPaused_ = !isPaused_;
+}
+
+void Scene::toggleDownsampleMode()
+{
+ switch (contextDesc_.eDownsampleMode)
+ {
+ case Nv::Vl::DownsampleMode::FULL:
+ contextDesc_.eDownsampleMode = Nv::Vl::DownsampleMode::HALF;
+ break;
+
+ case Nv::Vl::DownsampleMode::HALF:
+ contextDesc_.eDownsampleMode = Nv::Vl::DownsampleMode::QUARTER;
+ break;
+
+ case Nv::Vl::DownsampleMode::QUARTER:
+ contextDesc_.eDownsampleMode = Nv::Vl::DownsampleMode::FULL;
+ break;
+ }
+ invalidateCtx();
+}
+
+void Scene::toggleMsaaMode()
+{
+ if (contextDesc_.eDownsampleMode == Nv::Vl::DownsampleMode::FULL)
+ return;
+
+ switch (contextDesc_.eInternalSampleMode)
+ {
+ case Nv::Vl::MultisampleMode::SINGLE:
+ contextDesc_.eInternalSampleMode = Nv::Vl::MultisampleMode::MSAA2;
+ break;
+
+ case Nv::Vl::MultisampleMode::MSAA2:
+ contextDesc_.eInternalSampleMode = Nv::Vl::MultisampleMode::MSAA4;
+ break;
+
+ case Nv::Vl::MultisampleMode::MSAA4:
+ contextDesc_.eInternalSampleMode = Nv::Vl::MultisampleMode::SINGLE;
+ break;
+ }
+ invalidateCtx();
+}
+
+void Scene::toggleFiltering()
+{
+ if (contextDesc_.eDownsampleMode == Nv::Vl::DownsampleMode::FULL)
+ return;
+
+ contextDesc_.eFilterMode = (contextDesc_.eFilterMode == Nv::Vl::FilterMode::TEMPORAL) ? Nv::Vl::FilterMode::NONE : Nv::Vl::FilterMode::TEMPORAL;
+ invalidateCtx();
+}
+
+void Scene::toggleUpsampleMode()
+{
+ if (contextDesc_.eDownsampleMode == Nv::Vl::DownsampleMode::FULL)
+ return;
+
+ switch (postprocessDesc_.eUpsampleQuality)
+ {
+ case Nv::Vl::UpsampleQuality::POINT:
+ postprocessDesc_.eUpsampleQuality = Nv::Vl::UpsampleQuality::BILINEAR;
+ break;
+
+ case Nv::Vl::UpsampleQuality::BILINEAR:
+ if (contextDesc_.eFilterMode == Nv::Vl::FilterMode::TEMPORAL)
+ postprocessDesc_.eUpsampleQuality = Nv::Vl::UpsampleQuality::BILATERAL;
+ else
+ postprocessDesc_.eUpsampleQuality = Nv::Vl::UpsampleQuality::POINT;
+ break;
+
+ case Nv::Vl::UpsampleQuality::BILATERAL:
+ postprocessDesc_.eUpsampleQuality = Nv::Vl::UpsampleQuality::POINT;
+ break;
+ }
+}
+
+void Scene::toggleFog()
+{
+ postprocessDesc_.bDoFog = !postprocessDesc_.bDoFog;
+}
+
+void Scene::toggleViewpoint()
+{
+ viewpoint_ = (viewpoint_+1)%4;
+}
+
+void Scene::toggleIntensity()
+{
+ lightPower_ = (lightPower_+1)%6;
+}
+
+void Scene::toggleMediumType()
+{
+ mediumType_ = (mediumType_+1)%4;
+}
+
+
+void Scene::toggleLightMode()
+{
+ switch (lightMode_)
+ {
+ default:
+ case Scene::eLightMode::DIRECTIONAL:
+ lightMode_ = Scene::eLightMode::SPOTLIGHT;
+ break;
+
+ case Scene::eLightMode::SPOTLIGHT:
+ lightMode_ = Scene::eLightMode::OMNI;
+ break;
+
+ case Scene::eLightMode::OMNI:
+ lightMode_ = Scene::eLightMode::DIRECTIONAL;
+ break;
+ }
+}
+
+Scene::eLightMode Scene::getLightMode()
+{
+ return lightMode_;
+}
+
+void Scene::getLightViewpoint(Nv::NvVec3 & vPos, Nv::NvMat44 & mViewProj)
+{
+ Nv::NvVec3 vOrigin = Nv::NvVec3(0, 0, 0);
+ Nv::NvVec3 vUp = Nv::NvVec3(0, 1, 0);
+ switch (getLightMode())
+ {
+ case Scene::eLightMode::OMNI:
+ {
+ vPos = lightTransform_.transform(Nv::NvVec3(15, 10, 0));
+ Nv::NvMat44 mLightView = Nv::NvMat44(Nv::NvVec3(1,0,0), Nv::NvVec3(0,1,0), Nv::NvVec3(0,0,1), -vPos);
+ Nv::NvMat44 mLightProj = Nv::NvMat44(Nv::NvIdentity);
+ mViewProj = mLightProj*mLightView;
+ }
+ break;
+
+ case Scene::eLightMode::SPOTLIGHT:
+ {
+ vPos = Nv::NvVec3(10, 15, 5);
+ Nv::NvMat44 mLightView = LookAtTransform(vPos, vOrigin, vUp);
+ Nv::NvMat44 mLightProj = PerspectiveProjLH(
+ SPOTLIGHT_FALLOFF_ANGLE,
+ 1.0f,
+ 0.50f, LIGHT_RANGE);
+ mViewProj = mLightProj*mLightView;
+ }
+ break;
+
+ default:
+ case eLightMode::DIRECTIONAL:
+ {
+ vPos = Nv::NvVec3(10, 15, 5);
+ Nv::NvMat44 mLightView = LookAtTransform(vPos, vOrigin, vUp);
+ Nv::NvMat44 mLightProj = OrthographicProjLH(25.0f, 25.0f, 0.50f, LIGHT_RANGE);
+
+ mViewProj = mLightProj*mLightView;
+ }
+ break;
+ }
+}
+
+Nv::NvVec3 Scene::getLightIntensity()
+{
+ const Nv::NvVec3 LIGHT_POWER[] = {
+ 1.00f*Nv::NvVec3(1.00f, 0.95f, 0.90f),
+ 0.50f*Nv::NvVec3(1.00f, 0.95f, 0.90f),
+ 1.50f*Nv::NvVec3(1.00f, 0.95f, 0.90f),
+ 1.00f*Nv::NvVec3(1.00f, 0.75f, 0.50f),
+ 1.00f*Nv::NvVec3(0.75f, 1.00f, 0.75f),
+ 1.00f*Nv::NvVec3(0.50f, 0.75f, 1.00f)
+ };
+
+ switch (getLightMode())
+ {
+ case Scene::eLightMode::OMNI:
+ return 25000.0f*LIGHT_POWER[lightPower_];
+
+ case Scene::eLightMode::SPOTLIGHT:
+ return 50000.0f*LIGHT_POWER[lightPower_];
+
+ default:
+ case eLightMode::DIRECTIONAL:
+ return 250.0f*LIGHT_POWER[lightPower_];
+ }
+}
+
+const Nv::Vl::ViewerDesc * Scene::getViewerDesc()
+{
+ static Nv::Vl::ViewerDesc viewerDesc;
+ Nv::NvVec3 vOrigin = Nv::NvVec3(0, 0, 0);
+ Nv::NvVec3 vUp = Nv::NvVec3(0, 1, 0);
+ Nv::NvVec3 VIEWPOINTS[] = {
+ Nv::NvVec3(0, 0, -17.5f),
+ Nv::NvVec3(0, 17.5f, 0),
+ Nv::NvVec3(0, -17.5f, 0),
+ Nv::NvVec3(17.5f, 0, 0),
+ };
+ Nv::NvVec3 VIEWPOINT_UP[] = {
+ Nv::NvVec3(0, 1, 0),
+ Nv::NvVec3(0, 0, -1),
+ Nv::NvVec3(0, 0, -1),
+ Nv::NvVec3(0, 1, 0),
+ };
+ Nv::NvVec3 vEyePos = VIEWPOINTS[viewpoint_];
+ Nv::NvMat44 mEyeView = LookAtTransform(vEyePos, vOrigin, VIEWPOINT_UP[viewpoint_]);
+ Nv::NvMat44 mEyeProj = PerspectiveProjLH(
+ Nv::NvPiDivFour,
+ static_cast<float>(contextDesc_.framebuffer.uWidth)/static_cast<float>(contextDesc_.framebuffer.uHeight),
+ 0.50f, 50.0f );
+ Nv::NvMat44 mEyeViewProj = mEyeProj*mEyeView;
+
+ viewerDesc.mProj = NVtoNVC(mEyeProj);
+ viewerDesc.mViewProj = NVtoNVC(mEyeViewProj);
+ viewerDesc.vEyePosition = NVtoNVC(vEyePos);
+ viewerDesc.uViewportWidth = contextDesc_.framebuffer.uWidth;
+ viewerDesc.uViewportHeight = contextDesc_.framebuffer.uHeight;
+
+ return &viewerDesc;
+}
+
+const Nv::Vl::LightDesc * Scene::getLightDesc()
+{
+ static Nv::Vl::LightDesc lightDesc;
+ const float LIGHT_RANGE = 50.0f;
+
+ Nv::NvVec3 vLightPos;
+ Nv::NvMat44 mLightViewProj;
+ getLightViewpoint(vLightPos, mLightViewProj);
+ Nv::NvMat44 mLightViewProj_Inv = Inverse(mLightViewProj);
+
+ lightDesc.vIntensity = NVtoNVC(getLightIntensity());
+ lightDesc.mLightToWorld = NVtoNVC(mLightViewProj_Inv);
+
+ switch (getLightMode())
+ {
+ case Scene::eLightMode::OMNI:
+ {
+ lightDesc.eType = Nv::Vl::LightType::OMNI;
+ lightDesc.Omni.fZNear = 0.5f;
+ lightDesc.Omni.fZFar = LIGHT_RANGE;
+ lightDesc.Omni.vPosition = NVtoNVC(vLightPos);
+ lightDesc.Omni.eAttenuationMode = Nv::Vl::AttenuationMode::INV_POLYNOMIAL;
+ const float LIGHT_SOURCE_RADIUS = 0.5f; // virtual radius of a spheroid light source
+ lightDesc.Omni.fAttenuationFactors[0] = 1.0f;
+ lightDesc.Omni.fAttenuationFactors[1] = 2.0f / LIGHT_SOURCE_RADIUS;
+ lightDesc.Omni.fAttenuationFactors[2] = 1.0f / (LIGHT_SOURCE_RADIUS*LIGHT_SOURCE_RADIUS);
+ lightDesc.Omni.fAttenuationFactors[3] = 0.0f;
+ }
+ break;
+
+ case Scene::eLightMode::SPOTLIGHT:
+ {
+ Nv::NvVec3 vLightDirection = -vLightPos;
+ vLightDirection.normalize();
+ lightDesc.eType = Nv::Vl::LightType::SPOTLIGHT;
+ lightDesc.Spotlight.fZNear = 0.5f;
+ lightDesc.Spotlight.fZFar = LIGHT_RANGE;
+ lightDesc.Spotlight.eFalloffMode = Nv::Vl::SpotlightFalloffMode::FIXED;
+ lightDesc.Spotlight.fFalloff_Power = SPOTLIGHT_FALLOFF_POWER;
+ lightDesc.Spotlight.fFalloff_CosTheta = Nv::intrinsics::cos(SPOTLIGHT_FALLOFF_ANGLE);
+ lightDesc.Spotlight.vDirection = NVtoNVC(vLightDirection);
+ lightDesc.Spotlight.vPosition = NVtoNVC(vLightPos);
+ lightDesc.Spotlight.eAttenuationMode = Nv::Vl::AttenuationMode::INV_POLYNOMIAL;
+ const float LIGHT_SOURCE_RADIUS = 1.0f; // virtual radius of a spheroid light source
+ lightDesc.Spotlight.fAttenuationFactors[0] = 1.0f;
+ lightDesc.Spotlight.fAttenuationFactors[1] = 2.0f / LIGHT_SOURCE_RADIUS;
+ lightDesc.Spotlight.fAttenuationFactors[2] = 1.0f / (LIGHT_SOURCE_RADIUS*LIGHT_SOURCE_RADIUS);
+ lightDesc.Spotlight.fAttenuationFactors[3] = 0.0f;
+ }
+ break;
+
+ default:
+ case eLightMode::DIRECTIONAL:
+ {
+ Nv::NvVec3 vLightDirection = -vLightPos;
+ vLightDirection.normalize();
+ lightDesc.eType = Nv::Vl::LightType::DIRECTIONAL;
+ lightDesc.Directional.vDirection = NVtoNVC(vLightDirection);
+ }
+ }
+ return &lightDesc;
+}
+
+const Nv::Vl::MediumDesc * Scene::getMediumDesc()
+{
+ static Nv::Vl::MediumDesc mediumDesc;
+
+ const float SCATTER_PARAM_SCALE = 0.0001f;
+ mediumDesc.uNumPhaseTerms = 0;
+
+ uint32_t t = 0;
+
+ mediumDesc.PhaseTerms[t].ePhaseFunc = Nv::Vl::PhaseFunctionType::RAYLEIGH;
+ mediumDesc.PhaseTerms[t].vDensity = NVtoNVC(10.00f * SCATTER_PARAM_SCALE * Nv::NvVec3(0.596f, 1.324f, 3.310f));
+ t++;
+
+ switch (mediumType_)
+ {
+ default:
+ case 0:
+ mediumDesc.PhaseTerms[t].ePhaseFunc = Nv::Vl::PhaseFunctionType::HENYEYGREENSTEIN;
+ mediumDesc.PhaseTerms[t].vDensity = NVtoNVC(10.00f * SCATTER_PARAM_SCALE * Nv::NvVec3(1.00f, 1.00f, 1.00f));
+ mediumDesc.PhaseTerms[t].fEccentricity = 0.85f;
+ t++;
+ mediumDesc.vAbsorption = NVtoNVC(5.0f * SCATTER_PARAM_SCALE * Nv::NvVec3(1, 1, 1));
+ break;
+
+ case 1:
+ mediumDesc.PhaseTerms[t].ePhaseFunc = Nv::Vl::PhaseFunctionType::HENYEYGREENSTEIN;
+ mediumDesc.PhaseTerms[t].vDensity = NVtoNVC(15.00f * SCATTER_PARAM_SCALE * Nv::NvVec3(1.00f, 1.00f, 1.00f));
+ mediumDesc.PhaseTerms[t].fEccentricity = 0.60f;
+ t++;
+ mediumDesc.vAbsorption = NVtoNVC(25.0f * SCATTER_PARAM_SCALE * Nv::NvVec3(1, 1, 1));
+ break;
+
+ case 2:
+ mediumDesc.PhaseTerms[t].ePhaseFunc = Nv::Vl::PhaseFunctionType::MIE_HAZY;
+ mediumDesc.PhaseTerms[t].vDensity = NVtoNVC(20.00f * SCATTER_PARAM_SCALE * Nv::NvVec3(1.00f, 1.00f, 1.00f));
+ t++;
+ mediumDesc.vAbsorption = NVtoNVC(25.0f * SCATTER_PARAM_SCALE * Nv::NvVec3(1, 1, 1));
+ break;
+
+ case 3:
+ mediumDesc.PhaseTerms[t].ePhaseFunc = Nv::Vl::PhaseFunctionType::MIE_MURKY;
+ mediumDesc.PhaseTerms[t].vDensity = NVtoNVC(30.00f * SCATTER_PARAM_SCALE * Nv::NvVec3(1.00f, 1.00f, 1.00f));
+ t++;
+ mediumDesc.vAbsorption = NVtoNVC(50.0f * SCATTER_PARAM_SCALE * Nv::NvVec3(1, 1, 1));
+ break;
+ }
+
+ mediumDesc.uNumPhaseTerms = t;
+
+ return &mediumDesc;
+}
+
+const Nv::Vl::PostprocessDesc * Scene::getPostprocessDesc()
+{
+ postprocessDesc_.vFogLight = NVtoNVC(getLightIntensity());
+ postprocessDesc_.fMultiscatter = 0.000002f;
+ return &postprocessDesc_;
+}
+
+void Scene::beginAccumulation(Nv::Vl::PlatformRenderCtx ctx, Nv::Vl::PlatformShaderResource sceneDepth)
+{
+ Nv::Vl::Status gwvl_status;
+ gwvl_status = Nv::Vl::BeginAccumulation(gwvlctx_, ctx, sceneDepth, getViewerDesc(), getMediumDesc(), debugMode_);
+ ASSERT_LOG(gwvl_status == Nv::Vl::Status::OK, "GWVL Error: %d", gwvl_status);
+}
+
+void Scene::renderVolume(Nv::Vl::PlatformRenderCtx ctx, Nv::Vl::PlatformShaderResource shadowmap)
+{
+ Nv::NvVec3 vLightPos;
+ Nv::NvMat44 mLightViewProj;
+ getLightViewpoint(vLightPos, mLightViewProj);
+
+ Nv::Vl::ShadowMapDesc shadowmapDesc;
+ {
+ shadowmapDesc.eType = (getLightMode() == Scene::eLightMode::OMNI) ? Nv::Vl::ShadowMapLayout::PARABOLOID : Nv::Vl::ShadowMapLayout::SIMPLE;
+ shadowmapDesc.uWidth = SHADOWMAP_RESOLUTION;
+ shadowmapDesc.uHeight = SHADOWMAP_RESOLUTION;
+ shadowmapDesc.uElementCount = 1;
+ shadowmapDesc.Elements[0].uOffsetX = 0;
+ shadowmapDesc.Elements[0].uOffsetY = 0;
+ shadowmapDesc.Elements[0].uWidth = shadowmapDesc.uWidth;
+ shadowmapDesc.Elements[0].uHeight = shadowmapDesc.uHeight;
+ shadowmapDesc.Elements[0].mViewProj = NVtoNVC(mLightViewProj);
+ shadowmapDesc.Elements[0].mArrayIndex = 0;
+ if (getLightMode() == Scene::eLightMode::OMNI)
+ {
+ shadowmapDesc.uElementCount = 2;
+ shadowmapDesc.Elements[1].uOffsetX = 0;
+ shadowmapDesc.Elements[1].uOffsetY = 0;
+ shadowmapDesc.Elements[1].uWidth = shadowmapDesc.uWidth;
+ shadowmapDesc.Elements[1].uHeight = shadowmapDesc.uHeight;
+ shadowmapDesc.Elements[1].mViewProj = NVtoNVC(mLightViewProj);
+ shadowmapDesc.Elements[1].mArrayIndex = 1;
+ }
+ }
+
+ Nv::Vl::VolumeDesc volumeDesc;
+ {
+ volumeDesc.fTargetRayResolution = 12.0f;
+ volumeDesc.uMaxMeshResolution = SHADOWMAP_RESOLUTION;
+ volumeDesc.fDepthBias = 0.0f;
+ volumeDesc.eTessQuality = Nv::Vl::TessellationQuality::HIGH;
+ }
+
+ Nv::Vl::Status gwvl_status;
+ gwvl_status = Nv::Vl::RenderVolume(gwvlctx_, ctx, shadowmap, &shadowmapDesc, getLightDesc(), &volumeDesc);
+ ASSERT_LOG(gwvl_status == Nv::Vl::Status::OK, "GWVL Error: %d", gwvl_status);
+}
+
+void Scene::endAccumulation(Nv::Vl::PlatformRenderCtx ctx)
+{
+ Nv::Vl::Status gwvl_status;
+ gwvl_status = Nv::Vl::EndAccumulation(gwvlctx_, ctx);
+ ASSERT_LOG(gwvl_status == Nv::Vl::Status::OK, "GWVL Error: %d", gwvl_status);
+}
+
+void Scene::applyLighting(Nv::Vl::PlatformRenderCtx ctx, Nv::Vl::PlatformRenderTarget sceneRT, Nv::Vl::PlatformShaderResource sceneDepth)
+{
+ Nv::Vl::Status gwvl_status;
+ gwvl_status = Nv::Vl::ApplyLighting(gwvlctx_, ctx, sceneRT, sceneDepth, getPostprocessDesc());
+ ASSERT_LOG(gwvl_status == Nv::Vl::Status::OK, "GWVL Error: %d", gwvl_status);
+}
+
+void Scene::animate(float dt)
+{
+ static uint64_t time_elapsed_us = 0;
+
+ // Update the scene
+ if (!isPaused_)
+ {
+ time_elapsed_us += static_cast<uint64_t>(dt * 1000000.0);
+ if (lightMode_ != eLightMode::OMNI)
+ {
+ float angle = float(dt) * Nv::NvPiDivFour;
+ sceneTransform_ = sceneTransform_ * Nv::NvMat44(
+ Nv::NvVec4(Nv::intrinsics::cos(angle), 0, -Nv::intrinsics::sin(angle), 0),
+ Nv::NvVec4(0, 1, 0, 0),
+ Nv::NvVec4(Nv::intrinsics::sin(angle), 0, Nv::intrinsics::cos(angle), 0),
+ Nv::NvVec4(0, 0, 0, 1)
+ );
+ }
+ else
+ {
+ sceneTransform_ = Nv::NvMat44(Nv::NvIdentity);
+ }
+
+ if (lightMode_ == eLightMode::OMNI)
+ {
+ const uint64_t CYCLE_LENGTH = 60000000;
+ float cyclePhase = static_cast<float>(time_elapsed_us % CYCLE_LENGTH) / static_cast<float>(CYCLE_LENGTH);
+ lightTransform_ = Nv::NvMat44(
+ Nv::NvVec4(Nv::intrinsics::cos(Nv::NvTwoPi*7.0f*cyclePhase), 0, 0, 0),
+ Nv::NvVec4(0, Nv::intrinsics::cos(Nv::NvTwoPi*3.0f*cyclePhase), 0, 0),
+ Nv::NvVec4(0, 0, 1, 0),
+ Nv::NvVec4(0, 0, 0, 1)
+ );
+ }
+ }
+}
+
+void Scene::setupObjectCB(ObjectCB * pObject, const Nv::NvVec3 & offset)
+{
+ pObject->mTransform = sceneTransform_*Nv::NvTransform(offset);
+ pObject->vColor[0] = 1.0f;
+ pObject->vColor[1] = 1.0f;
+ pObject->vColor[2] = 1.0f;
+}
+
+void Scene::setupLightViewCB(ViewCB * pView)
+{
+ getLightViewpoint(pView->vEyePos, pView->mProj);
+ pView->zNear = 0.50f;
+ pView->zFar = LIGHT_RANGE;
+}
+
+void Scene::setupSceneCBs(ViewCB * pView, LightCB * pLight)
+{
+ const Nv::Vl::ViewerDesc * viewerDesc = getViewerDesc();
+ pView->mProj = *reinterpret_cast<const Nv::NvMat44 *>(&viewerDesc->mViewProj);
+ pView->vEyePos = *reinterpret_cast<const Nv::NvVec3 *>(&viewerDesc->vEyePosition);
+ pView->zNear = 0.50f;
+ pView->zFar = 50.0f;
+
+ const Nv::Vl::LightDesc * lightDesc = getLightDesc();
+ getLightViewpoint(pLight->vLightPos, pLight->mLightViewProj);
+ pLight->vLightDirection = (-pLight->vLightPos);
+ pLight->vLightDirection.normalize();
+ pLight->fLightFalloffCosTheta = Nv::intrinsics::cos(SPOTLIGHT_FALLOFF_ANGLE);
+ pLight->fLightFalloffPower = SPOTLIGHT_FALLOFF_POWER;
+ pLight->vLightColor = getLightIntensity();
+ if (lightMode_ == eLightMode::SPOTLIGHT)
+ {
+ pLight->vLightAttenuationFactors = Nv::NvVec4(lightDesc->Spotlight.fAttenuationFactors);
+ }
+ else if (lightMode_ == eLightMode::OMNI)
+ {
+ pLight->vLightAttenuationFactors = Nv::NvVec4(lightDesc->Omni.fAttenuationFactors);
+ }
+ pLight->zNear = 0.50f;
+ pLight->zFar = LIGHT_RANGE;
+
+ const Nv::Vl::MediumDesc * mediumDesc = getMediumDesc();
+ pLight->vSigmaExtinction = *reinterpret_cast<const Nv::NvVec3 *>(&mediumDesc->vAbsorption);
+ for (uint32_t t = 0; t < mediumDesc->uNumPhaseTerms; ++t)
+ {
+ pLight->vSigmaExtinction = pLight->vSigmaExtinction + *reinterpret_cast<const Nv::NvVec3 *>(&mediumDesc->PhaseTerms[t].vDensity);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
diff --git a/samples/VolumetricLightingTest/scene.h b/samples/VolumetricLightingTest/scene.h
new file mode 100644
index 0000000..efed5af
--- /dev/null
+++ b/samples/VolumetricLightingTest/scene.h
@@ -0,0 +1,150 @@
+// 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 (c) 2003 - 2016 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 SCENE_H
+#define SCENE_H
+////////////////////////////////////////////////////////////////////////////////
+#include "common.h"
+#include <Nv/VolumetricLighting/NvVolumetricLighting.h>
+////////////////////////////////////////////////////////////////////////////////
+class Scene
+{
+public:
+ static const uint32_t SHADOWMAP_RESOLUTION;
+ static const float LIGHT_RANGE;
+ static const float SPOTLIGHT_FALLOFF_ANGLE;
+ static const float SPOTLIGHT_FALLOFF_POWER;
+
+ enum class eLightMode
+ {
+ UNKNOWN = -1,
+ DIRECTIONAL,
+ SPOTLIGHT,
+ OMNI,
+ COUNT
+ };
+
+ struct ViewCB
+ {
+ Nv::NvMat44 mProj;
+ Nv::NvVec3 vEyePos;
+ float pad1[1];
+ float zNear;
+ float zFar;
+ float pad2[2];
+ };
+
+ struct ObjectCB
+ {
+ Nv::NvMat44 mTransform;
+ float vColor[3];
+ float pad[1];
+ };
+
+ struct LightCB
+ {
+ Nv::NvMat44 mLightViewProj;
+ Nv::NvVec3 vLightDirection;
+ float fLightFalloffCosTheta;
+ Nv::NvVec3 vLightPos;
+ float fLightFalloffPower;
+ Nv::NvVec3 vLightColor;
+ float pad1[1];
+ Nv::NvVec4 vLightAttenuationFactors;
+ float zNear;
+ float zFar;
+ float pad2[2];
+ Nv::NvVec3 vSigmaExtinction;
+ float pad3[1];
+ };
+
+ Scene();
+ void Release();
+
+ bool isCtxValid();
+ void invalidateCtx();
+ void createCtx(const Nv::Vl::PlatformDesc * platform);
+
+ void updateFramebuffer(uint32_t w, uint32_t h, uint32_t s);
+
+ void setDebugMode(Nv::Vl::DebugFlags d);
+ void togglePause();
+ void toggleDownsampleMode();
+ void toggleMsaaMode();
+ void toggleFiltering();
+ void toggleUpsampleMode();
+ void toggleFog();
+ void toggleViewpoint();
+ void toggleIntensity();
+ void toggleMediumType();
+ void toggleLightMode();
+
+ eLightMode getLightMode();
+ void getLightViewpoint(Nv::NvVec3 & vPos, Nv::NvMat44 & mViewProj);
+ Nv::NvVec3 getLightIntensity();
+
+ const Nv::Vl::ViewerDesc * getViewerDesc();
+ const Nv::Vl::LightDesc * getLightDesc();
+ const Nv::Vl::MediumDesc * getMediumDesc();
+ const Nv::Vl::PostprocessDesc * getPostprocessDesc();
+
+ void beginAccumulation(Nv::Vl::PlatformRenderCtx ctx, Nv::Vl::PlatformShaderResource sceneDepth);
+ void renderVolume(Nv::Vl::PlatformRenderCtx ctx, Nv::Vl::PlatformShaderResource shadowmap);
+ void endAccumulation(Nv::Vl::PlatformRenderCtx ctx);
+ void applyLighting(Nv::Vl::PlatformRenderCtx ctx, Nv::Vl::PlatformRenderTarget sceneRT, Nv::Vl::PlatformShaderResource sceneDepth);
+
+ void setupObjectCB(ObjectCB * pObject, const Nv::NvVec3 & offset);
+ void setupLightViewCB(ViewCB * cb);
+ void setupSceneCBs(ViewCB * view_cb, LightCB * light_cb);
+ void animate(float dt);
+
+private:
+ Scene(const Scene & rhs) {rhs;};
+
+ Nv::Vl::Context gwvlctx_;
+ uint32_t shadowmapRes_;
+
+ bool isCtxValid_;
+ bool isPaused_;
+
+ eLightMode lightMode_;
+
+ Nv::Vl::DebugFlags debugMode_;
+ uint32_t viewpoint_;
+ uint32_t lightPower_;
+ uint32_t mediumType_;
+
+ Nv::NvMat44 sceneTransform_;
+ Nv::NvMat44 lightTransform_;
+
+ Nv::Vl::ContextDesc contextDesc_;
+ Nv::Vl::PostprocessDesc postprocessDesc_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+#endif // SCENE_H
diff --git a/samples/VolumetricLightingTest/shaders/post_PS.hlsl b/samples/VolumetricLightingTest/shaders/post_PS.hlsl
new file mode 100644
index 0000000..d0e5a4c
--- /dev/null
+++ b/samples/VolumetricLightingTest/shaders/post_PS.hlsl
@@ -0,0 +1,56 @@
+// 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 (c) 2003 - 2016 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 the shader permutations for code generation
+%% MUX_BEGIN %%
+%% MUX_END %%
+*/
+
+struct VS_QUAD_OUTPUT
+{
+ float4 vPos : SV_POSITION;
+ sample float2 vTex : TEXCOORD0;
+};
+
+float3 tonemap(float3 C)
+{
+ // Filmic -- model film properties
+ C = max(0, C - 0.004);
+ return (C*(6.2*C+0.5))/(C*(6.2*C+1.7)+0.06);
+}
+
+Texture2DMS<float4> tScene : register(t0);
+
+float4 main(VS_QUAD_OUTPUT input, uint sampleID : SV_SAMPLEINDEX) : SV_Target0
+{
+ float3 output = float3(0, 0, 0);
+ float3 s_hdr = tScene.Load(int2(input.vPos.xy), sampleID).rgb;
+ output = tonemap(s_hdr);
+ return float4(output, 1);
+}
diff --git a/samples/VolumetricLightingTest/shaders/quad_VS.hlsl b/samples/VolumetricLightingTest/shaders/quad_VS.hlsl
new file mode 100644
index 0000000..b8f666a
--- /dev/null
+++ b/samples/VolumetricLightingTest/shaders/quad_VS.hlsl
@@ -0,0 +1,47 @@
+// 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 (c) 2003 - 2016 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 the shader permutations for code generation
+%% MUX_BEGIN %%
+%% MUX_END %%
+*/
+
+struct VS_QUAD_OUTPUT
+{
+ float4 vPos : SV_POSITION;
+ sample float2 vTex : TEXCOORD0;
+};
+
+VS_QUAD_OUTPUT main(uint id : SV_VERTEXID)
+{
+ VS_QUAD_OUTPUT output;
+ output.vTex = float2((id << 1) & 2, id & 2);
+ output.vPos = float4(output.vTex * float2(2,-2) + float2(-1,1), 1, 1);
+ return output;
+}
diff --git a/samples/VolumetricLightingTest/shaders/scene_GS.hlsl b/samples/VolumetricLightingTest/shaders/scene_GS.hlsl
new file mode 100644
index 0000000..3315a79
--- /dev/null
+++ b/samples/VolumetricLightingTest/shaders/scene_GS.hlsl
@@ -0,0 +1,141 @@
+// 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 (c) 2003 - 2016 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 the shader permutations for code generation
+%% MUX_BEGIN %%
+
+%% MUX_END %%
+
+*/
+
+////////////////////////////////////////////////////////////////////////////////
+// Constant Buffers
+
+cbuffer CameraCB : register( b0 )
+{
+ column_major float4x4 c_mViewProj : packoffset(c0);
+ float3 c_vEyePos : packoffset(c4);
+ float c_fZNear : packoffset(c5);
+ float c_fZFar : packoffset(c5.y);
+};
+
+cbuffer ObjectCB : register( b1 )
+{
+ column_major float4x4 c_mObject : packoffset(c0);
+ float3 c_vObjectColor : packoffset(c4);
+};
+
+cbuffer LightCB : register( b2 )
+{
+ column_major float4x4 c_mLightViewProj : packoffset(c0);
+ float3 c_vLightDirection : packoffset(c4);
+ float c_fLightFalloffCosTheta : packoffset(c4.w);
+ float3 c_vLightPos : packoffset(c5);
+ float c_fLightFalloffPower : packoffset(c5.w);
+ float3 c_vLightColor : packoffset(c6);
+ float4 c_vLightAttenuationFactors : packoffset(c7);
+ float c_fLightZNear : packoffset(c8);
+ float c_fLightZNFar : packoffset(c8.y);
+ float3 c_vSigmaExtinction : packoffset(c9);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// IO Structures
+
+struct VS_OUTPUT
+{
+ float4 ScreenP : SV_POSITION;
+ float4 P : TEXCOORD0;
+ float3 N : NORMAL0;
+};
+
+struct GS_OUTPUT
+{
+ float4 ScreenP : SV_POSITION;
+ float4 P : TEXCOORD0;
+ float3 N : NORMAL;
+ uint Target : SV_RenderTargetArrayIndex;
+ float Wz : SV_ClipDistance0;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Geometry Shader
+
+float3 ParaboloidProject(float3 P, float zNear, float zFar)
+{
+ float3 outP;
+ float lenP = length(P.xyz);
+ outP.xyz = P.xyz/lenP;
+ outP.x = outP.x / (outP.z + 1);
+ outP.y = outP.y / (outP.z + 1);
+ outP.z = (lenP - zNear) / (zFar - zNear);
+ return outP;
+}
+
+void GenerateOmniTriangle(uint target, VS_OUTPUT vA, VS_OUTPUT vB, VS_OUTPUT vC, inout TriangleStream<GS_OUTPUT> output)
+{
+ GS_OUTPUT outValue;
+ outValue.Target = target;
+ outValue.ScreenP = float4(ParaboloidProject(vA.ScreenP.xyz, c_fZNear, c_fZFar), 1);
+ outValue.P = vA.P;
+ outValue.N = vA.N;
+ outValue.Wz = vA.ScreenP.z;
+ output.Append(outValue);
+ outValue.ScreenP = float4(ParaboloidProject(vB.ScreenP.xyz, c_fZNear, c_fZFar), 1);
+ outValue.P = vB.P;
+ outValue.N = vB.N;
+ outValue.Wz = vB.ScreenP.z;
+ output.Append(outValue);
+ outValue.ScreenP = float4(ParaboloidProject(vC.ScreenP.xyz, c_fZNear, c_fZFar), 1);
+ outValue.P = vC.P;
+ outValue.N = vC.N;
+ outValue.Wz = vC.ScreenP.z;
+ output.Append(outValue);
+ output.RestartStrip();
+}
+
+[maxvertexcount(6)]
+void main(triangle VS_OUTPUT input[3], inout TriangleStream<GS_OUTPUT> output)
+{
+ float minZ = min(input[0].ScreenP.z, min(input[1].ScreenP.z, input[2].ScreenP.z));
+ float maxZ = max(input[0].ScreenP.z, max(input[1].ScreenP.z, input[2].ScreenP.z));
+
+ if (maxZ >= 0)
+ {
+ GenerateOmniTriangle(0, input[0], input[1], input[2], output);
+ }
+
+ if (minZ <= 0)
+ {
+ input[0].ScreenP.z *= -1;
+ input[1].ScreenP.z *= -1;
+ input[2].ScreenP.z *= -1;
+ GenerateOmniTriangle(1, input[2], input[1], input[0], output);
+ }
+}
diff --git a/samples/VolumetricLightingTest/shaders/scene_PS.hlsl b/samples/VolumetricLightingTest/shaders/scene_PS.hlsl
new file mode 100644
index 0000000..66b7e9d
--- /dev/null
+++ b/samples/VolumetricLightingTest/shaders/scene_PS.hlsl
@@ -0,0 +1,177 @@
+// 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 (c) 2003 - 2016 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 the shader permutations for code generation
+%% MUX_BEGIN %%
+- LIGHTMODE:
+ - LIGHTMODE_DIRECTIONAL
+ - LIGHTMODE_SPOTLIGHT
+ - LIGHTMODE_OMNI
+%% MUX_END %%
+*/
+
+////////////////////////////////////////////////////////////////////////////////
+// Resources
+
+SamplerComparisonState sampShadowmap : register(s0);
+
+#if (LIGHTMODE == LIGHTMODE_DIRECTIONAL || LIGHTMODE == LIGHTMODE_SPOTLIGHT)
+ Texture2D<float> tShadowmap : register(t0);
+#elif (LIGHTMODE == LIGHTMODE_OMNI)
+ Texture2DArray <float1> tShadowmapArray : register(t0);
+#endif
+////////////////////////////////////////////////////////////////////////////////
+// Constant Buffers
+
+cbuffer CameraCB : register( b0 )
+{
+ column_major float4x4 c_mViewProj : packoffset(c0);
+ float3 c_vEyePos : packoffset(c4);
+ float c_fZNear : packoffset(c5);
+ float c_fZFar : packoffset(c5.y);
+};
+
+cbuffer ObjectCB : register( b1 )
+{
+ column_major float4x4 c_mObject : packoffset(c0);
+ float3 c_vObjectColor : packoffset(c4);
+};
+
+cbuffer LightCB : register( b2 )
+{
+ column_major float4x4 c_mLightViewProj : packoffset(c0);
+ float3 c_vLightDirection : packoffset(c4);
+ float c_fLightFalloffCosTheta : packoffset(c4.w);
+ float3 c_vLightPos : packoffset(c5);
+ float c_fLightFalloffPower : packoffset(c5.w);
+ float3 c_vLightColor : packoffset(c6);
+ float4 c_vLightAttenuationFactors : packoffset(c7);
+ float c_fLightZNear : packoffset(c8);
+ float c_fLightZFar : packoffset(c8.y);
+ float3 c_vSigmaExtinction : packoffset(c9);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// IO Structures
+
+struct VS_OUTPUT
+{
+ float4 ScreenP : SV_POSITION;
+ float4 P : TEXCOORD0;
+ float3 N : NORMAL0;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Pixel Shader
+
+float3 ParaboloidProject(float3 P, float zNear, float zFar)
+{
+ float3 outP;
+ float lenP = length(P.xyz);
+ outP.xyz = P.xyz/lenP;
+ outP.x = outP.x / (outP.z + 1);
+ outP.y = outP.y / (outP.z + 1);
+ outP.z = (lenP - zNear) / (zFar - zNear);
+ return outP;
+}
+
+float4 main(VS_OUTPUT input) : SV_Target0
+{
+ float3 P = input.P.xyz / input.P.w;
+ float3 N = normalize(input.N);
+ float3 Kd = c_vObjectColor;
+
+ //return float4(0.5*(N+1), 1);
+
+ const float SHADOW_BIAS = -0.001f;
+ float4 shadow_clip = mul(c_mLightViewProj, float4(P,1));
+ shadow_clip = shadow_clip / shadow_clip.w;
+ uint hemisphereID = (shadow_clip.z > 0) ? 0 : 1;
+ if (LIGHTMODE == LIGHTMODE_OMNI)
+ {
+ shadow_clip.z = abs(shadow_clip.z);
+ shadow_clip.xyz = ParaboloidProject(shadow_clip.xyz, c_fLightZNear, c_fLightZFar);
+ }
+ float2 shadow_tc = float2(0.5f, -0.5f)*shadow_clip.xy + 0.5f;
+ float receiver_depth = shadow_clip.z+SHADOW_BIAS;
+
+ float total_light = 0;
+ const int SHADOW_KERNEL = 2;
+ [unroll]
+ for (int ox=-SHADOW_KERNEL; ox<=SHADOW_KERNEL; ++ox)
+ {
+ [unroll]
+ for (int oy=-SHADOW_KERNEL; oy<=SHADOW_KERNEL; ++oy)
+ {
+#if (LIGHTMODE == LIGHTMODE_OMNI)
+ total_light += tShadowmapArray.SampleCmpLevelZero(sampShadowmap, float3(shadow_tc, hemisphereID), receiver_depth, int2(ox, oy)).x;
+#else
+ total_light += tShadowmap.SampleCmpLevelZero(sampShadowmap, shadow_tc, receiver_depth, int2(ox, oy)).x;
+#endif
+ }
+ }
+ float shadow_term = total_light / ((2*SHADOW_KERNEL+1) * (2*SHADOW_KERNEL+1));
+
+ float3 output = float3(0,0,0);
+ float3 L = -c_vLightDirection;
+ if (LIGHTMODE == LIGHTMODE_DIRECTIONAL)
+ {
+ float3 attenuation = shadow_term*dot(N, L);
+ float3 ambient = 0.001f*saturate(0.5f*(dot(N, L)+1.0f));
+ output += c_vLightColor*max(attenuation, ambient);
+
+ }
+ else if (LIGHTMODE == LIGHTMODE_SPOTLIGHT)
+ {
+ float light_to_world = length(P - c_vLightPos);
+ float3 W = (c_vLightPos - P)/light_to_world;
+
+ float distance_attenuation = 1.0f/(c_vLightAttenuationFactors.x + c_vLightAttenuationFactors.y*light_to_world + c_vLightAttenuationFactors.z*light_to_world*light_to_world) + c_vLightAttenuationFactors.w;
+
+ const float ANGLE_EPSILON = 0.00001f;
+ float angle_factor = saturate((dot(N, L)-c_fLightFalloffCosTheta)/(1-c_fLightFalloffCosTheta));
+ float spot_attenuation = (angle_factor > ANGLE_EPSILON) ? pow(angle_factor, c_fLightFalloffPower) : 0.0f;
+
+ float3 attenuation = distance_attenuation*spot_attenuation*shadow_term*dot(N, W);
+ float3 ambient = 0.00001f*saturate(0.5f*(dot(N, L)+1.0f));
+ output += c_vLightColor*max(attenuation, ambient)*exp(-c_vSigmaExtinction*light_to_world);
+ }
+ else if (LIGHTMODE == LIGHTMODE_OMNI)
+ {
+ float light_to_world = length(P - c_vLightPos);
+ float3 W = (c_vLightPos - P)/light_to_world;
+ float distance_attenuation = 1.0f/(c_vLightAttenuationFactors.x + c_vLightAttenuationFactors.y*light_to_world + c_vLightAttenuationFactors.z*light_to_world*light_to_world) + c_vLightAttenuationFactors.w;
+
+ float3 attenuation = distance_attenuation*shadow_term*dot(N, W);
+ float3 ambient = 0.00001f*saturate(0.5f*(dot(N, L)+1.0f));
+ output += c_vLightColor*max(attenuation, ambient)*exp(-c_vSigmaExtinction*light_to_world);
+ }
+
+ return float4(output, 1);
+}
diff --git a/samples/VolumetricLightingTest/shaders/scene_VS.hlsl b/samples/VolumetricLightingTest/shaders/scene_VS.hlsl
new file mode 100644
index 0000000..630b87c
--- /dev/null
+++ b/samples/VolumetricLightingTest/shaders/scene_VS.hlsl
@@ -0,0 +1,117 @@
+// 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 (c) 2003 - 2016 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 the shader permutations for code generation
+%% MUX_BEGIN %%
+%% MUX_END %%
+*/
+
+////////////////////////////////////////////////////////////////////////////////
+// Constant Buffers
+
+cbuffer CameraCB : register( b0 )
+{
+ column_major float4x4 c_mViewProj : packoffset(c0);
+ float3 c_vEyePos : packoffset(c4);
+ float c_fZNear : packoffset(c5);
+ float c_fZFar : packoffset(c5.y);
+};
+
+cbuffer ObjectCB : register( b1 )
+{
+ column_major float4x4 c_mObject : packoffset(c0);
+ float3 c_vObjectColor : packoffset(c4);
+};
+
+cbuffer LightCB : register( b2 )
+{
+ column_major float4x4 c_mLightViewProj : packoffset(c0);
+ float3 c_vLightDirection : packoffset(c4);
+ float c_fLightFalloffCosTheta : packoffset(c4.w);
+ float3 c_vLightPos : packoffset(c5);
+ float c_fLightFalloffPower : packoffset(c5.w);
+ float3 c_vLightColor : packoffset(c6);
+ float4 c_vLightAttenuationFactors : packoffset(c7);
+ float c_fLightZNear : packoffset(c8);
+ float c_fLightZNFar : packoffset(c8.y);
+ float3 c_vSigmaExtinction : packoffset(c9);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// IO Structures
+
+struct VS_OUTPUT
+{
+ float4 ScreenP : SV_POSITION;
+ float4 P : TEXCOORD0;
+ float3 N : NORMAL0;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Vertex Shader
+
+VS_OUTPUT main( uint id : SV_VERTEXID )
+{
+ VS_OUTPUT output;
+
+ // Faces
+ // +X, +Y, +Z, -X, -Y, -Z
+ // Vertices
+ // 0 ---15
+ // | / |
+ // | / |
+ // | / |
+ // 24--- 3
+
+ uint face_idx = id / 6;
+ uint vtx_idx = id % 6;
+ float3 P;
+ P.x = ((vtx_idx % 3) == 2) ? -1 : 1;
+ P.y = ((vtx_idx % 3) == 1) ? -1 : 1;
+ P.z = 0;
+ if ((face_idx % 3) == 0)
+ P.yzx = P.xyz;
+ else if ((face_idx % 3) == 1)
+ P.xzy = P.xyz;
+ // else if ((face_idx % 3) == 2)
+ // P.xyz = P.xyz;
+ P *= ((vtx_idx / 3) == 0) ? 1 : -1;
+
+ float3 N;
+ N.x = ((face_idx % 3) == 0) ? 1 : 0;
+ N.y = ((face_idx % 3) == 1) ? 1 : 0;
+ N.z = ((face_idx % 3) == 2) ? 1 : 0;
+ N *= ((face_idx / 3) == 0) ? 1 : -1;
+ P += N;
+
+ output.P = mul(c_mObject, float4(P, 1));
+ output.ScreenP = mul(c_mViewProj, output.P);
+ output.N = mul(c_mObject, float4(N, 0)).xyz;
+ return output;
+}
diff --git a/samples/bin/NvVolumetricLighting.win64.dll b/samples/bin/NvVolumetricLighting.win64.dll
new file mode 100644
index 0000000..0f3aff4
--- /dev/null
+++ b/samples/bin/NvVolumetricLighting.win64.dll
Binary files differ
diff --git a/samples/bin/VolumetricLightingTest.win64.exe b/samples/bin/VolumetricLightingTest.win64.exe
new file mode 100644
index 0000000..3096459
--- /dev/null
+++ b/samples/bin/VolumetricLightingTest.win64.exe
Binary files differ
diff --git a/samples/bin/VolumetricLightingTest_Readme.txt b/samples/bin/VolumetricLightingTest_Readme.txt
new file mode 100644
index 0000000..be5079a
--- /dev/null
+++ b/samples/bin/VolumetricLightingTest_Readme.txt
@@ -0,0 +1,15 @@
+F1 - Default View
+F2 - Scattering-only View
+F3 - Wireframe View
+
+F4 - Toggle Fullscreen
+
+Space - Pause animation
+
+V - Toggle Viewer Position
+L - Toggle Light Type (Spot, Point, Directional)
+O - Toggle Medium Type (Very Clear, Humid, Hazy, Murky)
+P - Toggle Light Power (Medium, Low, High, Red, Green, Blue)
+D - Toggle Downsample Mode (Full-Res, Half-Res, Quarter-Res)
+M - Toggle MSAA Mode (1x, 2x, 4x)
+U - Toggle Upsampling Mode (Point, Bilinear, Bilateral) \ No newline at end of file
diff --git a/samples/build/vs2012/VolumetricLightingTest.vcxproj b/samples/build/vs2012/VolumetricLightingTest.vcxproj
new file mode 100644
index 0000000..5f1fee5
--- /dev/null
+++ b/samples/build/vs2012/VolumetricLightingTest.vcxproj
@@ -0,0 +1,338 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="debug|x64">
+ <Configuration>debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="profile|x64">
+ <Configuration>profile</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="checked|x64">
+ <Configuration>checked</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="release|x64">
+ <Configuration>release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ApplicationEnvironment>title</ApplicationEnvironment>
+ <!-- - - - -->
+ <PlatformToolset>v110</PlatformToolset>
+ <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='profile|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='checked|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='profile|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='checked|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
+ <OutDir>./../../bin\</OutDir>
+ <IntDir>./x64/VolumetricLightingTest/debug\</IntDir>
+ <TargetExt>.exe</TargetExt>
+ <TargetName>VolumetricLightingTest.win64.D</TargetName>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
+ <ClCompile>
+ <CallingConvention>Cdecl</CallingConvention>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <OpenMPSupport>false</OpenMPSupport>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>/wd4995 /W4 /Oy- /EHsc -D_ITERATOR_DEBUG_LEVEL=0 /d2Zi+</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>./../../VolumetricLightingTest;./../../../include;$(IntDir);./../../../external/NvFoundation/1.1/include;./{user:ShaderOutputPath};%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN64;_UNICODE;UNICODE;_WINDOWS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;NV_FOUNDATION_DLL=0;NV_PLATFORM_D3D11=1;NV_DEBUG=1;NV_CHECKED=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>false</ExceptionHandling>
+ <WarningLevel>Level4</WarningLevel>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <PrecompiledHeaderFile></PrecompiledHeaderFile>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:x64 /SUBSYSTEM:WINDOWS /NOLOGO</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;dxguid.lib;d3d11.lib;NvVolumetricLighting.win64.D.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)VolumetricLightingTest.win64.D.exe</OutputFile>
+ <AdditionalLibraryDirectories>./../../../lib/win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>$(OutDir)/VolumetricLightingTest.win64.D.exe.pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)$(TargetName).lib</ImportLibrary>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <ResourceCompile>
+ </ResourceCompile>
+ <ProjectReference>
+ </ProjectReference>
+ </ItemDefinitionGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='profile|x64'">
+ <OutDir>./../../bin\</OutDir>
+ <IntDir>./x64/VolumetricLightingTest/profile\</IntDir>
+ <TargetExt>.exe</TargetExt>
+ <TargetName>VolumetricLightingTest.win64.P</TargetName>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='profile|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <OpenMPSupport>false</OpenMPSupport>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>/wd4995 /W4 /Oy- /EHsc /d2Zi+</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>./../../VolumetricLightingTest;./../../../include;$(IntDir);./../../../external/NvFoundation/1.1/include;./{user:ShaderOutputPath};%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN64;_UNICODE;UNICODE;_WINDOWS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;NV_FOUNDATION_DLL=0;NV_PLATFORM_D3D11=1;NV_PROFILE=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>false</ExceptionHandling>
+ <WarningLevel>Level4</WarningLevel>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <PrecompiledHeaderFile></PrecompiledHeaderFile>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:x64 /SUBSYSTEM:WINDOWS /NOLOGO</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;dxguid.lib;d3d11.lib;NvVolumetricLighting.win64.P.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)VolumetricLightingTest.win64.P.exe</OutputFile>
+ <AdditionalLibraryDirectories>./../../../lib/win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>$(OutDir)/VolumetricLightingTest.win64.P.exe.pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)$(TargetName).lib</ImportLibrary>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <ResourceCompile>
+ </ResourceCompile>
+ <ProjectReference>
+ </ProjectReference>
+ </ItemDefinitionGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='checked|x64'">
+ <OutDir>./../../bin\</OutDir>
+ <IntDir>./x64/VolumetricLightingTest/checked\</IntDir>
+ <TargetExt>.exe</TargetExt>
+ <TargetName>VolumetricLightingTest.win64.C</TargetName>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='checked|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <OpenMPSupport>false</OpenMPSupport>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>/wd4995 /W4 /Oy- /EHsc /d2Zi+</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>./../../VolumetricLightingTest;./../../../include;$(IntDir);./../../../external/NvFoundation/1.1/include;./{user:ShaderOutputPath};%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN64;_UNICODE;UNICODE;_WINDOWS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;NV_FOUNDATION_DLL=0;NV_PLATFORM_D3D11=1;NV_CHECKED=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>false</ExceptionHandling>
+ <WarningLevel>Level4</WarningLevel>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <PrecompiledHeaderFile></PrecompiledHeaderFile>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:x64 /SUBSYSTEM:WINDOWS /NOLOGO</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;dxguid.lib;d3d11.lib;NvVolumetricLighting.win64.C.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)VolumetricLightingTest.win64.C.exe</OutputFile>
+ <AdditionalLibraryDirectories>./../../../lib/win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>$(OutDir)/VolumetricLightingTest.win64.C.exe.pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)$(TargetName).lib</ImportLibrary>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <ResourceCompile>
+ </ResourceCompile>
+ <ProjectReference>
+ </ProjectReference>
+ </ItemDefinitionGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
+ <OutDir>./../../bin\</OutDir>
+ <IntDir>./x64/VolumetricLightingTest/release\</IntDir>
+ <TargetExt>.exe</TargetExt>
+ <TargetName>VolumetricLightingTest.win64</TargetName>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <OpenMPSupport>false</OpenMPSupport>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>/wd4995 /W4 /Oy- /EHsc /d2Zi+</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>./../../VolumetricLightingTest;./../../../include;$(IntDir);./../../../external/NvFoundation/1.1/include;./{user:ShaderOutputPath};%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN64;_UNICODE;UNICODE;_WINDOWS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;NV_FOUNDATION_DLL=0;NV_PLATFORM_D3D11=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>false</ExceptionHandling>
+ <WarningLevel>Level4</WarningLevel>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <PrecompiledHeaderFile></PrecompiledHeaderFile>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:x64 /SUBSYSTEM:WINDOWS /NOLOGO</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;dxguid.lib;d3d11.lib;NvVolumetricLighting.win64.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)VolumetricLightingTest.win64.exe</OutputFile>
+ <AdditionalLibraryDirectories>./../../../lib/win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>$(OutDir)/VolumetricLightingTest.win64.exe.pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)$(TargetName).lib</ImportLibrary>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <ResourceCompile>
+ </ResourceCompile>
+ <ProjectReference>
+ </ProjectReference>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\VolumetricLightingTest\common.h">
+ </ClInclude>
+ <ClInclude Include="..\..\VolumetricLightingTest\scene.h">
+ </ClInclude>
+ <ClCompile Include="..\..\VolumetricLightingTest\main.cpp">
+ </ClCompile>
+ <ClCompile Include="..\..\VolumetricLightingTest\scene.cpp">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\VolumetricLightingTest\d3d11\compiled_shaders_d3d11.h">
+ </ClInclude>
+ <ClInclude Include="..\..\VolumetricLightingTest\d3d11\d3d11_util.h">
+ </ClInclude>
+ <ClInclude Include="..\..\VolumetricLightingTest\d3d11\DeviceManager.h">
+ </ClInclude>
+ <ClCompile Include="..\..\VolumetricLightingTest\d3d11\compiled_shaders_d3d11.cpp">
+ </ClCompile>
+ <ClCompile Include="..\..\VolumetricLightingTest\d3d11\d3d11_main.cpp">
+ </ClCompile>
+ <ClCompile Include="..\..\VolumetricLightingTest\d3d11\d3d11_util.cpp">
+ </ClCompile>
+ <ClCompile Include="..\..\VolumetricLightingTest\d3d11\DeviceManager.cpp">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\quad_VS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\VolumetricLightingTest\shaders\quad_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/quad_VS.mux.h;$(IntDir)shaders/quad_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\VolumetricLightingTest\shaders\quad_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/quad_VS.mux.h;$(IntDir)shaders/quad_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\VolumetricLightingTest\shaders\quad_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/quad_VS.mux.h;$(IntDir)shaders/quad_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\VolumetricLightingTest\shaders\quad_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/quad_VS.mux.h;$(IntDir)shaders/quad_VS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\scene_VS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\VolumetricLightingTest\shaders\scene_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/scene_VS.mux.h;$(IntDir)shaders/scene_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\VolumetricLightingTest\shaders\scene_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/scene_VS.mux.h;$(IntDir)shaders/scene_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\VolumetricLightingTest\shaders\scene_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/scene_VS.mux.h;$(IntDir)shaders/scene_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\VolumetricLightingTest\shaders\scene_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/scene_VS.mux.h;$(IntDir)shaders/scene_VS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\scene_GS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tgs_5_0" ..\..\VolumetricLightingTest\shaders\scene_GS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/scene_GS.mux.h;$(IntDir)shaders/scene_GS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tgs_5_0" ..\..\VolumetricLightingTest\shaders\scene_GS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/scene_GS.mux.h;$(IntDir)shaders/scene_GS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tgs_5_0" ..\..\VolumetricLightingTest\shaders\scene_GS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/scene_GS.mux.h;$(IntDir)shaders/scene_GS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tgs_5_0" ..\..\VolumetricLightingTest\shaders\scene_GS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/scene_GS.mux.h;$(IntDir)shaders/scene_GS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\post_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\VolumetricLightingTest\shaders\post_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/post_PS.mux.h;$(IntDir)shaders/post_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\VolumetricLightingTest\shaders\post_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/post_PS.mux.h;$(IntDir)shaders/post_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\VolumetricLightingTest\shaders\post_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/post_PS.mux.h;$(IntDir)shaders/post_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\VolumetricLightingTest\shaders\post_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/post_PS.mux.h;$(IntDir)shaders/post_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\scene_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\VolumetricLightingTest\shaders\scene_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/scene_PS.mux.h;$(IntDir)shaders/scene_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\VolumetricLightingTest\shaders\scene_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/scene_PS.mux.h;$(IntDir)shaders/scene_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\VolumetricLightingTest\shaders\scene_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/scene_PS.mux.h;$(IntDir)shaders/scene_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\VolumetricLightingTest\shaders\scene_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/scene_PS.mux.h;$(IntDir)shaders/scene_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets"></ImportGroup>
+</Project>
diff --git a/samples/build/vs2012/VolumetricLightingTest.vcxproj.filters b/samples/build/vs2012/VolumetricLightingTest.vcxproj.filters
new file mode 100644
index 0000000..845b330
--- /dev/null
+++ b/samples/build/vs2012/VolumetricLightingTest.vcxproj.filters
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="src"><!-- -->
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\VolumetricLightingTest\common.h">
+ <Filter>src</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\VolumetricLightingTest\scene.h">
+ <Filter>src</Filter>
+ </ClInclude>
+ <ClCompile Include="..\..\VolumetricLightingTest\main.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\VolumetricLightingTest\scene.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="src (platform)"><!-- -->
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\VolumetricLightingTest\d3d11\compiled_shaders_d3d11.h">
+ <Filter>src (platform)</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\VolumetricLightingTest\d3d11\d3d11_util.h">
+ <Filter>src (platform)</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\VolumetricLightingTest\d3d11\DeviceManager.h">
+ <Filter>src (platform)</Filter>
+ </ClInclude>
+ <ClCompile Include="..\..\VolumetricLightingTest\d3d11\compiled_shaders_d3d11.cpp">
+ <Filter>src (platform)</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\VolumetricLightingTest\d3d11\d3d11_main.cpp">
+ <Filter>src (platform)</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\VolumetricLightingTest\d3d11\d3d11_util.cpp">
+ <Filter>src (platform)</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\VolumetricLightingTest\d3d11\DeviceManager.cpp">
+ <Filter>src (platform)</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="src (shaders)"><!-- Shadermux -->
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\quad_VS.hlsl">
+ <Filter>src (shaders)</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\scene_VS.hlsl">
+ <Filter>src (shaders)</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\scene_GS.hlsl">
+ <Filter>src (shaders)</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\post_PS.hlsl">
+ <Filter>src (shaders)</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\scene_PS.hlsl">
+ <Filter>src (shaders)</Filter>
+ </CustomBuild>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/samples/build/vs2012/VolumetricLighting_Samples.sln b/samples/build/vs2012/VolumetricLighting_Samples.sln
new file mode 100644
index 0000000..3887eb4
--- /dev/null
+++ b/samples/build/vs2012/VolumetricLighting_Samples.sln
@@ -0,0 +1,30 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VolumetricLightingTest", "./VolumetricLightingTest.vcxproj", "{00F4B5B4-B6F4-3D3F-6500-2878F07A3100}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ checked|x64 = checked|x64
+ debug|x64 = debug|x64
+ profile|x64 = profile|x64
+ release|x64 = release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {00F4B5B4-B6F4-3D3F-6500-2878F07A3100}.checked|x64.ActiveCfg = checked|x64
+ {00F4B5B4-B6F4-3D3F-6500-2878F07A3100}.checked|x64.Build.0 = checked|x64
+ {00F4B5B4-B6F4-3D3F-6500-2878F07A3100}.debug|x64.ActiveCfg = debug|x64
+ {00F4B5B4-B6F4-3D3F-6500-2878F07A3100}.debug|x64.Build.0 = debug|x64
+ {00F4B5B4-B6F4-3D3F-6500-2878F07A3100}.profile|x64.ActiveCfg = profile|x64
+ {00F4B5B4-B6F4-3D3F-6500-2878F07A3100}.profile|x64.Build.0 = profile|x64
+ {00F4B5B4-B6F4-3D3F-6500-2878F07A3100}.release|x64.ActiveCfg = release|x64
+ {00F4B5B4-B6F4-3D3F-6500-2878F07A3100}.release|x64.Build.0 = release|x64
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddins) = postSolution
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ EndGlobalSection
+EndGlobal
diff --git a/samples/build/vs2013/VolumetricLightingTest.vcxproj b/samples/build/vs2013/VolumetricLightingTest.vcxproj
new file mode 100644
index 0000000..18c69e1
--- /dev/null
+++ b/samples/build/vs2013/VolumetricLightingTest.vcxproj
@@ -0,0 +1,338 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="debug|x64">
+ <Configuration>debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="profile|x64">
+ <Configuration>profile</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="checked|x64">
+ <Configuration>checked</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="release|x64">
+ <Configuration>release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ApplicationEnvironment>title</ApplicationEnvironment>
+ <!-- - - - -->
+ <PlatformToolset>v110</PlatformToolset>
+ <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='profile|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='checked|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='profile|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='checked|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
+ <OutDir>./../../bin\</OutDir>
+ <IntDir>./x64/VolumetricLightingTest/debug\</IntDir>
+ <TargetExt>.exe</TargetExt>
+ <TargetName>VolumetricLightingTest.win64.D</TargetName>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
+ <ClCompile>
+ <CallingConvention>Cdecl</CallingConvention>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <OpenMPSupport>false</OpenMPSupport>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>/wd4995 /W4 /Oy- /EHsc -D_ITERATOR_DEBUG_LEVEL=0 /d2Zi+</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>./../../VolumetricLightingTest;./../../../include;$(IntDir);./../../../external/NvFoundation/1.1/include;./{user:ShaderOutputPath};%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN64;_UNICODE;UNICODE;_WINDOWS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;NV_FOUNDATION_DLL=0;NV_PLATFORM_D3D11=1;NV_DEBUG=1;NV_CHECKED=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>false</ExceptionHandling>
+ <WarningLevel>Level4</WarningLevel>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <PrecompiledHeaderFile></PrecompiledHeaderFile>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:x64 /SUBSYSTEM:WINDOWS /NOLOGO</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;dxguid.lib;d3d11.lib;NvVolumetricLighting.win64.D.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)VolumetricLightingTest.win64.D.exe</OutputFile>
+ <AdditionalLibraryDirectories>./../../../lib/win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>$(OutDir)/VolumetricLightingTest.win64.D.exe.pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)$(TargetName).lib</ImportLibrary>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <ResourceCompile>
+ </ResourceCompile>
+ <ProjectReference>
+ </ProjectReference>
+ </ItemDefinitionGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='profile|x64'">
+ <OutDir>./../../bin\</OutDir>
+ <IntDir>./x64/VolumetricLightingTest/profile\</IntDir>
+ <TargetExt>.exe</TargetExt>
+ <TargetName>VolumetricLightingTest.win64.P</TargetName>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='profile|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <OpenMPSupport>false</OpenMPSupport>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>/wd4995 /W4 /Oy- /EHsc /d2Zi+</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>./../../VolumetricLightingTest;./../../../include;$(IntDir);./../../../external/NvFoundation/1.1/include;./{user:ShaderOutputPath};%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN64;_UNICODE;UNICODE;_WINDOWS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;NV_FOUNDATION_DLL=0;NV_PLATFORM_D3D11=1;NV_PROFILE=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>false</ExceptionHandling>
+ <WarningLevel>Level4</WarningLevel>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <PrecompiledHeaderFile></PrecompiledHeaderFile>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:x64 /SUBSYSTEM:WINDOWS /NOLOGO</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;dxguid.lib;d3d11.lib;NvVolumetricLighting.win64.P.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)VolumetricLightingTest.win64.P.exe</OutputFile>
+ <AdditionalLibraryDirectories>./../../../lib/win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>$(OutDir)/VolumetricLightingTest.win64.P.exe.pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)$(TargetName).lib</ImportLibrary>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <ResourceCompile>
+ </ResourceCompile>
+ <ProjectReference>
+ </ProjectReference>
+ </ItemDefinitionGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='checked|x64'">
+ <OutDir>./../../bin\</OutDir>
+ <IntDir>./x64/VolumetricLightingTest/checked\</IntDir>
+ <TargetExt>.exe</TargetExt>
+ <TargetName>VolumetricLightingTest.win64.C</TargetName>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='checked|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <OpenMPSupport>false</OpenMPSupport>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>/wd4995 /W4 /Oy- /EHsc /d2Zi+</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>./../../VolumetricLightingTest;./../../../include;$(IntDir);./../../../external/NvFoundation/1.1/include;./{user:ShaderOutputPath};%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN64;_UNICODE;UNICODE;_WINDOWS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;NV_FOUNDATION_DLL=0;NV_PLATFORM_D3D11=1;NV_CHECKED=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>false</ExceptionHandling>
+ <WarningLevel>Level4</WarningLevel>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <PrecompiledHeaderFile></PrecompiledHeaderFile>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:x64 /SUBSYSTEM:WINDOWS /NOLOGO</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;dxguid.lib;d3d11.lib;NvVolumetricLighting.win64.C.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)VolumetricLightingTest.win64.C.exe</OutputFile>
+ <AdditionalLibraryDirectories>./../../../lib/win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>$(OutDir)/VolumetricLightingTest.win64.C.exe.pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)$(TargetName).lib</ImportLibrary>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <ResourceCompile>
+ </ResourceCompile>
+ <ProjectReference>
+ </ProjectReference>
+ </ItemDefinitionGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
+ <OutDir>./../../bin\</OutDir>
+ <IntDir>./x64/VolumetricLightingTest/release\</IntDir>
+ <TargetExt>.exe</TargetExt>
+ <TargetName>VolumetricLightingTest.win64</TargetName>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <OpenMPSupport>false</OpenMPSupport>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>/wd4995 /W4 /Oy- /EHsc /d2Zi+</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>./../../VolumetricLightingTest;./../../../include;$(IntDir);./../../../external/NvFoundation/1.1/include;./{user:ShaderOutputPath};%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN64;_UNICODE;UNICODE;_WINDOWS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;NV_FOUNDATION_DLL=0;NV_PLATFORM_D3D11=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>false</ExceptionHandling>
+ <WarningLevel>Level4</WarningLevel>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <PrecompiledHeaderFile></PrecompiledHeaderFile>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:x64 /SUBSYSTEM:WINDOWS /NOLOGO</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;dxguid.lib;d3d11.lib;NvVolumetricLighting.win64.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)VolumetricLightingTest.win64.exe</OutputFile>
+ <AdditionalLibraryDirectories>./../../../lib/win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>$(OutDir)/VolumetricLightingTest.win64.exe.pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)$(TargetName).lib</ImportLibrary>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <ResourceCompile>
+ </ResourceCompile>
+ <ProjectReference>
+ </ProjectReference>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\VolumetricLightingTest\common.h">
+ </ClInclude>
+ <ClInclude Include="..\..\VolumetricLightingTest\scene.h">
+ </ClInclude>
+ <ClCompile Include="..\..\VolumetricLightingTest\main.cpp">
+ </ClCompile>
+ <ClCompile Include="..\..\VolumetricLightingTest\scene.cpp">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\VolumetricLightingTest\d3d11\compiled_shaders_d3d11.h">
+ </ClInclude>
+ <ClInclude Include="..\..\VolumetricLightingTest\d3d11\d3d11_util.h">
+ </ClInclude>
+ <ClInclude Include="..\..\VolumetricLightingTest\d3d11\DeviceManager.h">
+ </ClInclude>
+ <ClCompile Include="..\..\VolumetricLightingTest\d3d11\compiled_shaders_d3d11.cpp">
+ </ClCompile>
+ <ClCompile Include="..\..\VolumetricLightingTest\d3d11\d3d11_main.cpp">
+ </ClCompile>
+ <ClCompile Include="..\..\VolumetricLightingTest\d3d11\d3d11_util.cpp">
+ </ClCompile>
+ <ClCompile Include="..\..\VolumetricLightingTest\d3d11\DeviceManager.cpp">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\quad_VS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\VolumetricLightingTest\shaders\quad_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/quad_VS.mux.h;$(IntDir)shaders/quad_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\VolumetricLightingTest\shaders\quad_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/quad_VS.mux.h;$(IntDir)shaders/quad_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\VolumetricLightingTest\shaders\quad_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/quad_VS.mux.h;$(IntDir)shaders/quad_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\VolumetricLightingTest\shaders\quad_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/quad_VS.mux.h;$(IntDir)shaders/quad_VS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\scene_VS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\VolumetricLightingTest\shaders\scene_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/scene_VS.mux.h;$(IntDir)shaders/scene_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\VolumetricLightingTest\shaders\scene_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/scene_VS.mux.h;$(IntDir)shaders/scene_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\VolumetricLightingTest\shaders\scene_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/scene_VS.mux.h;$(IntDir)shaders/scene_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\VolumetricLightingTest\shaders\scene_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/scene_VS.mux.h;$(IntDir)shaders/scene_VS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\scene_GS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tgs_5_0" ..\..\VolumetricLightingTest\shaders\scene_GS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/scene_GS.mux.h;$(IntDir)shaders/scene_GS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tgs_5_0" ..\..\VolumetricLightingTest\shaders\scene_GS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/scene_GS.mux.h;$(IntDir)shaders/scene_GS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tgs_5_0" ..\..\VolumetricLightingTest\shaders\scene_GS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/scene_GS.mux.h;$(IntDir)shaders/scene_GS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tgs_5_0" ..\..\VolumetricLightingTest\shaders\scene_GS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/scene_GS.mux.h;$(IntDir)shaders/scene_GS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\post_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\VolumetricLightingTest\shaders\post_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/post_PS.mux.h;$(IntDir)shaders/post_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\VolumetricLightingTest\shaders\post_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/post_PS.mux.h;$(IntDir)shaders/post_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\VolumetricLightingTest\shaders\post_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/post_PS.mux.h;$(IntDir)shaders/post_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\VolumetricLightingTest\shaders\post_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/post_PS.mux.h;$(IntDir)shaders/post_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\scene_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\VolumetricLightingTest\shaders\scene_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/scene_PS.mux.h;$(IntDir)shaders/scene_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\VolumetricLightingTest\shaders\scene_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/scene_PS.mux.h;$(IntDir)shaders/scene_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\VolumetricLightingTest\shaders\scene_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/scene_PS.mux.h;$(IntDir)shaders/scene_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../VolumetricLightingTest/../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\VolumetricLightingTest\shaders\scene_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/scene_PS.mux.h;$(IntDir)shaders/scene_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets"></ImportGroup>
+</Project>
diff --git a/samples/build/vs2013/VolumetricLightingTest.vcxproj.filters b/samples/build/vs2013/VolumetricLightingTest.vcxproj.filters
new file mode 100644
index 0000000..845b330
--- /dev/null
+++ b/samples/build/vs2013/VolumetricLightingTest.vcxproj.filters
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="src"><!-- -->
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\VolumetricLightingTest\common.h">
+ <Filter>src</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\VolumetricLightingTest\scene.h">
+ <Filter>src</Filter>
+ </ClInclude>
+ <ClCompile Include="..\..\VolumetricLightingTest\main.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\VolumetricLightingTest\scene.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="src (platform)"><!-- -->
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\VolumetricLightingTest\d3d11\compiled_shaders_d3d11.h">
+ <Filter>src (platform)</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\VolumetricLightingTest\d3d11\d3d11_util.h">
+ <Filter>src (platform)</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\VolumetricLightingTest\d3d11\DeviceManager.h">
+ <Filter>src (platform)</Filter>
+ </ClInclude>
+ <ClCompile Include="..\..\VolumetricLightingTest\d3d11\compiled_shaders_d3d11.cpp">
+ <Filter>src (platform)</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\VolumetricLightingTest\d3d11\d3d11_main.cpp">
+ <Filter>src (platform)</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\VolumetricLightingTest\d3d11\d3d11_util.cpp">
+ <Filter>src (platform)</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\VolumetricLightingTest\d3d11\DeviceManager.cpp">
+ <Filter>src (platform)</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="src (shaders)"><!-- Shadermux -->
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\quad_VS.hlsl">
+ <Filter>src (shaders)</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\scene_VS.hlsl">
+ <Filter>src (shaders)</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\scene_GS.hlsl">
+ <Filter>src (shaders)</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\post_PS.hlsl">
+ <Filter>src (shaders)</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\VolumetricLightingTest\shaders\scene_PS.hlsl">
+ <Filter>src (shaders)</Filter>
+ </CustomBuild>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/samples/build/vs2013/VolumetricLighting_Samples.sln b/samples/build/vs2013/VolumetricLighting_Samples.sln
new file mode 100644
index 0000000..7b2b63d
--- /dev/null
+++ b/samples/build/vs2013/VolumetricLighting_Samples.sln
@@ -0,0 +1,30 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VolumetricLightingTest", "./VolumetricLightingTest.vcxproj", "{00F4B5B4-B6F4-3D3F-6500-2878F07A3100}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ checked|x64 = checked|x64
+ debug|x64 = debug|x64
+ profile|x64 = profile|x64
+ release|x64 = release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {00F4B5B4-B6F4-3D3F-6500-2878F07A3100}.checked|x64.ActiveCfg = checked|x64
+ {00F4B5B4-B6F4-3D3F-6500-2878F07A3100}.checked|x64.Build.0 = checked|x64
+ {00F4B5B4-B6F4-3D3F-6500-2878F07A3100}.debug|x64.ActiveCfg = debug|x64
+ {00F4B5B4-B6F4-3D3F-6500-2878F07A3100}.debug|x64.Build.0 = debug|x64
+ {00F4B5B4-B6F4-3D3F-6500-2878F07A3100}.profile|x64.ActiveCfg = profile|x64
+ {00F4B5B4-B6F4-3D3F-6500-2878F07A3100}.profile|x64.Build.0 = profile|x64
+ {00F4B5B4-B6F4-3D3F-6500-2878F07A3100}.release|x64.ActiveCfg = release|x64
+ {00F4B5B4-B6F4-3D3F-6500-2878F07A3100}.release|x64.Build.0 = release|x64
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddins) = postSolution
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ EndGlobalSection
+EndGlobal
diff --git a/src/NvVolumetricLighting.cpp b/src/NvVolumetricLighting.cpp
new file mode 100644
index 0000000..e5c7fa5
--- /dev/null
+++ b/src/NvVolumetricLighting.cpp
@@ -0,0 +1,250 @@
+// 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 (c) 2003 - 2016 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 <Nv/VolumetricLighting/NvVolumetricLighting.h>
+#include <NvAllocatorCallback.h>
+
+#include "common.h"
+#include "context_common.h"
+
+#if defined( NV_PLATFORM_D3D11 )
+# include "d3d11/context_d3d11.h"
+#endif
+
+// [Add other platforms here]
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace
+{
+ bool g_isLoaded = false;
+}
+
+/*==============================================================================
+ Override memory operators
+==============================================================================*/
+namespace
+{
+ // Default allocator
+ class DefaultAllocator : public Nv::NvAllocatorCallback
+ {
+ virtual void* allocate(size_t size, const char* typeName, const char* filename, int line)
+ {
+ LOG("GWVL Allocation: %u bytes (%s:%d)", size, filename, line);
+ return malloc(size);
+ }
+
+ virtual void deallocate(void* ptr)
+ {
+ free(ptr);
+ }
+ } g_defaultAllocator;
+
+ // Actual allocator to use
+ Nv::NvAllocatorCallback * g_allocator;
+}
+
+#pragma push_macro("new")
+#undef new
+void * operator new(size_t size, const char * filename, int line)
+{
+ return g_allocator->allocate(size, "Gameworks Volumetric Lighting", filename, line);
+}
+
+void operator delete(void * ptr, const char * filename, int line)
+{
+ filename; line;
+ g_allocator->deallocate(ptr);
+}
+
+void operator delete (void * ptr)
+{
+ g_allocator->deallocate(ptr);
+}
+
+void * operator new[](size_t size, const char * filename, int line)
+{
+ return g_allocator->allocate(size, "Gameworks Volumetric Lighting", filename, line);
+}
+
+void operator delete[](void * ptr, const char * filename, int line)
+{
+ filename; line;
+ g_allocator->deallocate(ptr);
+}
+
+void operator delete[](void * ptr)
+{
+ g_allocator->deallocate(ptr);
+}
+#pragma pop_macro("new")
+
+/*==============================================================================
+ Assert handler
+==============================================================================*/
+
+namespace
+{
+ Nv::NvAssertHandler * g_assert;
+
+ class DefaultAssertHandler : public Nv::NvAssertHandler
+ {
+ virtual void operator()(const char* exp, const char* file, int line, bool& ignore)
+ {
+ LOG("%s(%d): Assertion Failed (%s)", file, line, exp);
+ BREAK();
+ }
+ } g_defaultAssertHandler;
+};
+
+namespace nvidia
+{
+ NvAssertHandler& NvGetAssertHandler()
+ {
+ return *g_assert;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace Nv { namespace VolumetricLighting {
+////////////////////////////////////////////////////////////////////////////////
+
+/*==============================================================================
+ API Functions
+==============================================================================*/
+
+//------------------------------------------------------------------------------
+//! Load the library and initialize global state
+NV_VOLUMETRICLIGHTING_API(Status) OpenLibrary(NvAllocatorCallback * allocator, NvAssertHandler * assert_handler, const VersionDesc & link_version)
+{
+ if ( link_version.Major != LIBRARY_VERSION.Major || link_version.Minor != LIBRARY_VERSION.Minor)
+ return Status::INVALID_VERSION;
+
+ g_allocator = (allocator) ? allocator : &g_defaultAllocator;
+ g_assert = (assert_handler) ? assert_handler : &g_defaultAssertHandler;
+
+ g_isLoaded = true;
+ return Status::OK;
+}
+
+//------------------------------------------------------------------------------
+//! Release the library and resources, and un-initialize all global state
+NV_VOLUMETRICLIGHTING_API(Status) CloseLibrary()
+{
+ if (g_isLoaded == false)
+ return Status::UNINITIALIZED;
+
+ g_isLoaded = false;
+ return Status::OK;
+}
+
+//------------------------------------------------------------------------------
+//! Create a new context for rendering to a specified framebuffer
+NV_VOLUMETRICLIGHTING_API(Status) CreateContext(Context & out_ctx, const PlatformDesc * pPlatformDesc, const ContextDesc * pContextDesc)
+{
+ if (g_isLoaded == false)
+ return Status::UNINITIALIZED;
+
+ if (pPlatformDesc == nullptr || pContextDesc == nullptr)
+ return Status::INVALID_PARAMETER;
+
+ out_ctx = nullptr;
+ switch (pPlatformDesc->platform)
+ {
+
+# if defined(NV_PLATFORM_D3D11)
+ case PlatformName::D3D11:
+ {
+ ContextImp_D3D11 * ctx_imp = nullptr;
+ Status create_status = ContextImp_D3D11::Create(&ctx_imp, pPlatformDesc, pContextDesc);
+ if (create_status != Status::OK)
+ {
+ return create_status;
+ }
+ else
+ {
+ out_ctx = static_cast<ContextImp_Common *>(ctx_imp);
+ return Status::OK;
+ }
+ }
+# endif
+ // [Add other platforms here]
+
+ default:
+ return Status::INVALID_PARAMETER;
+ }
+}
+
+//------------------------------------------------------------------------------
+//! Release the context and any associated resources
+NV_VOLUMETRICLIGHTING_API(Status) ReleaseContext(Context & ctx)
+{
+ if (ctx)
+ {
+ ContextImp_Common * vl_ctx = reinterpret_cast<ContextImp_Common *>(ctx);
+ delete vl_ctx;
+ ctx = nullptr;
+ return Status::OK;
+ }
+ else
+ {
+ return Status::INVALID_PARAMETER;
+ }
+}
+
+//------------------------------------------------------------------------------
+//! Begin accumulation of lighting volumes for a view
+NV_VOLUMETRICLIGHTING_API(Status) BeginAccumulation(Context ctx, PlatformRenderCtx renderCtx, PlatformShaderResource sceneDepth, ViewerDesc const* pViewerDesc, MediumDesc const* pMediumDesc, DebugFlags debugFlags)
+{
+ return reinterpret_cast<ContextImp_Common *>(ctx)->BeginAccumulation(renderCtx, sceneDepth, pViewerDesc, pMediumDesc, debugFlags);
+}
+
+//------------------------------------------------------------------------------
+//! Add a lighting volume to the accumulated results
+NV_VOLUMETRICLIGHTING_API(Status) RenderVolume(Context ctx, PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc)
+{
+ return reinterpret_cast<ContextImp_Common *>(ctx)->RenderVolume(renderCtx, shadowMap, pShadowMapDesc, pLightDesc, pVolumeDesc);
+}
+
+//------------------------------------------------------------------------------
+//! Finish accumulation of lighting volumes
+NV_VOLUMETRICLIGHTING_API(Status) EndAccumulation(Context ctx, PlatformRenderCtx renderCtx)
+{
+ return reinterpret_cast<ContextImp_Common *>(ctx)->EndAccumulation(renderCtx);
+}
+
+//------------------------------------------------------------------------------
+//! Resolve the results and composite into the provided scene
+NV_VOLUMETRICLIGHTING_API(Status) ApplyLighting(Context ctx, PlatformRenderCtx renderCtx, PlatformRenderTarget sceneTarget, PlatformShaderResource sceneDepth, PostprocessDesc const* pPostprocessDesc)
+{
+ return reinterpret_cast<ContextImp_Common *>(ctx)->ApplyLighting(renderCtx, sceneTarget, sceneDepth, pPostprocessDesc);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+}; /*namespace VolumetricLighting*/ }; /*namespace Nv*/
+////////////////////////////////////////////////////////////////////////////////
diff --git a/src/build/vs2012/NvVolumetricLighting.sln b/src/build/vs2012/NvVolumetricLighting.sln
new file mode 100644
index 0000000..32872d8
--- /dev/null
+++ b/src/build/vs2012/NvVolumetricLighting.sln
@@ -0,0 +1,30 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NvVolumetricLighting", "./NvVolumetricLighting.vcxproj", "{24C9474A-2D4C-EA01-97B4-6B52DA9A5490}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ checked|x64 = checked|x64
+ debug|x64 = debug|x64
+ profile|x64 = profile|x64
+ release|x64 = release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {24C9474A-2D4C-EA01-97B4-6B52DA9A5490}.checked|x64.ActiveCfg = checked|x64
+ {24C9474A-2D4C-EA01-97B4-6B52DA9A5490}.checked|x64.Build.0 = checked|x64
+ {24C9474A-2D4C-EA01-97B4-6B52DA9A5490}.debug|x64.ActiveCfg = debug|x64
+ {24C9474A-2D4C-EA01-97B4-6B52DA9A5490}.debug|x64.Build.0 = debug|x64
+ {24C9474A-2D4C-EA01-97B4-6B52DA9A5490}.profile|x64.ActiveCfg = profile|x64
+ {24C9474A-2D4C-EA01-97B4-6B52DA9A5490}.profile|x64.Build.0 = profile|x64
+ {24C9474A-2D4C-EA01-97B4-6B52DA9A5490}.release|x64.ActiveCfg = release|x64
+ {24C9474A-2D4C-EA01-97B4-6B52DA9A5490}.release|x64.Build.0 = release|x64
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddins) = postSolution
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ EndGlobalSection
+EndGlobal
diff --git a/src/build/vs2012/NvVolumetricLighting.vcxproj b/src/build/vs2012/NvVolumetricLighting.vcxproj
new file mode 100644
index 0000000..8561fd3
--- /dev/null
+++ b/src/build/vs2012/NvVolumetricLighting.vcxproj
@@ -0,0 +1,454 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="debug|x64">
+ <Configuration>debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="profile|x64">
+ <Configuration>profile</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="checked|x64">
+ <Configuration>checked</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="release|x64">
+ <Configuration>release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ApplicationEnvironment>title</ApplicationEnvironment>
+ <!-- - - - -->
+ <PlatformToolset>v110</PlatformToolset>
+ <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='profile|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='checked|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='profile|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='checked|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
+ <OutDir>./../../../redist/win64\</OutDir>
+ <IntDir>./x64/NvVolumetricLighting/debug\</IntDir>
+ <TargetExt>.dll</TargetExt>
+ <TargetName>NvVolumetricLighting.win64.D</TargetName>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <SkipCopyingSymbolsToOutputDirectory>true</SkipCopyingSymbolsToOutputDirectory>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
+ <ClCompile>
+ <CallingConvention>Cdecl</CallingConvention>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <OpenMPSupport>false</OpenMPSupport>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>/W4 /Oy- /EHsc -D_ITERATOR_DEBUG_LEVEL=0 /d2Zi+</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>./{user:ShaderOutputPath};$(WindowsSDK_IncludePath);./../..;./../../../include;$(IntDir);./../../../external/NvFoundation/1.1/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_UNICODE;UNICODE;_WINDOWS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_LIB;NV_FOUNDATION_DLL=1;_WIN64;NV_PLATFORM_D3D11=1;NV_DEBUG=1;NV_CHECKED=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>false</ExceptionHandling>
+ <WarningLevel>Level4</WarningLevel>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <PrecompiledHeaderFile></PrecompiledHeaderFile>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:x64 /SUBSYSTEM:WINDOWS /NOLOGO</AdditionalOptions>
+ <AdditionalDependencies>d3d11.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)NvVolumetricLighting.win64.D.dll</OutputFile>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>$(OutDir)/NvVolumetricLighting.win64.D.dll.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <ImportLibrary>./../../../lib/win64/NvVolumetricLighting.win64.D.lib</ImportLibrary>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <ResourceCompile>
+ </ResourceCompile>
+ <ProjectReference>
+ </ProjectReference>
+ <PostBuildEvent>
+ <Command>XCOPY /Y /F "../../../redist/win64/$(TargetFileName)" "../../../samples/bin/"</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='profile|x64'">
+ <OutDir>./../../../redist/win64\</OutDir>
+ <IntDir>./x64/NvVolumetricLighting/profile\</IntDir>
+ <TargetExt>.dll</TargetExt>
+ <TargetName>NvVolumetricLighting.win64.P</TargetName>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <SkipCopyingSymbolsToOutputDirectory>true</SkipCopyingSymbolsToOutputDirectory>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='profile|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <OpenMPSupport>false</OpenMPSupport>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>/W4 /Oy- /EHsc /d2Zi+</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>./{user:ShaderOutputPath};$(WindowsSDK_IncludePath);./../..;./../../../include;$(IntDir);./../../../external/NvFoundation/1.1/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_UNICODE;UNICODE;_WINDOWS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_LIB;NV_FOUNDATION_DLL=1;_WIN64;NV_PLATFORM_D3D11=1;NV_PROFILE=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>false</ExceptionHandling>
+ <WarningLevel>Level4</WarningLevel>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <PrecompiledHeaderFile></PrecompiledHeaderFile>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:x64 /SUBSYSTEM:WINDOWS /NOLOGO</AdditionalOptions>
+ <AdditionalDependencies>d3d11.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)NvVolumetricLighting.win64.P.dll</OutputFile>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>$(OutDir)/NvVolumetricLighting.win64.P.dll.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <ImportLibrary>./../../../lib/win64/NvVolumetricLighting.win64.P.lib</ImportLibrary>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <ResourceCompile>
+ </ResourceCompile>
+ <ProjectReference>
+ </ProjectReference>
+ <PostBuildEvent>
+ <Command>XCOPY /Y /F "../../../redist/win64/$(TargetFileName)" "../../../samples/bin/"</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='checked|x64'">
+ <OutDir>./../../../redist/win64\</OutDir>
+ <IntDir>./x64/NvVolumetricLighting/checked\</IntDir>
+ <TargetExt>.dll</TargetExt>
+ <TargetName>NvVolumetricLighting.win64.C</TargetName>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <SkipCopyingSymbolsToOutputDirectory>true</SkipCopyingSymbolsToOutputDirectory>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='checked|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <OpenMPSupport>false</OpenMPSupport>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>/W4 /Oy- /EHsc /d2Zi+</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>./{user:ShaderOutputPath};$(WindowsSDK_IncludePath);./../..;./../../../include;$(IntDir);./../../../external/NvFoundation/1.1/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_UNICODE;UNICODE;_WINDOWS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_LIB;NV_FOUNDATION_DLL=1;_WIN64;NV_PLATFORM_D3D11=1;NV_CHECKED=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>false</ExceptionHandling>
+ <WarningLevel>Level4</WarningLevel>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <PrecompiledHeaderFile></PrecompiledHeaderFile>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:x64 /SUBSYSTEM:WINDOWS /NOLOGO</AdditionalOptions>
+ <AdditionalDependencies>d3d11.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)NvVolumetricLighting.win64.C.dll</OutputFile>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>$(OutDir)/NvVolumetricLighting.win64.C.dll.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <ImportLibrary>./../../../lib/win64/NvVolumetricLighting.win64.C.lib</ImportLibrary>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <ResourceCompile>
+ </ResourceCompile>
+ <ProjectReference>
+ </ProjectReference>
+ <PostBuildEvent>
+ <Command>XCOPY /Y /F "../../../redist/win64/$(TargetFileName)" "../../../samples/bin/"</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
+ <OutDir>./../../../redist/win64\</OutDir>
+ <IntDir>./x64/NvVolumetricLighting/release\</IntDir>
+ <TargetExt>.dll</TargetExt>
+ <TargetName>NvVolumetricLighting.win64</TargetName>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <SkipCopyingSymbolsToOutputDirectory>true</SkipCopyingSymbolsToOutputDirectory>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <OpenMPSupport>false</OpenMPSupport>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>/W4 /Oy- /EHsc /d2Zi+</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>./{user:ShaderOutputPath};$(WindowsSDK_IncludePath);./../..;./../../../include;$(IntDir);./../../../external/NvFoundation/1.1/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_UNICODE;UNICODE;_WINDOWS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_LIB;NV_FOUNDATION_DLL=1;_WIN64;NV_PLATFORM_D3D11=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>false</ExceptionHandling>
+ <WarningLevel>Level4</WarningLevel>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <PrecompiledHeaderFile></PrecompiledHeaderFile>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:x64 /SUBSYSTEM:WINDOWS /NOLOGO</AdditionalOptions>
+ <AdditionalDependencies>d3d11.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)NvVolumetricLighting.win64.dll</OutputFile>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>$(OutDir)/NvVolumetricLighting.win64.dll.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <ImportLibrary>./../../../lib/win64/NvVolumetricLighting.win64.lib</ImportLibrary>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <ResourceCompile>
+ </ResourceCompile>
+ <ProjectReference>
+ </ProjectReference>
+ <PostBuildEvent>
+ <Command>XCOPY /Y /F "../../../redist/win64/$(TargetFileName)" "../../../samples/bin/"</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\Nv\VolumetricLighting\NvVolumetricLighting.h">
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\common.h">
+ </ClInclude>
+ <ClInclude Include="..\..\context_common.h">
+ </ClInclude>
+ <ClCompile Include="..\..\context_common.cpp">
+ </ClCompile>
+ <ClCompile Include="..\..\NvVolumetricLighting.cpp">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\shaders\Quad_VS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\shaders\Quad_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/Quad_VS.mux.h;$(IntDir)shaders/Quad_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\shaders\Quad_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/Quad_VS.mux.h;$(IntDir)shaders/Quad_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\shaders\Quad_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/Quad_VS.mux.h;$(IntDir)shaders/Quad_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\shaders\Quad_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/Quad_VS.mux.h;$(IntDir)shaders/Quad_VS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\RenderVolume_VS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\shaders\RenderVolume_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/RenderVolume_VS.mux.h;$(IntDir)shaders/RenderVolume_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\shaders\RenderVolume_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/RenderVolume_VS.mux.h;$(IntDir)shaders/RenderVolume_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\shaders\RenderVolume_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/RenderVolume_VS.mux.h;$(IntDir)shaders/RenderVolume_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\shaders\RenderVolume_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/RenderVolume_VS.mux.h;$(IntDir)shaders/RenderVolume_VS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\RenderVolume_HS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Ths_5_0" ..\..\shaders\RenderVolume_HS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/RenderVolume_HS.mux.h;$(IntDir)shaders/RenderVolume_HS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Ths_5_0" ..\..\shaders\RenderVolume_HS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/RenderVolume_HS.mux.h;$(IntDir)shaders/RenderVolume_HS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Ths_5_0" ..\..\shaders\RenderVolume_HS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/RenderVolume_HS.mux.h;$(IntDir)shaders/RenderVolume_HS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Ths_5_0" ..\..\shaders\RenderVolume_HS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/RenderVolume_HS.mux.h;$(IntDir)shaders/RenderVolume_HS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\RenderVolume_DS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tds_5_0" ..\..\shaders\RenderVolume_DS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/RenderVolume_DS.mux.h;$(IntDir)shaders/RenderVolume_DS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tds_5_0" ..\..\shaders\RenderVolume_DS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/RenderVolume_DS.mux.h;$(IntDir)shaders/RenderVolume_DS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tds_5_0" ..\..\shaders\RenderVolume_DS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/RenderVolume_DS.mux.h;$(IntDir)shaders/RenderVolume_DS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tds_5_0" ..\..\shaders\RenderVolume_DS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/RenderVolume_DS.mux.h;$(IntDir)shaders/RenderVolume_DS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\Apply_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Apply_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/Apply_PS.mux.h;$(IntDir)shaders/Apply_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Apply_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/Apply_PS.mux.h;$(IntDir)shaders/Apply_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Apply_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/Apply_PS.mux.h;$(IntDir)shaders/Apply_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Apply_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/Apply_PS.mux.h;$(IntDir)shaders/Apply_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\ComputePhaseLookup_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\ComputePhaseLookup_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/ComputePhaseLookup_PS.mux.h;$(IntDir)shaders/ComputePhaseLookup_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\ComputePhaseLookup_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/ComputePhaseLookup_PS.mux.h;$(IntDir)shaders/ComputePhaseLookup_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\ComputePhaseLookup_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/ComputePhaseLookup_PS.mux.h;$(IntDir)shaders/ComputePhaseLookup_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\ComputePhaseLookup_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/ComputePhaseLookup_PS.mux.h;$(IntDir)shaders/ComputePhaseLookup_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\Debug_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Debug_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/Debug_PS.mux.h;$(IntDir)shaders/Debug_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Debug_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/Debug_PS.mux.h;$(IntDir)shaders/Debug_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Debug_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/Debug_PS.mux.h;$(IntDir)shaders/Debug_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Debug_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/Debug_PS.mux.h;$(IntDir)shaders/Debug_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\DownsampleDepth_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\DownsampleDepth_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/DownsampleDepth_PS.mux.h;$(IntDir)shaders/DownsampleDepth_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\DownsampleDepth_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/DownsampleDepth_PS.mux.h;$(IntDir)shaders/DownsampleDepth_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\DownsampleDepth_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/DownsampleDepth_PS.mux.h;$(IntDir)shaders/DownsampleDepth_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\DownsampleDepth_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/DownsampleDepth_PS.mux.h;$(IntDir)shaders/DownsampleDepth_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\RenderVolume_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\RenderVolume_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/RenderVolume_PS.mux.h;$(IntDir)shaders/RenderVolume_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\RenderVolume_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/RenderVolume_PS.mux.h;$(IntDir)shaders/RenderVolume_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\RenderVolume_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/RenderVolume_PS.mux.h;$(IntDir)shaders/RenderVolume_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\RenderVolume_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/RenderVolume_PS.mux.h;$(IntDir)shaders/RenderVolume_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\Resolve_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Resolve_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/Resolve_PS.mux.h;$(IntDir)shaders/Resolve_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Resolve_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/Resolve_PS.mux.h;$(IntDir)shaders/Resolve_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Resolve_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/Resolve_PS.mux.h;$(IntDir)shaders/Resolve_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Resolve_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/Resolve_PS.mux.h;$(IntDir)shaders/Resolve_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\TemporalFilter_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\TemporalFilter_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/TemporalFilter_PS.mux.h;$(IntDir)shaders/TemporalFilter_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\TemporalFilter_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/TemporalFilter_PS.mux.h;$(IntDir)shaders/TemporalFilter_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\TemporalFilter_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/TemporalFilter_PS.mux.h;$(IntDir)shaders/TemporalFilter_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\TemporalFilter_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/TemporalFilter_PS.mux.h;$(IntDir)shaders/TemporalFilter_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\ComputeLightLUT_CS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tcs_5_0" ..\..\shaders\ComputeLightLUT_CS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/ComputeLightLUT_CS.mux.h;$(IntDir)shaders/ComputeLightLUT_CS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tcs_5_0" ..\..\shaders\ComputeLightLUT_CS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/ComputeLightLUT_CS.mux.h;$(IntDir)shaders/ComputeLightLUT_CS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tcs_5_0" ..\..\shaders\ComputeLightLUT_CS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/ComputeLightLUT_CS.mux.h;$(IntDir)shaders/ComputeLightLUT_CS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tcs_5_0" ..\..\shaders\ComputeLightLUT_CS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/ComputeLightLUT_CS.mux.h;$(IntDir)shaders/ComputeLightLUT_CS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\d3d11\compiled_shaders_d3d11.h">
+ </ClInclude>
+ <ClInclude Include="..\..\d3d11\context_d3d11.h">
+ </ClInclude>
+ <ClInclude Include="..\..\d3d11\d3d11_util.h">
+ </ClInclude>
+ <ClCompile Include="..\..\d3d11\compiled_shaders_d3d11.cpp">
+ </ClCompile>
+ <ClCompile Include="..\..\d3d11\context_d3d11.cpp">
+ </ClCompile>
+ <ClCompile Include="..\..\d3d11\d3d11_util.cpp">
+ </ClCompile>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets"></ImportGroup>
+</Project>
diff --git a/src/build/vs2012/NvVolumetricLighting.vcxproj.filters b/src/build/vs2012/NvVolumetricLighting.vcxproj.filters
new file mode 100644
index 0000000..b0d05b6
--- /dev/null
+++ b/src/build/vs2012/NvVolumetricLighting.vcxproj.filters
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="public"><!-- -->
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\Nv\VolumetricLighting\NvVolumetricLighting.h">
+ <Filter>public</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="common"><!-- -->
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\common.h">
+ <Filter>common</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\context_common.h">
+ <Filter>common</Filter>
+ </ClInclude>
+ <ClCompile Include="..\..\context_common.cpp">
+ <Filter>common</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\NvVolumetricLighting.cpp">
+ <Filter>common</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="shaders"><!-- Shadermux -->
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\shaders\Quad_VS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\RenderVolume_VS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\RenderVolume_HS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\RenderVolume_DS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\Apply_PS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\ComputePhaseLookup_PS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\Debug_PS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\DownsampleDepth_PS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\RenderVolume_PS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\Resolve_PS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\TemporalFilter_PS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\ComputeLightLUT_CS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="d3d11"><!-- -->
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\d3d11\compiled_shaders_d3d11.h">
+ <Filter>d3d11</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\d3d11\context_d3d11.h">
+ <Filter>d3d11</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\d3d11\d3d11_util.h">
+ <Filter>d3d11</Filter>
+ </ClInclude>
+ <ClCompile Include="..\..\d3d11\compiled_shaders_d3d11.cpp">
+ <Filter>d3d11</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\d3d11\context_d3d11.cpp">
+ <Filter>d3d11</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\d3d11\d3d11_util.cpp">
+ <Filter>d3d11</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/src/build/vs2013/NvVolumetricLighting.sln b/src/build/vs2013/NvVolumetricLighting.sln
new file mode 100644
index 0000000..a6f3508
--- /dev/null
+++ b/src/build/vs2013/NvVolumetricLighting.sln
@@ -0,0 +1,30 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NvVolumetricLighting", "./NvVolumetricLighting.vcxproj", "{24C9474A-2D4C-EA01-97B4-6B52DA9A5490}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ checked|x64 = checked|x64
+ debug|x64 = debug|x64
+ profile|x64 = profile|x64
+ release|x64 = release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {24C9474A-2D4C-EA01-97B4-6B52DA9A5490}.checked|x64.ActiveCfg = checked|x64
+ {24C9474A-2D4C-EA01-97B4-6B52DA9A5490}.checked|x64.Build.0 = checked|x64
+ {24C9474A-2D4C-EA01-97B4-6B52DA9A5490}.debug|x64.ActiveCfg = debug|x64
+ {24C9474A-2D4C-EA01-97B4-6B52DA9A5490}.debug|x64.Build.0 = debug|x64
+ {24C9474A-2D4C-EA01-97B4-6B52DA9A5490}.profile|x64.ActiveCfg = profile|x64
+ {24C9474A-2D4C-EA01-97B4-6B52DA9A5490}.profile|x64.Build.0 = profile|x64
+ {24C9474A-2D4C-EA01-97B4-6B52DA9A5490}.release|x64.ActiveCfg = release|x64
+ {24C9474A-2D4C-EA01-97B4-6B52DA9A5490}.release|x64.Build.0 = release|x64
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddins) = postSolution
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ EndGlobalSection
+EndGlobal
diff --git a/src/build/vs2013/NvVolumetricLighting.vcxproj b/src/build/vs2013/NvVolumetricLighting.vcxproj
new file mode 100644
index 0000000..1f95b60
--- /dev/null
+++ b/src/build/vs2013/NvVolumetricLighting.vcxproj
@@ -0,0 +1,454 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="debug|x64">
+ <Configuration>debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="profile|x64">
+ <Configuration>profile</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="checked|x64">
+ <Configuration>checked</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="release|x64">
+ <Configuration>release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ApplicationEnvironment>title</ApplicationEnvironment>
+ <!-- - - - -->
+ <PlatformToolset>v110</PlatformToolset>
+ <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='profile|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='checked|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='profile|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='checked|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
+ <OutDir>./../../../redist/win64\</OutDir>
+ <IntDir>./x64/NvVolumetricLighting/debug\</IntDir>
+ <TargetExt>.dll</TargetExt>
+ <TargetName>NvVolumetricLighting.win64.D</TargetName>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <SkipCopyingSymbolsToOutputDirectory>true</SkipCopyingSymbolsToOutputDirectory>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
+ <ClCompile>
+ <CallingConvention>Cdecl</CallingConvention>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <OpenMPSupport>false</OpenMPSupport>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>/W4 /Oy- /EHsc -D_ITERATOR_DEBUG_LEVEL=0 /d2Zi+</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>./{user:ShaderOutputPath};./../..;./../../../include;$(IntDir);./../../../external/NvFoundation/1.1/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_UNICODE;UNICODE;_WINDOWS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_LIB;NV_FOUNDATION_DLL=1;_WIN64;NV_PLATFORM_D3D11=1;NV_DEBUG=1;NV_CHECKED=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>false</ExceptionHandling>
+ <WarningLevel>Level4</WarningLevel>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <PrecompiledHeaderFile></PrecompiledHeaderFile>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:x64 /SUBSYSTEM:WINDOWS /NOLOGO</AdditionalOptions>
+ <AdditionalDependencies>d3d11.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)NvVolumetricLighting.win64.D.dll</OutputFile>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>$(OutDir)/NvVolumetricLighting.win64.D.dll.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <ImportLibrary>./../../../lib/win64/NvVolumetricLighting.win64.D.lib</ImportLibrary>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <ResourceCompile>
+ </ResourceCompile>
+ <ProjectReference>
+ </ProjectReference>
+ <PostBuildEvent>
+ <Command>XCOPY /Y /F "../../../redist/win64/$(TargetFileName)" "../../../samples/bin/"</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='profile|x64'">
+ <OutDir>./../../../redist/win64\</OutDir>
+ <IntDir>./x64/NvVolumetricLighting/profile\</IntDir>
+ <TargetExt>.dll</TargetExt>
+ <TargetName>NvVolumetricLighting.win64.P</TargetName>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <SkipCopyingSymbolsToOutputDirectory>true</SkipCopyingSymbolsToOutputDirectory>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='profile|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <OpenMPSupport>false</OpenMPSupport>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>/W4 /Oy- /EHsc /d2Zi+</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>./{user:ShaderOutputPath};./../..;./../../../include;$(IntDir);./../../../external/NvFoundation/1.1/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_UNICODE;UNICODE;_WINDOWS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_LIB;NV_FOUNDATION_DLL=1;_WIN64;NV_PLATFORM_D3D11=1;NV_PROFILE=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>false</ExceptionHandling>
+ <WarningLevel>Level4</WarningLevel>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <PrecompiledHeaderFile></PrecompiledHeaderFile>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:x64 /SUBSYSTEM:WINDOWS /NOLOGO</AdditionalOptions>
+ <AdditionalDependencies>d3d11.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)NvVolumetricLighting.win64.P.dll</OutputFile>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>$(OutDir)/NvVolumetricLighting.win64.P.dll.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <ImportLibrary>./../../../lib/win64/NvVolumetricLighting.win64.P.lib</ImportLibrary>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <ResourceCompile>
+ </ResourceCompile>
+ <ProjectReference>
+ </ProjectReference>
+ <PostBuildEvent>
+ <Command>XCOPY /Y /F "../../../redist/win64/$(TargetFileName)" "../../../samples/bin/"</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='checked|x64'">
+ <OutDir>./../../../redist/win64\</OutDir>
+ <IntDir>./x64/NvVolumetricLighting/checked\</IntDir>
+ <TargetExt>.dll</TargetExt>
+ <TargetName>NvVolumetricLighting.win64.C</TargetName>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <SkipCopyingSymbolsToOutputDirectory>true</SkipCopyingSymbolsToOutputDirectory>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='checked|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <OpenMPSupport>false</OpenMPSupport>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>/W4 /Oy- /EHsc /d2Zi+</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>./{user:ShaderOutputPath};./../..;./../../../include;$(IntDir);./../../../external/NvFoundation/1.1/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_UNICODE;UNICODE;_WINDOWS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_LIB;NV_FOUNDATION_DLL=1;_WIN64;NV_PLATFORM_D3D11=1;NV_CHECKED=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>false</ExceptionHandling>
+ <WarningLevel>Level4</WarningLevel>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <PrecompiledHeaderFile></PrecompiledHeaderFile>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:x64 /SUBSYSTEM:WINDOWS /NOLOGO</AdditionalOptions>
+ <AdditionalDependencies>d3d11.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)NvVolumetricLighting.win64.C.dll</OutputFile>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>$(OutDir)/NvVolumetricLighting.win64.C.dll.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <ImportLibrary>./../../../lib/win64/NvVolumetricLighting.win64.C.lib</ImportLibrary>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <ResourceCompile>
+ </ResourceCompile>
+ <ProjectReference>
+ </ProjectReference>
+ <PostBuildEvent>
+ <Command>XCOPY /Y /F "../../../redist/win64/$(TargetFileName)" "../../../samples/bin/"</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
+ <OutDir>./../../../redist/win64\</OutDir>
+ <IntDir>./x64/NvVolumetricLighting/release\</IntDir>
+ <TargetExt>.dll</TargetExt>
+ <TargetName>NvVolumetricLighting.win64</TargetName>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <SkipCopyingSymbolsToOutputDirectory>true</SkipCopyingSymbolsToOutputDirectory>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
+ <ClCompile>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <OpenMPSupport>false</OpenMPSupport>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>/W4 /Oy- /EHsc /d2Zi+</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>./{user:ShaderOutputPath};./../..;./../../../include;$(IntDir);./../../../external/NvFoundation/1.1/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_UNICODE;UNICODE;_WINDOWS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_LIB;NV_FOUNDATION_DLL=1;_WIN64;NV_PLATFORM_D3D11=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>false</ExceptionHandling>
+ <WarningLevel>Level4</WarningLevel>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <PrecompiledHeaderFile></PrecompiledHeaderFile>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:x64 /SUBSYSTEM:WINDOWS /NOLOGO</AdditionalOptions>
+ <AdditionalDependencies>d3d11.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)NvVolumetricLighting.win64.dll</OutputFile>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ProgramDatabaseFile>$(OutDir)/NvVolumetricLighting.win64.dll.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <ImportLibrary>./../../../lib/win64/NvVolumetricLighting.win64.lib</ImportLibrary>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <ResourceCompile>
+ </ResourceCompile>
+ <ProjectReference>
+ </ProjectReference>
+ <PostBuildEvent>
+ <Command>XCOPY /Y /F "../../../redist/win64/$(TargetFileName)" "../../../samples/bin/"</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\Nv\VolumetricLighting\NvVolumetricLighting.h">
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\common.h">
+ </ClInclude>
+ <ClInclude Include="..\..\context_common.h">
+ </ClInclude>
+ <ClCompile Include="..\..\context_common.cpp">
+ </ClCompile>
+ <ClCompile Include="..\..\NvVolumetricLighting.cpp">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\shaders\Quad_VS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\shaders\Quad_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/Quad_VS.mux.h;$(IntDir)shaders/Quad_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\shaders\Quad_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/Quad_VS.mux.h;$(IntDir)shaders/Quad_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\shaders\Quad_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/Quad_VS.mux.h;$(IntDir)shaders/Quad_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\shaders\Quad_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/Quad_VS.mux.h;$(IntDir)shaders/Quad_VS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\RenderVolume_VS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\shaders\RenderVolume_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/RenderVolume_VS.mux.h;$(IntDir)shaders/RenderVolume_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\shaders\RenderVolume_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/RenderVolume_VS.mux.h;$(IntDir)shaders/RenderVolume_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\shaders\RenderVolume_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/RenderVolume_VS.mux.h;$(IntDir)shaders/RenderVolume_VS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tvs_5_0" ..\..\shaders\RenderVolume_VS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/RenderVolume_VS.mux.h;$(IntDir)shaders/RenderVolume_VS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\RenderVolume_HS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Ths_5_0" ..\..\shaders\RenderVolume_HS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/RenderVolume_HS.mux.h;$(IntDir)shaders/RenderVolume_HS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Ths_5_0" ..\..\shaders\RenderVolume_HS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/RenderVolume_HS.mux.h;$(IntDir)shaders/RenderVolume_HS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Ths_5_0" ..\..\shaders\RenderVolume_HS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/RenderVolume_HS.mux.h;$(IntDir)shaders/RenderVolume_HS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Ths_5_0" ..\..\shaders\RenderVolume_HS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/RenderVolume_HS.mux.h;$(IntDir)shaders/RenderVolume_HS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\RenderVolume_DS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tds_5_0" ..\..\shaders\RenderVolume_DS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/RenderVolume_DS.mux.h;$(IntDir)shaders/RenderVolume_DS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tds_5_0" ..\..\shaders\RenderVolume_DS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/RenderVolume_DS.mux.h;$(IntDir)shaders/RenderVolume_DS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tds_5_0" ..\..\shaders\RenderVolume_DS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/RenderVolume_DS.mux.h;$(IntDir)shaders/RenderVolume_DS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tds_5_0" ..\..\shaders\RenderVolume_DS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/RenderVolume_DS.mux.h;$(IntDir)shaders/RenderVolume_DS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\Apply_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Apply_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/Apply_PS.mux.h;$(IntDir)shaders/Apply_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Apply_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/Apply_PS.mux.h;$(IntDir)shaders/Apply_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Apply_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/Apply_PS.mux.h;$(IntDir)shaders/Apply_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Apply_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/Apply_PS.mux.h;$(IntDir)shaders/Apply_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\ComputePhaseLookup_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\ComputePhaseLookup_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/ComputePhaseLookup_PS.mux.h;$(IntDir)shaders/ComputePhaseLookup_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\ComputePhaseLookup_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/ComputePhaseLookup_PS.mux.h;$(IntDir)shaders/ComputePhaseLookup_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\ComputePhaseLookup_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/ComputePhaseLookup_PS.mux.h;$(IntDir)shaders/ComputePhaseLookup_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\ComputePhaseLookup_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/ComputePhaseLookup_PS.mux.h;$(IntDir)shaders/ComputePhaseLookup_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\Debug_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Debug_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/Debug_PS.mux.h;$(IntDir)shaders/Debug_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Debug_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/Debug_PS.mux.h;$(IntDir)shaders/Debug_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Debug_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/Debug_PS.mux.h;$(IntDir)shaders/Debug_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Debug_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/Debug_PS.mux.h;$(IntDir)shaders/Debug_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\DownsampleDepth_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\DownsampleDepth_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/DownsampleDepth_PS.mux.h;$(IntDir)shaders/DownsampleDepth_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\DownsampleDepth_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/DownsampleDepth_PS.mux.h;$(IntDir)shaders/DownsampleDepth_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\DownsampleDepth_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/DownsampleDepth_PS.mux.h;$(IntDir)shaders/DownsampleDepth_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\DownsampleDepth_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/DownsampleDepth_PS.mux.h;$(IntDir)shaders/DownsampleDepth_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\RenderVolume_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\RenderVolume_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/RenderVolume_PS.mux.h;$(IntDir)shaders/RenderVolume_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\RenderVolume_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/RenderVolume_PS.mux.h;$(IntDir)shaders/RenderVolume_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\RenderVolume_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/RenderVolume_PS.mux.h;$(IntDir)shaders/RenderVolume_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\RenderVolume_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/RenderVolume_PS.mux.h;$(IntDir)shaders/RenderVolume_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\Resolve_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Resolve_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/Resolve_PS.mux.h;$(IntDir)shaders/Resolve_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Resolve_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/Resolve_PS.mux.h;$(IntDir)shaders/Resolve_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Resolve_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/Resolve_PS.mux.h;$(IntDir)shaders/Resolve_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\Resolve_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/Resolve_PS.mux.h;$(IntDir)shaders/Resolve_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\TemporalFilter_PS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\TemporalFilter_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/TemporalFilter_PS.mux.h;$(IntDir)shaders/TemporalFilter_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\TemporalFilter_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/TemporalFilter_PS.mux.h;$(IntDir)shaders/TemporalFilter_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\TemporalFilter_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/TemporalFilter_PS.mux.h;$(IntDir)shaders/TemporalFilter_PS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tps_5_0" ..\..\shaders\TemporalFilter_PS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/TemporalFilter_PS.mux.h;$(IntDir)shaders/TemporalFilter_PS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\ComputeLightLUT_CS.hlsl">
+ <Command Condition="'$(Configuration)|$(Platform)'=='debug|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tcs_5_0" ..\..\shaders\ComputeLightLUT_CS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='debug|x64'">$(IntDir)shaders/ComputeLightLUT_CS.mux.h;$(IntDir)shaders/ComputeLightLUT_CS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='profile|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tcs_5_0" ..\..\shaders\ComputeLightLUT_CS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='profile|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='profile|x64'">$(IntDir)shaders/ComputeLightLUT_CS.mux.h;$(IntDir)shaders/ComputeLightLUT_CS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='checked|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tcs_5_0" ..\..\shaders\ComputeLightLUT_CS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='checked|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='checked|x64'">$(IntDir)shaders/ComputeLightLUT_CS.mux.h;$(IntDir)shaders/ComputeLightLUT_CS.mux.bytecode;</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='release|x64'">"../../../tools/shadermux.exe" -l 0 -w -f -o "$(IntDir)shaders" -p d3d11 -c "/Tcs_5_0" ..\..\shaders\ComputeLightLUT_CS.hlsl</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='release|x64'">Precompiling shader permutations for %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='release|x64'">$(IntDir)shaders/ComputeLightLUT_CS.mux.h;$(IntDir)shaders/ComputeLightLUT_CS.mux.bytecode;</Outputs>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\d3d11\compiled_shaders_d3d11.h">
+ </ClInclude>
+ <ClInclude Include="..\..\d3d11\context_d3d11.h">
+ </ClInclude>
+ <ClInclude Include="..\..\d3d11\d3d11_util.h">
+ </ClInclude>
+ <ClCompile Include="..\..\d3d11\compiled_shaders_d3d11.cpp">
+ </ClCompile>
+ <ClCompile Include="..\..\d3d11\context_d3d11.cpp">
+ </ClCompile>
+ <ClCompile Include="..\..\d3d11\d3d11_util.cpp">
+ </ClCompile>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets"></ImportGroup>
+</Project>
diff --git a/src/build/vs2013/NvVolumetricLighting.vcxproj.filters b/src/build/vs2013/NvVolumetricLighting.vcxproj.filters
new file mode 100644
index 0000000..b0d05b6
--- /dev/null
+++ b/src/build/vs2013/NvVolumetricLighting.vcxproj.filters
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="public"><!-- -->
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\Nv\VolumetricLighting\NvVolumetricLighting.h">
+ <Filter>public</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="common"><!-- -->
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\common.h">
+ <Filter>common</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\context_common.h">
+ <Filter>common</Filter>
+ </ClInclude>
+ <ClCompile Include="..\..\context_common.cpp">
+ <Filter>common</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\NvVolumetricLighting.cpp">
+ <Filter>common</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="shaders"><!-- Shadermux -->
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\shaders\Quad_VS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\RenderVolume_VS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\RenderVolume_HS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\RenderVolume_DS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\Apply_PS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\ComputePhaseLookup_PS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\Debug_PS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\DownsampleDepth_PS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\RenderVolume_PS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\Resolve_PS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\TemporalFilter_PS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\shaders\ComputeLightLUT_CS.hlsl">
+ <Filter>shaders</Filter>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="d3d11"><!-- -->
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\d3d11\compiled_shaders_d3d11.h">
+ <Filter>d3d11</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\d3d11\context_d3d11.h">
+ <Filter>d3d11</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\d3d11\d3d11_util.h">
+ <Filter>d3d11</Filter>
+ </ClInclude>
+ <ClCompile Include="..\..\d3d11\compiled_shaders_d3d11.cpp">
+ <Filter>d3d11</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\d3d11\context_d3d11.cpp">
+ <Filter>d3d11</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\d3d11\d3d11_util.cpp">
+ <Filter>d3d11</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/src/common.h b/src/common.h
new file mode 100644
index 0000000..4c76a87
--- /dev/null
+++ b/src/common.h
@@ -0,0 +1,261 @@
+// 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 (c) 2003 - 2016 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 COMMON_H
+#define COMMON_H
+////////////////////////////////////////////////////////////////////////////////
+
+#include <NvPreprocessor.h>
+#include <NvAssert.h>
+#include <NvIntrinsics.h>
+#include <NvMath.h>
+#include <NvFoundationMath.h>
+#include <NvCTypes.h>
+
+#if (NV_WIN32 || NV_WIN64)
+#include <Windows.h>
+#endif
+
+namespace Nv
+{
+ using namespace nvidia;
+} // namespace Nv
+
+////////////////////////////////////////////////////////////////////////////////
+
+/*==============================================================================
+ GFSDK Conversion stubs
+==============================================================================*/
+
+NV_FORCE_INLINE Nv::NvVec2 NVCtoNV(const NvcVec2 & rhs)
+{
+ return *reinterpret_cast<const Nv::NvVec2 *>(&rhs);
+}
+
+NV_FORCE_INLINE Nv::NvVec3 NVCtoNV(const NvcVec3 & rhs)
+{
+ return *reinterpret_cast<const Nv::NvVec3 *>(&rhs);
+}
+
+NV_FORCE_INLINE Nv::NvVec4 NVCtoNV(const NvcVec4 & rhs)
+{
+ return *reinterpret_cast<const Nv::NvVec4 *>(&rhs);
+}
+
+NV_FORCE_INLINE Nv::NvMat44 NVCtoNV(const NvcMat44 & rhs)
+{
+ return *reinterpret_cast<const Nv::NvMat44 *>(&rhs);
+}
+
+NV_FORCE_INLINE Nv::NvMat44 Inverse(const Nv::NvMat44 & in)
+{
+ const float * m = in.front();
+ float inv[16];
+ float det;
+ int i;
+
+ inv[0] = m[5] * m[10] * m[15] -
+ m[5] * m[11] * m[14] -
+ m[9] * m[6] * m[15] +
+ m[9] * m[7] * m[14] +
+ m[13] * m[6] * m[11] -
+ m[13] * m[7] * m[10];
+
+ inv[4] = -m[4] * m[10] * m[15] +
+ m[4] * m[11] * m[14] +
+ m[8] * m[6] * m[15] -
+ m[8] * m[7] * m[14] -
+ m[12] * m[6] * m[11] +
+ m[12] * m[7] * m[10];
+
+ inv[8] = m[4] * m[9] * m[15] -
+ m[4] * m[11] * m[13] -
+ m[8] * m[5] * m[15] +
+ m[8] * m[7] * m[13] +
+ m[12] * m[5] * m[11] -
+ m[12] * m[7] * m[9];
+
+ inv[12] = -m[4] * m[9] * m[14] +
+ m[4] * m[10] * m[13] +
+ m[8] * m[5] * m[14] -
+ m[8] * m[6] * m[13] -
+ m[12] * m[5] * m[10] +
+ m[12] * m[6] * m[9];
+
+ inv[1] = -m[1] * m[10] * m[15] +
+ m[1] * m[11] * m[14] +
+ m[9] * m[2] * m[15] -
+ m[9] * m[3] * m[14] -
+ m[13] * m[2] * m[11] +
+ m[13] * m[3] * m[10];
+
+ inv[5] = m[0] * m[10] * m[15] -
+ m[0] * m[11] * m[14] -
+ m[8] * m[2] * m[15] +
+ m[8] * m[3] * m[14] +
+ m[12] * m[2] * m[11] -
+ m[12] * m[3] * m[10];
+
+ inv[9] = -m[0] * m[9] * m[15] +
+ m[0] * m[11] * m[13] +
+ m[8] * m[1] * m[15] -
+ m[8] * m[3] * m[13] -
+ m[12] * m[1] * m[11] +
+ m[12] * m[3] * m[9];
+
+ inv[13] = m[0] * m[9] * m[14] -
+ m[0] * m[10] * m[13] -
+ m[8] * m[1] * m[14] +
+ m[8] * m[2] * m[13] +
+ m[12] * m[1] * m[10] -
+ m[12] * m[2] * m[9];
+
+ inv[2] = m[1] * m[6] * m[15] -
+ m[1] * m[7] * m[14] -
+ m[5] * m[2] * m[15] +
+ m[5] * m[3] * m[14] +
+ m[13] * m[2] * m[7] -
+ m[13] * m[3] * m[6];
+
+ inv[6] = -m[0] * m[6] * m[15] +
+ m[0] * m[7] * m[14] +
+ m[4] * m[2] * m[15] -
+ m[4] * m[3] * m[14] -
+ m[12] * m[2] * m[7] +
+ m[12] * m[3] * m[6];
+
+ inv[10] = m[0] * m[5] * m[15] -
+ m[0] * m[7] * m[13] -
+ m[4] * m[1] * m[15] +
+ m[4] * m[3] * m[13] +
+ m[12] * m[1] * m[7] -
+ m[12] * m[3] * m[5];
+
+ inv[14] = -m[0] * m[5] * m[14] +
+ m[0] * m[6] * m[13] +
+ m[4] * m[1] * m[14] -
+ m[4] * m[2] * m[13] -
+ m[12] * m[1] * m[6] +
+ m[12] * m[2] * m[5];
+
+ inv[3] = -m[1] * m[6] * m[11] +
+ m[1] * m[7] * m[10] +
+ m[5] * m[2] * m[11] -
+ m[5] * m[3] * m[10] -
+ m[9] * m[2] * m[7] +
+ m[9] * m[3] * m[6];
+
+ inv[7] = m[0] * m[6] * m[11] -
+ m[0] * m[7] * m[10] -
+ m[4] * m[2] * m[11] +
+ m[4] * m[3] * m[10] +
+ m[8] * m[2] * m[7] -
+ m[8] * m[3] * m[6];
+
+ inv[11] = -m[0] * m[5] * m[11] +
+ m[0] * m[7] * m[9] +
+ m[4] * m[1] * m[11] -
+ m[4] * m[3] * m[9] -
+ m[8] * m[1] * m[7] +
+ m[8] * m[3] * m[5];
+
+ inv[15] = m[0] * m[5] * m[10] -
+ m[0] * m[6] * m[9] -
+ m[4] * m[1] * m[10] +
+ m[4] * m[2] * m[9] +
+ m[8] * m[1] * m[6] -
+ m[8] * m[2] * m[5];
+
+ det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
+
+ if (det == 0)
+ return Nv::NvMat44(Nv::NvZero);
+
+ det = 1.0f / det;
+
+ for (i = 0; i < 16; i++)
+ inv[i] = inv[i] * det;
+
+ return Nv::NvMat44(inv);
+}
+/*==============================================================================
+ Helper macros
+==============================================================================*/
+
+#if (NV_DEBUG)
+# include <stdio.h>
+# include <assert.h>
+# if (NV_WIN32 || NV_WIN64)
+# define LOG(fmt, ...) { char debug_string[1024]; _snprintf_c(debug_string, 1024, fmt "\n", ##__VA_ARGS__); OutputDebugStringA(debug_string); }
+# define BREAK() DebugBreak();
+# else
+# define LOG(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)
+# define BREAK() abort();
+# endif
+# define ASSERT_LOG(test, msg, ...) if (!(test)) { LOG(msg, ##__VA_ARGS__); NV_ALWAYS_ASSERT(); }
+#else
+# define LOG(fmt, ...)
+# define ASSERT_LOG(test, msg, ...)
+# define BREAK()
+#endif
+
+// Validate internal call
+#define V_(f) { Status v_s = f; if (v_s != Status::OK) return v_s; }
+
+// Validate D3D call
+#define VD3D_(f) { HRESULT v_hr = f; if (FAILED(v_hr)) {LOG("Call Failure: %u", v_hr); return Status::API_ERROR;} }
+
+// Validate resource creation
+#define V_CREATE(x, f) x = f; if (x == nullptr) return Status::RESOURCE_FAILURE;
+
+#define SIZE_OF_ARRAY(a) (sizeof(a)/sizeof(a[0]))
+#define SAFE_DELETE(x) if((x) != nullptr) {delete (x); (x)=nullptr;}
+#define SAFE_RELEASE(x) if((x) != nullptr) {((IUnknown *)(x))->Release(); (x)=nullptr;}
+#define SAFE_RELEASE_ARRAY(x) for (unsigned _sr_count=0; _sr_count<SIZE_OF_ARRAY(x); ++_sr_count) {if((x)[_sr_count] != nullptr) {((IUnknown *)(x)[_sr_count])->Release(); (x)[_sr_count]=nullptr;}}
+#define SAFE_DELETE_ARRAY(x) if (x != nullptr) {SAFE_RELEASE_ARRAY(x); delete[] x; x=nullptr;}
+
+/*==============================================================================
+ Memory Management
+==============================================================================*/
+
+void * operator new(size_t size, const char * filename, int line);
+void operator delete(void * ptr, const char * filename, int line);
+void operator delete (void * ptr);
+void * operator new[](size_t size, const char * filename, int line);
+void operator delete[](void * ptr, const char * filename, int line);
+void operator delete[](void * ptr);
+
+#if (NV_CHECKED)
+# define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
+# define new new(__FILENAME__, __LINE__)
+#else
+# define new new("NvVolumetricLighting.dll", 0)
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+#endif // COMMON_H
diff --git a/src/context_common.cpp b/src/context_common.cpp
new file mode 100644
index 0000000..f8bfd1f
--- /dev/null
+++ b/src/context_common.cpp
@@ -0,0 +1,431 @@
+// 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 (c) 2003 - 2016 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 <Nv/VolumetricLighting/NvVolumetricLighting.h>
+
+#include "common.h"
+#include "context_common.h"
+
+////////////////////////////////////////////////////////////////////////////////
+namespace Nv { namespace VolumetricLighting {
+////////////////////////////////////////////////////////////////////////////////
+
+ContextImp_Common::ContextImp_Common(const ContextDesc * pContextDesc)
+{
+ isInitialized_ = false;
+ jitterIndex_ = 0;
+ lastFrameIndex_ = -1;
+ nextFrameIndex_ = -0;
+ intrinsics::memCopy(&this->contextDesc_, pContextDesc, sizeof(ContextDesc));
+}
+
+/*==============================================================================
+ API Hooks
+==============================================================================*/
+
+
+Status ContextImp_Common::BeginAccumulation(PlatformRenderCtx renderCtx, PlatformShaderResource sceneDepth, ViewerDesc const* pViewerDesc, MediumDesc const* pMediumDesc, DebugFlags debugFlags)
+{
+ debugFlags_ = (uint32_t) debugFlags;
+ intrinsics::memCopy(&viewerDesc_, pViewerDesc, sizeof(ViewerDesc));
+ V_( BeginAccumulation_Start(renderCtx, sceneDepth, pViewerDesc, pMediumDesc) );
+ V_( BeginAccumulation_UpdateMediumLUT(renderCtx) );
+ V_( BeginAccumulation_CopyDepth(renderCtx, sceneDepth) );
+ V_( BeginAccumulation_End(renderCtx, sceneDepth, pViewerDesc, pMediumDesc) );
+ return Status::OK;
+}
+
+Status ContextImp_Common::RenderVolume(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc)
+{
+ V_( RenderVolume_Start(renderCtx, shadowMap, pShadowMapDesc, pLightDesc, pVolumeDesc) );
+ switch (pLightDesc->eType)
+ {
+ case LightType::DIRECTIONAL:
+ V_( RenderVolume_DoVolume_Directional(renderCtx, shadowMap, pShadowMapDesc, pLightDesc, pVolumeDesc) );
+ break;
+
+ case LightType::SPOTLIGHT:
+ V_( RenderVolume_DoVolume_Spotlight(renderCtx, shadowMap, pShadowMapDesc, pLightDesc, pVolumeDesc) );
+ break;
+
+ case LightType::OMNI:
+ V_( RenderVolume_DoVolume_Omni(renderCtx, shadowMap, pShadowMapDesc, pLightDesc, pVolumeDesc) );
+ break;
+
+ default:
+ // Error -- unsupported light type
+ return Status::INVALID_PARAMETER;
+ break;
+ }
+ V_( RenderVolume_End(renderCtx, shadowMap, pShadowMapDesc, pLightDesc, pVolumeDesc) );
+ return Status::OK;
+}
+
+Status ContextImp_Common::EndAccumulation(PlatformRenderCtx renderCtx)
+{
+ V_( EndAccumulation_Imp(renderCtx) );
+ return Status::OK;
+}
+
+Status ContextImp_Common::ApplyLighting(PlatformRenderCtx renderCtx, PlatformRenderTarget sceneTarget, PlatformShaderResource sceneDepth, PostprocessDesc const* pPostprocessDesc)
+{
+ V_( ApplyLighting_Start(renderCtx, sceneTarget, sceneDepth, pPostprocessDesc) );
+ if (getFilterMode() == FilterMode::TEMPORAL)
+ {
+ V_( ApplyLighting_Resolve(renderCtx, pPostprocessDesc) );
+ V_( ApplyLighting_TemporalFilter(renderCtx, sceneDepth, pPostprocessDesc) );
+ }
+ else if (isInternalMSAA())
+ {
+ V_( ApplyLighting_Resolve(renderCtx, pPostprocessDesc) );
+ }
+ V_( ApplyLighting_Composite(renderCtx, sceneTarget, sceneDepth, pPostprocessDesc) );
+ V_( ApplyLighting_End(renderCtx, sceneTarget, sceneDepth, pPostprocessDesc) );
+
+ // Update frame counters as needed
+ jitterIndex_ = (jitterIndex_ + 1) % MAX_JITTER_STEPS;
+ lastFrameIndex_ = nextFrameIndex_;
+ nextFrameIndex_ = (nextFrameIndex_ + 1) % 2;
+ return Status::OK;
+}
+
+/*==============================================================================
+ Helper methods
+==============================================================================*/
+
+uint32_t ContextImp_Common::getOutputBufferWidth() const
+{
+ return contextDesc_.framebuffer.uWidth;
+}
+
+uint32_t ContextImp_Common::getOutputBufferHeight() const
+{
+ return contextDesc_.framebuffer.uHeight;
+}
+
+uint32_t ContextImp_Common::getOutputViewportWidth() const
+{
+ return viewerDesc_.uViewportWidth;
+}
+
+uint32_t ContextImp_Common::getOutputViewportHeight() const
+{
+ return viewerDesc_.uViewportHeight;
+}
+
+uint32_t ContextImp_Common::getOutputSampleCount() const
+{
+ return contextDesc_.framebuffer.uSamples;
+}
+
+float ContextImp_Common::getInternalScale() const
+{
+ switch (contextDesc_.eDownsampleMode)
+ {
+ default:
+ case DownsampleMode::FULL:
+ return 1.00f;
+
+ case DownsampleMode::HALF:
+ return 0.50f;
+
+ case DownsampleMode::QUARTER:
+ return 0.25f;
+ }
+}
+
+uint32_t ContextImp_Common::getInternalBufferWidth() const
+{
+ switch (contextDesc_.eDownsampleMode)
+ {
+ default:
+ case DownsampleMode::FULL:
+ return contextDesc_.framebuffer.uWidth;
+
+ case DownsampleMode::HALF:
+ return contextDesc_.framebuffer.uWidth >> 1;
+
+ case DownsampleMode::QUARTER:
+ return contextDesc_.framebuffer.uWidth >> 2;
+ }
+}
+
+uint32_t ContextImp_Common::getInternalBufferHeight() const
+{
+ switch (contextDesc_.eDownsampleMode)
+ {
+ default:
+ case DownsampleMode::FULL:
+ return contextDesc_.framebuffer.uHeight;
+
+ case DownsampleMode::HALF:
+ return contextDesc_.framebuffer.uHeight >> 1;
+
+ case DownsampleMode::QUARTER:
+ return contextDesc_.framebuffer.uHeight >> 2;
+ }
+}
+
+uint32_t ContextImp_Common::getInternalViewportWidth() const
+{
+ switch (contextDesc_.eDownsampleMode)
+ {
+ default:
+ case DownsampleMode::FULL:
+ return viewerDesc_.uViewportWidth;
+
+ case DownsampleMode::HALF:
+ return viewerDesc_.uViewportWidth >> 1;
+
+ case DownsampleMode::QUARTER:
+ return viewerDesc_.uViewportWidth >> 2;
+ }
+}
+
+uint32_t ContextImp_Common::getInternalViewportHeight() const
+{
+ switch (contextDesc_.eDownsampleMode)
+ {
+ default:
+ case DownsampleMode::FULL:
+ return viewerDesc_.uViewportHeight;
+
+ case DownsampleMode::HALF:
+ return viewerDesc_.uViewportHeight >> 1;
+
+ case DownsampleMode::QUARTER:
+ return viewerDesc_.uViewportHeight >> 2;
+ }
+}
+
+uint32_t ContextImp_Common::getInternalSampleCount() const
+{
+ switch (contextDesc_.eInternalSampleMode)
+ {
+ default:
+ case MultisampleMode::SINGLE:
+ return 1;
+
+ case MultisampleMode::MSAA2:
+ return 2;
+
+ case MultisampleMode::MSAA4:
+ return 4;
+ }
+}
+
+bool ContextImp_Common::isOutputMSAA() const
+{
+ return (getOutputSampleCount() > 1);
+}
+
+bool ContextImp_Common::isInternalMSAA() const
+{
+ return (getInternalSampleCount() > 1);
+}
+
+FilterMode ContextImp_Common::getFilterMode() const
+{
+ return contextDesc_.eFilterMode;
+}
+
+NvVec2 ContextImp_Common::getJitter() const
+{
+ if (getFilterMode() == FilterMode::TEMPORAL)
+ {
+ auto HaltonSequence = [](int index, int base) -> float
+ {
+ float result = 0;
+ float f = 1;
+ int i = index + 1;
+ while (i > 0)
+ {
+ f = f / float(base);
+ result += f * (i % base);
+ i = i / base;
+ }
+ return result;
+ };
+
+ return NvVec2((HaltonSequence(jitterIndex_, 2) - 0.5f), (HaltonSequence(jitterIndex_, 3) - 0.5f));
+ }
+ else
+ {
+ return NvVec2(0, 0);
+ }
+}
+
+uint32_t ContextImp_Common::getCoarseResolution(const VolumeDesc *pVolumeDesc) const
+{
+ switch (pVolumeDesc->eTessQuality)
+ {
+ default:
+ case TessellationQuality::HIGH:
+ return pVolumeDesc->uMaxMeshResolution / 64;
+
+ case TessellationQuality::MEDIUM:
+ return pVolumeDesc->uMaxMeshResolution / 32;
+
+ case TessellationQuality::LOW:
+ return pVolumeDesc->uMaxMeshResolution / 16;
+ }
+}
+/*==============================================================================
+ Constant Buffer Setup
+==============================================================================*/
+
+void ContextImp_Common::SetupCB_PerContext(PerContextCB * cb)
+{
+ cb->vOutputSize = NvVec2(static_cast<float>(getOutputBufferWidth()), static_cast<float>(getOutputBufferHeight()));
+ cb->vOutputSize_Inv = NvVec2(1.f / cb->vOutputSize.x, 1.f / cb->vOutputSize.y);
+ cb->vBufferSize = NvVec2(static_cast<float>(getInternalBufferWidth()), static_cast<float>(getInternalBufferHeight()));
+ cb->vBufferSize_Inv = NvVec2(1.f / cb->vBufferSize.x, 1.f / cb->vBufferSize.y);
+ cb->fResMultiplier = 1.f / getInternalScale();
+ cb->uSampleCount = getInternalSampleCount();
+}
+
+void ContextImp_Common::SetupCB_PerFrame(ViewerDesc const* pViewerDesc, MediumDesc const* pMediumDesc, PerFrameCB * cb)
+{
+ cb->mProj = NVCtoNV(pViewerDesc->mProj);
+ cb->mViewProj = NVCtoNV(pViewerDesc->mViewProj);
+ cb->mViewProj_Inv = Inverse(cb->mViewProj);
+ cb->vOutputViewportSize = NvVec2(static_cast<float>(getOutputViewportWidth()), static_cast<float>(getOutputViewportHeight()));
+ cb->vOutputViewportSize_Inv = NvVec2(1.f / cb->vOutputViewportSize.x, 1.f / cb->vOutputViewportSize.y);
+ cb->vViewportSize = NvVec2(static_cast<float>(getInternalViewportWidth()), static_cast<float>(getInternalViewportHeight()));
+ cb->vViewportSize_Inv = NvVec2(1.f / cb->vViewportSize.x, 1.f / cb->vViewportSize.y);
+ cb->vEyePosition = NVCtoNV(pViewerDesc->vEyePosition);
+ cb->vJitterOffset = getJitter();
+ float proj_33 = cb->mProj(2, 2);
+ float proj_34 = cb->mProj(2, 3);
+ cb->fZNear = -proj_34 / proj_33;
+ cb->fZFar = proj_34 / (1.0f - proj_33);
+
+ const float SCATTER_EPSILON = 0.000001f;
+ NvVec3 total_scatter = NvVec3(SCATTER_EPSILON, SCATTER_EPSILON, SCATTER_EPSILON);
+ cb->uNumPhaseTerms = pMediumDesc->uNumPhaseTerms;
+ for (uint32_t p = 0; p < pMediumDesc->uNumPhaseTerms; ++p)
+ {
+ cb->uPhaseFunc[p][0] = static_cast<uint32_t>(pMediumDesc->PhaseTerms[p].ePhaseFunc);
+ NvVec3 density = NVCtoNV(pMediumDesc->PhaseTerms[p].vDensity);
+ cb->vPhaseParams[p] = NvVec4(density.x, density.y, density.z, pMediumDesc->PhaseTerms[p].fEccentricity);
+ total_scatter += density;
+ }
+ NvVec3 absorption = NVCtoNV(pMediumDesc->vAbsorption);
+ cb->vScatterPower.x = 1-exp(-total_scatter.x);
+ cb->vScatterPower.y = 1-exp(-total_scatter.y);
+ cb->vScatterPower.z = 1-exp(-total_scatter.z);
+ cb->vSigmaExtinction = total_scatter + absorption;
+}
+
+void ContextImp_Common::SetupCB_PerVolume(ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc, PerVolumeCB * cb)
+{
+ cb->mLightToWorld = NVCtoNV(pLightDesc->mLightToWorld);
+ cb->vLightIntensity = NVCtoNV(pLightDesc->vIntensity);
+ switch (pLightDesc->eType)
+ {
+ case LightType::DIRECTIONAL:
+ cb->vLightDir = NVCtoNV(pLightDesc->Directional.vDirection);
+ break;
+
+ case LightType::SPOTLIGHT:
+ cb->vLightDir = NVCtoNV(pLightDesc->Spotlight.vDirection);
+ cb->vLightPos = NVCtoNV(pLightDesc->Spotlight.vPosition);
+ cb->fLightZNear = pLightDesc->Spotlight.fZNear;
+ cb->fLightZFar = pLightDesc->Spotlight.fZFar;
+ cb->fLightFalloffAngle = pLightDesc->Spotlight.fFalloff_CosTheta;
+ cb->fLightFalloffPower = pLightDesc->Spotlight.fFalloff_Power;
+ cb->vAttenuationFactors = *reinterpret_cast<const NvVec4 *>(pLightDesc->Spotlight.fAttenuationFactors);
+ break;
+
+ case LightType::OMNI:
+ cb->vLightPos = NVCtoNV(pLightDesc->Omni.vPosition);
+ cb->fLightZNear = pLightDesc->Omni.fZNear;
+ cb->fLightZFar = pLightDesc->Omni.fZFar;
+ cb->vAttenuationFactors = *reinterpret_cast<const NvVec4 *>(pLightDesc->Omni.fAttenuationFactors);
+ default:
+ break;
+ };
+ cb->fDepthBias = pVolumeDesc->fDepthBias;
+
+ cb->uMeshResolution = getCoarseResolution(pVolumeDesc);
+
+ NvVec4 vw1 = cb->mLightToWorld.transform(NvVec4(-1, -1, 1, 1));
+ NvVec4 vw2 = cb->mLightToWorld.transform(NvVec4( 1, 1, 1, 1));
+ vw1 = vw1 / vw1.w;
+ vw2 = vw2 / vw2.w;
+ float fCrossLength = ((vw1).getXYZ() - (vw2).getXYZ()).magnitude();
+ float fSideLength = sqrtf(0.5f*fCrossLength*fCrossLength);
+ cb->fGridSectionSize = fSideLength / static_cast<float>(cb->uMeshResolution);
+ cb->fTargetRaySize = pVolumeDesc->fTargetRayResolution;
+
+ for (int i=0;i<MAX_SHADOWMAP_ELEMENTS;++i)
+ {
+ cb->vElementOffsetAndScale[i].x = (float)pShadowMapDesc->Elements[i].uOffsetX / pShadowMapDesc->uWidth;
+ cb->vElementOffsetAndScale[i].y = (float)pShadowMapDesc->Elements[i].uOffsetY / pShadowMapDesc->uHeight;
+ cb->vElementOffsetAndScale[i].z = (float)pShadowMapDesc->Elements[i].uWidth / pShadowMapDesc->uWidth;
+ cb->vElementOffsetAndScale[i].w = (float)pShadowMapDesc->Elements[i].uHeight / pShadowMapDesc->uHeight;
+ cb->mLightProj[i] = NVCtoNV(pShadowMapDesc->Elements[i].mViewProj);
+ cb->mLightProj_Inv[i] = Inverse(cb->mLightProj[i]);
+ cb->uElementIndex[i][0] = pShadowMapDesc->Elements[i].mArrayIndex;
+ }
+
+ cb->vShadowMapDim.x = static_cast<float>(pShadowMapDesc->uWidth);
+ cb->vShadowMapDim.y = static_cast<float>(pShadowMapDesc->uHeight);
+}
+
+void ContextImp_Common::SetupCB_PerApply(PostprocessDesc const* pPostprocessDesc, PerApplyCB * cb)
+{
+ if (getFilterMode() == FilterMode::TEMPORAL)
+ {
+ cb->fHistoryFactor = (lastFrameIndex_ == -1) ? 0.0f : pPostprocessDesc->fTemporalFactor;
+ cb->fFilterThreshold = pPostprocessDesc->fFilterThreshold;
+ if (lastFrameIndex_ == -1)
+ {
+ lastViewProj_ = NVCtoNV(pPostprocessDesc->mUnjitteredViewProj);
+ lastFrameIndex_ = (nextFrameIndex_+1)%2;
+ }
+ else
+ {
+ lastViewProj_ = nextViewProj_;
+ }
+ nextViewProj_ = NVCtoNV(pPostprocessDesc->mUnjitteredViewProj);
+ cb->mHistoryXform = lastViewProj_ * Inverse(nextViewProj_);
+ }
+ else
+ {
+ cb->mHistoryXform = NvMat44(NvIdentity);
+ cb->fFilterThreshold = 0.0f;
+ cb->fHistoryFactor = 0.0f;
+ }
+ cb->vFogLight = NVCtoNV(pPostprocessDesc->vFogLight);
+ cb->fMultiScattering = pPostprocessDesc->fMultiscatter;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+}; /*namespace VolumetricLighting*/ }; /*namespace Nv*/
+////////////////////////////////////////////////////////////////////////////////
diff --git a/src/context_common.h b/src/context_common.h
new file mode 100644
index 0000000..386c4b7
--- /dev/null
+++ b/src/context_common.h
@@ -0,0 +1,249 @@
+// 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 (c) 2003 - 2016 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 CONTEXT_COMMON_H
+#define CONTEXT_COMMON_H
+////////////////////////////////////////////////////////////////////////////////
+
+#include <Nv/VolumetricLighting/NvVolumetricLighting.h>
+
+#include "common.h"
+
+/*==============================================================================
+ Forward Declarations
+==============================================================================*/
+
+#pragma warning(disable: 4100)
+////////////////////////////////////////////////////////////////////////////////
+namespace Nv { namespace VolumetricLighting {
+////////////////////////////////////////////////////////////////////////////////
+
+/*==============================================================================
+ Constants
+==============================================================================*/
+const uint32_t MAX_JITTER_STEPS = 8;
+
+// These need to match the values in ComputeLightLUT_CS.hlsl
+const uint32_t LIGHT_LUT_DEPTH_RESOLUTION = 128;
+const uint32_t LIGHT_LUT_WDOTV_RESOLUTION = 512;
+
+/*==============================================================================
+ Base Context Implementation
+==============================================================================*/
+
+class ContextImp_Common
+{
+public:
+ // Clean up common resources
+ virtual ~ContextImp_Common() {};
+
+ //--------------------------------------------------------------------------
+ // API Hooks
+ Status BeginAccumulation(PlatformRenderCtx renderCtx, PlatformShaderResource sceneDepth, ViewerDesc const* pViewerDesc, MediumDesc const* pMediumDesc, DebugFlags debugFlags);
+ Status RenderVolume(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc);
+ Status EndAccumulation(PlatformRenderCtx renderCtx);
+ Status ApplyLighting(PlatformRenderCtx renderCtx, PlatformRenderTarget sceneTarget, PlatformShaderResource sceneDepth, PostprocessDesc const* pPostprocessDesc);
+
+protected:
+
+ //--------------------------------------------------------------------------
+ // Implementation Stubs
+
+ // BeginAccumulation
+ virtual Status BeginAccumulation_Start(PlatformRenderCtx renderCtx, PlatformShaderResource sceneDepth, ViewerDesc const* pViewerDesc, MediumDesc const* pMediumDesc) = 0;
+ virtual Status BeginAccumulation_UpdateMediumLUT(PlatformRenderCtx renderCtx) = 0;
+ virtual Status BeginAccumulation_CopyDepth(PlatformRenderCtx renderCtx, PlatformShaderResource sceneDepth) = 0;
+ virtual Status BeginAccumulation_End(PlatformRenderCtx renderCtx, PlatformShaderResource sceneDepth, ViewerDesc const* pViewerDesc, MediumDesc const* pMediumDesc) = 0;
+
+ // RenderVolume
+ virtual Status RenderVolume_Start(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc) = 0;
+ virtual Status RenderVolume_DoVolume_Directional(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc) = 0;
+ virtual Status RenderVolume_DoVolume_Spotlight(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc) = 0;
+ virtual Status RenderVolume_DoVolume_Omni(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc) = 0;
+ virtual Status RenderVolume_End(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc) = 0;
+
+ // EndAccumulation
+ virtual Status EndAccumulation_Imp(PlatformRenderCtx renderCtx) = 0;
+
+ // ApplyLighting
+ virtual Status ApplyLighting_Start(PlatformRenderCtx renderCtx, PlatformRenderTarget sceneTarget, PlatformShaderResource sceneDepth, PostprocessDesc const* pPostprocessDesc) = 0;
+ virtual Status ApplyLighting_Resolve(PlatformRenderCtx renderCtx, PostprocessDesc const* pPostprocessDesc) = 0;
+ virtual Status ApplyLighting_TemporalFilter(PlatformRenderCtx renderCtx, PlatformShaderResource sceneDepth, PostprocessDesc const* pPostprocessDesc) = 0;
+ virtual Status ApplyLighting_Composite(PlatformRenderCtx renderCtx, PlatformRenderTarget sceneTarget, PlatformShaderResource sceneDepth, PostprocessDesc const* pPostprocessDesc) = 0;
+ virtual Status ApplyLighting_End(PlatformRenderCtx renderCtx, PlatformRenderTarget sceneTarget, PlatformShaderResource sceneDepth, PostprocessDesc const* pPostprocessDesc) = 0;
+
+ //--------------------------------------------------------------------------
+ // Constructors
+ // Protected constructor - Should only ever instantiate children
+ ContextImp_Common() {};
+
+ // Call this from base-class for actual initialization
+ ContextImp_Common(const ContextDesc * pContextDesc);
+
+ //--------------------------------------------------------------------------
+ // Helper functions
+ NvVec2 getJitter() const;
+ uint32_t getOutputBufferWidth() const;
+ uint32_t getOutputBufferHeight() const;
+ uint32_t getOutputViewportWidth() const;
+ uint32_t getOutputViewportHeight() const;
+ uint32_t getOutputSampleCount() const;
+ float getInternalScale() const;
+ uint32_t getInternalBufferWidth() const;
+ uint32_t getInternalBufferHeight() const;
+ uint32_t getInternalViewportWidth() const;
+ uint32_t getInternalViewportHeight() const;
+ uint32_t getInternalSampleCount() const;
+ bool isOutputMSAA() const;
+ bool isInternalMSAA() const;
+ FilterMode getFilterMode() const;
+ uint32_t getCoarseResolution(const VolumeDesc * pVolumeDesc) const;
+
+
+ //--------------------------------------------------------------------------
+ // Constant Buffers
+
+ struct PerContextCB
+ {
+ // c0
+ NvVec2 vOutputSize;
+ NvVec2 vOutputSize_Inv;
+ // c1
+ NvVec2 vBufferSize;
+ NvVec2 vBufferSize_Inv;
+ // c2
+ float fResMultiplier;
+ uint32_t uSampleCount;
+ float pad1[2];
+ };
+ void SetupCB_PerContext(PerContextCB * cb);
+
+ struct PerFrameCB
+ {
+ // c0+4
+ NvMat44 mProj;
+ // c4+4
+ NvMat44 mViewProj;
+ // c8+4
+ NvMat44 mViewProj_Inv;
+ // c12
+ NvVec2 vOutputViewportSize;
+ NvVec2 vOutputViewportSize_Inv;
+ // c13
+ NvVec2 vViewportSize;
+ NvVec2 vViewportSize_Inv;
+ // c14
+ NvVec3 vEyePosition;
+ float pad1[1];
+ // c15
+ NvVec2 vJitterOffset;
+ float fZNear;
+ float fZFar;
+ // c16
+ NvVec3 vScatterPower;
+ uint32_t uNumPhaseTerms;
+ // c17
+ NvVec3 vSigmaExtinction;
+ float pad2[1];
+ // c18+MAX_PHASE_TERMS (4)
+ uint32_t uPhaseFunc[MAX_PHASE_TERMS][4];
+ // c22
+ NvVec4 vPhaseParams[MAX_PHASE_TERMS];
+ };
+ void SetupCB_PerFrame(ViewerDesc const* pViewerDesc, MediumDesc const* pMediumDesc, PerFrameCB * cb);
+
+ struct PerVolumeCB
+ {
+ // c0+4
+ NvMat44 mLightToWorld;
+ // c4
+ float fLightFalloffAngle;
+ float fLightFalloffPower;
+ float fGridSectionSize;
+ float fLightToEyeDepth;
+ // c5
+ float fLightZNear;
+ float fLightZFar;
+ float pad[2];
+ // c6
+ NvVec4 vAttenuationFactors;
+ // c7+16
+ NvMat44 mLightProj[4];
+ // c23+16
+ NvMat44 mLightProj_Inv[4];
+ // c39
+ NvVec3 vLightDir;
+ float fDepthBias;
+ // c40
+ NvVec3 vLightPos;
+ uint32_t uMeshResolution;
+ // c41
+ NvVec3 vLightIntensity;
+ float fTargetRaySize;
+ // c42+4
+ NvVec4 vElementOffsetAndScale[4];
+ // c46
+ NvVec4 vShadowMapDim;
+ // c47+4
+ // Only first index of each "row" is used.
+ // (Need to do this because HLSL can only stride arrays by full offset)
+ uint32_t uElementIndex[4][4];
+ };
+ void SetupCB_PerVolume(ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc, PerVolumeCB * cb);
+
+ struct PerApplyCB
+ {
+ // c0
+ NvMat44 mHistoryXform;
+ // c4
+ float fFilterThreshold;
+ float fHistoryFactor;
+ float pad1[2];
+ // c5
+ NvVec3 vFogLight;
+ float fMultiScattering;
+ };
+ void SetupCB_PerApply(PostprocessDesc const* pPostprocessDesc, PerApplyCB * cb);
+
+ //--------------------------------------------------------------------------
+ // Miscellaneous internal state
+ bool isInitialized_;
+ uint32_t debugFlags_;
+ ContextDesc contextDesc_;
+ ViewerDesc viewerDesc_;
+ uint32_t jitterIndex_;
+ int32_t lastFrameIndex_;
+ int32_t nextFrameIndex_;
+ NvMat44 lastViewProj_;
+ NvMat44 nextViewProj_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+}; /*namespace VolumetricLighting*/ }; /*namespace Nv*/
+////////////////////////////////////////////////////////////////////////////////
+#endif // CONTEXT_COMMON_H
diff --git a/src/d3d11/compiled_shaders_d3d11.cpp b/src/d3d11/compiled_shaders_d3d11.cpp
new file mode 100644
index 0000000..2a23501
--- /dev/null
+++ b/src/d3d11/compiled_shaders_d3d11.cpp
@@ -0,0 +1,43 @@
+// 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 (c) 2003 - 2016 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 <stdint.h>
+namespace d3d11 { namespace shaders {
+ #include <shaders/Apply_PS.mux.bytecode>
+ #include <shaders/ComputeLightLUT_CS.mux.bytecode>
+ #include <shaders/ComputePhaseLookup_PS.mux.bytecode>
+ #include <shaders/Debug_PS.mux.bytecode>
+ #include <shaders/DownsampleDepth_PS.mux.bytecode>
+ #include <shaders/Quad_VS.mux.bytecode>
+ #include <shaders/RenderVolume_VS.mux.bytecode>
+ #include <shaders/RenderVolume_HS.mux.bytecode>
+ #include <shaders/RenderVolume_DS.mux.bytecode>
+ #include <shaders/RenderVolume_PS.mux.bytecode>
+ #include <shaders/Resolve_PS.mux.bytecode>
+ #include <shaders/TemporalFilter_PS.mux.bytecode>
+}; /* namespace shaders */ }; /* namespace d3d11 */
diff --git a/src/d3d11/compiled_shaders_d3d11.h b/src/d3d11/compiled_shaders_d3d11.h
new file mode 100644
index 0000000..885b1c3
--- /dev/null
+++ b/src/d3d11/compiled_shaders_d3d11.h
@@ -0,0 +1,52 @@
+// 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 (c) 2003 - 2016 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 COMPILED_SHADERS_D3D11_H
+#define COMPILED_SHADERS_D3D11_H
+////////////////////////////////////////////////////////////////////////////////
+#include <stdint.h>
+namespace d3d11 { namespace shaders {
+ #include <shaders/Apply_PS.mux.h>
+ #include <shaders/ComputeLightLUT_CS.mux.h>
+ #include <shaders/ComputePhaseLookup_PS.mux.h>
+ #include <shaders/Debug_PS.mux.h>
+ #include <shaders/DownsampleDepth_PS.mux.h>
+ #include <shaders/Quad_VS.mux.h>
+ #include <shaders/RenderVolume_VS.mux.h>
+ #include <shaders/RenderVolume_HS.mux.h>
+ #include <shaders/RenderVolume_DS.mux.h>
+ #include <shaders/RenderVolume_PS.mux.h>
+ #include <shaders/Resolve_PS.mux.h>
+ #include <shaders/TemporalFilter_PS.mux.h>
+}; /* namespace shaders */ }; /* namespace d3d11 */
+// We use the namespaces to avoid conflicts if supporting multiple APIs
+// but they aren't needed wherever these would be included.
+using namespace d3d11;
+using namespace shaders;
+////////////////////////////////////////////////////////////////////////////////
+#endif // COMPILED_SHADERS_D3D11_H
diff --git a/src/d3d11/context_d3d11.cpp b/src/d3d11/context_d3d11.cpp
new file mode 100644
index 0000000..9bb2f4a
--- /dev/null
+++ b/src/d3d11/context_d3d11.cpp
@@ -0,0 +1,1257 @@
+// 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 (c) 2003 - 2016 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.h"
+#include "context_d3d11.h"
+#include "compiled_shaders_d3d11.h"
+#include "d3d11_util.h"
+
+#include <stdint.h>
+#include <d3d11.h>
+
+#pragma warning(disable: 4100)
+////////////////////////////////////////////////////////////////////////////////
+namespace Nv { namespace VolumetricLighting {
+////////////////////////////////////////////////////////////////////////////////
+const uint8_t STENCIL_REF = 0xFF;
+
+/*==============================================================================
+ Create a context and load/allocate/generate resources
+==============================================================================*/
+
+Status ContextImp_D3D11::Create(ContextImp_D3D11 ** out_ctx, const PlatformDesc * pPlatformDesc, const ContextDesc * pContextDesc)
+{
+ ID3D11Device * pDevice = pPlatformDesc->d3d11.pDevice;
+ if (pDevice->GetFeatureLevel() < D3D_FEATURE_LEVEL_11_0)
+ return Status::UNSUPPORTED_DEVICE;
+
+ *out_ctx = new ContextImp_D3D11(pContextDesc);
+ Status result = (*out_ctx)->CreateResources(pDevice);
+ if (result != Status::OK)
+ {
+ delete *out_ctx;
+ *out_ctx = nullptr;
+ return result;
+ }
+ else
+ {
+ return Status::OK;
+ }
+}
+
+Status ContextImp_D3D11::CreateResources(ID3D11Device * device)
+{
+ //--------------------------------------------------------------------------
+ // Shaders
+# define LOAD_SHADERS(x) LoadShaders(device, ##x##::permutation_code, ##x##::permutation_length, shaders::##x##::PERMUTATION_ENTRY_COUNT, shaders.##x)
+ VD3D_(LOAD_SHADERS(Apply_PS));
+ VD3D_(LOAD_SHADERS(ComputeLightLUT_CS));
+ VD3D_(LOAD_SHADERS(ComputePhaseLookup_PS));
+ VD3D_(LOAD_SHADERS(Debug_PS));
+ VD3D_(LOAD_SHADERS(DownsampleDepth_PS));
+ VD3D_(LOAD_SHADERS(Quad_VS));
+ VD3D_(LOAD_SHADERS(RenderVolume_VS));
+ VD3D_(LOAD_SHADERS(RenderVolume_HS));
+ VD3D_(LOAD_SHADERS(RenderVolume_DS));
+ VD3D_(LOAD_SHADERS(RenderVolume_PS));
+ VD3D_(LOAD_SHADERS(Resolve_PS));
+ VD3D_(LOAD_SHADERS(TemporalFilter_PS));
+# undef LOAD_SHADERS
+
+ //--------------------------------------------------------------------------
+ // Constant Buffers
+ V_CREATE(pPerContextCB, ConstantBuffer<PerContextCB>::Create(device));
+ V_CREATE(pPerFrameCB, ConstantBuffer<PerFrameCB>::Create(device));
+ V_CREATE(pPerVolumeCB, ConstantBuffer<PerVolumeCB>::Create(device));
+ V_CREATE(pPerApplyCB, ConstantBuffer<PerApplyCB>::Create(device));
+
+ //--------------------------------------------------------------------------
+ // Shader Resources
+ V_CREATE(pDepth_, DepthTarget::Create(device, getInternalBufferWidth(), getInternalBufferHeight(), getInternalSampleCount(), DXGI_FORMAT_D24_UNORM_S8_UINT, 1, "NvVl::Depth"));
+ V_CREATE(pPhaseLUT_, RenderTarget::Create(device, 1, LIGHT_LUT_WDOTV_RESOLUTION, 1, DXGI_FORMAT_R16G16B16A16_FLOAT, "NvVl::Phase LUT"));
+ V_CREATE(pLightLUT_P_[0], RenderTarget::Create(device, LIGHT_LUT_DEPTH_RESOLUTION, LIGHT_LUT_WDOTV_RESOLUTION, 1, DXGI_FORMAT_R16G16B16A16_FLOAT, "NvVl::Light LUT Point [0]"));
+ V_CREATE(pLightLUT_P_[1], RenderTarget::Create(device, LIGHT_LUT_DEPTH_RESOLUTION, LIGHT_LUT_WDOTV_RESOLUTION, 1, DXGI_FORMAT_R16G16B16A16_FLOAT, "NvVl::Light LUT Point [1]"));
+ V_CREATE(pLightLUT_S1_[0], RenderTarget::Create(device, LIGHT_LUT_DEPTH_RESOLUTION, LIGHT_LUT_WDOTV_RESOLUTION, 1, DXGI_FORMAT_R16G16B16A16_FLOAT, "NvVl::Light LUT Spot 1 [0]"));
+ V_CREATE(pLightLUT_S1_[1], RenderTarget::Create(device, LIGHT_LUT_DEPTH_RESOLUTION, LIGHT_LUT_WDOTV_RESOLUTION, 1, DXGI_FORMAT_R16G16B16A16_FLOAT, "NvVl::Light LUT Spot 1 [1]"));
+ V_CREATE(pLightLUT_S2_[0], RenderTarget::Create(device, LIGHT_LUT_DEPTH_RESOLUTION, LIGHT_LUT_WDOTV_RESOLUTION, 1, DXGI_FORMAT_R16G16B16A16_FLOAT, "NvVl::Light LUT Spot 2 [0]"));
+ V_CREATE(pLightLUT_S2_[1], RenderTarget::Create(device, LIGHT_LUT_DEPTH_RESOLUTION, LIGHT_LUT_WDOTV_RESOLUTION, 1, DXGI_FORMAT_R16G16B16A16_FLOAT, "NvVl::Light LUT Spot 2 [1]"));
+ V_CREATE(pAccumulation_, RenderTarget::Create(device, getInternalBufferWidth(), getInternalBufferHeight(), getInternalSampleCount(), DXGI_FORMAT_R16G16B16A16_FLOAT, "NvVl::Accumulation"));
+
+ if (isInternalMSAA() || getFilterMode() == FilterMode::TEMPORAL)
+ {
+ V_CREATE(pResolvedAccumulation_, RenderTarget::Create(device, getInternalBufferWidth(), getInternalBufferHeight(), 1, DXGI_FORMAT_R16G16B16A16_FLOAT, "NvVl::Resolved Accumulation"));
+ V_CREATE(pResolvedDepth_, RenderTarget::Create(device, getInternalBufferWidth(), getInternalBufferHeight(), 1, DXGI_FORMAT_R16G16_FLOAT, "NvVl::Resolved Depth"));
+ }
+
+ if (getFilterMode() == FilterMode::TEMPORAL)
+ {
+ for (int i=0; i<2; ++i)
+ {
+ V_CREATE(pFilteredDepth_[i], RenderTarget::Create(device, getInternalBufferWidth(), getInternalBufferHeight(), 1, DXGI_FORMAT_R16G16_FLOAT, "NvVl::Filtered Depth"));
+ V_CREATE(pFilteredAccumulation_[i], RenderTarget::Create(device, getInternalBufferWidth(), getInternalBufferHeight(), 1, DXGI_FORMAT_R16G16B16A16_FLOAT, "NvVl::Filtered Accumulation"));
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ // States
+ // Rasterizer State
+ {
+ CD3D11_RASTERIZER_DESC rsDesc((CD3D11_DEFAULT()));
+ rsDesc.FrontCounterClockwise = TRUE;
+ rsDesc.CullMode = D3D11_CULL_NONE;
+ rsDesc.DepthClipEnable = FALSE;
+ VD3D_(device->CreateRasterizerState(&rsDesc, &states.rs.cull_none));
+ }
+ {
+ CD3D11_RASTERIZER_DESC rsDesc((CD3D11_DEFAULT()));
+ rsDesc.FrontCounterClockwise = TRUE;
+ rsDesc.CullMode = D3D11_CULL_FRONT;
+ rsDesc.DepthClipEnable = FALSE;
+ VD3D_(device->CreateRasterizerState(&rsDesc, &states.rs.cull_front));
+ }
+ {
+ CD3D11_RASTERIZER_DESC rsDesc((CD3D11_DEFAULT()));
+ rsDesc.FillMode = D3D11_FILL_WIREFRAME;
+ rsDesc.FrontCounterClockwise = TRUE;
+ rsDesc.CullMode = D3D11_CULL_NONE;
+ rsDesc.DepthClipEnable = FALSE;
+ VD3D_(device->CreateRasterizerState(&rsDesc, &states.rs.wireframe));
+ }
+ // Sampler State
+ {
+ CD3D11_SAMPLER_DESC ssDesc((CD3D11_DEFAULT()));
+ ssDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
+ VD3D_(device->CreateSamplerState(&ssDesc, &states.ss.point));
+ }
+ {
+ CD3D11_SAMPLER_DESC ssDesc((CD3D11_DEFAULT()));
+ ssDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
+ VD3D_(device->CreateSamplerState(&ssDesc, &states.ss.linear));
+ }
+ // Depth-Stencil
+ {
+ // Depth Disabled
+ CD3D11_DEPTH_STENCIL_DESC dsDesc((CD3D11_DEFAULT()));
+ dsDesc.DepthEnable = FALSE;
+ VD3D_(device->CreateDepthStencilState(&dsDesc, &states.ds.no_depth));
+ }
+ {
+ // Write-only Depth DS
+ CD3D11_DEPTH_STENCIL_DESC dsDesc((CD3D11_DEFAULT()));
+ dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ VD3D_(device->CreateDepthStencilState(&dsDesc, &states.ds.write_only_depth));
+ }
+ {
+ // Render Volume DS
+ CD3D11_DEPTH_STENCIL_DESC dsDesc((CD3D11_DEFAULT()));
+ dsDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
+ dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
+ dsDesc.StencilEnable = TRUE;
+ dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+ dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
+ dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+ dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
+ dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ VD3D_(device->CreateDepthStencilState(&dsDesc, &states.ds.render_volume));
+ }
+ {
+ // Render Volume Boundary DS
+ CD3D11_DEPTH_STENCIL_DESC dsDesc((CD3D11_DEFAULT()));
+ dsDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
+ dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
+ dsDesc.StencilEnable = TRUE;
+ dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_NEVER;
+ dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+ dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
+ dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+ dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
+ dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ VD3D_(device->CreateDepthStencilState(&dsDesc, &states.ds.render_volume_boundary));
+ }
+ {
+ // Render volume cap DS
+ CD3D11_DEPTH_STENCIL_DESC dsDesc((CD3D11_DEFAULT()));
+ dsDesc.DepthEnable = FALSE;
+ dsDesc.StencilEnable = TRUE;
+ dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_LESS_EQUAL;
+ dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+ dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
+ dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_LESS_EQUAL;
+ dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+ dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
+ dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ VD3D_(device->CreateDepthStencilState(&dsDesc, &states.ds.render_volume_cap));
+ }
+ {
+ // Finish Volume DS
+ CD3D11_DEPTH_STENCIL_DESC dsDesc((CD3D11_DEFAULT()));
+ dsDesc.DepthEnable = FALSE;
+ dsDesc.StencilEnable = TRUE;
+ dsDesc.StencilWriteMask = 0x00;
+ dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_NEVER;
+ dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+ dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
+ dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_GREATER;
+ dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+ dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
+ dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ VD3D_(device->CreateDepthStencilState(&dsDesc, &states.ds.finish_volume));
+ }
+ {
+ // Read-Only Depth DS
+ CD3D11_DEPTH_STENCIL_DESC dsDesc((CD3D11_DEFAULT()));
+ dsDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
+ dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
+ VD3D_(device->CreateDepthStencilState(&dsDesc, &states.ds.read_only_depth));
+ }
+ // Blend State
+ {
+ CD3D11_BLEND_DESC bsDesc((CD3D11_DEFAULT()));
+ bsDesc.RenderTarget[0].RenderTargetWriteMask = 0x00000000;
+ VD3D_(device->CreateBlendState(&bsDesc, &states.bs.no_color));
+ }
+ {
+ CD3D11_BLEND_DESC bsDesc((CD3D11_DEFAULT()));
+ VD3D_(device->CreateBlendState(&bsDesc, &states.bs.no_blending));
+ }
+ {
+ CD3D11_BLEND_DESC bsDesc((CD3D11_DEFAULT()));
+ bsDesc.RenderTarget[0].BlendEnable = TRUE;
+ bsDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
+ bsDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_BLEND_FACTOR;
+ bsDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE;
+ bsDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
+ bsDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_BLEND_FACTOR;
+ bsDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
+ VD3D_(device->CreateBlendState(&bsDesc, &states.bs.additive));
+ }
+ {
+ CD3D11_BLEND_DESC bsDesc((CD3D11_DEFAULT()));
+ bsDesc.RenderTarget[0].BlendEnable = TRUE;
+ bsDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
+ bsDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_BLEND_FACTOR;
+ bsDesc.RenderTarget[0].DestBlend = D3D11_BLEND_SRC1_COLOR;
+ bsDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
+ bsDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO;
+ bsDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
+ VD3D_(device->CreateBlendState(&bsDesc, &states.bs.additive_modulate));
+ }
+ {
+ CD3D11_BLEND_DESC bsDesc((CD3D11_DEFAULT()));
+ bsDesc.RenderTarget[0].BlendEnable = TRUE;
+ bsDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
+ bsDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
+ bsDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
+ bsDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
+ bsDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO;
+ bsDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_SRC1_ALPHA;
+ VD3D_(device->CreateBlendState(&bsDesc, &states.bs.debug_blend));
+ }
+ return Status::OK;
+}
+
+/*==============================================================================
+ Constructor / Destructor
+==============================================================================*/
+
+ContextImp_D3D11::ContextImp_D3D11(const ContextDesc * pContextDesc) : ContextImp_Common(pContextDesc)
+{
+ shaders.Apply_PS = nullptr;
+ shaders.ComputeLightLUT_CS = nullptr;
+ shaders.ComputePhaseLookup_PS = nullptr;
+ shaders.Debug_PS = nullptr;
+ shaders.DownsampleDepth_PS = nullptr;
+ shaders.Quad_VS = nullptr;
+ shaders.RenderVolume_VS = nullptr;
+ shaders.RenderVolume_HS = nullptr;
+ shaders.RenderVolume_DS = nullptr;
+ shaders.RenderVolume_PS = nullptr;
+ shaders.Resolve_PS = nullptr;
+ shaders.TemporalFilter_PS = nullptr;
+
+ pPerContextCB = nullptr;
+ pPerFrameCB = nullptr;
+ pPerVolumeCB = nullptr;
+ pPerApplyCB = nullptr;
+
+ pDepth_ = nullptr;
+ pPhaseLUT_ = nullptr;
+ pLightLUT_P_[0] = nullptr;
+ pLightLUT_P_[1] = nullptr;
+ pLightLUT_S1_[0] = nullptr;
+ pLightLUT_S1_[1] = nullptr;
+ pLightLUT_S2_[0] = nullptr;
+ pLightLUT_S2_[1] = nullptr;
+ pAccumulation_ = nullptr;
+ pResolvedAccumulation_ = nullptr;
+ pResolvedDepth_ = nullptr;
+ for (int i=0; i<2; ++i)
+ {
+ pFilteredAccumulation_[i] = nullptr;
+ pFilteredDepth_[i] = nullptr;
+ }
+
+ states.rs.cull_none = nullptr;
+ states.rs.cull_front = nullptr;
+ states.rs.wireframe = nullptr;
+ states.ss.point = nullptr;
+ states.ss.linear = nullptr;
+ states.ds.no_depth = nullptr;
+ states.ds.write_only_depth = nullptr;
+ states.ds.read_only_depth = nullptr;
+ states.ds.render_volume = nullptr;
+ states.ds.render_volume_boundary = nullptr;
+ states.ds.render_volume_cap = nullptr;
+ states.ds.finish_volume = nullptr;
+ states.bs.no_color = nullptr;
+ states.bs.no_blending = nullptr;
+ states.bs.additive = nullptr;
+ states.bs.additive_modulate = nullptr;
+ states.bs.debug_blend = nullptr;
+}
+
+ContextImp_D3D11::~ContextImp_D3D11()
+{
+ SAFE_DELETE_ARRAY(shaders.Apply_PS);
+ SAFE_DELETE_ARRAY(shaders.ComputeLightLUT_CS);
+ SAFE_DELETE_ARRAY(shaders.ComputePhaseLookup_PS);
+ SAFE_DELETE_ARRAY(shaders.Debug_PS);
+ SAFE_DELETE_ARRAY(shaders.DownsampleDepth_PS);
+ SAFE_DELETE_ARRAY(shaders.Quad_VS);
+ SAFE_DELETE_ARRAY(shaders.RenderVolume_VS);
+ SAFE_DELETE_ARRAY(shaders.RenderVolume_HS);
+ SAFE_DELETE_ARRAY(shaders.RenderVolume_DS);
+ SAFE_DELETE_ARRAY(shaders.RenderVolume_PS);
+ SAFE_DELETE_ARRAY(shaders.Resolve_PS);
+ SAFE_DELETE_ARRAY(shaders.TemporalFilter_PS);
+
+ SAFE_DELETE(pPerContextCB);
+ SAFE_DELETE(pPerFrameCB);
+ SAFE_DELETE(pPerVolumeCB);
+ SAFE_DELETE(pPerApplyCB);
+
+ SAFE_DELETE(pDepth_);
+ SAFE_DELETE(pPhaseLUT_);
+ SAFE_DELETE(pLightLUT_P_[0]);
+ SAFE_DELETE(pLightLUT_P_[1]);
+ SAFE_DELETE(pLightLUT_S1_[0]);
+ SAFE_DELETE(pLightLUT_S1_[1]);
+ SAFE_DELETE(pLightLUT_S2_[0]);
+ SAFE_DELETE(pLightLUT_S2_[1]);
+ SAFE_DELETE(pAccumulation_);
+ SAFE_DELETE(pResolvedAccumulation_);
+ SAFE_DELETE(pResolvedDepth_);
+ for (int i = 0; i < 2; ++i)
+ {
+ SAFE_DELETE(pFilteredAccumulation_[i]);
+ SAFE_DELETE(pFilteredDepth_[i]);
+ }
+
+ SAFE_RELEASE(states.rs.cull_none);
+ SAFE_RELEASE(states.rs.cull_front);
+ SAFE_RELEASE(states.rs.wireframe);
+ SAFE_RELEASE(states.ss.point);
+ SAFE_RELEASE(states.ss.linear);
+ SAFE_RELEASE(states.ds.no_depth);
+ SAFE_RELEASE(states.ds.write_only_depth);
+ SAFE_RELEASE(states.ds.read_only_depth);
+ SAFE_RELEASE(states.ds.render_volume);
+ SAFE_RELEASE(states.ds.render_volume_boundary);
+ SAFE_RELEASE(states.ds.render_volume_cap);
+ SAFE_RELEASE(states.ds.finish_volume);
+ SAFE_RELEASE(states.bs.no_color);
+ SAFE_RELEASE(states.bs.no_blending);
+ SAFE_RELEASE(states.bs.additive);
+ SAFE_RELEASE(states.bs.additive_modulate);
+ SAFE_RELEASE(states.bs.debug_blend);
+}
+
+/*==============================================================================
+ BeginAccumulation
+==============================================================================*/
+
+Status ContextImp_D3D11::BeginAccumulation_Start(PlatformRenderCtx renderCtx, PlatformShaderResource sceneDepth, ViewerDesc const* pViewerDesc, MediumDesc const* pMediumDesc)
+{
+ ID3D11DeviceContext * dxCtx = renderCtx;
+
+ NV_PERFEVENT_BEGIN(dxCtx, "NvVl::BeginAccumulation");
+
+ if (!isInitialized_)
+ {
+ // Update the per-context constant buffer on the first frame it's used
+ isInitialized_ = true;
+ SetupCB_PerContext(pPerContextCB->Map(dxCtx));
+ pPerContextCB->Unmap(dxCtx);
+ }
+
+ // Setup the constant buffer
+ SetupCB_PerFrame(pViewerDesc, pMediumDesc, pPerFrameCB->Map(dxCtx));
+ pPerFrameCB->Unmap(dxCtx);
+
+ ID3D11Buffer* pCBs[] = {
+ pPerContextCB->getCB(),
+ pPerFrameCB->getCB(),
+ nullptr, // pPerVolumeCB - Invalid
+ nullptr // pPerApplyCB - Invalid
+ };
+ dxCtx->VSSetConstantBuffers(0, 4, pCBs);
+ dxCtx->PSSetConstantBuffers(0, 4, pCBs);
+
+ ID3D11SamplerState * pSamplers[] = {
+ states.ss.point,
+ states.ss.linear
+ };
+ dxCtx->PSSetSamplers(0, 2, pSamplers);
+
+ return Status::OK;
+}
+
+Status ContextImp_D3D11::BeginAccumulation_UpdateMediumLUT(PlatformRenderCtx renderCtx)
+{
+ ID3D11DeviceContext * dxCtx = renderCtx;
+ NV_PERFEVENT(dxCtx, "UpdateMediumLUT");
+
+ FLOAT black[] = {0,0,0,0};
+ dxCtx->ClearRenderTargetView(pPhaseLUT_->getRTV(), black);
+
+ D3D11_VIEWPORT viewport;
+ viewport.TopLeftX = 0.0f;
+ viewport.TopLeftY = 0.0f;
+ viewport.Width = 1;
+ viewport.Height = LIGHT_LUT_WDOTV_RESOLUTION;
+ viewport.MinDepth = 0.f;
+ viewport.MaxDepth = 1.f;
+ dxCtx->RSSetViewports(1, &viewport);
+
+ ID3D11RenderTargetView * RTVs[] = { pPhaseLUT_->getRTV() };
+ dxCtx->OMSetRenderTargets(1, RTVs, nullptr);
+ dxCtx->OMSetDepthStencilState(states.ds.no_depth, 0);
+ dxCtx->OMSetBlendState(states.bs.no_blending, nullptr, 0xFFFFFFFF);
+ dxCtx->PSSetShader(shaders.ComputePhaseLookup_PS[ComputePhaseLookup_PS::SINGLE], nullptr, 0);
+ V_( DrawFullscreen(dxCtx) );
+ return Status::OK;
+}
+
+Status ContextImp_D3D11::BeginAccumulation_CopyDepth(PlatformRenderCtx renderCtx, PlatformShaderResource sceneDepth)
+{
+ ID3D11DeviceContext * dxCtx = renderCtx;
+ ID3D11ShaderResourceView * sceneDepth_SRV = sceneDepth;
+ NV_PERFEVENT(dxCtx, "CopyDepth");
+
+ dxCtx->ClearDepthStencilView(pDepth_->getDSV(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
+
+ D3D11_VIEWPORT viewport;
+ viewport.TopLeftX = 0.0f;
+ viewport.TopLeftY = 0.0f;
+ viewport.Width = static_cast<float>(getInternalViewportWidth());
+ viewport.Height = static_cast<float>(getInternalViewportHeight());
+ viewport.MinDepth = 0.f;
+ viewport.MaxDepth = 1.f;
+ dxCtx->RSSetViewports(1, &viewport);
+
+ dxCtx->PSSetShaderResources(0, 1, &sceneDepth_SRV);
+ ID3D11RenderTargetView * NULL_RTVs[] = { nullptr };
+ dxCtx->OMSetRenderTargets(1, NULL_RTVs, pDepth_->getDSV());
+ dxCtx->OMSetDepthStencilState(states.ds.write_only_depth, 0);
+ dxCtx->OMSetBlendState(states.bs.no_color, nullptr, 0xFFFFFFFF);
+ DownsampleDepth_PS::Desc ps_desc = DownsampleDepth_PS::Desc(isOutputMSAA() ? DownsampleDepth_PS::SAMPLEMODE_MSAA : DownsampleDepth_PS::SAMPLEMODE_SINGLE);
+ dxCtx->PSSetShader(shaders.DownsampleDepth_PS[ps_desc], nullptr, 0);
+ V_( DrawFullscreen(dxCtx) );
+ return Status::OK;
+}
+
+Status ContextImp_D3D11::BeginAccumulation_End(PlatformRenderCtx renderCtx, PlatformShaderResource sceneDepth, ViewerDesc const* pViewerDesc, MediumDesc const* pMediumDesc)
+{
+ ID3D11DeviceContext * dxCtx = renderCtx;
+ FLOAT black[] = {0,0,0,0};
+ dxCtx->ClearRenderTargetView(pAccumulation_->getRTV(), black);
+
+ NV_PERFEVENT_END(dxCtx);
+ return Status::OK;
+}
+
+/*==============================================================================
+ RenderVolume
+==============================================================================*/
+Status ContextImp_D3D11::RenderVolume_Start(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc)
+{
+ ID3D11DeviceContext * dxCtx = renderCtx;
+ NV_PERFEVENT_BEGIN(dxCtx, "NvVl::RenderVolume");
+
+ // Setup the constant buffer
+ SetupCB_PerVolume(pShadowMapDesc, pLightDesc, pVolumeDesc, pPerVolumeCB->Map(dxCtx));
+ pPerVolumeCB->Unmap(dxCtx);
+
+ dxCtx->ClearDepthStencilView(pDepth_->getDSV(), D3D11_CLEAR_STENCIL, 1.0f, STENCIL_REF);
+
+ // Set up all the state common for this pass
+ ID3D11Buffer * pCBs[] = {
+ pPerContextCB->getCB(),
+ pPerFrameCB->getCB(),
+ pPerVolumeCB->getCB(),
+ nullptr // pPerApplyCB: Invalid
+ };
+ dxCtx->VSSetConstantBuffers(0, 4, pCBs);
+ dxCtx->HSSetConstantBuffers(0, 4, pCBs);
+ dxCtx->DSSetConstantBuffers(0, 4, pCBs);
+ dxCtx->PSSetConstantBuffers(0, 4, pCBs);
+ dxCtx->CSSetConstantBuffers(0, 4, pCBs);
+
+ ID3D11SamplerState * pSamplers[] = {
+ states.ss.point,
+ states.ss.linear
+ };
+ dxCtx->VSSetSamplers(0, 2, pSamplers);
+ dxCtx->HSSetSamplers(0, 2, pSamplers);
+ dxCtx->DSSetSamplers(0, 2, pSamplers);
+ dxCtx->PSSetSamplers(0, 2, pSamplers);
+ dxCtx->CSSetSamplers(0, 2, pSamplers);
+
+ return Status::OK;
+}
+
+Status ContextImp_D3D11::RenderVolume_DoVolume_Directional(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc)
+{
+ ID3D11DeviceContext * dxCtx = renderCtx;
+ ID3D11ShaderResourceView * pShadowMap_SRV = shadowMap.d3d11;
+
+ NV_PERFEVENT(dxCtx, "Directional");
+
+ uint32_t mesh_resolution = getCoarseResolution(pVolumeDesc);
+
+ //--------------------------------------------------------------------------
+ // Draw tessellated grid
+
+ D3D11_VIEWPORT viewport;
+ viewport.TopLeftX = 0.0f;
+ viewport.TopLeftY = 0.0f;
+ viewport.Width = static_cast<float>(getInternalViewportWidth());
+ viewport.Height = static_cast<float>(getInternalViewportHeight());
+ viewport.MinDepth = 0.f;
+ viewport.MaxDepth = 1.f;
+ dxCtx->RSSetViewports(1, &viewport);
+ dxCtx->RSSetState(states.rs.cull_none);
+ dxCtx->OMSetBlendState(states.bs.additive, nullptr, 0xFFFFFFFF);
+
+ ID3D11RenderTargetView * RTVs[] = { pAccumulation_->getRTV() };
+ dxCtx->OMSetRenderTargets(1, RTVs, pDepth_->getDSV());
+
+ // Determine DS/HS permutation
+ RenderVolume_HS::Desc hs_desc;
+ hs_desc.flags.MAXTESSFACTOR = (RenderVolume_HS::eMAXTESSFACTOR) pVolumeDesc->eTessQuality;
+
+ RenderVolume_DS::Desc ds_desc;
+
+ switch (pShadowMapDesc->eType)
+ {
+ case ShadowMapLayout::SIMPLE:
+ case ShadowMapLayout::CASCADE_ATLAS:
+ hs_desc.flags.SHADOWMAPTYPE = RenderVolume_HS::SHADOWMAPTYPE_ATLAS;
+ ds_desc.flags.SHADOWMAPTYPE = RenderVolume_DS::SHADOWMAPTYPE_ATLAS;
+ break;
+
+ case ShadowMapLayout::CASCADE_ARRAY:
+ hs_desc.flags.SHADOWMAPTYPE = RenderVolume_HS::SHADOWMAPTYPE_ARRAY;
+ ds_desc.flags.SHADOWMAPTYPE = RenderVolume_DS::SHADOWMAPTYPE_ARRAY;
+ break;
+
+ default:
+ return Status::INVALID_PARAMETER;
+ };
+
+ switch (pShadowMapDesc->uElementCount)
+ {
+ case 0:
+ if (pShadowMapDesc->eType != ShadowMapLayout::SIMPLE)
+ {
+ return Status::INVALID_PARAMETER;
+ }
+ case 1:
+ hs_desc.flags.CASCADECOUNT = RenderVolume_HS::CASCADECOUNT_1;
+ ds_desc.flags.CASCADECOUNT = RenderVolume_DS::CASCADECOUNT_1;
+ break;
+
+ case 2:
+ hs_desc.flags.CASCADECOUNT = RenderVolume_HS::CASCADECOUNT_2;
+ ds_desc.flags.CASCADECOUNT = RenderVolume_DS::CASCADECOUNT_2;
+ break;
+
+ case 3:
+ hs_desc.flags.CASCADECOUNT = RenderVolume_HS::CASCADECOUNT_3;
+ ds_desc.flags.CASCADECOUNT = RenderVolume_DS::CASCADECOUNT_3;
+ break;
+
+ case 4:
+ hs_desc.flags.CASCADECOUNT = RenderVolume_HS::CASCADECOUNT_4;
+ ds_desc.flags.CASCADECOUNT = RenderVolume_DS::CASCADECOUNT_4;
+ break;
+
+ default:
+ return Status::INVALID_PARAMETER;
+ };
+ hs_desc.flags.VOLUMETYPE = RenderVolume_HS::VOLUMETYPE_FRUSTUM;
+ ds_desc.flags.VOLUMETYPE = RenderVolume_DS::VOLUMETYPE_FRUSTUM;
+
+ // Determine PS permutation
+ RenderVolume_PS::Desc ps_desc;
+ ps_desc.flags.SAMPLEMODE = isInternalMSAA() ? RenderVolume_PS::SAMPLEMODE_MSAA : RenderVolume_PS::SAMPLEMODE_SINGLE;
+ ps_desc.flags.LIGHTMODE = RenderVolume_PS::LIGHTMODE_DIRECTIONAL;
+ ps_desc.flags.PASSMODE = RenderVolume_PS::PASSMODE_GEOMETRY;
+ ps_desc.flags.ATTENUATIONMODE = RenderVolume_PS::ATTENUATIONMODE_NONE; // unused for directional
+
+ dxCtx->HSSetShader(shaders.RenderVolume_HS[hs_desc], nullptr, 0);
+ dxCtx->DSSetShader(shaders.RenderVolume_DS[ds_desc], nullptr, 0);
+ dxCtx->PSSetShader(shaders.RenderVolume_PS[ps_desc], nullptr, 0);
+
+ ID3D11ShaderResourceView * SRVs[] = {
+ nullptr,
+ pShadowMap_SRV,
+ nullptr,
+ nullptr,
+ pPhaseLUT_->getSRV(),
+ };
+ dxCtx->VSSetShaderResources(0, 5, SRVs);
+ dxCtx->HSSetShaderResources(0, 5, SRVs);
+ dxCtx->DSSetShaderResources(0, 5, SRVs);
+ dxCtx->PSSetShaderResources(0, 5, SRVs);
+
+ dxCtx->OMSetDepthStencilState(states.ds.render_volume, STENCIL_REF);
+
+ DrawFrustumGrid(dxCtx, mesh_resolution);
+ dxCtx->HSSetShader(nullptr, nullptr, 0);
+ dxCtx->DSSetShader(nullptr, nullptr, 0);
+
+ //--------------------------------------------------------------------------
+ // Remove the illumination from the base of the scene (re-lit by sky later)
+ DrawFrustumBase(dxCtx, mesh_resolution);
+
+ //--------------------------------------------------------------------------
+ // Render the bounds of the frustum
+ if (debugFlags_ & (uint32_t)DebugFlags::WIREFRAME)
+ return Status::OK;
+
+ ps_desc.flags.PASSMODE = RenderVolume_PS::PASSMODE_SKY;
+ dxCtx->PSSetShader(shaders.RenderVolume_PS[ps_desc], nullptr, 0);
+ dxCtx->OMSetDepthStencilState(states.ds.render_volume_boundary, STENCIL_REF);
+ DrawFullscreen(dxCtx);
+
+ //--------------------------------------------------------------------------
+ // Finish the rendering by filling in stenciled gaps
+ dxCtx->OMSetDepthStencilState(states.ds.finish_volume, STENCIL_REF);
+ dxCtx->OMSetRenderTargets(1, RTVs, pDepth_->getReadOnlyDSV());
+ SRVs[2] = pDepth_->getSRV();
+ dxCtx->PSSetShaderResources(2, 1, &SRVs[2]);
+ ps_desc.flags.PASSMODE = RenderVolume_PS::PASSMODE_FINAL;
+ dxCtx->PSSetShader(shaders.RenderVolume_PS[ps_desc], nullptr, 0);
+ DrawFullscreen(dxCtx);
+
+ return Status::OK;
+}
+
+Status ContextImp_D3D11::RenderVolume_DoVolume_Spotlight(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc)
+{
+ ID3D11DeviceContext * dxCtx = renderCtx;
+ ID3D11ShaderResourceView * pShadowMap_SRV = shadowMap.d3d11;
+
+ NV_PERFEVENT(dxCtx, "Spotlight");
+
+ uint32_t mesh_resolution = getCoarseResolution(pVolumeDesc);
+
+ ID3D11ShaderResourceView * SRVs[16] = { nullptr };
+ ID3D11UnorderedAccessView * UAVs[16] = { nullptr };
+
+ //--------------------------------------------------------------------------
+ // Create look-up table
+ if (pLightDesc->Spotlight.eFalloffMode == SpotlightFalloffMode::NONE)
+ {
+ NV_PERFEVENT(dxCtx, "Generate Light LUT");
+ ComputeLightLUT_CS::Desc cs_desc;
+ cs_desc.flags.LIGHTMODE = ComputeLightLUT_CS::LIGHTMODE_OMNI;
+ cs_desc.flags.ATTENUATIONMODE = (ComputeLightLUT_CS::eATTENUATIONMODE) pLightDesc->Spotlight.eAttenuationMode;
+
+ UAVs[0] = pLightLUT_P_[0]->getUAV();
+ dxCtx->CSSetUnorderedAccessViews(0, 1, UAVs, 0);
+ SRVs[4] = pPhaseLUT_->getSRV();
+ dxCtx->CSSetShaderResources(0, 6, SRVs);
+ cs_desc.flags.COMPUTEPASS = ComputeLightLUT_CS::COMPUTEPASS_CALCULATE;
+ dxCtx->CSSetShader(shaders.ComputeLightLUT_CS[cs_desc], nullptr, 0);
+ dxCtx->Dispatch(LIGHT_LUT_DEPTH_RESOLUTION / 32, LIGHT_LUT_WDOTV_RESOLUTION / 8, 1);
+
+ UAVs[0] = pLightLUT_P_[1]->getUAV();
+ dxCtx->CSSetUnorderedAccessViews(0, 1, UAVs, 0);
+ SRVs[5] = pLightLUT_P_[0]->getSRV();
+ dxCtx->CSSetShaderResources(0, 6, SRVs);
+ cs_desc.flags.COMPUTEPASS = ComputeLightLUT_CS::COMPUTEPASS_SUM;
+ dxCtx->CSSetShader(shaders.ComputeLightLUT_CS[cs_desc], nullptr, 0);
+ dxCtx->Dispatch(1, LIGHT_LUT_WDOTV_RESOLUTION / 4, 1);
+
+ dxCtx->CSSetShader(nullptr, nullptr, 0);
+ UAVs[0] = nullptr;
+ dxCtx->CSSetUnorderedAccessViews(0, 1, UAVs, 0);
+ }
+ else if (pLightDesc->Spotlight.eFalloffMode == SpotlightFalloffMode::FIXED)
+ {
+ NV_PERFEVENT(dxCtx, "Generate Light LUT");
+ ComputeLightLUT_CS::Desc cs_desc;
+ cs_desc.flags.LIGHTMODE = ComputeLightLUT_CS::LIGHTMODE_SPOTLIGHT;
+ cs_desc.flags.ATTENUATIONMODE = (ComputeLightLUT_CS::eATTENUATIONMODE) pLightDesc->Spotlight.eAttenuationMode;
+
+ UAVs[0] = pLightLUT_P_[0]->getUAV();
+ UAVs[1] = pLightLUT_S1_[0]->getUAV();
+ UAVs[2] = pLightLUT_S2_[0]->getUAV();
+ dxCtx->CSSetUnorderedAccessViews(0, 3, UAVs, 0);
+ SRVs[4] = pPhaseLUT_->getSRV();
+ dxCtx->CSSetShaderResources(0, 8, SRVs);
+ cs_desc.flags.COMPUTEPASS = ComputeLightLUT_CS::COMPUTEPASS_CALCULATE;
+ dxCtx->CSSetShader(shaders.ComputeLightLUT_CS[cs_desc], nullptr, 0);
+ dxCtx->Dispatch(LIGHT_LUT_DEPTH_RESOLUTION / 32, LIGHT_LUT_WDOTV_RESOLUTION / 8, 1);
+
+ UAVs[0] = pLightLUT_P_[1]->getUAV();
+ UAVs[1] = pLightLUT_S1_[1]->getUAV();
+ UAVs[2] = pLightLUT_S2_[1]->getUAV();
+ dxCtx->CSSetUnorderedAccessViews(0, 3, UAVs, 0);
+ SRVs[5] = pLightLUT_P_[0]->getSRV();
+ SRVs[6] = pLightLUT_S1_[0]->getSRV();
+ SRVs[7] = pLightLUT_S2_[0]->getSRV();
+ dxCtx->CSSetShaderResources(0, 8, SRVs);
+ cs_desc.flags.COMPUTEPASS = ComputeLightLUT_CS::COMPUTEPASS_SUM;
+ dxCtx->CSSetShader(shaders.ComputeLightLUT_CS[cs_desc], nullptr, 0);
+ dxCtx->Dispatch(1, LIGHT_LUT_WDOTV_RESOLUTION / 4, 3);
+
+ dxCtx->CSSetShader(nullptr, nullptr, 0);
+ UAVs[0] = nullptr;
+ UAVs[1] = nullptr;
+ UAVs[2] = nullptr;
+ dxCtx->CSSetUnorderedAccessViews(0, 3, UAVs, 0);
+ }
+
+ //--------------------------------------------------------------------------
+ // Draw tessellated grid
+
+ D3D11_VIEWPORT viewport;
+ viewport.TopLeftX = 0.0f;
+ viewport.TopLeftY = 0.0f;
+ viewport.Width = static_cast<float>(getInternalViewportWidth());
+ viewport.Height = static_cast<float>(getInternalViewportHeight());
+ viewport.MinDepth = 0.f;
+ viewport.MaxDepth = 1.f;
+ dxCtx->RSSetViewports(1, &viewport);
+ dxCtx->RSSetState(states.rs.cull_none);
+ dxCtx->OMSetBlendState(states.bs.additive, nullptr, 0xFFFFFFFF);
+
+ ID3D11RenderTargetView * RTVs[] = { pAccumulation_->getRTV() };
+ dxCtx->OMSetRenderTargets(1, RTVs, pDepth_->getDSV());
+
+ // Determine DS/HS permutation
+ RenderVolume_HS::Desc hs_desc;
+ hs_desc.flags.SHADOWMAPTYPE = RenderVolume_HS::SHADOWMAPTYPE_ATLAS;
+ hs_desc.flags.CASCADECOUNT = RenderVolume_HS::CASCADECOUNT_1;
+ hs_desc.flags.VOLUMETYPE = RenderVolume_HS::VOLUMETYPE_FRUSTUM;
+ hs_desc.flags.MAXTESSFACTOR = (RenderVolume_HS::eMAXTESSFACTOR) pVolumeDesc->eTessQuality;
+
+ RenderVolume_DS::Desc ds_desc;
+ ds_desc.flags.SHADOWMAPTYPE = RenderVolume_DS::SHADOWMAPTYPE_ATLAS;
+ ds_desc.flags.CASCADECOUNT = RenderVolume_DS::CASCADECOUNT_1;
+ ds_desc.flags.VOLUMETYPE = RenderVolume_DS::VOLUMETYPE_FRUSTUM;
+
+ // Determine PS permutation
+ RenderVolume_PS::Desc ps_desc;
+ ps_desc.flags.SAMPLEMODE = isInternalMSAA() ? RenderVolume_PS::SAMPLEMODE_MSAA : RenderVolume_PS::SAMPLEMODE_SINGLE;
+ ps_desc.flags.LIGHTMODE = RenderVolume_PS::LIGHTMODE_SPOTLIGHT;
+ ps_desc.flags.PASSMODE = RenderVolume_PS::PASSMODE_GEOMETRY;
+ ps_desc.flags.ATTENUATIONMODE = (RenderVolume_PS::eATTENUATIONMODE) pLightDesc->Spotlight.eAttenuationMode;
+ ps_desc.flags.FALLOFFMODE = (RenderVolume_PS::eFALLOFFMODE) pLightDesc->Spotlight.eFalloffMode;
+
+ dxCtx->HSSetShader(shaders.RenderVolume_HS[hs_desc], nullptr, 0);
+ dxCtx->DSSetShader(shaders.RenderVolume_DS[ds_desc], nullptr, 0);
+ dxCtx->PSSetShader(shaders.RenderVolume_PS[ps_desc], nullptr, 0);
+
+ SRVs[1] = pShadowMap_SRV;
+ SRVs[4] = pPhaseLUT_->getSRV();
+ SRVs[5] = pLightLUT_P_[1]->getSRV();
+ SRVs[6] = pLightLUT_S1_[1]->getSRV();
+ SRVs[7] = pLightLUT_S2_[1]->getSRV();
+ dxCtx->VSSetShaderResources(0, 8, SRVs);
+ dxCtx->HSSetShaderResources(0, 8, SRVs);
+ dxCtx->DSSetShaderResources(0, 8, SRVs);
+ dxCtx->PSSetShaderResources(0, 8, SRVs);
+
+ dxCtx->OMSetDepthStencilState(states.ds.render_volume, STENCIL_REF);
+ DrawFrustumGrid(dxCtx, mesh_resolution);
+ dxCtx->HSSetShader(nullptr, nullptr, 0);
+ dxCtx->DSSetShader(nullptr, nullptr, 0);
+
+ //--------------------------------------------------------------------------
+ // Render the bounds of the spotlight volume
+ dxCtx->RSSetState(states.rs.cull_front);
+ DrawFrustumCap(dxCtx, mesh_resolution);
+
+ //--------------------------------------------------------------------------
+ // Finish the rendering by filling in stenciled gaps
+ dxCtx->OMSetDepthStencilState(states.ds.finish_volume, STENCIL_REF);
+ dxCtx->OMSetRenderTargets(1, RTVs, pDepth_->getReadOnlyDSV());
+ SRVs[2] = pDepth_->getSRV();
+ dxCtx->PSSetShaderResources(2, 1, &SRVs[2]);
+ ps_desc.flags.PASSMODE = RenderVolume_PS::PASSMODE_FINAL;
+ dxCtx->PSSetShader(shaders.RenderVolume_PS[ps_desc], nullptr, 0);
+ DrawFullscreen(dxCtx);
+
+ return Status::OK;
+}
+
+Status ContextImp_D3D11::RenderVolume_DoVolume_Omni(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc)
+{
+ ID3D11DeviceContext * dxCtx = renderCtx;
+ ID3D11ShaderResourceView * pShadowMap_SRV = shadowMap.d3d11;
+
+ NV_PERFEVENT(dxCtx, "Omni");
+
+ uint32_t mesh_resolution = getCoarseResolution(pVolumeDesc);
+
+ ID3D11ShaderResourceView * SRVs[] = {
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr
+ };
+
+ ID3D11UnorderedAccessView * UAVs[] = {
+ nullptr
+ };
+
+ //--------------------------------------------------------------------------
+ // Create look-up table
+ {
+ NV_PERFEVENT(dxCtx, "Generate Light LUT");
+ ComputeLightLUT_CS::Desc cs_desc;
+ cs_desc.flags.LIGHTMODE = ComputeLightLUT_CS::LIGHTMODE_OMNI;
+ cs_desc.flags.ATTENUATIONMODE = (ComputeLightLUT_CS::eATTENUATIONMODE) pLightDesc->Omni.eAttenuationMode;
+
+ UAVs[0] = pLightLUT_P_[0]->getUAV();
+ dxCtx->CSSetUnorderedAccessViews(0, 1, UAVs, 0);
+ SRVs[4] = pPhaseLUT_->getSRV();
+ dxCtx->CSSetShaderResources(0, 6, SRVs);
+ cs_desc.flags.COMPUTEPASS = ComputeLightLUT_CS::COMPUTEPASS_CALCULATE;
+ dxCtx->CSSetShader(shaders.ComputeLightLUT_CS[cs_desc], nullptr, 0);
+ dxCtx->Dispatch(LIGHT_LUT_DEPTH_RESOLUTION / 32, LIGHT_LUT_WDOTV_RESOLUTION / 8, 1);
+
+ UAVs[0] = pLightLUT_P_[1]->getUAV();
+ dxCtx->CSSetUnorderedAccessViews(0, 1, UAVs, 0);
+ SRVs[5] = pLightLUT_P_[0]->getSRV();
+ dxCtx->CSSetShaderResources(0, 6, SRVs);
+ cs_desc.flags.COMPUTEPASS = ComputeLightLUT_CS::COMPUTEPASS_SUM;
+ dxCtx->CSSetShader(shaders.ComputeLightLUT_CS[cs_desc], nullptr, 0);
+ dxCtx->Dispatch(1, LIGHT_LUT_WDOTV_RESOLUTION / 4, 1);
+
+ dxCtx->CSSetShader(nullptr, nullptr, 0);
+ UAVs[0] = nullptr;
+ dxCtx->CSSetUnorderedAccessViews(0, 1, UAVs, 0);
+ }
+
+ //--------------------------------------------------------------------------
+ // Draw tessellated grid
+ D3D11_VIEWPORT viewport;
+ viewport.TopLeftX = 0.0f;
+ viewport.TopLeftY = 0.0f;
+ viewport.Width = static_cast<float>(getInternalViewportWidth());
+ viewport.Height = static_cast<float>(getInternalViewportHeight());
+ viewport.MinDepth = 0.f;
+ viewport.MaxDepth = 1.f;
+ dxCtx->RSSetViewports(1, &viewport);
+ dxCtx->RSSetState(states.rs.cull_none);
+ dxCtx->OMSetBlendState(states.bs.additive, nullptr, 0xFFFFFFFF);
+
+ ID3D11RenderTargetView * RTVs[] = { pAccumulation_->getRTV() };
+ dxCtx->OMSetRenderTargets(1, RTVs, pDepth_->getDSV());
+
+ // Determine DS/HS permutation
+ RenderVolume_HS::Desc hs_desc;
+ hs_desc.flags.SHADOWMAPTYPE = RenderVolume_HS::SHADOWMAPTYPE_ARRAY;
+ hs_desc.flags.CASCADECOUNT = RenderVolume_HS::CASCADECOUNT_1;
+ hs_desc.flags.VOLUMETYPE = RenderVolume_HS::VOLUMETYPE_PARABOLOID;
+ hs_desc.flags.MAXTESSFACTOR = (RenderVolume_HS::eMAXTESSFACTOR) pVolumeDesc->eTessQuality;
+
+ RenderVolume_DS::Desc ds_desc;
+ ds_desc.flags.SHADOWMAPTYPE = RenderVolume_DS::SHADOWMAPTYPE_ARRAY;
+ ds_desc.flags.CASCADECOUNT = RenderVolume_DS::CASCADECOUNT_1;
+ ds_desc.flags.VOLUMETYPE = RenderVolume_DS::VOLUMETYPE_PARABOLOID;
+
+ // Determine PS permutation
+ RenderVolume_PS::Desc ps_desc;
+ ps_desc.flags.SAMPLEMODE = isInternalMSAA() ? RenderVolume_PS::SAMPLEMODE_MSAA : RenderVolume_PS::SAMPLEMODE_SINGLE;
+ ps_desc.flags.LIGHTMODE = RenderVolume_PS::LIGHTMODE_OMNI;
+ ps_desc.flags.PASSMODE = RenderVolume_PS::PASSMODE_GEOMETRY;
+ ps_desc.flags.ATTENUATIONMODE = (RenderVolume_PS::eATTENUATIONMODE) pLightDesc->Omni.eAttenuationMode;
+
+ dxCtx->HSSetShader(shaders.RenderVolume_HS[hs_desc], nullptr, 0);
+ dxCtx->DSSetShader(shaders.RenderVolume_DS[ds_desc], nullptr, 0);
+ dxCtx->PSSetShader(shaders.RenderVolume_PS[ps_desc], nullptr, 0);
+
+ SRVs[1] = pShadowMap_SRV;
+ SRVs[5] = pLightLUT_P_[1]->getSRV();
+ dxCtx->VSSetShaderResources(0, 6, SRVs);
+ dxCtx->HSSetShaderResources(0, 6, SRVs);
+ dxCtx->DSSetShaderResources(0, 6, SRVs);
+ dxCtx->PSSetShaderResources(0, 6, SRVs);
+
+ dxCtx->OMSetDepthStencilState(states.ds.render_volume, STENCIL_REF);
+ DrawOmniVolume(dxCtx, mesh_resolution);
+ dxCtx->HSSetShader(nullptr, nullptr, 0);
+ dxCtx->DSSetShader(nullptr, nullptr, 0);
+
+ //--------------------------------------------------------------------------
+ // Finish the rendering by filling in stenciled gaps
+ dxCtx->OMSetDepthStencilState(states.ds.finish_volume, STENCIL_REF);
+ dxCtx->OMSetRenderTargets(1, RTVs, pDepth_->getReadOnlyDSV());
+ SRVs[2] = pDepth_->getSRV();
+ dxCtx->PSSetShaderResources(2, 1, &SRVs[2]);
+ ps_desc.flags.PASSMODE = RenderVolume_PS::PASSMODE_FINAL;
+ dxCtx->PSSetShader(shaders.RenderVolume_PS[ps_desc], nullptr, 0);
+ DrawFullscreen(dxCtx);
+
+ return Status::OK;
+}
+
+Status ContextImp_D3D11::RenderVolume_End(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc)
+{
+ ID3D11DeviceContext * dxCtx = renderCtx;
+ ID3D11RenderTargetView * NULL_RTV = nullptr;
+ dxCtx->OMSetRenderTargets(1, &NULL_RTV, nullptr);
+ NV_PERFEVENT_END(dxCtx);
+ return Status::OK;
+}
+
+/*==============================================================================
+ EndAccumulation
+==============================================================================*/
+Status ContextImp_D3D11::EndAccumulation_Imp(PlatformRenderCtx renderCtx)
+{
+ ID3D11DeviceContext * dxCtx = renderCtx;
+ dxCtx;
+ return Status::OK;
+}
+
+/*==============================================================================
+ ApplyLighting
+==============================================================================*/
+Status ContextImp_D3D11::ApplyLighting_Start(PlatformRenderCtx renderCtx, PlatformRenderTarget sceneTarget, PlatformShaderResource sceneDepth, PostprocessDesc const* pPostprocessDesc)
+{
+ ID3D11DeviceContext * dxCtx = renderCtx;
+
+ NV_PERFEVENT_BEGIN(dxCtx, "NvVl::ApplyLighting");
+
+ // Setup the constant buffer
+ SetupCB_PerApply(pPostprocessDesc, pPerApplyCB->Map(dxCtx));
+ pPerApplyCB->Unmap(dxCtx);
+
+ ID3D11Buffer* pCBs[] = {
+ pPerContextCB->getCB(),
+ pPerFrameCB->getCB(),
+ nullptr, // pPerVolumeCB - Invalid
+ pPerApplyCB->getCB(),
+ };
+ dxCtx->VSSetConstantBuffers(0, 4, pCBs);
+ dxCtx->PSSetConstantBuffers(0, 4, pCBs);
+
+ ID3D11SamplerState * pSamplers[] = {
+ states.ss.point,
+ states.ss.linear
+ };
+ dxCtx->PSSetSamplers(0, 2, pSamplers);
+ dxCtx->OMSetDepthStencilState(states.ds.no_depth, 0xFF);
+ dxCtx->OMSetBlendState(states.bs.no_blending, nullptr, 0xFFFFFFFF);
+
+ D3D11_VIEWPORT viewport;
+ viewport.TopLeftX = 0.0f;
+ viewport.TopLeftY = 0.0f;
+ viewport.Width = static_cast<float>(getInternalViewportWidth());
+ viewport.Height = static_cast<float>(getInternalViewportHeight());
+ viewport.MinDepth = 0.f;
+ viewport.MaxDepth = 1.f;
+ dxCtx->RSSetViewports(1, &viewport);
+
+ pAccumulatedOutput_ = pAccumulation_;
+
+ return Status::OK;
+}
+
+Status ContextImp_D3D11::ApplyLighting_Resolve(PlatformRenderCtx renderCtx, PostprocessDesc const* pPostprocessDesc)
+{
+ ID3D11DeviceContext * dxCtx = renderCtx;
+
+ NV_PERFEVENT(dxCtx, "Resolve");
+
+ Resolve_PS::Desc ps_desc;
+ ps_desc.flags.SAMPLEMODE = isInternalMSAA() ? Resolve_PS::SAMPLEMODE_MSAA : Resolve_PS::SAMPLEMODE_SINGLE;
+ dxCtx->PSSetShader(shaders.Resolve_PS[ps_desc], nullptr, 0);
+ ID3D11ShaderResourceView * SRVs[] = {
+ pAccumulation_->getSRV(),
+ pDepth_->getSRV()
+ };
+ dxCtx->PSSetShaderResources(0, 2, SRVs);
+ ID3D11RenderTargetView * RTVs[] = {
+ pResolvedAccumulation_->getRTV(),
+ pResolvedDepth_->getRTV()
+ };
+ dxCtx->OMSetRenderTargets(2, RTVs, nullptr);
+ DrawFullscreen(dxCtx);
+ pAccumulatedOutput_ = pResolvedAccumulation_;
+ ID3D11RenderTargetView * NULL_RTVs[] = { nullptr, nullptr };
+ dxCtx->OMSetRenderTargets(2, NULL_RTVs, nullptr);
+ return Status::OK;
+}
+
+Status ContextImp_D3D11::ApplyLighting_TemporalFilter(PlatformRenderCtx renderCtx, PlatformShaderResource sceneDepth, PostprocessDesc const* pPostprocessDesc)
+{
+ ID3D11DeviceContext * dxCtx = renderCtx;
+
+ NV_PERFEVENT(dxCtx, "TemporalFilter");
+
+ dxCtx->PSSetShader(shaders.TemporalFilter_PS[TemporalFilter_PS::SINGLE], nullptr, 0);
+ ID3D11ShaderResourceView * SRVs[] = {
+ pResolvedAccumulation_->getSRV(),
+ pFilteredAccumulation_[lastFrameIndex_]->getSRV(),
+ pResolvedDepth_->getSRV(),
+ nullptr,
+ pFilteredDepth_[lastFrameIndex_]->getSRV()
+ };
+ dxCtx->PSSetShaderResources(0, 4, SRVs);
+ ID3D11RenderTargetView * RTVs[] = {
+ pFilteredAccumulation_[nextFrameIndex_]->getRTV(),
+ pFilteredDepth_[nextFrameIndex_]->getRTV()
+ };
+ dxCtx->OMSetRenderTargets(2, RTVs, nullptr);
+ DrawFullscreen(dxCtx);
+ pAccumulatedOutput_ = pFilteredAccumulation_[nextFrameIndex_];
+ ID3D11RenderTargetView * NULL_RTVs[] = { nullptr, nullptr };
+ dxCtx->OMSetRenderTargets(2, NULL_RTVs, nullptr);
+ return Status::OK;
+}
+
+Status ContextImp_D3D11::ApplyLighting_Composite(PlatformRenderCtx renderCtx, PlatformRenderTarget sceneTarget, PlatformShaderResource sceneDepth, PostprocessDesc const* pPostprocessDesc)
+{
+ ID3D11DeviceContext * dxCtx = renderCtx;
+ ID3D11RenderTargetView * pScene_RTV = sceneTarget.d3d11;
+ ID3D11ShaderResourceView * pSceneDepth_SRV = sceneDepth.d3d11;
+
+ NV_PERFEVENT(dxCtx, "Composite");
+
+ D3D11_VIEWPORT viewport;
+ viewport.TopLeftX = 0.0f;
+ viewport.TopLeftY = 0.0f;
+ viewport.Width = static_cast<float>(getOutputViewportWidth());
+ viewport.Height = static_cast<float>(getOutputViewportHeight());
+ viewport.MinDepth = 0.f;
+ viewport.MaxDepth = 1.f;
+ dxCtx->RSSetViewports(1, &viewport);
+
+ if (debugFlags_ & (uint32_t)DebugFlags::NO_BLENDING)
+ {
+ dxCtx->OMSetBlendState(states.bs.debug_blend, nullptr, 0xFFFFFFFF);
+ }
+ else
+ {
+ FLOAT blend_factor[] = { pPostprocessDesc->fBlendfactor, pPostprocessDesc->fBlendfactor, pPostprocessDesc->fBlendfactor, pPostprocessDesc->fBlendfactor };
+ dxCtx->OMSetBlendState(states.bs.additive_modulate, blend_factor, 0xFFFFFFFF);
+ }
+ dxCtx->OMSetRenderTargets(1, &pScene_RTV, nullptr);
+
+ Apply_PS::Desc ps_desc;
+ ps_desc.flags.SAMPLEMODE = isOutputMSAA() ? Apply_PS::SAMPLEMODE_MSAA : Apply_PS::SAMPLEMODE_SINGLE;
+ switch (pPostprocessDesc->eUpsampleQuality)
+ {
+ default:
+ case UpsampleQuality::POINT:
+ ps_desc.flags.UPSAMPLEMODE = Apply_PS::UPSAMPLEMODE_POINT;
+ break;
+
+ case UpsampleQuality::BILINEAR:
+ ps_desc.flags.UPSAMPLEMODE = Apply_PS::UPSAMPLEMODE_BILINEAR;
+ break;
+
+ case UpsampleQuality::BILATERAL:
+ ps_desc.flags.UPSAMPLEMODE = Apply_PS::UPSAMPLEMODE_BILATERAL;
+ break;
+ }
+ if (pPostprocessDesc->bDoFog == false)
+ ps_desc.flags.FOGMODE = Apply_PS::FOGMODE_NONE;
+ else if (pPostprocessDesc->bIgnoreSkyFog == true)
+ ps_desc.flags.FOGMODE = Apply_PS::FOGMODE_NOSKY;
+ else
+ ps_desc.flags.FOGMODE = Apply_PS::FOGMODE_FULL;
+ dxCtx->PSSetShader(shaders.Apply_PS[ps_desc], nullptr, 0);
+ ID3D11ShaderResourceView * SRVs[] = {
+ pAccumulatedOutput_->getSRV(),
+ pSceneDepth_SRV,
+ nullptr,
+ nullptr,
+ pPhaseLUT_->getSRV()
+ };
+ if (pFilteredDepth_[nextFrameIndex_])
+ SRVs[2] = pFilteredDepth_[nextFrameIndex_]->getSRV();
+ dxCtx->PSSetShaderResources(0, 5, SRVs);
+ DrawFullscreen(dxCtx);
+
+ ID3D11RenderTargetView * NULL_RTV = nullptr;
+ dxCtx->OMSetRenderTargets(1, &NULL_RTV, nullptr);
+ return Status::OK;
+}
+
+Status ContextImp_D3D11::ApplyLighting_End(PlatformRenderCtx renderCtx, PlatformRenderTarget sceneTarget, PlatformShaderResource sceneDepth, PostprocessDesc const* pPostprocessDesc)
+{
+ ID3D11DeviceContext * dxCtx = renderCtx;
+ dxCtx;
+ NV_PERFEVENT_END(dxCtx);
+ return Status::OK;
+}
+
+/*==============================================================================
+ Utility functions
+==============================================================================*/
+
+Status ContextImp_D3D11::DrawFullscreen(ID3D11DeviceContext * dxCtx)
+{
+ NV_PERFEVENT(dxCtx, "DrawFullscreen");
+ dxCtx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ dxCtx->IASetVertexBuffers(0,0,nullptr, nullptr,nullptr);
+ dxCtx->IASetInputLayout(nullptr);
+ dxCtx->IASetIndexBuffer(nullptr, DXGI_FORMAT_R16_UINT, 0);
+ dxCtx->RSSetState(states.rs.cull_none);
+ dxCtx->VSSetShader(shaders.Quad_VS[Quad_VS::SINGLE], nullptr, 0);
+ dxCtx->HSSetShader(nullptr, nullptr, 0);
+ dxCtx->DSSetShader(nullptr, nullptr, 0);
+ dxCtx->Draw(3, 0);
+ return Status::OK;
+}
+
+Status ContextImp_D3D11::DrawFrustumGrid(ID3D11DeviceContext * dxCtx, uint32_t resolution)
+{
+ NV_PERFEVENT(dxCtx, "DrawFrustumGrid");
+ dxCtx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST);
+ dxCtx->IASetVertexBuffers(0,0,nullptr, nullptr,nullptr);
+ dxCtx->IASetInputLayout(nullptr);
+ dxCtx->IASetIndexBuffer(nullptr, DXGI_FORMAT_R16_UINT, 0);
+ RenderVolume_VS::Desc vs_desc;
+ vs_desc.flags.MESHMODE = RenderVolume_VS::MESHMODE_FRUSTUM_GRID;
+ dxCtx->VSSetShader(shaders.RenderVolume_VS[vs_desc], nullptr, 0);
+
+ if (debugFlags_ & (uint32_t)DebugFlags::WIREFRAME)
+ {
+ dxCtx->RSSetState(states.rs.wireframe);
+ dxCtx->OMSetBlendState(states.bs.no_blending, nullptr, 0xFFFFFFFF);
+ dxCtx->PSSetShader(shaders.Debug_PS[Debug_PS::SINGLE], nullptr, 0);
+ }
+
+ uint32_t vtx_count = 4 * resolution * resolution;
+ dxCtx->Draw(vtx_count, 0);
+ return Status::OK;
+}
+
+Status ContextImp_D3D11::DrawFrustumBase(ID3D11DeviceContext * dxCtx, uint32_t resolution)
+{
+ NV_PERFEVENT(dxCtx, "DrawFrustumBase");
+ dxCtx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ dxCtx->IASetVertexBuffers(0,0,nullptr, nullptr,nullptr);
+ dxCtx->IASetInputLayout(nullptr);
+ dxCtx->IASetIndexBuffer(nullptr, DXGI_FORMAT_R16_UINT, 0);
+ RenderVolume_VS::Desc vs_desc;
+ vs_desc.flags.MESHMODE = RenderVolume_VS::MESHMODE_FRUSTUM_BASE;
+ dxCtx->VSSetShader(shaders.RenderVolume_VS[vs_desc], nullptr, 0);
+ dxCtx->HSSetShader(nullptr, nullptr, 0);
+ dxCtx->DSSetShader(nullptr, nullptr, 0);
+
+ if (debugFlags_ & (uint32_t)DebugFlags::WIREFRAME)
+ {
+ dxCtx->RSSetState(states.rs.wireframe);
+ dxCtx->OMSetBlendState(states.bs.no_blending, nullptr, 0xFFFFFFFF);
+ dxCtx->PSSetShader(shaders.Debug_PS[Debug_PS::SINGLE], nullptr, 0);
+ }
+
+ dxCtx->Draw(6, 0);
+ return Status::OK;
+}
+
+Status ContextImp_D3D11::DrawFrustumCap(ID3D11DeviceContext * dxCtx, uint32_t resolution)
+{
+ NV_PERFEVENT(dxCtx, "DrawFrustumCap");
+ dxCtx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ dxCtx->IASetVertexBuffers(0,0,nullptr, nullptr,nullptr);
+ dxCtx->IASetInputLayout(nullptr);
+ dxCtx->IASetIndexBuffer(nullptr, DXGI_FORMAT_R16_UINT, 0);
+ RenderVolume_VS::Desc vs_desc;
+ vs_desc.flags.MESHMODE = RenderVolume_VS::MESHMODE_FRUSTUM_CAP;
+ dxCtx->VSSetShader(shaders.RenderVolume_VS[vs_desc], nullptr, 0);
+ dxCtx->HSSetShader(nullptr, nullptr, 0);
+ dxCtx->DSSetShader(nullptr, nullptr, 0);
+
+ if (debugFlags_ & (uint32_t)DebugFlags::WIREFRAME)
+ {
+ dxCtx->RSSetState(states.rs.wireframe);
+ dxCtx->OMSetBlendState(states.bs.no_blending, nullptr, 0xFFFFFFFF);
+ dxCtx->PSSetShader(shaders.Debug_PS[Debug_PS::SINGLE], nullptr, 0);
+ }
+
+ uint32_t vtx_count = 4*3*(resolution+1) + 6;
+ dxCtx->Draw(vtx_count, 0);
+ return Status::OK;
+}
+
+Status ContextImp_D3D11::DrawOmniVolume(ID3D11DeviceContext * dxCtx, uint32_t resolution)
+{
+ NV_PERFEVENT(dxCtx, "DrawOmniVolume");
+ dxCtx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST);
+ dxCtx->IASetVertexBuffers(0,0,nullptr, nullptr,nullptr);
+ dxCtx->IASetInputLayout(nullptr);
+ dxCtx->IASetIndexBuffer(nullptr, DXGI_FORMAT_R16_UINT, 0);
+ RenderVolume_VS::Desc vs_desc;
+ vs_desc.flags.MESHMODE = RenderVolume_VS::MESHMODE_OMNI_VOLUME;
+ dxCtx->VSSetShader(shaders.RenderVolume_VS[vs_desc], nullptr, 0);
+
+ if (debugFlags_ & (uint32_t)DebugFlags::WIREFRAME)
+ {
+ dxCtx->RSSetState(states.rs.wireframe);
+ dxCtx->OMSetBlendState(states.bs.no_blending, nullptr, 0xFFFFFFFF);
+ dxCtx->PSSetShader(shaders.Debug_PS[Debug_PS::SINGLE], nullptr, 0);
+ }
+
+ uint32_t vtx_count = 6 * 4 * resolution * resolution;
+ dxCtx->Draw(vtx_count, 0);
+ return Status::OK;
+}
+////////////////////////////////////////////////////////////////////////////////
+}; /*namespace Nv*/ }; /*namespace VolumetricLighting*/
+////////////////////////////////////////////////////////////////////////////////
diff --git a/src/d3d11/context_d3d11.h b/src/d3d11/context_d3d11.h
new file mode 100644
index 0000000..82a6931
--- /dev/null
+++ b/src/d3d11/context_d3d11.h
@@ -0,0 +1,191 @@
+// 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 (c) 2003 - 2016 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 CONTEXT_D3D11_H
+#define CONTEXT_D3D11_H
+////////////////////////////////////////////////////////////////////////////////
+#include <Nv/VolumetricLighting/NvVolumetricLighting.h>
+
+#include <vector> // TODO: remove this dependency
+#include "context_common.h"
+/*==============================================================================
+ Forward Declarations
+==============================================================================*/
+// D3D11 Types
+struct ID3D11VertexShader;
+struct ID3D11HullShader;
+struct ID3D11DomainShader;
+struct ID3D11GeometryShader;
+struct ID3D11PixelShader;
+struct ID3D11ComputeShader;
+struct ID3D11RasterizerState;
+struct ID3D11SamplerState;
+struct ID3D11DepthStencilState;
+struct ID3D11BlendState;
+struct ID3D11InputLayout;
+struct ID3D11Buffer;
+
+// Helper Types
+class Texture2D;
+class RenderTarget;
+class DepthTarget;
+template <class T> class ConstantBuffer;
+
+////////////////////////////////////////////////////////////////////////////////
+namespace Nv { namespace VolumetricLighting {
+////////////////////////////////////////////////////////////////////////////////
+
+class ContextImp_D3D11 : public ContextImp_Common
+{
+public:
+ // Creates the context and resources
+ static Status Create(ContextImp_D3D11 ** out_ctx, const PlatformDesc * pPlatformDesc, const ContextDesc * pContextDesc);
+
+ // Clean up the context on delete
+ virtual ~ContextImp_D3D11();
+
+protected:
+ // BeginAccumulation
+ Status BeginAccumulation_Start(PlatformRenderCtx renderCtx, PlatformShaderResource sceneDepth, ViewerDesc const* pViewerDesc, MediumDesc const* pMediumDesc);
+ Status BeginAccumulation_UpdateMediumLUT(PlatformRenderCtx renderCtx);
+ Status BeginAccumulation_CopyDepth(PlatformRenderCtx renderCtx, PlatformShaderResource sceneDepth);
+ Status BeginAccumulation_End(PlatformRenderCtx renderCtx, PlatformShaderResource sceneDepth, ViewerDesc const* pViewerDesc, MediumDesc const* pMediumDesc);
+
+ // RenderVolume
+ Status RenderVolume_Start(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc);
+ Status RenderVolume_DoVolume_Directional(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc);
+ Status RenderVolume_DoVolume_Spotlight(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc);
+ Status RenderVolume_DoVolume_Omni(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc);
+ Status RenderVolume_End(PlatformRenderCtx renderCtx, PlatformShaderResource shadowMap, ShadowMapDesc const* pShadowMapDesc, LightDesc const* pLightDesc, VolumeDesc const* pVolumeDesc);
+
+ // EndAccumulation
+ Status EndAccumulation_Imp(PlatformRenderCtx renderCtx);
+
+ // ApplyLighting
+ Status ApplyLighting_Start(PlatformRenderCtx renderCtx, PlatformRenderTarget sceneTarget, PlatformShaderResource sceneDepth, PostprocessDesc const* pPostprocessDesc);
+ Status ApplyLighting_Resolve(PlatformRenderCtx renderCtx, PostprocessDesc const* pPostprocessDesc);
+ Status ApplyLighting_TemporalFilter(PlatformRenderCtx renderCtx, PlatformShaderResource sceneDepth, PostprocessDesc const* pPostprocessDesc);
+ Status ApplyLighting_Composite(PlatformRenderCtx renderCtx, PlatformRenderTarget sceneTarget, PlatformShaderResource sceneDepth, PostprocessDesc const* pPostprocessDesc);
+ Status ApplyLighting_End(PlatformRenderCtx renderCtx, PlatformRenderTarget sceneTarget, PlatformShaderResource sceneDepth, PostprocessDesc const* pPostprocessDesc);
+
+private:
+ // Private default constructor
+ // Should never be called
+ ContextImp_D3D11() {};
+
+ // Initializing Destructor
+ // Setup all code that can't fail
+ ContextImp_D3D11(const ContextDesc * pContextDesc);
+
+ // Called by Create internally
+ Status CreateResources(ID3D11Device * device);
+
+ // Do a fullscreen pass with the bound pixel-shader
+ Status DrawFullscreen(ID3D11DeviceContext * dxCtx);
+
+ Status DrawFrustumGrid(ID3D11DeviceContext * dxCtx, uint32_t resolution);
+ Status DrawFrustumBase(ID3D11DeviceContext * dxCtx, uint32_t resolution);
+ Status DrawFrustumCap(ID3D11DeviceContext * dxCtx, uint32_t resolution);
+ Status DrawOmniVolume(ID3D11DeviceContext * dxCtx, uint32_t resolution);
+
+ struct
+ {
+ ID3D11PixelShader ** Apply_PS;
+ ID3D11ComputeShader ** ComputeLightLUT_CS;
+ ID3D11PixelShader ** ComputePhaseLookup_PS;
+ ID3D11PixelShader ** Debug_PS;
+ ID3D11PixelShader ** DownsampleDepth_PS;
+ ID3D11VertexShader ** Quad_VS;
+ ID3D11VertexShader ** RenderVolume_VS;
+ ID3D11HullShader ** RenderVolume_HS;
+ ID3D11DomainShader ** RenderVolume_DS;
+ ID3D11PixelShader ** RenderVolume_PS;
+ ID3D11PixelShader ** Resolve_PS;
+ ID3D11PixelShader ** TemporalFilter_PS;
+ } shaders;
+
+ ConstantBuffer<PerContextCB> * pPerContextCB;
+ ConstantBuffer<PerFrameCB> * pPerFrameCB;
+ ConstantBuffer<PerVolumeCB> * pPerVolumeCB;
+ ConstantBuffer<PerApplyCB> * pPerApplyCB;
+
+ DepthTarget * pDepth_;
+ RenderTarget * pPhaseLUT_;
+ RenderTarget * pLightLUT_P_[2];
+ RenderTarget * pLightLUT_S1_[2];
+ RenderTarget * pLightLUT_S2_[2];
+ RenderTarget * pAccumulation_;
+ RenderTarget * pResolvedAccumulation_;
+ RenderTarget * pResolvedDepth_;
+ RenderTarget * pFilteredAccumulation_[2];
+ RenderTarget * pFilteredDepth_[2];
+
+ RenderTarget * pAccumulatedOutput_;
+
+ struct
+ {
+ struct
+ {
+ ID3D11RasterizerState * cull_none;
+ ID3D11RasterizerState * cull_front;
+ ID3D11RasterizerState * wireframe;
+ } rs;
+
+ struct
+ {
+ ID3D11SamplerState * point;
+ ID3D11SamplerState * linear;
+ } ss;
+
+ struct
+ {
+ ID3D11DepthStencilState * no_depth;
+ ID3D11DepthStencilState * write_only_depth;
+ ID3D11DepthStencilState * read_only_depth;
+ ID3D11DepthStencilState * render_volume;
+ ID3D11DepthStencilState * render_volume_boundary;
+ ID3D11DepthStencilState * remove_volume_base;
+ ID3D11DepthStencilState * render_volume_cap;
+ ID3D11DepthStencilState * finish_volume;
+ } ds;
+
+ struct
+ {
+ ID3D11BlendState * no_color;
+ ID3D11BlendState * no_blending;
+ ID3D11BlendState * additive;
+ ID3D11BlendState * additive_modulate;
+ ID3D11BlendState * debug_blend;
+ } bs;
+ } states;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+}; /*namespace VolumetricLighting*/ }; /*namespace Nv*/
+////////////////////////////////////////////////////////////////////////////////
+#endif // CONTEXT_D3D11_H
diff --git a/src/d3d11/d3d11_util.cpp b/src/d3d11/d3d11_util.cpp
new file mode 100644
index 0000000..4226fdb
--- /dev/null
+++ b/src/d3d11/d3d11_util.cpp
@@ -0,0 +1,347 @@
+// 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 (c) 2003 - 2016 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.h"
+#include "d3d11_util.h"
+#include <d3d11.h>
+
+/*==============================================================================
+ Overloaded functions to make shader compilation simpler
+==============================================================================*/
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11VertexShader ** out_shader)
+ { return device->CreateVertexShader(data, length, nullptr, out_shader); }
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11HullShader ** out_shader)
+ { return device->CreateHullShader(data, length, nullptr, out_shader); }
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11DomainShader ** out_shader)
+ { return device->CreateDomainShader(data, length, nullptr, out_shader); }
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11GeometryShader ** out_shader)
+ { return device->CreateGeometryShader(data, length, nullptr, out_shader); }
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11PixelShader ** out_shader)
+ { return device->CreatePixelShader(data, length, nullptr, out_shader); }
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11ComputeShader ** out_shader)
+ { return device->CreateComputeShader(data, length, nullptr, out_shader); }
+/*==============================================================================
+ Texture resource management helpers
+==============================================================================*/
+
+//------------------------------------------------------------------------------
+ShaderResource::ShaderResource(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11UnorderedAccessView * uav)
+{
+ resource_ = resource;
+ srv_ = srv;
+ uav_ = uav;
+}
+
+ShaderResource::~ShaderResource()
+{
+ SAFE_RELEASE(resource_);
+ SAFE_RELEASE(srv_);
+ SAFE_RELEASE(uav_);
+}
+
+//------------------------------------------------------------------------------
+RenderTarget * RenderTarget::Create(ID3D11Device * device, UINT width, UINT height, UINT samples, DXGI_FORMAT format, const char * debug_name)
+{
+ ID3D11Texture2D * tex = nullptr;
+ ID3D11ShaderResourceView * srv = nullptr;
+ ID3D11RenderTargetView * rtv = nullptr;
+ ID3D11UnorderedAccessView * uav = nullptr;
+
+ CD3D11_TEXTURE2D_DESC texDesc;
+ texDesc.ArraySize = 1;
+ texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
+ if (samples == 1)
+ texDesc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
+ texDesc.CPUAccessFlags = 0;
+ texDesc.Format = format;
+ texDesc.Width = width;
+ texDesc.Height = height;
+ texDesc.MipLevels = 1;
+ texDesc.MiscFlags = 0;
+ if (samples > 1)
+ {
+ texDesc.SampleDesc.Count = samples;
+ texDesc.SampleDesc.Quality = 0;//static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN);
+ }
+ else
+ {
+ texDesc.SampleDesc.Count = 1;
+ texDesc.SampleDesc.Quality = 0;
+ }
+ texDesc.Usage = D3D11_USAGE_DEFAULT;
+ device->CreateTexture2D(&texDesc, nullptr, &tex);
+ if (tex == nullptr)
+ {
+ return nullptr;
+ }
+
+ CD3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = texDesc.Format;
+ if (samples > 1)
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
+ }
+ else
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Texture2D.MostDetailedMip = 0;
+ srvDesc.Texture2D.MipLevels = 1;
+ }
+ device->CreateShaderResourceView(tex, &srvDesc, &srv);
+ if (srv == nullptr)
+ {
+ tex->Release();
+ return nullptr;
+ }
+
+ CD3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = texDesc.Format;
+ if (samples > 1)
+ {
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
+ }
+ else
+ {
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = 0;
+ }
+ device->CreateRenderTargetView(tex, &rtvDesc, &rtv);
+ if (rtv == nullptr)
+ {
+ tex->Release();
+ srv->Release();
+ return nullptr;
+ }
+
+ if (samples == 1)
+ {
+ CD3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
+ uavDesc.Format = texDesc.Format;
+ uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
+ uavDesc.Texture2D.MipSlice = 0;
+ device->CreateUnorderedAccessView(tex, &uavDesc, &uav);
+ if (uav == nullptr)
+ {
+ tex->Release();
+ srv->Release();
+ rtv->Release();
+ return nullptr;
+ }
+ }
+#if (NV_DEBUG || NV_PROFILE)
+ if (debug_name)
+ {
+ tex->SetPrivateData(WKPDID_D3DDebugObjectName, (UINT)strlen(debug_name), debug_name);
+ }
+#else
+ debug_name;
+#endif
+ return new RenderTarget(tex, srv, rtv, uav);
+}
+
+RenderTarget::RenderTarget(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11RenderTargetView * rtv, ID3D11UnorderedAccessView * uav)
+ : ShaderResource(resource, srv, uav)
+{
+ rtv_ = rtv;
+}
+
+RenderTarget::~RenderTarget()
+{
+ SAFE_RELEASE(rtv_);
+}
+
+//------------------------------------------------------------------------------
+DepthTarget * DepthTarget::Create(ID3D11Device * device, UINT width, UINT height, UINT samples, DXGI_FORMAT format, uint32_t slices, char * debug_name)
+{
+ ID3D11Texture2D * tex = nullptr;
+ ID3D11ShaderResourceView * srv = nullptr;
+ ID3D11DepthStencilView * dsv = nullptr;
+ ID3D11DepthStencilView * dsv_ro = nullptr;
+
+ DXGI_FORMAT tex_format;
+ DXGI_FORMAT srv_format;
+ DXGI_FORMAT dsv_format;
+ switch (format)
+ {
+ case DXGI_FORMAT_D32_FLOAT:
+ tex_format = DXGI_FORMAT_R32_TYPELESS;
+ srv_format = DXGI_FORMAT_R32_FLOAT;
+ dsv_format = DXGI_FORMAT_D32_FLOAT;
+ break;
+
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ tex_format = DXGI_FORMAT_R24G8_TYPELESS;
+ srv_format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
+ dsv_format = DXGI_FORMAT_D24_UNORM_S8_UINT;
+ break;
+
+ case DXGI_FORMAT_D16_UNORM:
+ tex_format = DXGI_FORMAT_R16_TYPELESS;
+ srv_format = DXGI_FORMAT_R16_UNORM;
+ dsv_format = DXGI_FORMAT_D16_UNORM;
+ break;
+
+ default:
+ return nullptr;
+ }
+
+ CD3D11_TEXTURE2D_DESC texDesc;
+ texDesc.ArraySize = slices;
+ texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL;
+ texDesc.CPUAccessFlags = 0;
+ texDesc.Format = tex_format;
+ texDesc.Width = width;
+ texDesc.Height = height;
+ texDesc.MipLevels = 1;
+ texDesc.MiscFlags = 0;
+ if (samples > 1)
+ {
+ texDesc.SampleDesc.Count = samples;
+ texDesc.SampleDesc.Quality = 0;//static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN);
+ }
+ else
+ {
+ texDesc.SampleDesc.Count = 1;
+ texDesc.SampleDesc.Quality = 0;
+ }
+ texDesc.Usage = D3D11_USAGE_DEFAULT;
+ device->CreateTexture2D(&texDesc, nullptr, &tex);
+ if (tex == nullptr)
+ {
+ return nullptr;
+ }
+
+ CD3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = srv_format;
+ if (slices == 1)
+ {
+ if (samples > 1)
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
+ }
+ else
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Texture2D.MostDetailedMip = 0;
+ srvDesc.Texture2D.MipLevels = 1;
+ }
+ }
+ else
+ {
+ if (samples > 1)
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
+ srvDesc.Texture2DMSArray.FirstArraySlice = 0;
+ srvDesc.Texture2DMSArray.ArraySize = slices;
+ }
+ else
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+ srvDesc.Texture2DArray.MostDetailedMip = 0;
+ srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.FirstArraySlice = 0;
+ srvDesc.Texture2DArray.ArraySize = slices;
+ }
+ }
+ device->CreateShaderResourceView(tex, &srvDesc, &srv);
+
+ if (srv == nullptr)
+ {
+ tex->Release();
+ return nullptr;
+ }
+
+ CD3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Flags = 0;
+ dsvDesc.Format = dsv_format;
+ if (slices == 1)
+ {
+ if (samples > 1)
+ {
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
+ }
+ else
+ {
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+ dsvDesc.Texture2D.MipSlice = 0;
+ }
+ }
+ else
+ {
+ if (samples > 1)
+ {
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY;
+ dsvDesc.Texture2DMSArray.FirstArraySlice = 0;
+ dsvDesc.Texture2DMSArray.ArraySize = slices;
+ }
+ else
+ {
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
+ dsvDesc.Texture2DArray.MipSlice = 0;
+ dsvDesc.Texture2DArray.FirstArraySlice = 0;
+ dsvDesc.Texture2DArray.ArraySize = slices;
+ }
+ }
+
+ device->CreateDepthStencilView(tex, &dsvDesc, &dsv);
+ dsvDesc.Flags |= D3D11_DSV_READ_ONLY_DEPTH;
+ if (dsv_format == DXGI_FORMAT_D24_UNORM_S8_UINT)
+ dsvDesc.Flags |= D3D11_DSV_READ_ONLY_STENCIL;
+ device->CreateDepthStencilView(tex, &dsvDesc, &dsv_ro);
+ if (dsv == nullptr || dsv_ro == nullptr)
+ {
+ tex->Release();
+ srv->Release();
+ return nullptr;
+ }
+
+#if (NV_DEBUG || NV_PROFILE)
+ if (debug_name)
+ {
+ tex->SetPrivateData(WKPDID_D3DDebugObjectName, (UINT)strlen(debug_name), debug_name);
+ }
+#else
+ debug_name;
+#endif
+
+ return new DepthTarget(tex, srv, dsv, dsv_ro, nullptr);
+}
+
+DepthTarget::DepthTarget(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11DepthStencilView * dsv, ID3D11DepthStencilView * readonly_dsv, ID3D11UnorderedAccessView * uav)
+ : ShaderResource(resource, srv, uav)
+{
+ dsv_ = dsv;
+ readonly_dsv_ = readonly_dsv;
+}
+
+DepthTarget::~DepthTarget()
+{
+ SAFE_RELEASE(dsv_);
+ SAFE_RELEASE(readonly_dsv_);
+}
+
diff --git a/src/d3d11/d3d11_util.h b/src/d3d11/d3d11_util.h
new file mode 100644
index 0000000..e9322cf
--- /dev/null
+++ b/src/d3d11/d3d11_util.h
@@ -0,0 +1,234 @@
+// 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 (c) 2003 - 2016 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 D3D11_UTIL_H
+#define D3D11_UTIL_H
+////////////////////////////////////////////////////////////////////////////////
+#include "common.h"
+
+#include <d3d11.h>
+#include <d3d11_1.h>
+
+#pragma warning( disable: 4127 )
+
+////////////////////////////////////////////////////////////////////////////////
+/*==============================================================================
+ Overloaded functions to make shader compilation simpler
+==============================================================================*/
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11VertexShader ** out_shader);
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11HullShader ** out_shader);
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11DomainShader ** out_shader);
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11GeometryShader ** out_shader);
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11PixelShader ** out_shader);
+HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11ComputeShader ** out_shader);
+
+
+template <class T>
+NV_FORCE_INLINE HRESULT LoadShaders(ID3D11Device * device, const void ** shader_codes, const uint32_t * shader_lengths, UINT count, T ** &out_shaders)
+{
+ HRESULT hr = S_OK;
+ out_shaders = new T*[count];
+ for (UINT i = 0; i < count; ++i)
+ {
+ const void * code = shader_codes[i];
+ uint32_t length = shader_lengths[i];
+ if (code == nullptr)
+ {
+ out_shaders[i] = nullptr;
+ continue;
+ }
+ hr = CompileShader(device, code, length, &out_shaders[i]);
+ ASSERT_LOG(hr == S_OK, "Failure loading shader");
+ if (FAILED(hr))
+ break;
+ }
+ return hr;
+}
+
+/*==============================================================================
+ Perf Events
+==============================================================================*/
+
+class ScopedPerfEvent
+{
+public:
+ ScopedPerfEvent(ID3D11DeviceContext * ctx, const wchar_t * msg)
+ {
+ ctx->QueryInterface(IID_ID3DUserDefinedAnnotation, reinterpret_cast<void **>(&pPerf));
+ if (pPerf)
+ {
+ pPerf->BeginEvent(msg);
+ }
+ }
+
+ ~ScopedPerfEvent()
+ {
+ if (pPerf)
+ {
+ pPerf->EndEvent();
+ SAFE_RELEASE(pPerf);
+ }
+ };
+
+private:
+ ScopedPerfEvent() : pPerf(nullptr) {};
+ ID3DUserDefinedAnnotation * pPerf;
+};
+
+#if (NV_PROFILE)
+# define NV_PERFEVENT(c, t) ScopedPerfEvent perfevent_##__COUNTER__##(c, L##t)
+# define NV_PERFEVENT_BEGIN(c, t) { \
+ ID3DUserDefinedAnnotation * pPerf_##__COUNTER__ ; \
+ c->QueryInterface(IID_ID3DUserDefinedAnnotation, reinterpret_cast<void **>(&pPerf_##__COUNTER__##)); \
+ if (pPerf_##__COUNTER__##) { pPerf_##__COUNTER__##->BeginEvent(L##t); pPerf_##__COUNTER__##->Release(); } }
+# define NV_PERFEVENT_END(c) { \
+ ID3DUserDefinedAnnotation * pPerf_##__COUNTER__ ; \
+ c->QueryInterface(IID_ID3DUserDefinedAnnotation, reinterpret_cast<void **>(&pPerf_##__COUNTER__##)); \
+ if (pPerf_##__COUNTER__##) { pPerf_##__COUNTER__##->EndEvent(); pPerf_##__COUNTER__##->Release(); } }
+#else
+# define NV_PERFEVENT(c, t)
+# define NV_PERFEVENT_BEGIN(c, t)
+# define NV_PERFEVENT_END(c)
+#endif
+
+/*==============================================================================
+ Constant buffer management
+==============================================================================*/
+
+template <class T>
+class ConstantBuffer
+{
+public:
+ static ConstantBuffer<T> * Create(ID3D11Device * device)
+ {
+ HRESULT hr;
+ ID3D11Buffer * cb = nullptr;
+
+ static_assert((sizeof(T) % 16) == 0, "Constant buffer size must be 16-byte aligned");
+
+ CD3D11_BUFFER_DESC cbDesc;
+ cbDesc.ByteWidth = sizeof(T);
+ cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ cbDesc.Usage = D3D11_USAGE_DYNAMIC;
+ cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ cbDesc.MiscFlags = 0;
+ cbDesc.StructureByteStride = 1;
+ hr = device->CreateBuffer(&cbDesc, nullptr, &cb);
+ if (cb == nullptr)
+ return nullptr;
+ return new ConstantBuffer<T>(cb);
+ }
+
+ ConstantBuffer(ID3D11Buffer * b)
+ {
+ buffer_ = b;
+ }
+
+ ~ConstantBuffer()
+ {
+ SAFE_RELEASE(buffer_);
+ }
+
+ T * Map(ID3D11DeviceContext * ctx)
+ {
+ HRESULT hr;
+ D3D11_MAPPED_SUBRESOURCE data;
+ hr = ctx->Map(buffer_, 0, D3D11_MAP_WRITE_DISCARD, 0, &data);
+ return static_cast<T*>(data.pData);
+ }
+
+ void Unmap(ID3D11DeviceContext * ctx)
+ {
+ ctx->Unmap(buffer_, 0);
+ }
+
+ ID3D11Buffer * getCB() { return buffer_; }
+
+private:
+ ConstantBuffer() {};
+
+ ID3D11Buffer *buffer_;
+};
+
+/*==============================================================================
+ Texture resource management helpers
+==============================================================================*/
+
+//------------------------------------------------------------------------------
+class ShaderResource
+{
+public:
+ ShaderResource(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11UnorderedAccessView * uav);
+ ~ShaderResource();
+
+ ID3D11Resource * getResource() { return resource_; }
+ ID3D11ShaderResourceView * getSRV() { return srv_; }
+ ID3D11UnorderedAccessView * getUAV() { return uav_; }
+
+protected:
+ ShaderResource() {};
+
+ ID3D11Resource * resource_;
+ ID3D11ShaderResourceView * srv_;
+ ID3D11UnorderedAccessView * uav_;
+};
+
+//------------------------------------------------------------------------------
+class RenderTarget : public ShaderResource
+{
+public:
+ static RenderTarget * Create(ID3D11Device * device, UINT width, UINT height, UINT samples, DXGI_FORMAT format, const char * debug_name=nullptr);
+ RenderTarget(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11RenderTargetView * rtv, ID3D11UnorderedAccessView * uav);
+ ~RenderTarget();
+
+ ID3D11RenderTargetView * getRTV() { return rtv_; }
+
+protected:
+ RenderTarget() {};
+ ID3D11RenderTargetView * rtv_;
+};
+
+//------------------------------------------------------------------------------
+class DepthTarget : public ShaderResource
+{
+public:
+ static DepthTarget * Create(ID3D11Device * device, UINT width, UINT height, UINT samples, DXGI_FORMAT format, uint32_t slices=1, char * debug_name=nullptr);
+ DepthTarget(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11DepthStencilView * dsv, ID3D11DepthStencilView * readonly_dsv, ID3D11UnorderedAccessView * uav);
+ ~DepthTarget();
+
+ ID3D11DepthStencilView * getDSV() { return dsv_; }
+ ID3D11DepthStencilView * getReadOnlyDSV() { return readonly_dsv_; }
+
+protected:
+ DepthTarget() {};
+ ID3D11DepthStencilView * dsv_;
+ ID3D11DepthStencilView * readonly_dsv_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+#endif // D3D11_UTIL_H \ No newline at end of file
diff --git a/src/shaders/Apply_PS.hlsl b/src/shaders/Apply_PS.hlsl
new file mode 100644
index 0000000..0e19e46
--- /dev/null
+++ b/src/shaders/Apply_PS.hlsl
@@ -0,0 +1,176 @@
+// 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 (c) 2003 - 2016 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 the shader permutations for code generation
+%% MUX_BEGIN %%
+
+- SAMPLEMODE:
+ - SAMPLEMODE_SINGLE
+ - SAMPLEMODE_MSAA
+
+- UPSAMPLEMODE:
+ - UPSAMPLEMODE_POINT
+ - UPSAMPLEMODE_BILINEAR
+ - UPSAMPLEMODE_BILATERAL
+
+- FOGMODE:
+ - FOGMODE_NONE
+ - FOGMODE_NOSKY
+ - FOGMODE_FULL
+
+%% MUX_END %%
+*/
+
+#include "ShaderCommon.h"
+
+Texture2D<float4> tGodraysBuffer : register(t0);
+#if (SAMPLEMODE == SAMPLEMODE_MSAA)
+ Texture2DMS<float> tSceneDepth : register(t1);
+#elif (SAMPLEMODE == SAMPLEMODE_SINGLE)
+ Texture2D<float> tSceneDepth : register(t1);
+#endif
+Texture2D<float2> tGodraysDepth : register(t2);
+Texture2D<float4> tPhaseLUT : register(t4);
+
+struct PS_APPLY_OUTPUT
+{
+ float4 inscatter : SV_TARGET0;
+ float4 transmission : SV_TARGET1;
+};
+
+float3 Tonemap(float3 s)
+{
+ return s / (float3(1,1,1) + s);
+}
+
+float3 Tonemap_Inv(float3 s)
+{
+ return s / (float3(1,1,1) - s);
+}
+
+
+float CalcVariance(float x, float x_sqr)
+{
+ return abs(x_sqr - x*x);
+}
+
+PS_APPLY_OUTPUT main(VS_QUAD_OUTPUT input
+#if (SAMPLEMODE == SAMPLEMODE_MSAA)
+ , uint sampleID : SV_SAMPLEINDEX
+#endif
+ )
+{
+ PS_APPLY_OUTPUT output;
+ output.transmission = float4(1,1,1,1);
+ output.inscatter = float4(0,0,0,1);
+
+ float2 texcoord = input.vTex * g_vViewportSize * g_vBufferSize_Inv;
+
+#if (SAMPLEMODE == SAMPLEMODE_MSAA)
+ float scene_depth = tSceneDepth.Load(int2(input.vTex*g_vOutputViewportSize), sampleID).x;
+#elif (SAMPLEMODE == SAMPLEMODE_SINGLE)
+ float scene_depth = tSceneDepth.SampleLevel(sPoint, input.vTex * g_vViewportSize * g_vBufferSize_Inv, 0).x;
+#endif
+ scene_depth = LinearizeDepth(scene_depth, g_fZNear, g_fZFar);
+
+
+
+ // Quality of the upsampling interpolator
+ // 0: Point (no up-sample)
+ // 1: Bilinear
+ // 2: Bilateral
+ float3 inscatter_sample = float3(0,0,0);
+ if (UPSAMPLEMODE == UPSAMPLEMODE_POINT)
+ {
+ inscatter_sample = tGodraysBuffer.SampleLevel( sPoint, texcoord, 0).rgb;
+ }
+ else if (UPSAMPLEMODE == UPSAMPLEMODE_BILINEAR)
+ {
+ inscatter_sample = tGodraysBuffer.SampleLevel( sBilinear, texcoord, 0).rgb;
+ }
+ else if (UPSAMPLEMODE == UPSAMPLEMODE_BILATERAL)
+ {
+ const float2 NEIGHBOR_OFFSETS[] = {
+ float2(-1, -1), float2( 0, -1), float2( 1, -1),
+ float2(-1, 0), float2( 0, 0), float2( 1, 0),
+ float2(-1, 1), float2( 0, 1), float2( 1, 1)
+ };
+ const float GAUSSIAN_WIDTH = 1.0f;
+
+ float2 max_dimensions = floor(g_vViewportSize);
+ float2 base_tc = input.vTex * max_dimensions;
+
+ float total_weight = 0;
+ [unroll]
+ for (int n=0; n<9; ++n)
+ {
+ float2 sample_tc = max( float2(0,0), min(max_dimensions, base_tc + NEIGHBOR_OFFSETS[n]));
+
+ float weight = 0.0f;
+ float2 sample_location = floor(sample_tc) + float2(0.5f, 0.5f);
+ weight = GaussianApprox(sample_location - base_tc, GAUSSIAN_WIDTH);
+
+ const float DEPTH_RANGE = 0.10f;
+
+ float2 neighbor_depth = tGodraysDepth.Load(int3(sample_location.xy, 0)).rg;
+ float depth_diff = abs(scene_depth - neighbor_depth.r);
+ float neighbor_variance = CalcVariance(neighbor_depth.r, neighbor_depth.g);
+ float neighbor_stddev = sqrt(neighbor_variance);
+ float depth_weight = saturate(1 - depth_diff / DEPTH_RANGE);
+ depth_weight = depth_weight*depth_weight*(1-neighbor_stddev);
+ weight *= depth_weight;
+
+ inscatter_sample += weight * Tonemap(tGodraysBuffer.Load(int3(sample_location.xy, 0)).rgb);
+ total_weight += weight;
+ }
+
+ if (total_weight > 0.0f)
+ {
+ inscatter_sample = Tonemap_Inv(inscatter_sample / total_weight);
+ }
+ else
+ {
+ inscatter_sample = tGodraysBuffer.SampleLevel(sBilinear, texcoord, 0).rgb;
+ }
+ }
+
+ output.inscatter.rgb = inscatter_sample.rgb;
+ if (FOGMODE != FOGMODE_NONE)
+ {
+ if ((FOGMODE != FOGMODE_NOSKY) || (scene_depth < 1.f))
+ {
+ float scene_distance = g_fZFar * scene_depth;
+ float3 sigma_ext = g_vSigmaExtinction;
+ output.inscatter.rgb += g_fMultiScattering * g_vFogLight * g_vScatterPower * (1-exp(-sigma_ext*scene_distance)) / sigma_ext;
+ output.transmission.rgb = exp(-sigma_ext*scene_distance);
+ }
+ }
+
+ return output;
+} \ No newline at end of file
diff --git a/src/shaders/ComputeLightLUT_CS.hlsl b/src/shaders/ComputeLightLUT_CS.hlsl
new file mode 100644
index 0000000..fca70dd
--- /dev/null
+++ b/src/shaders/ComputeLightLUT_CS.hlsl
@@ -0,0 +1,192 @@
+// 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 (c) 2003 - 2016 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 the shader permutations for code generation
+%% MUX_BEGIN %%
+
+- LIGHTMODE:
+ - LIGHTMODE_OMNI
+ - LIGHTMODE_SPOTLIGHT
+
+- ATTENUATIONMODE:
+ - ATTENUATIONMODE_NONE
+ - ATTENUATIONMODE_POLYNOMIAL
+ - ATTENUATIONMODE_INV_POLYNOMIAL
+
+- COMPUTEPASS:
+ - COMPUTEPASS_CALCULATE
+ - COMPUTEPASS_SUM
+
+%% MUX_END %%
+*/
+
+#include "ShaderCommon.h"
+
+float4 PackLut(float3 v, float s)
+{
+ return float4(v/s, s);
+}
+
+float3 UnpackLut(float4 v)
+{
+ return v.rgb*v.a;
+}
+
+Texture2D<float4> tPhaseLUT : register(t4);
+RWTexture2D<float4> rwLightLUT_P : register(u0);
+RWTexture2D<float4> rwLightLUT_S1 : register(u1);
+RWTexture2D<float4> rwLightLUT_S2 : register(u2);
+
+// These need to match the values in context_common.h
+static const uint LIGHT_LUT_DEPTH_RESOLUTION = 128;
+static const uint LIGHT_LUT_WDOTV_RESOLUTION = 512;
+
+#if (COMPUTEPASS == COMPUTEPASS_CALCULATE)
+
+static const uint2 BLOCK_SIZE = uint2(32, 8);
+groupshared float3 sAccum_P[BLOCK_SIZE.x*BLOCK_SIZE.y];
+
+#if (LIGHTMODE == LIGHTMODE_SPOTLIGHT)
+groupshared float3 sAccum_S1[BLOCK_SIZE.x*BLOCK_SIZE.y];
+groupshared float3 sAccum_S2[BLOCK_SIZE.x*BLOCK_SIZE.y];
+#endif
+
+[numthreads( BLOCK_SIZE.x, BLOCK_SIZE.y, 1 )]
+void main(uint3 gthreadID : SV_GroupThreadID, uint2 dispatchID : SV_DispatchThreadID, uint2 groupID : SV_GroupID)
+{
+ uint idx = gthreadID.y*BLOCK_SIZE.x + gthreadID.x;
+ float2 coord = float2(dispatchID) / float2(LIGHT_LUT_DEPTH_RESOLUTION-1, LIGHT_LUT_WDOTV_RESOLUTION-1);
+
+ float angle = coord.y * PI;
+ float cos_WV = -cos(angle);
+
+ float3 vW = g_vEyePosition - g_vLightPos;
+ float Wsqr = dot(vW, vW);
+ float W_length = sqrt(Wsqr);
+ float t0 = max(0.0f, W_length-g_fLightZFar);
+ float t_range = g_fLightZFar + W_length - t0;
+ float t = t0 + coord.x*t_range;
+
+ float WdotV = cos_WV*W_length;
+ float Dsqr = max(Wsqr+2*WdotV*t+t*t, 0.0f);
+ float D = sqrt(Dsqr);
+ float cos_phi = (t>0 && D>0) ? (t*t + Dsqr - Wsqr) / (2 * t*D) : cos_WV;
+ float3 extinction = exp(-g_vSigmaExtinction*(D+t));
+ float3 phase_factor = GetPhaseFactor(tPhaseLUT, -cos_phi);
+ float attenuation = AttenuationFunc(D);
+ float3 inscatter = phase_factor*attenuation*extinction;
+
+ // Scale by dT because we are doing quadrature
+ inscatter *= t_range / float(LIGHT_LUT_DEPTH_RESOLUTION);
+
+ inscatter = inscatter / g_vScatterPower;
+ sAccum_P[idx] = inscatter;
+#if (LIGHTMODE == LIGHTMODE_SPOTLIGHT)
+ sAccum_S1[idx] = (D==0) ? 0.0f : inscatter/D;
+ sAccum_S2[idx] = t*sAccum_S1[idx];
+#endif
+
+
+ [unroll]
+ for (uint d=1; d<32; d = d<<1)
+ {
+ if (gthreadID.x >= d)
+ {
+ sAccum_P[idx] += sAccum_P[idx - d];
+#if (LIGHTMODE == LIGHTMODE_SPOTLIGHT)
+ sAccum_S1[idx] += sAccum_S1[idx - d];
+ sAccum_S2[idx] += sAccum_S2[idx - d];
+#endif
+ }
+ }
+
+ static const float LUT_SCALE = 32.0f / 32768.0f;
+ rwLightLUT_P[dispatchID] = PackLut(sAccum_P[idx], LUT_SCALE);
+#if (LIGHTMODE == LIGHTMODE_SPOTLIGHT)
+ float max_t = 2*(t0 + t_range);
+ rwLightLUT_S1[dispatchID] = PackLut(sAccum_S1[idx], LUT_SCALE);
+ rwLightLUT_S2[dispatchID] = PackLut(sAccum_S2[idx], LUT_SCALE*max_t);
+#endif
+}
+
+#elif (COMPUTEPASS == COMPUTEPASS_SUM)
+
+static const uint2 BLOCK_SIZE = uint2(32, 4);
+
+Texture2D<float4> tLightLUT_P : register(t5);
+Texture2D<float4> tLightLUT_S1 : register(t6);
+Texture2D<float4> tLightLUT_S2 : register(t7);
+
+groupshared float3 sOffset[BLOCK_SIZE.y];
+
+[numthreads( BLOCK_SIZE.x, BLOCK_SIZE.y, 1 )]
+void main(uint3 gthreadID : SV_GroupThreadID, uint3 dispatchID : SV_DispatchThreadID, uint2 groupID : SV_GroupID)
+{
+ uint t_offset = 0;
+
+ if (gthreadID.x == 0)
+ {
+ sOffset[gthreadID.y] = float3(0, 0, 0);
+ }
+
+ [unroll]
+ for (uint t = 0; t < LIGHT_LUT_DEPTH_RESOLUTION; t += BLOCK_SIZE.x)
+ {
+ uint2 tc = dispatchID.xy + uint2(t, 0);
+ float4 s = float4(0,0,0,0);
+#if (LIGHTMODE == LIGHTMODE_SPOTLIGHT)
+ if (dispatchID.z == 2)
+ s = tLightLUT_S2[tc];
+ else if (dispatchID.z == 1)
+ s = tLightLUT_S1[tc];
+ else
+ s = tLightLUT_P[tc];
+#else
+ s = tLightLUT_P[tc];
+#endif
+ float3 v = UnpackLut(s) + sOffset[gthreadID.y];
+ if (gthreadID.x == (BLOCK_SIZE.x-1))
+ {
+ sOffset[gthreadID.y] = v;
+ }
+ s.a *= LIGHT_LUT_DEPTH_RESOLUTION/32;
+#if (LIGHTMODE == LIGHTMODE_SPOTLIGHT)
+ if (dispatchID.z == 2)
+ rwLightLUT_S2[tc] = PackLut(v, s.a);
+ else if (dispatchID.z == 1)
+ rwLightLUT_S1[tc] = PackLut(v, s.a);
+ else
+ rwLightLUT_P[tc] = PackLut(v, s.a);
+#else
+ rwLightLUT_P[tc] = PackLut(v, s.a);
+#endif
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/shaders/ComputePhaseLookup_PS.hlsl b/src/shaders/ComputePhaseLookup_PS.hlsl
new file mode 100644
index 0000000..7487c40
--- /dev/null
+++ b/src/shaders/ComputePhaseLookup_PS.hlsl
@@ -0,0 +1,150 @@
+// 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 (c) 2003 - 2016 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 the shader permutations for code generation
+%% MUX_BEGIN %%
+
+%% MUX_END %%
+*/
+
+#include "ShaderCommon.h"
+
+// using the phase functions directly isn't correct, because they are supposed to be
+// integrated over the subtended solid angle. This falls apart as sin(theta)
+// approaches 0 (ie. cos(theta) aproaches +1 or -1).
+// We apply a sliding scale to the functions to compensate for this somewhat.
+
+#define NORMALIZE_PHASE_FUNCTIONS 1
+
+float ScatterPhase_Isotropic()
+{
+ return 1.f / (4.f * PI);
+}
+
+float ScatterPhase_Rayleigh(float cosa)
+{
+ float cos_term = cosa*cosa; // ^2
+ float phase_term = (3.f/(16.f*PI)) * (1.f + cos_term);
+#if NORMALIZE_PHASE_FUNCTIONS
+ cos_term *= cos_term; // ^4
+ return phase_term*(1-cos_term/8.f);
+#else
+ return phase_term;
+#endif
+}
+
+float ScatterPhase_HenyeyGreenstein(float cosa, float g)
+{
+#if NORMALIZE_PHASE_FUNCTIONS
+ // "normalized" Henyey-Greenstein
+ float g_sqr = g*g;
+ float num = (1 - abs(g));
+ float denom = sqrt( max(1-2*g*cosa+g_sqr, 0) );
+ float frac = num/denom;
+ float scale = g_sqr + (1 - g_sqr) / (4*PI);
+ return scale * (frac*frac*frac);
+#else
+ // Classic Henyey-Greenstein
+ float k1 = (1.f-g*g);
+ float k2 = (1.f + g*g - 2.f*g*cosa);
+ return (1.f / (4.f*PI)) * k1 / pow(abs(k2), 1.5f);
+#endif
+}
+
+float ScatterPhase_MieHazy(float cosa)
+{
+ float cos_term = 0.5f*(1+cosa);
+ float cos_term_2 = cos_term*cos_term; // ^2
+ float cos_term_4 = cos_term_2*cos_term_2; // ^4
+ float cos_term_8 = cos_term_4*cos_term_4; // ^8
+ float phase_term = (1.f/(4.f*PI))*(0.5f+(9.f/2.f)*cos_term_8);
+#if NORMALIZE_PHASE_FUNCTIONS
+ return phase_term * (1-cos_term_8/2.0f);
+#else
+ return phase_term;
+#endif
+}
+
+float ScatterPhase_MieMurky(float cosa)
+{
+ float cos_term = 0.5f*(1+cosa);
+ float cos_term_2 = cos_term*cos_term; // ^2
+ float cos_term_4 = cos_term_2*cos_term_2; // ^4
+ float cos_term_8 = cos_term_4*cos_term_4; // ^8
+ float cos_term_16 = cos_term_8*cos_term_8; // ^16
+ float cos_term_32 = cos_term_16*cos_term_16; // ^32
+ float phase_term = (1.f/(4.f*PI))*(0.5f+(33.f/2.f)*cos_term_32);
+#if NORMALIZE_PHASE_FUNCTIONS
+ return phase_term * (1-cos_term_32/2.0f);
+#else
+ return phase_term;
+#endif
+}
+
+float4 main(VS_QUAD_OUTPUT input) : SV_TARGET
+{
+ float cos_theta = -cos(PI*input.vTex.y);
+ float3 phase_factor = float3(0,0,0);
+ float3 total_scatter = float3(0,0,0);
+
+ // These must match the PhaseFunctionType enum in NvVolumetricLighting.h
+ static const uint PHASEFUNC_ISOTROPIC = 0;
+ static const uint PHASEFUNC_RAYLEIGH = 1;
+ static const uint PHASEFUNC_HG = 2;
+ static const uint PHASEFUNC_MIEHAZY = 3;
+ static const uint PHASEFUNC_MIEMURKY = 4;
+
+ for (uint i=0; i<g_uNumPhaseTerms; ++i)
+ {
+ float3 term_scatter = g_vPhaseParams[i].rgb;
+ total_scatter += term_scatter;
+ if (g_uPhaseFunc[i] == PHASEFUNC_ISOTROPIC)
+ {
+ phase_factor += term_scatter*ScatterPhase_Isotropic();
+ }
+ else if (g_uPhaseFunc[i] == PHASEFUNC_RAYLEIGH)
+ {
+ phase_factor += term_scatter*ScatterPhase_Rayleigh(cos_theta);
+ }
+ else if (g_uPhaseFunc[i] == PHASEFUNC_HG)
+ {
+ phase_factor += term_scatter*ScatterPhase_HenyeyGreenstein(cos_theta, g_vPhaseParams[i].a);
+ }
+ else if (g_uPhaseFunc[i] == PHASEFUNC_MIEHAZY)
+ {
+ phase_factor += term_scatter*ScatterPhase_MieHazy(cos_theta);
+ }
+ else if (g_uPhaseFunc[i] == PHASEFUNC_MIEMURKY)
+ {
+ phase_factor += term_scatter*ScatterPhase_MieMurky(cos_theta);
+ }
+ }
+ phase_factor = phase_factor / total_scatter;
+ return float4(phase_factor, 1);
+}
diff --git a/src/shaders/Debug_PS.hlsl b/src/shaders/Debug_PS.hlsl
new file mode 100644
index 0000000..a2cd9cf
--- /dev/null
+++ b/src/shaders/Debug_PS.hlsl
@@ -0,0 +1,42 @@
+// 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 (c) 2003 - 2016 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 the shader permutations for code generation
+%% MUX_BEGIN %%
+
+%% MUX_END %%
+*/
+
+#include "ShaderCommon.h"
+
+float4 main(PS_POLYGONAL_INPUT input, bool bIsFrontFace : SV_ISFRONTFACE) : SV_TARGET
+{
+ return bIsFrontFace ? float4(1,0,0,1) : float4(0,1,0,1);
+}
+ \ No newline at end of file
diff --git a/src/shaders/DownsampleDepth_PS.hlsl b/src/shaders/DownsampleDepth_PS.hlsl
new file mode 100644
index 0000000..4f4efdd
--- /dev/null
+++ b/src/shaders/DownsampleDepth_PS.hlsl
@@ -0,0 +1,82 @@
+// 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 (c) 2003 - 2016 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 the shader permutations for code generation
+%% MUX_BEGIN %%
+
+- SAMPLEMODE:
+ - SAMPLEMODE_SINGLE
+ - SAMPLEMODE_MSAA
+
+%% MUX_END %%
+*/
+
+#include "ShaderCommon.h"
+
+#if (SAMPLEMODE == SAMPLEMODE_SINGLE)
+Texture2D<float> tDepthMap : register(t0);
+#elif (SAMPLEMODE == SAMPLEMODE_MSAA)
+Texture2DMS<float> tDepthMap : register(t0);
+#endif
+
+uint Unused(uint input)
+{
+ return input;
+}
+
+float main(
+ VS_QUAD_OUTPUT input
+ , uint sampleID : SV_SAMPLEINDEX
+ ) : SV_DEPTH
+{
+ float2 jitter = float2(0.0f, 0.0f);
+ uint2 pixelIdx = uint2(input.vPos.xy);
+ if ( (pixelIdx.x+pixelIdx.y)%2 )
+ {
+ jitter.xy = g_vJitterOffset.xy;
+ }
+ else
+ {
+ jitter.xy = g_vJitterOffset.yx;
+ }
+
+#if defined(__PSSL__)
+ Unused(sampleID);//Fix a compiler warning with pssl.
+ float2 tc = (floor(input.vTex.xy*g_vOutputViewportSize) + GetViVjLinearSample() + jitter)*g_vOutputSize_Inv;
+#else
+ float2 tc = (EvaluateAttributeAtSample(input.vTex.xy, sampleID)*g_vOutputViewportSize + jitter)*g_vOutputSize_Inv;
+#endif
+
+#if (SAMPLEMODE == SAMPLEMODE_SINGLE)
+ return tDepthMap.SampleLevel(sPoint, tc, 0).x;
+#elif (SAMPLEMODE == SAMPLEMODE_MSAA)
+ int2 load_tc = int2(tc*g_vOutputSize);
+ return tDepthMap.Load(load_tc, 0).x;
+#endif
+}
diff --git a/src/shaders/Quad_VS.hlsl b/src/shaders/Quad_VS.hlsl
new file mode 100644
index 0000000..bbb0ae2
--- /dev/null
+++ b/src/shaders/Quad_VS.hlsl
@@ -0,0 +1,46 @@
+// 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 (c) 2003 - 2016 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 the shader permutations for code generation
+%% MUX_BEGIN %%
+
+%% MUX_END %%
+*/
+
+#include "ShaderCommon.h"
+
+VS_QUAD_OUTPUT main(uint id : SV_VERTEXID)
+{
+ VS_QUAD_OUTPUT output;
+ output.vTex = float2((id << 1) & 2, id & 2);
+ output.vPos = float4(output.vTex * float2(2,-2) + float2(-1,1), 1, 1);
+ output.vWorldPos = mul( g_mViewProjInv, output.vPos );
+ output.vWorldPos *= 1.0f / output.vWorldPos.w;
+ return output;
+}
diff --git a/src/shaders/RenderVolume_DS.hlsl b/src/shaders/RenderVolume_DS.hlsl
new file mode 100644
index 0000000..880e9ed
--- /dev/null
+++ b/src/shaders/RenderVolume_DS.hlsl
@@ -0,0 +1,181 @@
+// 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 (c) 2003 - 2016 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 the shader permutations for code generation
+%% MUX_BEGIN %%
+
+- SHADOWMAPTYPE:
+ - SHADOWMAPTYPE_ATLAS
+ - SHADOWMAPTYPE_ARRAY
+
+- CASCADECOUNT:
+ - CASCADECOUNT_1: 1
+ - CASCADECOUNT_2: 2
+ - CASCADECOUNT_3: 3
+ - CASCADECOUNT_4: 4
+
+- VOLUMETYPE:
+ - VOLUMETYPE_FRUSTUM
+ - VOLUMETYPE_PARABOLOID
+
+%% MUX_END %%
+*/
+
+#include "ShaderCommon.h"
+
+#define COARSE_CASCADE (CASCADECOUNT-1)
+
+#if (SHADOWMAPTYPE == SHADOWMAPTYPE_ATLAS)
+Texture2D<float> tShadowMap : register(t1);
+#elif (SHADOWMAPTYPE == SHADOWMAPTYPE_ARRAY)
+Texture2DArray<float> tShadowMap : register(t1);
+#endif
+
+float SampleShadowMap(float2 tex_coord, int cascade)
+{
+ float depth_value = 1.0f;
+ float2 lookup_coord = g_vElementOffsetAndScale[cascade].zw * tex_coord + g_vElementOffsetAndScale[cascade].xy;
+#if (SHADOWMAPTYPE == SHADOWMAPTYPE_ATLAS)
+ depth_value = tShadowMap.SampleLevel( sBilinear, lookup_coord, 0).x;
+#elif (SHADOWMAPTYPE == SHADOWMAPTYPE_ARRAY)
+ depth_value = tShadowMap.SampleLevel( sBilinear, float3( lookup_coord, (float)g_uElementIndex[cascade] ), 0).x;
+#endif
+ return depth_value;
+}
+
+float3 ParaboloidProject(float3 P, float zNear, float zFar)
+{
+ float3 outP;
+ float lenP = length(P.xyz);
+ outP.xyz = P.xyz/lenP;
+ outP.x = outP.x / (outP.z + 1);
+ outP.y = outP.y / (outP.z + 1);
+ outP.z = (lenP - zNear) / (zFar - zNear);
+ return outP;
+}
+
+float3 ParaboloidUnproject(float3 P, float zNear, float zFar)
+{
+ // Use a quadratic to find the Z component
+ // then reverse the projection to find the unit vector, and scale
+ float L = P.z*(zFar-zNear) + zNear;
+
+ float qa = P.x*P.x + P.y*P.y + 1;
+ float qb = 2*(P.x*P.x + P.y*P.y);
+ float qc = P.x*P.x + P.y*P.y - 1;
+ float z = (-qb + sqrt(qb*qb - 4*qa*qc)) / (2*qa);
+
+ float3 outP;
+ outP.x = P.x * (z + 1);
+ outP.y = P.y * (z + 1);
+ outP.z = z;
+ return outP*L;
+}
+
+HS_POLYGONAL_CONSTANT_DATA_OUTPUT Unused(HS_POLYGONAL_CONSTANT_DATA_OUTPUT input)
+{
+ return input;
+}
+
+[domain("quad")]
+PS_POLYGONAL_INPUT main( HS_POLYGONAL_CONSTANT_DATA_OUTPUT input, float2 uv : SV_DOMAINLOCATION, const OutputPatch<HS_POLYGONAL_CONTROL_POINT_OUTPUT, 4> Patch )
+{
+ Unused(input);//Fix a compiler warning with pssl.
+
+ PS_POLYGONAL_INPUT output = (PS_POLYGONAL_INPUT)0;
+
+ float3 vClipIn1 = lerp(Patch[0].vClipPos.xyz, Patch[1].vClipPos.xyz, uv.x);
+ float3 vClipIn2 = lerp(Patch[3].vClipPos.xyz, Patch[2].vClipPos.xyz, uv.x);
+ float3 vClipIn = lerp(vClipIn1, vClipIn2, uv.y);
+
+ float4 vPos1 = lerp(Patch[0].vWorldPos, Patch[1].vWorldPos, uv.x);
+ float4 vPos2 = lerp(Patch[3].vWorldPos, Patch[2].vWorldPos, uv.x);
+ float4 vWorldPos = lerp(vPos1, vPos2, uv.y);
+
+ if (VOLUMETYPE == VOLUMETYPE_FRUSTUM)
+ {
+ if (all(abs(vClipIn.xy) < EDGE_FACTOR))
+ {
+ int iCascade = -1;
+ float4 vClipPos = float4(0,0,0,1);
+
+ [unroll]
+ for (int i = COARSE_CASCADE;i >= 0; --i)
+ {
+ // Try to refetch from finer cascade
+ float4 vClipPosCascade = mul( g_mLightProj[i], vWorldPos );
+ vClipPosCascade *= 1.f / vClipPosCascade.w;
+ if (all(abs(vClipPosCascade.xy) < 1.0f))
+ {
+
+ float2 vTex = float2(0.5*vClipPosCascade.x + 0.5, -0.5*vClipPosCascade.y + 0.5);
+ float depthSample = SampleShadowMap(vTex, i);
+ if (depthSample < 1.0f)
+ {
+
+ vClipPos.xy = vClipPosCascade.xy;
+ vClipPos.z = depthSample;
+ iCascade = i;
+ }
+ }
+ }
+
+ if (iCascade >= 0)
+ {
+ vWorldPos = mul( g_mLightProjInv[iCascade], float4(vClipPos.xyz, 1) );
+ vWorldPos *= 1.0f / vWorldPos.w;
+ vWorldPos.xyz = g_vEyePosition + (1.0f-g_fGodrayBias)*(vWorldPos.xyz-g_vEyePosition);
+ }
+ }
+ else
+ {
+ vWorldPos = mul(g_mLightToWorld, float4(vClipIn.xy, 1, 1));
+ vWorldPos *= 1.0f / vWorldPos.w;
+ }
+ }
+ else if (VOLUMETYPE == VOLUMETYPE_PARABOLOID)
+ {
+ vClipIn.xyz = normalize(vClipIn.xyz);
+ float4 shadowPos = mul(g_mLightProj[0], vWorldPos);
+ shadowPos.xyz = shadowPos.xyz/shadowPos.w;
+ uint hemisphereID = (shadowPos.z > 0) ? 0 : 1;
+ shadowPos.z = abs(shadowPos.z);
+ shadowPos.xyz = ParaboloidProject(shadowPos.xyz, g_fLightZNear, g_fLightZFar);
+ float2 shadowTC = float2(0.5f, -0.5f)*shadowPos.xy + 0.5f;
+ float depthSample = SampleShadowMap(shadowTC, hemisphereID);
+ float sceneDepth = depthSample*(g_fLightZFar-g_fLightZNear)+g_fLightZNear;
+ vWorldPos = mul( g_mLightProjInv[0], float4(vClipIn.xyz * sceneDepth, 1));
+ vWorldPos *= 1.0f / vWorldPos.w;
+ }
+
+ // Transform world position with viewprojection matrix
+ output.vWorldPos = vWorldPos;
+ output.vPos = mul( g_mViewProj, output.vWorldPos );
+ return output;
+}
diff --git a/src/shaders/RenderVolume_HS.hlsl b/src/shaders/RenderVolume_HS.hlsl
new file mode 100644
index 0000000..1689e15
--- /dev/null
+++ b/src/shaders/RenderVolume_HS.hlsl
@@ -0,0 +1,182 @@
+// 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 (c) 2003 - 2016 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 the shader permutations for code generation
+%% MUX_BEGIN %%
+
+- SHADOWMAPTYPE:
+ - SHADOWMAPTYPE_ATLAS
+ - SHADOWMAPTYPE_ARRAY
+
+- CASCADECOUNT:
+ - CASCADECOUNT_1: 1
+ - CASCADECOUNT_2: 2
+ - CASCADECOUNT_3: 3
+ - CASCADECOUNT_4: 4
+
+- VOLUMETYPE:
+ - VOLUMETYPE_FRUSTUM
+ - VOLUMETYPE_PARABOLOID
+
+- MAXTESSFACTOR:
+ - MAXTESSFACTOR_LOW: 16.0f
+ - MAXTESSFACTOR_MEDIUM: 32.0f
+ - MAXTESSFACTOR_HIGH: 64.0f
+%% MUX_END %%
+*/
+
+#define COARSE_CASCADE (CASCADECOUNT-1)
+
+#include "ShaderCommon.h"
+
+float3 NearestPos(float3 vStartPos, float3 vEndPos)
+{
+ float3 vPos = (g_vEyePosition - vStartPos);
+ float3 vLine = (vEndPos - vStartPos);
+ float lineLength = length(vLine);
+ float t = max(0, min(lineLength, dot(vPos, vLine)/lineLength));
+ return vStartPos + (t/lineLength)*vLine;
+}
+
+float CalcTessFactor(float3 vStartPos, float3 vEndPos)
+{
+ float section_size = length(vEndPos - vStartPos);
+ float3 vWorldPos = 0.5f*(vStartPos+vEndPos);
+ float3 vEyeVec = (vWorldPos.xyz - g_vEyePosition);
+ float4 clip_pos = mul( g_mProj, float4(0, 0, length(vEyeVec), 1) );
+ float projected_size = abs(section_size * g_mProj._m11 / clip_pos.w);
+ float desired_splits = (projected_size*g_vOutputViewportSize.y)/(g_fTargetRaySize);
+ return min(MAXTESSFACTOR, max(1, desired_splits));
+}
+
+bool IntersectsFrustum(float4 vPos1, float4 vPos2)
+{
+ return !(vPos1.x > 1.0 && vPos2.x > 1.0 || vPos1.x < -1.0 && vPos2.x < -1.0)
+ || !(vPos1.y > 1.0 && vPos2.y > 1.0 || vPos1.y < -1.0 && vPos2.y < -1.0)
+ || !(vPos1.z < 0.0 && vPos2.z < 0.0);
+}
+
+HS_POLYGONAL_CONSTANT_DATA_OUTPUT HS_POLYGONAL_CONSTANT_FUNC( /*uint PatchID : SV_PRIMITIVEID,*/ const OutputPatch<HS_POLYGONAL_CONTROL_POINT_OUTPUT, 4> opPatch)
+{
+ HS_POLYGONAL_CONSTANT_DATA_OUTPUT output = (HS_POLYGONAL_CONSTANT_DATA_OUTPUT)0;
+
+ bool bIsVisible = false;
+#if 1
+ //Frustum cull
+ [unroll]
+ for (int j=0; j<4; ++j)
+ {
+ float4 vScreenClip = mul(g_mViewProj, opPatch[j].vWorldPos);
+ vScreenClip *= 1.0f / vScreenClip.w;
+ float4 vOriginPos = float4(0,0,0,1);
+ if (VOLUMETYPE == VOLUMETYPE_FRUSTUM)
+ {
+ vOriginPos = mul(g_mLightToWorld, float4(opPatch[j].vClipPos.xy, 0, 1));
+ }
+ else if (VOLUMETYPE == VOLUMETYPE_PARABOLOID)
+ {
+ vOriginPos = float4(g_vLightPos, 1);
+ }
+ float4 vScreenClipOrigin = mul(g_mViewProj, vOriginPos);
+ vScreenClipOrigin *= 1.0f / vScreenClipOrigin.w;
+ bIsVisible = bIsVisible || IntersectsFrustum(vScreenClip, vScreenClipOrigin);
+ }
+#else
+ bIsVisible = true;
+#endif
+
+ if (bIsVisible)
+ {
+ float3 nearest_pos[4];
+ for (int j=0; j < 4; ++j)
+ {
+ float3 start_pos;
+ if (VOLUMETYPE == VOLUMETYPE_FRUSTUM)
+ {
+ float4 p = mul(g_mLightToWorld, float4(opPatch[j].vClipPos.xy, 0, 1));
+ start_pos = p.xyz / p.w;
+ }
+ else if (VOLUMETYPE == VOLUMETYPE_PARABOLOID)
+ start_pos = g_vLightPos;
+ else
+ start_pos = float3(0, 0, 0);
+ nearest_pos[j] = NearestPos(start_pos, opPatch[j].vWorldPos.xyz);
+ }
+
+ float tess_factor[4];
+ [unroll]
+ for (int k=0; k<4; ++k)
+ {
+ float tess_near = CalcTessFactor(nearest_pos[(k+3)%4], nearest_pos[k]);
+ float tess_far = CalcTessFactor(opPatch[(k+3)%4].vWorldPos.xyz, opPatch[k].vWorldPos.xyz);
+ tess_factor[k] = max(tess_near, tess_far);
+ if (VOLUMETYPE == VOLUMETYPE_FRUSTUM)
+ {
+ bool bIsEdge = !(all((abs(opPatch[(k + 3) % 4].vClipPos.xy) < EDGE_FACTOR) || (abs(opPatch[k].vClipPos.xy) < EDGE_FACTOR)));
+ output.fEdges[k] = (bIsEdge) ? 1.0f : tess_factor[k];
+ }
+ else if (VOLUMETYPE == VOLUMETYPE_PARABOLOID)
+ {
+ output.fEdges[k] = tess_factor[k];
+ }
+ else
+ {
+ output.fEdges[k] = 1;
+ }
+
+ }
+ output.fInside[0] = max(tess_factor[1], tess_factor[3]);
+ output.fInside[1] = max(tess_factor[0], tess_factor[2]);
+ }
+ else
+ {
+ output.fEdges[0] = 0;
+ output.fEdges[1] = 0;
+ output.fEdges[2] = 0;
+ output.fEdges[3] = 0;
+ output.fInside[0] = 0;
+ output.fInside[1] = 0;
+ }
+
+ return output;
+}
+
+[domain("quad")]
+[partitioning("integer")]
+[outputtopology("triangle_ccw")]
+[outputcontrolpoints(4)]
+[patchconstantfunc("HS_POLYGONAL_CONSTANT_FUNC")]
+[maxtessfactor(MAXTESSFACTOR)]
+HS_POLYGONAL_CONTROL_POINT_OUTPUT main( InputPatch<HS_POLYGONAL_INPUT, 4> ipPatch, uint uCPID : SV_OUTPUTCONTROLPOINTID )
+{
+ HS_POLYGONAL_CONTROL_POINT_OUTPUT output = (HS_POLYGONAL_CONTROL_POINT_OUTPUT)0;
+ output.vWorldPos = ipPatch[uCPID].vWorldPos;
+ output.vClipPos = ipPatch[uCPID].vClipPos;
+ return output;
+}
diff --git a/src/shaders/RenderVolume_PS.hlsl b/src/shaders/RenderVolume_PS.hlsl
new file mode 100644
index 0000000..f2724c2
--- /dev/null
+++ b/src/shaders/RenderVolume_PS.hlsl
@@ -0,0 +1,403 @@
+// 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 (c) 2003 - 2016 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.
+//
+
+/*
+%% MUX_BEGIN %%
+# Define the shader permutations for code generation
+
+# Are we operating on single sample or MSAA buffer
+- SAMPLEMODE:
+ - SAMPLEMODE_SINGLE
+ - SAMPLEMODE_MSAA
+
+# What type of light are we rendering
+- LIGHTMODE:
+ - LIGHTMODE_DIRECTIONAL
+ - LIGHTMODE_SPOTLIGHT
+ - LIGHTMODE_OMNI
+
+# What sort of pass are we rendering
+- PASSMODE:
+ - PASSMODE_GEOMETRY
+ - PASSMODE_SKY
+ - PASSMODE_FINAL
+
+# What is our distance attenuation function
+- ATTENUATIONMODE:
+ - ATTENUATIONMODE_NONE
+ - ATTENUATIONMODE_POLYNOMIAL
+ - ATTENUATIONMODE_INV_POLYNOMIAL
+
+# What is our spotlight angular falloff mode
+- FALLOFFMODE:
+ - FALLOFFMODE_NONE
+ - FALLOFFMODE_FIXED
+ - FALLOFFMODE_CUSTOM
+
+%% MUX_END %%
+*/
+
+#include "ShaderCommon.h"
+
+#if (PASSMODE == PASSMODE_FINAL)
+# if (SAMPLEMODE == SAMPLEMODE_SINGLE)
+
+ Texture2D<float> tSceneDepth : register(t2);
+ float LoadSceneDepth(uint2 pos, uint s)
+ {
+ return tSceneDepth.Load(int3(pos.xy, 0)).x;
+ }
+
+# elif (SAMPLEMODE == SAMPLEMODE_MSAA)
+
+ Texture2DMS<float> tSceneDepth : register(t2);
+ float LoadSceneDepth(uint2 pos, uint s)
+ {
+ return tSceneDepth.Load(int2(pos.xy), s).x;
+ }
+
+# endif
+#else
+
+ float LoadSceneDepth(uint2 pos, uint s)
+ {
+ return 1.0f;
+ }
+
+#endif
+
+Texture2D<float4> tPhaseLUT : register(t4);
+Texture2D<float4> tLightLUT_P : register(t5);
+Texture2D<float4> tLightLUT_S1 : register(t6);
+Texture2D<float4> tLightLUT_S2 : register(t7);
+
+float GetLutCoord_X(float t, float light_dist)
+{
+ float t0 = max(0.0f, light_dist-g_fLightZFar);
+ float t_range = g_fLightZFar + light_dist - t0;
+ return (t-t0) / t_range;
+}
+
+float GetLutCoord_Y(float cos_theta)
+{
+ return acos(-cos_theta) / PI;
+}
+
+float3 SampleLut(Texture2D tex, float2 tc)
+{
+ float4 s = tex.SampleLevel(sBilinear, tc, 0);
+ return s.rgb*s.a;
+}
+////////////////////////////////////////////////////////////////////////////////
+// Integration code
+
+#define INTEGRATE(result, fn, data, step_count, t0, t1) \
+{ \
+ float t_step = (t1-t0)/float(step_count); \
+ float3 sum = float3(0,0,0); \
+ sum += fn(data, t0); \
+ float t = t0+t_step; \
+ [unroll] \
+ for (uint istep=1; istep<step_count-1; istep += 2) \
+ { \
+ sum += 4*fn(data, t); \
+ t += t_step; \
+ sum += 2*fn(data, t); \
+ t += t_step; \
+ } \
+ sum += 4*fn(data, t); \
+ sum += fn(data, t1); \
+ result = (t_step/3.0f) * sum; \
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Directional Light
+
+struct LightEvaluatorData_Directional {
+ float VdotL;
+ float3 sigma;
+};
+
+float3 LightEvaluator_Directional(LightEvaluatorData_Directional data, float t)
+{
+ float3 light_to_world_depth = g_fLightToEyeDepth + t*data.VdotL;
+ return exp(-data.sigma*(t+light_to_world_depth));
+}
+
+float3 Integrate_Directional(float eye_dist, float3 vV, float3 vL)
+{
+ float VdotL = dot(vV, vL);
+ // Manually integrate over interval
+ LightEvaluatorData_Directional evaluator;
+ float3 sigma = g_vSigmaExtinction;
+ evaluator.VdotL = VdotL;
+ const uint STEP_COUNT = 6;
+ float3 integral = float3(0,0,0);
+ INTEGRATE(integral, LightEvaluator_Directional, evaluator, STEP_COUNT, 0, eye_dist);
+ return GetPhaseFactor(tPhaseLUT, -VdotL)*integral*exp(g_fLightToEyeDepth*(evaluator.sigma.r+evaluator.sigma.g+evaluator.sigma.b)/3.f);
+}
+
+float3 Integrate_SimpleDirectional(float eye_dist, float3 vV, float3 vL)
+{
+ // Do basic directional light
+ float VdotL = dot(vV, vL);
+ float3 sigma = g_vSigmaExtinction;
+ return GetPhaseFactor(tPhaseLUT, -VdotL) * (1 - exp(-sigma*eye_dist)) / (sigma);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Spotlight
+
+bool IntersectCone(out float t0, out float t1, float t_max, float cos_theta, float3 vW, float3 vV, float3 vL, float WdotL, float VdotL)
+{
+ float cos_sqr = cos_theta * cos_theta;
+ float sin_sqr = 1 - cos_sqr;
+ float3 v_proj = vV - VdotL*vL;
+ float3 w_proj = vW - WdotL*vL;
+
+ float A = cos_sqr*dot(v_proj, v_proj) - sin_sqr*VdotL*VdotL;
+ float B = 2 * cos_sqr*dot(v_proj, w_proj) - 2 * sin_sqr*VdotL*WdotL;
+ float C = cos_sqr*dot(w_proj, w_proj) - sin_sqr*WdotL*WdotL;
+
+ float det = B*B - 4 * A*C;
+ float denom = 2 * A;
+ if (det < 0.0f || denom == 0.0f)
+ {
+ t0 = 0;
+ t1 = 0;
+ return false;
+ }
+ else
+ {
+ bool hit = true;
+ float root = sqrt(det);
+ t0 = (-B - root) / denom;
+ t1 = (-B + root) / denom;
+
+ float vW_len = length(vW);
+ float WdotL_norm = (vW_len > 0.0f) ? WdotL / vW_len : 1.0f;
+ if (WdotL_norm >= cos_theta)
+ {
+ if (VdotL >= cos_theta)
+ t1 = t_max;
+ t0 = 0;
+ }
+ else if (WdotL_norm <= -cos_theta)
+ {
+ if (t0 < 0 && t1>0)
+ hit = false;
+ t0 = t0;
+ t1 = t_max;
+ }
+ else
+ {
+ if (t0 < 0 && t1 < 0)
+ hit = false;
+ else if (dot(vL, vW + t0*vV) < 0)
+ hit = false;
+ else if (t1<0)
+ t1 = t_max;
+ }
+
+ if (t0 > t_max)
+ {
+ t0 = 0;
+ t1 = 0;
+ hit = false;
+ }
+
+ return hit;
+ }
+}
+
+struct LightEvaluatorData_Spotlight
+{
+ float3 sigma;
+ float light_theta;
+ float light_falloff_power;
+ float Wsqr;
+ float WdotV;
+ float WdotL;
+ float VdotL;
+};
+
+float3 LightEvaluator_Spotlight(LightEvaluatorData_Spotlight data, float t)
+{
+ float Dsqr = max(data.Wsqr+2*data.WdotV*t+t*t, 0.0f);
+ float D = sqrt(Dsqr);
+ float cos_phi = (t>0 && D>0) ? (t*t + Dsqr - data.Wsqr) / (2 * t*D) : 0;
+ float3 phase_factor = GetPhaseFactor(tPhaseLUT, -cos_phi);
+ float distance_attenuation = AttenuationFunc(D);
+ float Dproj = data.WdotL + t*data.VdotL;
+ float cos_alpha = (D>0.0f) ? Dproj/D : 1.0f;
+ float angle_factor = saturate(cos_alpha-data.light_theta)/(1-data.light_theta);
+ const float ANGLE_EPSILON = 0.000001f;
+ float spot_attenuation = (angle_factor > ANGLE_EPSILON) ? pow(abs(angle_factor), data.light_falloff_power) : 0.0f;
+ float3 media_attenuation = exp(-data.sigma*(t+D));
+ return phase_factor*distance_attenuation*spot_attenuation*media_attenuation;
+}
+
+float3 Integrate_Spotlight(float eye_dist, float3 vW, float3 vV, float3 vL)
+{
+ float3 integral = float3(0, 0, 0);
+ float WdotL = dot(vW, vL);
+ float VdotL = dot(vV, vL);
+ float t0=0, t1=1;
+ if (IntersectCone(t0, t1, eye_dist, g_fLightFalloffAngle, vW, vV, vL, WdotL, VdotL))
+ {
+ t1 = min(t1, eye_dist);
+
+ if (FALLOFFMODE == FALLOFFMODE_NONE)
+ {
+ float light_dist = length(vW);
+ float3 vW_norm = vW / light_dist;
+ float2 tc;
+ tc.x = GetLutCoord_X(t1, light_dist);
+ tc.y = GetLutCoord_Y(dot(vW_norm, vV));
+ integral = SampleLut(tLightLUT_P, tc);
+ if (t0 > 0)
+ {
+ tc.x = GetLutCoord_X(t0, light_dist);
+ integral -= SampleLut(tLightLUT_P, tc);
+ }
+ integral *= g_vScatterPower;
+ }
+ else if (FALLOFFMODE == FALLOFFMODE_FIXED)
+ {
+ float light_dist = length(vW);
+ float3 vW_norm = vW / light_dist;
+ float2 tc;
+ tc.x = GetLutCoord_X(t1, light_dist);
+ tc.y = GetLutCoord_Y(dot(vW_norm, vV));
+ integral = WdotL*SampleLut(tLightLUT_S1, tc) + VdotL*SampleLut(tLightLUT_S2, tc) - g_fLightFalloffAngle*SampleLut(tLightLUT_P, tc);
+ if (t0 > 0)
+ {
+ tc.x = GetLutCoord_X(t0, light_dist);
+ integral -= WdotL*SampleLut(tLightLUT_S1, tc) + VdotL*SampleLut(tLightLUT_S2, tc) - g_fLightFalloffAngle*SampleLut(tLightLUT_P, tc);
+ }
+ integral *= g_vScatterPower / (1-g_fLightFalloffAngle);
+ }
+ if (FALLOFFMODE == FALLOFFMODE_CUSTOM)
+ {
+ LightEvaluatorData_Spotlight evaluator;
+ evaluator.sigma = g_vSigmaExtinction;
+ evaluator.light_theta = g_fLightFalloffAngle;
+ evaluator.light_falloff_power = g_fLightFalloffPower;
+ evaluator.Wsqr = dot(vW, vW);
+ evaluator.WdotV = dot(vW, vV);
+ evaluator.WdotL = WdotL;
+ evaluator.VdotL = VdotL;
+ const uint STEP_COUNT = 8;
+ INTEGRATE(integral, LightEvaluator_Spotlight, evaluator, STEP_COUNT, t0, t1);
+ integral *= 6;
+ }
+ }
+ return integral;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Omni
+
+float3 Integrate_Omni(float eye_dist, float3 vW, float3 vV)
+{
+ float light_dist = length(vW);
+ vW = vW / light_dist;
+ float2 tc;
+ tc.x = GetLutCoord_X(eye_dist, light_dist);
+ tc.y = GetLutCoord_Y(dot(vW, vV));
+ return g_vScatterPower*SampleLut(tLightLUT_P, tc);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Shader Entrypoint
+
+float4 main(
+#if (PASSMODE == PASSMODE_FINAL)
+ VS_QUAD_OUTPUT pi
+ , uint sampleID : SV_SAMPLEINDEX
+#else
+ PS_POLYGONAL_INPUT pi
+#endif
+ , bool bIsFrontFace : SV_ISFRONTFACE
+ ) : SV_TARGET
+{
+#if (PASSMODE != PASSMODE_FINAL)
+ uint sampleID = 0;
+#endif
+ float fSign = 0;
+ float4 vWorldPos = float4(0, 0, 0, 1);
+ float eye_dist = 0;
+ float3 vV = float3(0, 0, 0);
+ if (PASSMODE == PASSMODE_GEOMETRY)
+ {
+ fSign = bIsFrontFace ? -1.0f : 1.0f;
+ vWorldPos = pi.vWorldPos;
+ eye_dist = length(vWorldPos.xyz - g_vEyePosition.xyz);
+ vV = (vWorldPos.xyz - g_vEyePosition.xyz) / eye_dist;
+ }
+ else if (PASSMODE == PASSMODE_SKY)
+ {
+ fSign = 1.0f;
+ eye_dist = g_fZFar;
+ vV = normalize(pi.vWorldPos.xyz - g_vEyePosition.xyz);
+ vWorldPos.xyz = g_vEyePosition.xyz + vV * eye_dist;
+ vWorldPos.w = 1;
+ }
+ else if (PASSMODE == PASSMODE_FINAL)
+ {
+ fSign = 1.0f;
+ float fSceneDepth = LoadSceneDepth(pi.vPos.xy, sampleID);
+ float4 vClipPos;
+ vClipPos.xy = float2(2, -2)*g_vViewportSize_Inv*pi.vPos.xy + float2(-1.0f, 1.0f);
+ vClipPos.z = fSceneDepth;
+ vClipPos.w = 1;
+ vWorldPos = mul(g_mViewProjInv, vClipPos);
+ vWorldPos *= 1.0f / vWorldPos.w;
+ eye_dist = length(vWorldPos.xyz - g_vEyePosition.xyz);
+ vV = (vWorldPos.xyz - g_vEyePosition.xyz) / eye_dist;
+ }
+
+ float3 vL = g_vLightDir.xyz;
+
+ float3 integral = float3(0,0,0);
+ if (LIGHTMODE == LIGHTMODE_DIRECTIONAL)
+ {
+ integral = Integrate_SimpleDirectional(eye_dist, vV, vL);
+ }
+ else if (LIGHTMODE == LIGHTMODE_SPOTLIGHT)
+ {
+ float3 vW = g_vEyePosition.xyz - g_vLightPos.xyz;
+ integral = Integrate_Spotlight(eye_dist, vW, vV, vL);
+ }
+ else if (LIGHTMODE == LIGHTMODE_OMNI)
+ {
+ float3 vW = g_vEyePosition.xyz - g_vLightPos.xyz;
+ integral = Integrate_Omni(eye_dist, vW, vV);
+ }
+ return float4(fSign*integral*g_vLightIntensity.rgb, 0);
+}
diff --git a/src/shaders/RenderVolume_VS.hlsl b/src/shaders/RenderVolume_VS.hlsl
new file mode 100644
index 0000000..dc5cdb8
--- /dev/null
+++ b/src/shaders/RenderVolume_VS.hlsl
@@ -0,0 +1,204 @@
+// 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 (c) 2003 - 2016 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 the shader permutations for code generation
+%% MUX_BEGIN %%
+- MESHMODE:
+ - MESHMODE_FRUSTUM_GRID
+ - MESHMODE_FRUSTUM_BASE
+ - MESHMODE_FRUSTUM_CAP
+ - MESHMODE_OMNI_VOLUME
+ - MESHMODE_GEOMETRY
+%% MUX_END %%
+*/
+
+#include "ShaderCommon.h"
+
+// Bypass vertex shader
+HS_POLYGONAL_INPUT main(
+#if (MESHMODE == MESHMODE_GEOMETRY)
+ float4 input_position : POSITION,
+#endif
+ uint id : SV_VERTEXID )
+{
+#if (MESHMODE != MESHMODE_GEOMETRY)
+ float4 input_position = float4(0,0,0,1);
+#endif
+ HS_POLYGONAL_INPUT output;
+ //
+ // Generate the mesh dynamically from the vertex ID
+ //
+ if (MESHMODE == MESHMODE_FRUSTUM_GRID)
+ {
+ const float patch_size = 2.0f / float(g_uMeshResolution);
+ uint patch_idx = id / 4;
+ uint patch_row = patch_idx / g_uMeshResolution;
+ uint patch_col = patch_idx % g_uMeshResolution;
+ output.vClipPos.x = patch_size*patch_col - 1.0f;
+ output.vClipPos.y = patch_size*patch_row - 1.0f;
+
+ uint vtx_idx = id % 4;
+ float2 vtx_offset;
+ if (vtx_idx == 0)
+ {
+ vtx_offset = float2(0, 0);
+ }
+ else if (vtx_idx == 1)
+ {
+ vtx_offset = float2(1, 0);
+ }
+ else if (vtx_idx == 2)
+ {
+ vtx_offset = float2(1, 1);
+ }
+ else // if (vtx_idx == 3)
+ {
+ vtx_offset = float2(0, 1);
+ }
+ output.vClipPos.xy += patch_size * vtx_offset;
+
+ output.vClipPos.z = 1.0f;
+ output.vClipPos.w = 1.0f;
+ }
+ else if (MESHMODE == MESHMODE_FRUSTUM_BASE)
+ {
+ uint vtx_idx = id % 3;
+ output.vClipPos.x = (vtx_idx == 0) ? 1 : -1;
+ output.vClipPos.y = (vtx_idx == 2) ? -1 : 1;
+ output.vClipPos.xy *= (id/3 == 0) ? 1 : -1;
+ output.vClipPos.z = 1.0f;
+ output.vClipPos.w = 1.0f;
+ }
+ else if (MESHMODE == MESHMODE_FRUSTUM_CAP)
+ {
+ uint tris_per_face = g_uMeshResolution+1;
+ uint verts_per_face = 3*tris_per_face;
+ uint face_idx = id / verts_per_face;
+ uint vtx_idx = id % 3;
+ if (face_idx < 4)
+ {
+ // Cap Side
+ const float patch_size = 2.0f / float(g_uMeshResolution);
+ const uint split_point = (g_uMeshResolution+1)/2;
+ float3 v;
+ uint tri_idx = (id%verts_per_face)/3;
+ if (tri_idx < g_uMeshResolution)
+ {
+ if (vtx_idx == 0)
+ v.x = (tri_idx >= split_point) ? 1 : -1;
+ else if (vtx_idx == 1)
+ v.x = patch_size * tri_idx - 1;
+ else // if (vtx_idx == 2)
+ v.x = patch_size * (tri_idx+1) - 1;
+ v.y = (vtx_idx == 0) ? 0 : 1;
+ }
+ else
+ {
+ if (vtx_idx == 1)
+ v.x = patch_size*split_point-1;
+ else
+ v.x = (vtx_idx == 0) ? -1 : 1;
+ v.y = (vtx_idx == 1) ? 1 : 0;
+ }
+ v.z = 1;
+ v.xz *= (face_idx/2 == 0) ? 1 : -1;
+ output.vClipPos.xyz = (face_idx%2 == 0) ? v.zxy : v.xzy*float3(-1,1,1);
+ }
+ else
+ {
+ // Z=0
+ uint tri_idx = (id-4*verts_per_face)/3;
+ output.vClipPos.x = (vtx_idx == 1) ? 1 : -1;
+ output.vClipPos.y = (vtx_idx == 2) ? 1 : -1;
+ output.vClipPos.xy *= (tri_idx == 0) ? 1 : -1;
+ output.vClipPos.z = 0.0f;
+ }
+ output.vClipPos.w = 1.0f;
+ }
+ else if (MESHMODE == MESHMODE_OMNI_VOLUME)
+ {
+ uint verts_per_face = 4*g_uMeshResolution*g_uMeshResolution;
+ uint face_idx = id / verts_per_face;
+ uint face_vert_idx = id % verts_per_face;
+
+ const float patch_size = 2.0f / float(g_uMeshResolution);
+ uint patch_idx = face_vert_idx / 4;
+ uint patch_row = patch_idx / g_uMeshResolution;
+ uint patch_col = patch_idx % g_uMeshResolution;
+
+ float3 P;
+ P.x = patch_size*patch_col - 1.0f;
+ P.y = patch_size*patch_row - 1.0f;
+
+ uint vtx_idx = id % 4;
+ float2 vtx_offset;
+ if (vtx_idx == 0)
+ {
+ vtx_offset = float2(0, 0);
+ }
+ else if (vtx_idx == 1)
+ {
+ vtx_offset = float2(1, 0);
+ }
+ else if (vtx_idx == 2)
+ {
+ vtx_offset = float2(1, 1);
+ }
+ else // if (vtx_idx == 3)
+ {
+ vtx_offset = float2(0, 1);
+ }
+ P.xy += patch_size * vtx_offset;
+ P.z = ((face_idx / 3) == 0) ? 1 : -1;
+ if ((face_idx % 3) == 0)
+ P.yzx = P.xyz * (((face_idx / 3) == 0) ? float3(1,1,1) : float3(-1,1,1));
+ else if ((face_idx % 3) == 1)
+ P.xzy = P.xyz * (((face_idx / 3) == 1) ? float3(1,1,1) : float3(-1,1,1));
+ else //if ((face_idx % 3) == 2)
+ P.xyz = P.xyz * (((face_idx / 3) == 0) ? float3(1,1,1) : float3(-1,1,1));
+ output.vClipPos = float4(normalize(P.xyz), 1);
+ }
+ else
+ {
+ output.vClipPos = input_position;
+
+ }
+
+ if (MESHMODE == MESHMODE_OMNI_VOLUME)
+ {
+ output.vWorldPos = mul(g_mLightToWorld, float4(g_fLightZFar*output.vClipPos.xyz, 1));
+ }
+ else
+ {
+ output.vWorldPos = mul(g_mLightToWorld, output.vClipPos);
+ }
+ output.vWorldPos = output.vWorldPos / output.vWorldPos.w;
+ output.vPos = mul(g_mViewProj, output.vWorldPos);
+ return output;
+}
diff --git a/src/shaders/Resolve_PS.hlsl b/src/shaders/Resolve_PS.hlsl
new file mode 100644
index 0000000..72c07f9
--- /dev/null
+++ b/src/shaders/Resolve_PS.hlsl
@@ -0,0 +1,179 @@
+// 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 (c) 2003 - 2016 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 the shader permutations for code generation
+%% MUX_BEGIN %%
+
+- SAMPLEMODE:
+ - SAMPLEMODE_SINGLE
+ - SAMPLEMODE_MSAA
+
+%% MUX_END %%
+*/
+
+#include "ShaderCommon.h"
+
+struct RESOLVE_OUTPUT
+{
+ float3 color : SV_TARGET0;
+ float2 depth : SV_TARGET1;
+};
+
+#if (SAMPLEMODE == SAMPLEMODE_MSAA)
+Texture2DMS<float4> tGodraysBuffer : register(t0);
+Texture2DMS<float> tGodraysDepth : register(t1);
+#elif (SAMPLEMODE == SAMPLEMODE_SINGLE)
+Texture2D<float4> tGodraysBuffer : register(t0);
+Texture2D<float> tGodraysDepth : register(t1);
+#endif
+
+#if (defined(__PSSL__) && (SAMPLEMODE == SAMPLEMODE_MSAA))
+Texture2D<int2> tFMask_color : register(t2);
+#endif
+
+#if defined(__PSSL__)
+static const int FMASK_UNKNOWN = 1 << 3; // color "unknown" is always represented as high bit in the 4bit fragment index
+
+int2 getFmask(Texture2D <int2> tex, int sample_count, int2 coord)
+{
+ // if 8 or less coverage samples, only load one VGPR (32bits / 4bits per sample)
+ // if more than 8 coverage samples, we need to load 2 VGPRs
+ int2 fmask;
+ if (sample_count <= 8)
+ {
+ fmask.x = tex.Load(int3(coord, 0)).x;
+ fmask.y = 0x88888888; // all invalid -- though in theory we shouldn't need to refer to them at all.
+ }
+ else
+ {
+ fmask.xy = tex.Load(int3(coord, 0)).xy;
+ }
+ return fmask;
+}
+
+int getFptr(int index, int2 fmask)
+{
+ const int bitShift = 4; // fmask load always returns a 4bit fragment index (fptr) per coverage sample, regardless of actual number of fragments.
+ const int mask = (1 << bitShift) - 1;
+ if (index < 8)
+ return (fmask.x >> (index*bitShift)) & mask;
+ else
+ return (fmask.y >> ((index-8)*bitShift)) & mask;
+}
+#endif
+
+RESOLVE_OUTPUT main(VS_QUAD_OUTPUT input)
+{
+ float3 result_color = 0.0f;
+ float result_depth = 0.0f;
+ float result_depth_sqr = 0.0f;
+
+#if (SAMPLEMODE == SAMPLEMODE_MSAA)
+ uint2 buffer_size;
+ uint buffer_samples;
+ tGodraysBuffer.GetDimensions(buffer_size.x, buffer_size.y, buffer_samples);
+#elif (SAMPLEMODE == SAMPLEMODE_SINGLE)
+ uint buffer_samples = 1;
+#endif
+
+ int2 base_tc = int2(input.vTex * g_vViewportSize);
+ const float FILTER_SCALE = 1.0f;
+ const int KERNEL_WIDTH = 1;
+ float total_weight = 0.0f;
+ [unroll]
+ for (int ox=-KERNEL_WIDTH; ox<=KERNEL_WIDTH; ++ox)
+ {
+ if ((base_tc.x + ox) < 0 || (base_tc.x + ox) >= g_vViewportSize.x) continue;
+
+ [unroll]
+ for (int oy=-KERNEL_WIDTH; oy<=KERNEL_WIDTH; ++oy)
+ {
+ if ((base_tc.y + oy) < 0 || (base_tc.y + oy) >= g_vViewportSize.y) continue;
+
+ int2 offset = int2(ox, oy);
+ int2 tc = base_tc + offset;
+
+#if (defined(__PSSL__) && (SAMPLEMODE == SAMPLEMODE_MSAA))
+ int2 fmask = getFmask(tFMask_color, buffer_samples, tc);
+#endif
+
+#if (SAMPLEMODE == SAMPLEMODE_MSAA)
+ for (uint s=0; s<buffer_samples; ++s)
+ {
+ float2 so = offset + tGodraysBuffer.GetSamplePosition(s);
+#elif (SAMPLEMODE == SAMPLEMODE_SINGLE)
+ {
+ float2 so = offset;
+#endif
+ bool is_valid_sample = false;
+#if (SAMPLEMODE == SAMPLEMODE_MSAA)
+# if defined(__PSSL__)
+ float3 sample_value = float3(0,0,0);
+ float sample_depth = 0.0f;
+ int fptr = getFptr(s, fmask);
+ if (fptr != FMASK_UNKNOWN)
+ {
+ sample_value = tGodraysBuffer.Load(tc, fptr).rgb;
+ sample_depth = tGodraysDepth.Load( tc, fptr ).r;
+ is_valid_sample = true;
+ }
+# else // !defined(__PSSL__)
+ is_valid_sample = true;
+ float3 sample_value = tGodraysBuffer.Load( tc, s ).rgb;
+ float sample_depth = tGodraysDepth.Load( tc, s ).r;
+# endif
+#elif (SAMPLEMODE == SAMPLEMODE_SINGLE)
+ is_valid_sample = true;
+ float3 sample_value = tGodraysBuffer.Load( int3(tc, 0) ).rgb;
+ float sample_depth = tGodraysDepth.Load( int3(tc, 0) ).r;
+#endif
+ sample_depth = LinearizeDepth(sample_depth, g_fZNear, g_fZFar);
+ if (!all(isfinite(sample_value)))
+ {
+ is_valid_sample = false;
+ }
+
+ if (is_valid_sample)
+ {
+ so *= g_fResMultiplier;
+ float weight = GaussianApprox(so, FILTER_SCALE);
+ result_color += weight * sample_value;
+ result_depth += weight * sample_depth;
+ result_depth_sqr += weight * sample_depth*sample_depth;
+ total_weight += weight;
+ }
+ }
+ }
+ }
+
+ RESOLVE_OUTPUT output;
+ output.color = (total_weight > 0.0f) ? result_color/total_weight : float3(0.f, 0.f, 0.f);
+ output.depth = (total_weight > 0.0f) ? float2(result_depth, result_depth_sqr)/total_weight : 1.0f;
+ return output;
+}
diff --git a/src/shaders/ShaderCommon.h b/src/shaders/ShaderCommon.h
new file mode 100644
index 0000000..f4b8f80
--- /dev/null
+++ b/src/shaders/ShaderCommon.h
@@ -0,0 +1,265 @@
+// 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 (C) 2013, NVIDIA Corporation. All rights reserved.
+
+/*===========================================================================
+Constants
+===========================================================================*/
+
+static const float PI = 3.1415926535898f;
+static const float EDGE_FACTOR = 1.0f - (2.0f/64.0f) * (1.0f/64.0f);
+static const uint MAX_PHASE_TERMS = 4;
+
+#ifdef __PSSL__
+static const float2 SAMPLE_POSITIONS[] = {
+ // 1x
+ float2( 0, 0)/16.f,
+ // 2x
+ float2(-4, 4)/16.f,
+ float2( 4,-4)/16.f,
+ // 4x
+ float2(-6, 6)/16.f,
+ float2( 6,-6)/16.f,
+ float2(-2,-2)/16.f,
+ float2( 2, 2)/16.f,
+ // 8x
+ float2(-7,-3)/16.f,
+ float2( 7, 3)/16.f,
+ float2( 1,-5)/16.f,
+ float2(-5, 5)/16.f,
+ float2(-3,-7)/16.f,
+ float2( 3, 7)/16.f,
+ float2( 5,-1)/16.f,
+ float2(-1, 1)/16.f
+};
+
+// constant buffers
+#define cbuffer ConstantBuffer
+
+// textures and samplers
+#define Texture2DMS MS_Texture2D
+#define Texture2DArray Texture2D_Array
+#define SampleLevel SampleLOD
+#define GetSamplePosition(s) GetSamplePoint(s)
+
+// semantics
+#define SV_DEPTH S_DEPTH_OUTPUT
+#define SV_DOMAINLOCATION S_DOMAIN_LOCATION
+#define SV_INSIDETESSFACTOR S_INSIDE_TESS_FACTOR
+#define SV_INSTANCEID S_INSTANCE_ID
+#define SV_ISFRONTFACE S_FRONT_FACE
+#define SV_OUTPUTCONTROLPOINTID S_OUTPUT_CONTROL_POINT_ID
+#define SV_POSITION S_POSITION
+#define SV_POSITION S_POSITION
+#define SV_PRIMITIVEID S_PRIMITIVE_ID
+#define SV_SAMPLEINDEX S_SAMPLE_INDEX
+#define SV_TARGET S_TARGET_OUTPUT
+#define SV_TARGET0 S_TARGET_OUTPUT0
+#define SV_TARGET1 S_TARGET_OUTPUT1
+#define SV_TESSFACTOR S_EDGE_TESS_FACTOR
+#define SV_VERTEXID S_VERTEX_ID
+
+// hull and domain shader properties
+#define domain DOMAIN_PATCH_TYPE
+#define partitioning PARTITIONING_TYPE
+#define outputtopology OUTPUT_TOPOLOGY_TYPE
+#define outputcontrolpoints OUTPUT_CONTROL_POINTS
+#define patchconstantfunc PATCH_CONSTANT_FUNC
+#define maxtessfactor MAX_TESS_FACTOR
+
+// need to figure out how to deal with those exactly:
+#define shared
+#endif
+
+/*===========================================================================
+Sampler states
+===========================================================================*/
+SamplerState sPoint : register(s0);
+SamplerState sBilinear : register(s1);
+
+/*===========================================================================
+Constant buffers
+===========================================================================*/
+shared cbuffer cbContext : register(b0)
+{
+ float2 g_vOutputSize : packoffset(c0);
+ float2 g_vOutputSize_Inv : packoffset(c0.z);
+ float2 g_vBufferSize : packoffset(c1);
+ float2 g_vBufferSize_Inv : packoffset(c1.z);
+ float g_fResMultiplier : packoffset(c2);
+ unsigned int g_uBufferSamples : packoffset(c2.y);
+}
+
+shared cbuffer cbFrame : register(b1)
+{
+ column_major float4x4 g_mProj : packoffset(c0);
+ column_major float4x4 g_mViewProj : packoffset(c4);
+ column_major float4x4 g_mViewProjInv: packoffset(c8);
+ float2 g_vOutputViewportSize : packoffset(c12);
+ float2 g_vOutputViewportSize_Inv : packoffset(c12.z);
+ float2 g_vViewportSize : packoffset(c13);
+ float2 g_vViewportSize_Inv : packoffset(c13.z);
+ float3 g_vEyePosition : packoffset(c14);
+ float2 g_vJitterOffset : packoffset(c15);
+ float g_fZNear : packoffset(c15.z);
+ float g_fZFar : packoffset(c15.w);
+ float3 g_vScatterPower : packoffset(c16);
+ unsigned int g_uNumPhaseTerms : packoffset(c16.w);
+ float3 g_vSigmaExtinction : packoffset(c17);
+ unsigned int g_uPhaseFunc[4] : packoffset(c18);
+ float4 g_vPhaseParams[4] : packoffset(c22);
+};
+
+shared cbuffer cbVolume : register(b2)
+{
+ column_major float4x4 g_mLightToWorld : packoffset(c0);
+ float g_fLightFalloffAngle : packoffset(c4.x);
+ float g_fLightFalloffPower : packoffset(c4.y);
+ float g_fGridSectionSize : packoffset(c4.z);
+ float g_fLightToEyeDepth : packoffset(c4.w);
+ float g_fLightZNear : packoffset(c5);
+ float g_fLightZFar : packoffset(c5.y);
+ float4 g_vLightAttenuationFactors : packoffset(c6);
+ column_major float4x4 g_mLightProj[4] : packoffset(c7);
+ column_major float4x4 g_mLightProjInv[4]: packoffset(c23);
+ float3 g_vLightDir : packoffset(c39);
+ float g_fGodrayBias : packoffset(c39.w);
+ float3 g_vLightPos : packoffset(c40);
+ unsigned int g_uMeshResolution : packoffset(c40.w);
+ float3 g_vLightIntensity : packoffset(c41);
+ float g_fTargetRaySize : packoffset(c41.w);
+ float4 g_vElementOffsetAndScale[4] : packoffset(c42);
+ float4 g_vShadowMapDim : packoffset(c46);
+ unsigned int g_uElementIndex[4] : packoffset(c47);
+};
+
+shared cbuffer cbApply : register(b3)
+{
+ column_major float4x4 g_mHistoryXform : packoffset(c0);
+ float g_fFilterThreshold : packoffset(c4);
+ float g_fHistoryFactor : packoffset(c4.y);
+ float3 g_vFogLight : packoffset(c5);
+ float g_fMultiScattering : packoffset(c5.w);
+};
+
+/*===========================================================================
+Shader inputs
+===========================================================================*/
+struct VS_POLYGONAL_INPUT
+{
+ float4 vPos : POSITION;
+};
+
+struct HS_POLYGONAL_INPUT
+{
+ float4 vPos : SV_POSITION;
+ float4 vWorldPos : TEXCOORD0;
+ float4 vClipPos : TEXCOORD1;
+};
+
+struct HS_POLYGONAL_CONTROL_POINT_OUTPUT
+{
+ float4 vWorldPos : TEXCOORD0;
+ float4 vClipPos : TEXCOORD1;
+};
+
+struct HS_POLYGONAL_CONSTANT_DATA_OUTPUT
+{
+ float fEdges[4] : SV_TESSFACTOR;
+ float fInside[2] : SV_INSIDETESSFACTOR;
+ float debug[4] : TEXCOORD2;
+};
+
+struct PS_POLYGONAL_INPUT
+{
+ float4 vPos : SV_POSITION;
+ float4 vWorldPos : TEXCOORD0;
+#ifdef __PSSL__
+ float dummy : CLIPPPOSDUMMY; //Workaround for compiler exception in polygon hull shaders.
+#endif
+};
+
+struct VS_QUAD_OUTPUT
+{
+ float4 vPos : SV_POSITION;
+ sample float4 vWorldPos : TEXCOORD0;
+ sample float2 vTex : TEXCOORD1;
+};
+
+/*===========================================================================
+Common functions
+===========================================================================*/
+
+float LinearizeDepth(float d, float zn, float zf)
+{
+ return d * zn / (zf - ((zf - zn) * d));
+}
+
+float WarpDepth(float z, float zn, float zf)
+{
+ return z * (1+zf/zn) / (1+z*zf/zn);
+}
+
+float MapDepth(float d, float zn, float zf)
+{
+ return (d - zn) / (zf - zn);
+}
+
+// Approximates a non-normalized gaussian with Sigma == 1
+float GaussianApprox(float2 sample_pos, float width)
+{
+ float x_sqr = sample_pos.x*sample_pos.x + sample_pos.y*sample_pos.y;
+ // exp(-0.5*(x/w)^2) ~ (1-(x/(8*w))^2)^32
+ float w = saturate(1.0f - x_sqr/(64.0f * width*width));
+ w = w*w; // ^2
+ w = w*w; // ^4
+ w = w*w; // ^8
+ w = w*w; // ^16
+ w = w*w; // ^32
+ return w;
+}
+
+#if defined(ATTENUATIONMODE)
+float AttenuationFunc(float d)
+{
+ if (ATTENUATIONMODE == ATTENUATIONMODE_POLYNOMIAL)
+ {
+ // 1-(A+Bx+Cx^2)
+ return saturate(1.0f - (g_vLightAttenuationFactors.x + g_vLightAttenuationFactors.y*d + g_vLightAttenuationFactors.z*d*d));
+ }
+ else if (ATTENUATIONMODE == ATTENUATIONMODE_INV_POLYNOMIAL)
+ {
+ // 1 / (A+Bx+Cx^2) + D
+ return saturate(1.0f / (g_vLightAttenuationFactors.x + g_vLightAttenuationFactors.y*d + g_vLightAttenuationFactors.z*d*d) + g_vLightAttenuationFactors.w);
+ }
+ else //if (ATTENUATIONMODE == ATTENUATIONMODE_NONE)
+ {
+ return 1.0f;
+ }
+}
+#endif
+
+float3 GetPhaseFactor(Texture2D tex, float cos_theta)
+{
+ float2 tc;
+ tc.x = 0;
+ tc.y = acos(clamp(-cos_theta, -1.0f, 1.0f)) / PI;
+ return g_vScatterPower*tex.SampleLevel(sBilinear, tc, 0).rgb;
+}
diff --git a/src/shaders/TemporalFilter_PS.hlsl b/src/shaders/TemporalFilter_PS.hlsl
new file mode 100644
index 0000000..082e577
--- /dev/null
+++ b/src/shaders/TemporalFilter_PS.hlsl
@@ -0,0 +1,207 @@
+// 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 (c) 2003 - 2016 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 the shader permutations for code generation
+%% MUX_BEGIN %%
+
+%% MUX_END %%
+*/
+
+#include "ShaderCommon.h"
+
+Texture2D<float4> tCurrBuffer : register(t0);
+Texture2D<float4> tLastBuffer : register(t1);
+Texture2D<float2> tCurrDepth : register(t2);
+Texture2D<float2> tLastDepth : register(t3);
+
+static const int2 NEIGHBOR_OFFSETS[] = {
+ int2(-1, -1), int2( 0, -1), int2( 1, -1),
+ int2(-1, 0), int2( 0, 0), int2( 1, 0),
+ int2(-1, 1), int2( 0, 1), int2( 1, 1)
+};
+
+#if 1
+static const float NEIGHBOR_WEIGHTS[] = {
+ 0.015625f, 0.125000f, 0.015625f,
+ 0.125000f, 1.000000f, 0.125000f,
+ 0.015625f, 0.125000f, 0.015625f,
+};
+#else
+static const float NEIGHBOR_WEIGHTS[] = {
+ 0, 0, 0,
+ 0, 1, 0,
+ 0, 0, 0,
+};
+#endif
+
+float RGB_to_Y (float3 input)
+{
+ return 0.50f*input.g + 0.25f*(input.r + input.b);
+}
+
+float3 RGB_to_YCoCg (float3 input)
+{
+ float3 ret;
+ float tmp = 0.25f*(input.r + input.b);
+ ret.x = 0.50f*input.g + tmp;
+ ret.y = 0.50f*(input.r - input.b);
+ ret.z = 0.50f*input.g - tmp;
+ return ret;
+}
+
+float3 YCoCg_to_RGB(float3 input)
+{
+ float3 ret;
+ float Y_val = input.x; float Co = input.y; float Cg = input.z;
+ float tmp = Y_val - Cg;
+ ret.r = tmp + Co;
+ ret.g = Y_val + Cg;
+ ret.b = tmp - Co;
+ return ret;
+}
+
+float3 Tonemap( float3 sample_rgb )
+{
+ sample_rgb = sample_rgb / (1 + sample_rgb);
+ return RGB_to_YCoCg(sample_rgb);
+}
+
+float3 Tonemap_Inv( float3 sample_YCoCg )
+{
+ float3 sample_rgb = YCoCg_to_RGB(sample_YCoCg);
+ return sample_rgb / (1 - sample_rgb);
+}
+
+struct FILTER_OUTPUT
+{
+ float3 color : SV_TARGET0;
+ float2 depth : SV_TARGET1;
+};
+
+FILTER_OUTPUT main(VS_QUAD_OUTPUT input)
+{
+ FILTER_OUTPUT output;
+
+ // load neighbors
+ float3 curr_sample = float3(0,0,0);
+ float2 curr_depth = float2(0,0);
+ float neighborhood_bounds_max = 0;
+ float neighborhood_bounds_min = 0;
+ int2 max_dimensions = int2(g_vViewportSize);
+ int2 base_tc = int2(floor(input.vTex.xy*max_dimensions));
+ float total_weight = -1.0f;
+
+ [unroll]
+ for (int n=0; n<9; ++n)
+ {
+ int2 sample_tc = max( int2(0,0), min(max_dimensions, base_tc + NEIGHBOR_OFFSETS[n]));
+ float3 neighbor_sample = max(float3(0,0,0), tCurrBuffer.Load(int3(sample_tc, 0)).rgb);
+ float2 neighbor_depth = tCurrDepth.Load(int3(sample_tc, 0)).rg;
+ bool is_valid = all(isfinite(neighbor_sample.xyz));
+ if (is_valid)
+ {
+ neighbor_sample = Tonemap(neighbor_sample);
+ float weight = NEIGHBOR_WEIGHTS[n];
+ curr_sample += weight*neighbor_sample;
+ curr_depth += weight*neighbor_depth;
+ if (total_weight <= 0.0f)
+ {
+ neighborhood_bounds_max = neighbor_sample.x;
+ neighborhood_bounds_min = neighbor_sample.x;
+ total_weight = weight;
+ }
+ else
+ {
+ neighborhood_bounds_max = max(neighborhood_bounds_max, neighbor_sample.x);
+ neighborhood_bounds_min = min(neighborhood_bounds_min, neighbor_sample.x);
+ total_weight += weight;
+ }
+ }
+ }
+ curr_sample = (total_weight > 0) ? curr_sample/total_weight : float3(0,0,0);
+ curr_depth = (total_weight > 0) ? curr_depth/total_weight : float2(1, 1);
+
+ // Transform and apply history
+ const float MAX_HISTORY_FACTOR = 0.98f;
+ float history_factor = g_fHistoryFactor;
+
+ float4 curr_clip;
+ curr_clip.xy = float2(2, -2) * input.vTex.xy + float2(-1, 1);
+ curr_clip.z = WarpDepth(curr_depth.x, g_fZNear, g_fZFar);
+ curr_clip.w = 1;
+ float4 last_clip = mul( g_mHistoryXform, curr_clip );
+ last_clip = last_clip/last_clip.w;
+
+ float2 last_tc = saturate((float2(0.5f, -0.5f)*last_clip.xy+float2(0.5f, 0.5f))) * max_dimensions;
+ float3 last_sample = tLastBuffer.Load(int3(last_tc, 0)).rgb;
+ float2 last_depth = tLastDepth.Load(int3(last_tc, 0)).rg;
+ last_sample = all(isfinite(last_sample)) ? Tonemap(last_sample) : curr_sample;
+
+ history_factor = all(abs(last_clip.xy) <= 1.0f) ? history_factor : 0.0f;
+
+ float2 clip_diff = (last_clip.xy - curr_clip.xy) * g_vViewportSize * g_vViewportSize_Inv.xx;
+ float clip_dist = length(clip_diff);
+ float movement_factor = saturate(1.0f - clip_dist/g_fFilterThreshold);
+ history_factor *= movement_factor*movement_factor*movement_factor;
+
+ float depth_diff = abs(curr_depth.r-last_depth.r);
+ float local_variance = abs(curr_depth.g - curr_depth.r*curr_depth.r) + abs(last_depth.g - last_depth.r*last_depth.r);
+ local_variance = max(local_variance, 0.0001f);
+#if 0
+ float local_stddev = sqrt(local_variance);
+ float depth_factor = saturate(depth_diff-local_stddev);
+ depth_factor = local_stddev / (local_stddev + depth_factor);
+#else
+ float depth_factor = saturate(depth_diff-local_variance);
+ depth_factor = local_variance / (local_variance + depth_factor);
+#endif
+ history_factor *= depth_factor;
+
+ // threshold based on neighbors
+ // Convert to Y Co Cg, then clip to bounds of neighborhood
+ float3 blended_sample = curr_sample;
+ float2 blended_depth = curr_depth;
+ if (history_factor > 0.0f)
+ {
+ const float CLIP_EPSILON = 0.0001f;
+ float3 clip_vec = last_sample - curr_sample;
+ float clamped_Y = max(neighborhood_bounds_min, min(neighborhood_bounds_max, last_sample.x));
+ float clip_factor_Y = (abs(clip_vec.x) > CLIP_EPSILON) ? abs((clamped_Y-curr_sample.x) / clip_vec.x) : 1.0f;
+ float clip_factor = clip_factor_Y;
+ float3 clipped_history = curr_sample + clip_factor*clip_vec;
+
+ history_factor = min(history_factor, MAX_HISTORY_FACTOR);
+ blended_sample = lerp(curr_sample, clipped_history, history_factor);
+ blended_depth = lerp(curr_depth, last_depth, history_factor);
+ }
+
+ output.color = Tonemap_Inv(blended_sample);
+ output.depth = blended_depth;
+ return output;
+}
diff --git a/tools/shadermux.exe b/tools/shadermux.exe
new file mode 100644
index 0000000..0a2377c
--- /dev/null
+++ b/tools/shadermux.exe
Binary files differ