aboutsummaryrefslogtreecommitdiff
path: root/samples/VolumetricLightingTest/d3d11/d3d11_main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'samples/VolumetricLightingTest/d3d11/d3d11_main.cpp')
-rw-r--r--samples/VolumetricLightingTest/d3d11/d3d11_main.cpp478
1 files changed, 478 insertions, 0 deletions
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;
+}