aboutsummaryrefslogtreecommitdiff
path: root/demo/d3d11/demoContextD3D11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'demo/d3d11/demoContextD3D11.cpp')
-rw-r--r--demo/d3d11/demoContextD3D11.cpp1147
1 files changed, 1147 insertions, 0 deletions
diff --git a/demo/d3d11/demoContextD3D11.cpp b/demo/d3d11/demoContextD3D11.cpp
new file mode 100644
index 0000000..0eaf0f4
--- /dev/null
+++ b/demo/d3d11/demoContextD3D11.cpp
@@ -0,0 +1,1147 @@
+#include "core/maths.h"
+#include "core/extrude.h"
+
+#include "shaders.h"
+
+#include "meshRenderD3D11.h"
+#include "pointRenderD3D11.h"
+#include "fluidRenderD3D11.h"
+#include "diffuseRenderD3D11.h"
+#include "debugLineRenderD3D11.h"
+
+#include "shadowMapD3D11.h"
+#include "renderTargetD3D11.h"
+
+#include "imguiGraphD3D11.h"
+
+#include "appD3D11Ctx.h"
+
+#include "../d3d/demoContext.h"
+#include "../d3d/loader.h"
+
+#include <d3d11.h>
+#include <d3dcompiler.h>
+
+#include <cstdlib>
+
+// this
+#include "demoContextD3D11.h"
+
+namespace
+{
+// COM object release utilities
+template <class T>
+void inline COMRelease(T& t)
+{
+ if (t) t->Release();
+ t = nullptr;
+}
+
+template <class T>
+void inline COMRelease(T& t, UINT arraySize)
+{
+ for (UINT i = 0; i < arraySize; i++)
+ {
+ if (t[i]) t[i]->Release();
+ t[i] = nullptr;
+ }
+}
+}
+
+extern Colour g_colors[];
+static const int kShadowResolution = 2048;
+
+DemoContext* CreateDemoContextD3D11()
+{
+ return new DemoContextD3D11;
+}
+
+DemoContextD3D11::DemoContextD3D11()
+{
+ m_appGraphCtx = nullptr;
+ m_appGraphCtxD3D11 = nullptr;
+ memset(&m_meshDrawParams, 0, sizeof(m_meshDrawParams));
+
+ m_spotMin = 0.5f;
+ m_spotMax = 1.0f;
+ m_shadowBias = 0.075f;
+
+ m_shadowMap = nullptr;
+ m_immediateMesh = nullptr;
+
+ m_window = nullptr;
+
+ m_msaaSamples = 1;
+
+ m_renderTimerDisjoint = nullptr;
+ m_renderTimerBegin = nullptr;
+ m_renderTimerEnd = nullptr;
+ m_renderCompletionFence = nullptr;
+
+ m_compositeBlendState = nullptr;
+
+ m_fluidResolvedTarget = nullptr;
+ m_fluidResolvedTargetSRV = nullptr;
+
+ m_debugLineRender = new DebugLineRenderD3D11;
+ m_meshRenderer = new MeshRendererD3D11;
+ m_pointRenderer = new PointRendererD3D11;
+ m_diffuseRenderer = new DiffuseRendererD3D11;
+}
+
+// convert an OpenGL style projection matrix to D3D (clip z range [0, 1])
+Matrix44 ConvertToD3DProjection(const Matrix44& proj)
+{
+ Matrix44 scale = Matrix44::kIdentity;
+ scale.columns[2][2] = 0.5f;
+
+ Matrix44 bias = Matrix44::kIdentity;
+ bias.columns[3][2] = 1.0f;
+
+ return scale*bias*proj;
+}
+
+#define checkDxErrors(err) __checkDxErrors (err, __FILE__, __LINE__)
+
+inline void __checkDxErrors(HRESULT err, const char *file, const int line)
+{
+ if (FAILED(err))
+ {
+ char* lpMsgBuf;
+
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ err,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&lpMsgBuf,
+ 0, NULL);
+
+ fprintf(stdout, "DX Error = %04d \"%s\" from file <%s>, line %i.\n",
+ err, lpMsgBuf, file, line);
+
+ exit(EXIT_FAILURE);
+ }
+}
+
+DemoContextD3D11::~DemoContextD3D11()
+{
+ imguiGraphDestroy();
+
+ COMRelease(m_renderTimerBegin);
+ COMRelease(m_renderTimerEnd);
+ COMRelease(m_renderTimerDisjoint);
+ COMRelease(m_renderCompletionFence);
+
+ COMRelease(m_compositeBlendState);
+
+ COMRelease(m_fluidResolvedTarget);
+ COMRelease(m_fluidResolvedTargetSRV);
+
+ delete m_immediateMesh;
+ delete m_debugLineRender;
+ delete m_meshRenderer;
+ delete m_pointRenderer;
+ delete m_diffuseRenderer;
+
+ // do this first, since it flushes all GPU work
+ AppGraphCtxReleaseRenderTarget(m_appGraphCtx);
+ AppGraphCtxRelease(m_appGraphCtx);
+}
+
+bool DemoContextD3D11::initialize(const RenderInitOptions& options)
+{
+ {
+ // Load external modules
+ loadModules(APP_CONTEXT_D3D11);
+ }
+
+ // must always have at least one sample
+ m_msaaSamples = Max(1, options.numMsaaSamples);
+ // create app graph context
+ m_appGraphCtx = AppGraphCtxCreate(0);
+ m_appGraphCtxD3D11 = cast_to_AppGraphCtxD3D11(m_appGraphCtx);
+
+ AppGraphCtxUpdateSize(m_appGraphCtx, options.window, options.fullscreen, m_msaaSamples);
+ _onWindowSizeChanged(m_appGraphCtxD3D11->m_winW, m_appGraphCtxD3D11->m_winH, false);
+
+ //AppGraphCtxInitRenderTarget(m_appGraphCtx, options.window, options.fullscreen, m_msaaSamples);
+ //gScene = getScene(0);
+
+ AppGraphColor clearVal = { 0.0f, 0.0f, 0.0f, 1.0f };
+ AppGraphCtxFrameStart(m_appGraphCtx, clearVal);
+
+ ID3D11Device* device = m_appGraphCtxD3D11->m_device;
+ ID3D11DeviceContext* deviceContext = m_appGraphCtxD3D11->m_deviceContext;
+
+ {
+ // create imgui, connect to app graph context
+ ImguiGraphDescD3D11 desc;
+ desc.device = device;
+ desc.deviceContext = deviceContext;
+ desc.winW = m_appGraphCtxD3D11->m_winW;
+ desc.winH = m_appGraphCtxD3D11->m_winH;
+
+ // Use Dx11 context
+ const int defaultFontHeight = (options.defaultFontHeight <= 0) ? 15 : options.defaultFontHeight;
+
+ if (!imguiGraphInit("../../data/DroidSans.ttf", float(defaultFontHeight), (ImguiGraphDesc*)&desc))
+ {
+ return false;
+ }
+ }
+
+ AppGraphCtxFramePresent(m_appGraphCtx, true);
+
+ m_pointRenderer->init(device, deviceContext);
+ m_meshRenderer->init(device, deviceContext, options.asyncComputeBenchmark);
+ m_debugLineRender->init(device, deviceContext);
+ m_diffuseRenderer->init(device, deviceContext);
+
+ {
+ // create blend state - used for composite phase of water rendering
+ D3D11_BLEND_DESC blendStateDesc = {};
+ blendStateDesc.RenderTarget[0].BlendEnable = TRUE;
+ blendStateDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
+ blendStateDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
+ blendStateDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
+ blendStateDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
+ blendStateDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
+ blendStateDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
+ blendStateDesc.RenderTarget[0].RenderTargetWriteMask = 0x0f;
+
+ if (FAILED(device->CreateBlendState(&blendStateDesc, &m_compositeBlendState)))
+ {
+ return false;
+ }
+ }
+
+ // create a mesh for immediate mode rendering
+ m_immediateMesh = new GpuMeshD3D11(device, deviceContext);
+
+ m_window = options.window;
+
+ D3D11_QUERY_DESC tdesc;
+ ZeroMemory(&tdesc, sizeof(tdesc));
+ tdesc.Query = D3D11_QUERY_TIMESTAMP;
+ device->CreateQuery(&tdesc, &m_renderTimerBegin);
+ device->CreateQuery(&tdesc, &m_renderTimerEnd);
+
+ tdesc.Query = D3D11_QUERY_EVENT;
+ device->CreateQuery(&tdesc, &m_renderCompletionFence);
+
+ ZeroMemory(&tdesc, sizeof(tdesc));
+ tdesc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT;
+ device->CreateQuery(&tdesc, &m_renderTimerDisjoint);
+
+ return true;
+}
+
+void DemoContextD3D11::getRenderDevice(void** deviceOut, void** contextOut)
+{
+ *deviceOut = m_appGraphCtxD3D11->m_device;
+ *contextOut = m_appGraphCtxD3D11->m_deviceContext;
+}
+
+void DemoContextD3D11::onSizeChanged(int width, int height, bool minimized)
+{
+ AppGraphCtxUpdateSize(m_appGraphCtx, m_window, false, m_msaaSamples);
+ _onWindowSizeChanged(m_appGraphCtxD3D11->m_winW, m_appGraphCtxD3D11->m_winH, false);
+}
+
+void DemoContextD3D11::_onWindowSizeChanged(int width, int height, bool minimized)
+{
+ if (m_fluidResolvedTarget)
+ {
+ D3D11_TEXTURE2D_DESC desc;
+ m_fluidResolvedTarget->GetDesc(&desc);
+ if (desc.Width == width && desc.Height == height)
+ {
+ return;
+ }
+
+ COMRelease(m_fluidResolvedTarget);
+ COMRelease(m_fluidResolvedTargetSRV);
+ }
+
+ // Recreate...
+
+ ID3D11Device* device = m_appGraphCtxD3D11->m_device;
+
+ // resolved texture target (for refraction / scene sampling)
+ {
+ D3D11_TEXTURE2D_DESC texDesc = {};
+ texDesc.Width = width;
+ texDesc.Height = height;
+ texDesc.MipLevels = 1;
+ texDesc.ArraySize = 1;
+ texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ texDesc.SampleDesc.Count = 1;
+ texDesc.SampleDesc.Quality = 0u;
+ texDesc.Usage = D3D11_USAGE_DEFAULT;
+ texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ texDesc.CPUAccessFlags = 0;
+ texDesc.MiscFlags = 0;
+
+ if (FAILED(device->CreateTexture2D(&texDesc, nullptr, &m_fluidResolvedTarget)))
+ {
+ return;
+ }
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
+ srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Texture2D.MipLevels = 1;
+ srvDesc.Texture2D.MostDetailedMip = 0;
+
+ if (FAILED(device->CreateShaderResourceView(m_fluidResolvedTarget, &srvDesc, &m_fluidResolvedTargetSRV)))
+ {
+ return;
+ }
+ }
+}
+
+void DemoContextD3D11::startFrame(Vec4 clear)
+{
+ AppGraphColor clearColor = { clear.x, clear.y, clear.z, clear.w };
+ AppGraphCtxFrameStart(m_appGraphCtx, clearColor);
+
+ MeshDrawParamsD3D& meshDrawParams = m_meshDrawParams;
+
+ memset(&meshDrawParams, 0, sizeof(MeshDrawParamsD3D));
+ meshDrawParams.renderStage = MESH_DRAW_LIGHT;
+ meshDrawParams.renderMode = MESH_RENDER_SOLID;
+ meshDrawParams.cullMode = MESH_CULL_BACK;
+ meshDrawParams.projection = (XMMATRIX)Matrix44::kIdentity;
+ meshDrawParams.view = (XMMATRIX)Matrix44::kIdentity;
+ meshDrawParams.model = DirectX::XMMatrixMultiply(
+ DirectX::XMMatrixScaling(1.0f, 1.0f, 1.0f),
+ DirectX::XMMatrixTranslation(0.0f, 0.0f, 0.0f)
+ );
+}
+
+void DemoContextD3D11::_flushFrame()
+{
+ m_appGraphCtxD3D11->m_deviceContext->Flush();
+}
+
+void DemoContextD3D11::endFrame()
+{
+ _flushFrame();
+
+ ImguiGraphDescD3D11 desc;
+
+ desc.device = m_appGraphCtxD3D11->m_device;
+ desc.deviceContext = m_appGraphCtxD3D11->m_deviceContext;
+ desc.winW = m_appGraphCtxD3D11->m_winW;
+ desc.winH = m_appGraphCtxD3D11->m_winH;
+
+ imguiGraphUpdate((ImguiGraphDesc*)&desc);
+ //m_imguiGraphContext->update(&desc);
+}
+
+void DemoContextD3D11::presentFrame(bool fullsync)
+{
+ AppGraphCtxFramePresent(m_appGraphCtx, fullsync);
+}
+
+void DemoContextD3D11::getViewRay(int x, int y, Vec3& origin, Vec3& dir)
+{
+ using namespace DirectX;
+
+ XMVECTOR nearVector = XMVector3Unproject(XMVectorSet(float(x), float(m_appGraphCtxD3D11->m_winH-y), 0.0f, 0.0f), 0.0f, 0.0f, (float)m_appGraphCtxD3D11->m_winW, (float)m_appGraphCtxD3D11->m_winH, 0.0f, 1.0f, (XMMATRIX)m_proj, XMMatrixIdentity(), (XMMATRIX)m_view);
+ XMVECTOR farVector = XMVector3Unproject(XMVectorSet(float(x), float(m_appGraphCtxD3D11->m_winH-y), 1.0f, 0.0f), 0.0f, 0.0f, (float)m_appGraphCtxD3D11->m_winW, (float)m_appGraphCtxD3D11->m_winH, 0.0f, 1.0f, (XMMATRIX)m_proj, XMMatrixIdentity(), (XMMATRIX)m_view);
+
+ origin = Vec3(XMVectorGetX(nearVector), XMVectorGetY(nearVector), XMVectorGetZ(nearVector));
+ XMVECTOR tmp = farVector - nearVector;
+ dir = Normalize(Vec3(XMVectorGetX(tmp), XMVectorGetY(tmp), XMVectorGetZ(tmp)));
+}
+
+void DemoContextD3D11::setFillMode(bool wire)
+{
+ m_meshDrawParams.renderMode = wire ? MESH_RENDER_WIREFRAME : MESH_RENDER_SOLID;
+}
+
+void DemoContextD3D11::setCullMode(bool enabled)
+{
+ m_meshDrawParams.cullMode = enabled ? MESH_CULL_BACK : MESH_CULL_NONE;
+}
+
+void DemoContextD3D11::setView(Matrix44 view, Matrix44 projection)
+{
+ Matrix44 vp = projection*view;
+
+ m_meshDrawParams.model = (XMMATRIX)Matrix44::kIdentity;
+ m_meshDrawParams.view = (XMMATRIX)view;
+ m_meshDrawParams.projection = (XMMATRIX)(ConvertToD3DProjection(projection));
+
+ m_view = view;
+ m_proj = ConvertToD3DProjection(projection);
+}
+
+FluidRenderer* DemoContextD3D11::createFluidRenderer(uint32_t width, uint32_t height)
+{
+ FluidRendererD3D11* renderer = new(_aligned_malloc(sizeof(FluidRendererD3D11), 16)) FluidRendererD3D11;
+ renderer->init(m_appGraphCtxD3D11->m_device, m_appGraphCtxD3D11->m_deviceContext, width, height);
+ return (FluidRenderer*)renderer;
+}
+
+void DemoContextD3D11::destroyFluidRenderer(FluidRenderer* rendererIn)
+{
+ FluidRendererD3D11* renderer = (FluidRendererD3D11*)rendererIn;
+ renderer->~FluidRendererD3D11();
+ _aligned_free(renderer);
+}
+
+FluidRenderBuffers* DemoContextD3D11::createFluidRenderBuffers(int numParticles, bool enableInterop)
+{
+ FluidRenderBuffersD3D11* buffers = new FluidRenderBuffersD3D11;
+ buffers->m_numParticles = numParticles;
+
+ ID3D11Device* device = m_appGraphCtxD3D11->m_device;
+
+ {
+ D3D11_BUFFER_DESC bufDesc;
+ bufDesc.ByteWidth = numParticles*sizeof(Vec4);
+ bufDesc.Usage = D3D11_USAGE_DYNAMIC;
+ bufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ bufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ bufDesc.MiscFlags = 0;
+ bufDesc.StructureByteStride = 0;
+
+ device->CreateBuffer(&bufDesc, NULL, &buffers->m_positions);
+
+ device->CreateBuffer(&bufDesc, NULL, &buffers->m_anisotropiesArr[0]);
+ device->CreateBuffer(&bufDesc, NULL, &buffers->m_anisotropiesArr[1]);
+ device->CreateBuffer(&bufDesc, NULL, &buffers->m_anisotropiesArr[2]);
+
+ bufDesc.ByteWidth = numParticles*sizeof(float);
+ device->CreateBuffer(&bufDesc, NULL, &buffers->m_densities);
+ }
+
+ {
+ D3D11_BUFFER_DESC bufDesc;
+ bufDesc.ByteWidth = numParticles * sizeof(int);
+ bufDesc.Usage = D3D11_USAGE_DYNAMIC;
+ bufDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+ bufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ bufDesc.MiscFlags = 0;
+ bufDesc.StructureByteStride = 0;
+
+ device->CreateBuffer(&bufDesc, NULL, &buffers->m_indices);
+ }
+
+ if (enableInterop)
+ {
+ extern NvFlexLibrary* g_flexLib;
+
+ buffers->m_positionsBuf = NvFlexRegisterD3DBuffer(g_flexLib, buffers->m_positions.Get(), numParticles, sizeof(Vec4));
+ buffers->m_densitiesBuf = NvFlexRegisterD3DBuffer(g_flexLib, buffers->m_densities.Get(), numParticles, sizeof(float));
+ buffers->m_indicesBuf = NvFlexRegisterD3DBuffer(g_flexLib, buffers->m_indices.Get(), numParticles, sizeof(int));
+
+ buffers->m_anisotropiesBufArr[0] = NvFlexRegisterD3DBuffer(g_flexLib, buffers->m_anisotropiesArr[0].Get(), numParticles, sizeof(Vec4));
+ buffers->m_anisotropiesBufArr[1] = NvFlexRegisterD3DBuffer(g_flexLib, buffers->m_anisotropiesArr[1].Get(), numParticles, sizeof(Vec4));
+ buffers->m_anisotropiesBufArr[2] = NvFlexRegisterD3DBuffer(g_flexLib, buffers->m_anisotropiesArr[2].Get(), numParticles, sizeof(Vec4));
+ }
+
+ return reinterpret_cast<FluidRenderBuffers*>(buffers);
+}
+
+void DemoContextD3D11::updateFluidRenderBuffers(FluidRenderBuffers* buffersIn, NvFlexSolver* solver, bool anisotropy, bool density)
+{
+ FluidRenderBuffersD3D11& buffers = *reinterpret_cast<FluidRenderBuffersD3D11*>(buffersIn);
+ if (!anisotropy)
+ {
+ // regular particles
+ NvFlexGetParticles(solver, buffers.m_positionsBuf, NULL);
+ }
+ else
+ {
+ // fluid buffers
+ NvFlexGetSmoothParticles(solver, buffers.m_positionsBuf, NULL);
+ NvFlexGetAnisotropy(solver, buffers.m_anisotropiesBufArr[0], buffers.m_anisotropiesBufArr[1], buffers.m_anisotropiesBufArr[2], NULL);
+ }
+
+ if (density)
+ {
+ NvFlexGetDensities(solver, buffers.m_densitiesBuf, NULL);
+ }
+ else
+ {
+ NvFlexGetPhases(solver, buffers.m_densitiesBuf, NULL);
+ }
+
+ NvFlexGetActive(solver, buffers.m_indicesBuf, NULL);
+}
+
+void DemoContextD3D11::updateFluidRenderBuffers(FluidRenderBuffers* buffersIn, Vec4* particles, float* densities, Vec4* anisotropy1, Vec4* anisotropy2, Vec4* anisotropy3, int numParticles, int* indices, int numIndices)
+{
+ FluidRenderBuffersD3D11& buffers = *reinterpret_cast<FluidRenderBuffersD3D11*>(buffersIn);
+ D3D11_MAPPED_SUBRESOURCE res;
+ ID3D11DeviceContext* deviceContext = m_appGraphCtxD3D11->m_deviceContext;
+
+ // vertices
+ if (particles)
+ {
+ deviceContext->Map(buffers.m_positions.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &res);
+ memcpy(res.pData, particles, sizeof(Vec4)*numParticles);
+ deviceContext->Unmap(buffers.m_positions.Get(), 0);
+ }
+
+ Vec4*const anisotropies[3] =
+ {
+ anisotropy1,
+ anisotropy2,
+ anisotropy3,
+ };
+
+ for (int i = 0; i < 3; i++)
+ {
+ const Vec4* anisotropy = anisotropies[i];
+ if (anisotropy)
+ {
+ deviceContext->Map(buffers.m_anisotropiesArr[i].Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &res);
+ memcpy(res.pData, anisotropy, sizeof(Vec4) * numParticles);
+ deviceContext->Unmap(buffers.m_anisotropiesArr[i].Get(), 0);
+ }
+ }
+
+ if (densities)
+ {
+ deviceContext->Map(buffers.m_densities.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &res);
+ memcpy(res.pData, densities, sizeof(float)*numParticles);
+ deviceContext->Unmap(buffers.m_densities.Get(), 0);
+ }
+
+ // indices
+ if (indices)
+ {
+ deviceContext->Map(buffers.m_indices.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &res);
+ memcpy(res.pData, indices, sizeof(int)*numIndices);
+ deviceContext->Unmap(buffers.m_indices.Get(), 0);
+ }
+}
+
+void DemoContextD3D11::destroyFluidRenderBuffers(FluidRenderBuffers* buffers)
+{
+ delete reinterpret_cast<FluidRenderBuffersD3D11*>(buffers);
+}
+
+ShadowMap* DemoContextD3D11::shadowCreate()
+{
+ ShadowMapD3D11* shadowMap = new(_aligned_malloc(sizeof(ShadowMapD3D11), 16)) ShadowMapD3D11;
+ shadowMap->init(m_appGraphCtxD3D11->m_device, kShadowResolution);
+ return (ShadowMap*)shadowMap;
+}
+
+void DemoContextD3D11::shadowDestroy(ShadowMap* map)
+{
+ ShadowMapD3D11* shadowMap = (ShadowMapD3D11*)map;
+ shadowMap->~ShadowMapD3D11();
+ _aligned_free(shadowMap);
+}
+
+void DemoContextD3D11::shadowBegin(ShadowMap* map)
+{
+ ShadowMapD3D11* shadowMap = (ShadowMapD3D11*)map;
+ shadowMap->bindAndClear(m_appGraphCtxD3D11->m_deviceContext);
+
+ m_meshDrawParams.renderStage = MESH_DRAW_SHADOW;
+ m_shadowMap = shadowMap;
+}
+
+void DemoContextD3D11::shadowEnd()
+{
+ ID3D11DeviceContext* deviceContext = m_appGraphCtxD3D11->m_deviceContext;
+
+ // reset to main frame buffer
+ deviceContext->RSSetViewports(1, &m_appGraphCtxD3D11->m_viewport);
+ deviceContext->OMSetRenderTargets(1, &m_appGraphCtxD3D11->m_rtv, m_appGraphCtxD3D11->m_dsv);
+ deviceContext->OMSetDepthStencilState(m_appGraphCtxD3D11->m_depthState, 0u);
+ deviceContext->ClearDepthStencilView(m_appGraphCtxD3D11->m_dsv, D3D11_CLEAR_DEPTH, 1.0, 0);
+
+ m_meshDrawParams.renderStage = MESH_DRAW_NULL;
+}
+
+void DemoContextD3D11::bindSolidShader(Vec3 lightPos, Vec3 lightTarget, Matrix44 lightTransform, ShadowMap* shadowMap, float bias, Vec4 fogColor)
+{
+ m_meshDrawParams.renderStage = MESH_DRAW_LIGHT;
+
+ m_meshDrawParams.grid = 0;
+ m_meshDrawParams.spotMin = m_spotMin;
+ m_meshDrawParams.spotMax = m_spotMax;
+ m_meshDrawParams.fogColor = (float4&)fogColor;
+
+ m_meshDrawParams.objectTransform = (float4x4&)Matrix44::kIdentity;
+
+ ShadowParamsD3D shadow;
+ RenderParamsUtilD3D::calcShadowParams(lightPos, lightTarget, lightTransform, m_shadowBias, &shadow);
+
+ m_meshDrawParams.lightTransform = shadow.lightTransform;
+ m_meshDrawParams.lightDir = shadow.lightDir;
+ m_meshDrawParams.lightPos = shadow.lightPos;
+ m_meshDrawParams.bias = shadow.bias;
+ memcpy(m_meshDrawParams.shadowTaps, shadow.shadowTaps, sizeof(shadow.shadowTaps));
+
+ m_shadowMap = (ShadowMapD3D11*)shadowMap;
+}
+
+void DemoContextD3D11::unbindSolidShader()
+{
+ m_meshDrawParams.renderStage = MESH_DRAW_NULL;
+}
+
+void DemoContextD3D11::graphicsTimerBegin()
+{
+ ID3D11DeviceContext* deviceContext = m_appGraphCtxD3D11->m_deviceContext;
+ deviceContext->Begin(m_renderTimerDisjoint);
+ deviceContext->End(m_renderTimerBegin); // yes End.
+}
+
+void DemoContextD3D11::graphicsTimerEnd()
+{
+ ID3D11DeviceContext* deviceContext = m_appGraphCtxD3D11->m_deviceContext;
+ deviceContext->End(m_renderTimerEnd);
+ deviceContext->End(m_renderTimerDisjoint);
+ m_timersSet = true;
+}
+
+float DemoContextD3D11::rendererGetDeviceTimestamps(unsigned long long* begin, unsigned long long* end, unsigned long long* freq)
+{
+ float renderTime = 0.0f;
+
+ if (m_timersSet)
+ {
+ ID3D11DeviceContext* deviceContext = m_appGraphCtxD3D11->m_deviceContext;
+
+ D3D11_QUERY_DATA_TIMESTAMP_DISJOINT tsDisjoint;
+ uint64_t renderBegin = 0;
+ uint64_t renderEnd = 0;
+
+ while (S_OK != deviceContext->GetData(m_renderTimerDisjoint, &tsDisjoint, sizeof(tsDisjoint), 0));
+ while (S_OK != deviceContext->GetData(m_renderTimerBegin, &renderBegin, sizeof(UINT64), 0));
+ while (S_OK != deviceContext->GetData(m_renderTimerEnd, &renderEnd, sizeof(UINT64), 0));
+
+ float renderTime = float(renderEnd - renderBegin) / float(tsDisjoint.Frequency);
+
+ if (begin) *begin = renderBegin;
+ if (end) *end = renderEnd;
+ if (freq) *freq = tsDisjoint.Frequency;
+ }
+
+ return renderTime;
+}
+
+void DemoContextD3D11::drawMesh(const Mesh* m, Vec3 color)
+{
+ if (m)
+ {
+ if (m->m_colours.size())
+ {
+ m_meshDrawParams.colorArray = 1;
+ m_immediateMesh->updateData((Vec3*)&m->m_positions[0], &m->m_normals[0], NULL, (Vec4*)&m->m_colours[0], (int*)&m->m_indices[0], m->GetNumVertices(), int(m->GetNumFaces()));
+ }
+ else
+ {
+ m_meshDrawParams.colorArray = 0;
+ m_immediateMesh->updateData((Vec3*)&m->m_positions[0], &m->m_normals[0], NULL, NULL, (int*)&m->m_indices[0], m->GetNumVertices(), int(m->GetNumFaces()));
+ }
+
+ m_meshDrawParams.color = (float4&)color;
+ m_meshDrawParams.secondaryColor = (float4&)color;
+ m_meshDrawParams.objectTransform = (float4x4&)Matrix44::kIdentity;
+ m_meshDrawParams.shadowMap = (ShadowMapD3D*)m_shadowMap;
+
+ m_meshRenderer->draw(m_immediateMesh, &m_meshDrawParams);
+
+ if (m->m_colours.size())
+ m_meshDrawParams.colorArray = 0;
+
+ }
+}
+
+void DemoContextD3D11::drawCloth(const Vec4* positions, const Vec4* normals, const float* uvs, const int* indices, int numTris, int numPositions, int colorIndex, float expand, bool twosided, bool smooth)
+{
+ if (!numTris)
+ return;
+
+ m_immediateMesh->updateData(positions, normals, NULL, NULL, indices, numPositions, numTris);
+
+ if (twosided)
+ SetCullMode(false);
+
+ m_meshDrawParams.bias = 0.0f;
+ m_meshDrawParams.expand = expand;
+
+ m_meshDrawParams.color = (const float4&)(g_colors[colorIndex + 1] * 1.5f);
+ m_meshDrawParams.secondaryColor = (const float4&)(g_colors[colorIndex] * 1.5f);
+ m_meshDrawParams.objectTransform = (float4x4&)Matrix44::kIdentity;
+ m_meshDrawParams.shadowMap = (ShadowMapD3D*)m_shadowMap;
+
+ m_meshRenderer->draw(m_immediateMesh, &m_meshDrawParams);
+
+ if (twosided)
+ setCullMode(true);
+
+ m_meshDrawParams.bias = m_shadowBias;
+ m_meshDrawParams.expand = 0.0f;
+}
+
+void DemoContextD3D11::drawRope(Vec4* positions, int* indices, int numIndices, float radius, int color)
+{
+ if (numIndices < 2)
+ return;
+
+ std::vector<Vec3> vertices;
+ std::vector<Vec3> normals;
+ std::vector<int> triangles;
+
+ // flatten curve
+ std::vector<Vec3> curve(numIndices);
+ for (int i = 0; i < numIndices; ++i)
+ curve[i] = Vec3(positions[indices[i]]);
+
+ const int resolution = 8;
+ const int smoothing = 3;
+
+ vertices.reserve(resolution*numIndices*smoothing);
+ normals.reserve(resolution*numIndices*smoothing);
+ triangles.reserve(numIndices*resolution * 6 * smoothing);
+
+ Extrude(&curve[0], int(curve.size()), vertices, normals, triangles, radius, resolution, smoothing);
+
+ m_immediateMesh->updateData(&vertices[0], &normals[0], NULL, NULL, &triangles[0], int(vertices.size()), int(triangles.size())/3);
+
+ setCullMode(false);
+
+ m_meshDrawParams.color = (const float4&)(g_colors[color % 8] * 1.5f);
+ m_meshDrawParams.secondaryColor = (const float4&)(g_colors[color % 8] * 1.5f);
+ m_meshDrawParams.objectTransform = (const float4x4&)Matrix44::kIdentity;
+ m_meshDrawParams.shadowMap = (ShadowMapD3D*)m_shadowMap;
+
+ m_meshRenderer->draw(m_immediateMesh, &m_meshDrawParams);
+
+ setCullMode(true);
+}
+
+void DemoContextD3D11::drawPlane(const Vec4& p, bool color)
+{
+ std::vector<Vec3> vertices;
+ std::vector<Vec3> normals;
+ std::vector<int> indices;
+
+ Vec3 u, v;
+ BasisFromVector(Vec3(p.x, p.y, p.z), &u, &v);
+
+ Vec3 c = Vec3(p.x, p.y, p.z)*-p.w;
+
+ m_meshDrawParams.shadowMap = (ShadowMapD3D*)m_shadowMap;
+
+ if (color)
+ m_meshDrawParams.color = (const float4&)(p * 0.5f + Vec4(0.5f, 0.5f, 0.5f, 0.5f));
+
+ const float kSize = 200.0f;
+ const int kGrid = 3;
+
+ // draw a grid of quads, otherwise z precision suffers
+ for (int x = -kGrid; x <= kGrid; ++x)
+ {
+ for (int y = -kGrid; y <= kGrid; ++y)
+ {
+ Vec3 coff = c + u*float(x)*kSize*2.0f + v*float(y)*kSize*2.0f;
+
+ int indexStart = int(vertices.size());
+
+ vertices.push_back(Vec3(coff + u*kSize + v*kSize));
+ vertices.push_back(Vec3(coff - u*kSize + v*kSize));
+ vertices.push_back(Vec3(coff - u*kSize - v*kSize));
+ vertices.push_back(Vec3(coff + u*kSize - v*kSize));
+
+ normals.push_back(Vec3(p.x, p.y, p.z));
+ normals.push_back(Vec3(p.x, p.y, p.z));
+ normals.push_back(Vec3(p.x, p.y, p.z));
+ normals.push_back(Vec3(p.x, p.y, p.z));
+
+
+ indices.push_back(indexStart+0);
+ indices.push_back(indexStart+1);
+ indices.push_back(indexStart+2);
+
+ indices.push_back(indexStart+2);
+ indices.push_back(indexStart+3);
+ indices.push_back(indexStart+0);
+ }
+ }
+
+ m_immediateMesh->updateData(&vertices[0], &normals[0], NULL, NULL, &indices[0], int(vertices.size()), int(indices.size())/3);
+ m_meshRenderer->draw(m_immediateMesh, &m_meshDrawParams);
+}
+
+void DemoContextD3D11::drawPlanes(Vec4* planes, int n, float bias)
+{
+ m_meshDrawParams.color = (float4&)Vec4(0.9f, 0.9f, 0.9f, 1.0f);
+
+ m_meshDrawParams.bias = 0.0f;
+ m_meshDrawParams.grid = 1;
+ m_meshDrawParams.expand = 0;
+
+ for (int i = 0; i < n; ++i)
+ {
+ Vec4 p = planes[i];
+ p.w -= bias;
+
+ drawPlane(p, false);
+ }
+
+ m_meshDrawParams.grid = 0;
+ m_meshDrawParams.bias = m_shadowBias;
+
+}
+
+GpuMesh* DemoContextD3D11::createGpuMesh(const Mesh* m)
+{
+ GpuMeshD3D11* mesh = new GpuMeshD3D11(m_appGraphCtxD3D11->m_device, m_appGraphCtxD3D11->m_deviceContext);
+ mesh->updateData((Vec3*)&m->m_positions[0], &m->m_normals[0], NULL, NULL, (int*)&m->m_indices[0], m->GetNumVertices(), int(m->GetNumFaces()));
+ return (GpuMesh*)mesh;
+}
+
+void DemoContextD3D11::destroyGpuMesh(GpuMesh* m)
+{
+ delete reinterpret_cast<GpuMeshD3D11*>(m);
+}
+
+void DemoContextD3D11::drawGpuMesh(GpuMesh* meshIn, const Matrix44& xform, const Vec3& color)
+{
+ if (meshIn)
+ {
+ GpuMeshD3D11* mesh = (GpuMeshD3D11*)meshIn;
+
+ MeshDrawParamsD3D params = m_meshDrawParams;
+
+ params.color = (float4&)color;
+ params.secondaryColor = (float4&)color;
+ params.objectTransform = (float4x4&)xform;
+ params.shadowMap = (ShadowMapD3D*)m_shadowMap;
+
+ m_meshRenderer->draw(mesh, &params);
+ }
+}
+
+void DemoContextD3D11::drawGpuMeshInstances(GpuMesh* meshIn, const Matrix44* xforms, int n, const Vec3& color)
+{
+ if (meshIn)
+ {
+ GpuMeshD3D11* mesh = (GpuMeshD3D11*)meshIn;
+
+ m_meshDrawParams.color = (float4&)color;
+ m_meshDrawParams.secondaryColor = (float4&)color;
+ m_meshDrawParams.shadowMap = (ShadowMapD3D*)m_shadowMap;
+
+ // copy params
+ MeshDrawParamsD3D params(m_meshDrawParams);
+
+ for (int i = 0; i < n; ++i)
+ {
+ params.objectTransform = (const float4x4&)xforms[i];
+ m_meshRenderer->draw(mesh, &params);
+ }
+ }
+}
+
+void DemoContextD3D11::drawPoints(FluidRenderBuffers* buffersIn, int n, int offset, float radius, float screenWidth, float screenAspect, float fov, Vec3 lightPos, Vec3 lightTarget, Matrix44 lightTransform, ShadowMap* shadowTex, bool showDensity)
+{
+ FluidRenderBuffersD3D11& buffers = *reinterpret_cast<FluidRenderBuffersD3D11*>(buffersIn);
+ if (n == 0)
+ return;
+
+ PointDrawParamsD3D params;
+
+ params.renderMode = POINT_RENDER_SOLID;
+ params.cullMode = POINT_CULL_BACK;
+ params.model = (const XMMATRIX&)Matrix44::kIdentity;
+ params.view = (const XMMATRIX&)m_view;
+ params.projection = (const XMMATRIX&)m_proj;
+
+ params.pointRadius = radius;
+ params.pointScale = screenWidth / screenAspect * (1.0f / (tanf(fov * 0.5f)));
+ params.spotMin = m_spotMin;
+ params.spotMax = m_spotMax;
+
+ int mode = 0;
+ if (showDensity)
+ mode = 1;
+ if (shadowTex == 0)
+ mode = 2;
+ params.mode = mode;
+
+ for (int i = 0; i < 8; i++)
+ params.colors[i] = *((const float4*)&g_colors[i].r);
+
+ // set shadow parameters
+ ShadowParamsD3D shadow;
+ RenderParamsUtilD3D::calcShadowParams(lightPos, lightTarget, lightTransform, m_shadowBias, &shadow);
+ params.lightTransform = shadow.lightTransform;
+ params.lightDir = shadow.lightDir;
+ params.lightPos = shadow.lightPos;
+ memcpy(params.shadowTaps, shadow.shadowTaps, sizeof(shadow.shadowTaps));
+
+ if (m_meshDrawParams.renderStage == MESH_DRAW_SHADOW)
+ {
+ params.renderStage = POINT_DRAW_SHADOW;
+ params.mode = 2;
+ }
+ else
+ {
+ params.renderStage = POINT_DRAW_LIGHT;
+ }
+
+ params.shadowMap = (ShadowMapD3D*)m_shadowMap;
+
+ m_pointRenderer->draw(&params, buffers.m_positions.Get(), buffers.m_densities.Get(), buffers.m_indices.Get(), n, offset);
+}
+
+void DemoContextD3D11::renderEllipsoids(FluidRenderer* rendererIn, FluidRenderBuffers* buffersIn, int n, int offset, float radius, float screenWidth, float screenAspect, float fov, Vec3 lightPos, Vec3 lightTarget, Matrix44 lightTransform, ShadowMap* shadowMap, Vec4 color, float blur, float ior, bool debug)
+{
+ FluidRenderBuffersD3D11& buffers = *reinterpret_cast<FluidRenderBuffersD3D11*>(buffersIn);
+ FluidRendererD3D11& renderer = *(FluidRendererD3D11*)rendererIn;
+ if (n == 0)
+ return;
+
+ ID3D11DeviceContext* deviceContext = m_appGraphCtxD3D11->m_deviceContext;
+
+ FluidDrawParamsD3D params;
+
+ params.renderMode = FLUID_RENDER_SOLID;
+ params.cullMode = FLUID_CULL_BACK;
+ params.model = (const XMMATRIX&)Matrix44::kIdentity;
+ params.view = (const XMMATRIX&)m_view;
+ params.projection = (XMMATRIX&)m_proj;
+
+ params.offset = offset;
+ params.n = n;
+ params.renderStage = FLUID_DRAW_LIGHT;
+
+ const float viewHeight = tanf(fov / 2.0f);
+ params.invViewport = float3(1.0f / screenWidth, screenAspect / screenWidth, 1.0f);
+ params.invProjection = float3(screenAspect * viewHeight, viewHeight, 1.0f);
+
+ params.shadowMap = (ShadowMapD3D*)m_shadowMap;
+
+ renderer.m_depthTexture.bindAndClear(m_appGraphCtxD3D11->m_deviceContext);
+
+ // draw static shapes into depth buffer
+ //DrawShapes();
+
+ renderer.drawEllipsoids(&params, &buffers);
+
+
+ //---------------------------------------------------------------
+ // build smooth depth
+
+ renderer.m_depthSmoothTexture.bindAndClear(deviceContext);
+
+ params.blurRadiusWorld = radius * 0.5f;
+ params.blurScale = screenWidth / screenAspect * (1.0f / (tanf(fov * 0.5f)));
+ params.invTexScale = float4(1.0f / screenAspect, 1.0f, 0.0f, 0.0f);
+ params.blurFalloff = blur;
+ params.debug = debug;
+
+ renderer.drawBlurDepth(&params);
+
+ //---------------------------------------------------------------
+ // composite
+
+ {
+ deviceContext->RSSetViewports(1, &m_appGraphCtxD3D11->m_viewport);
+ deviceContext->RSSetScissorRects(0, nullptr);
+
+ deviceContext->OMSetRenderTargets(1, &m_appGraphCtxD3D11->m_rtv, m_appGraphCtxD3D11->m_dsv);
+ deviceContext->OMSetDepthStencilState(m_appGraphCtxD3D11->m_depthState, 0u);
+
+ float blendFactor[4] = { 1.0, 1.0, 1.0, 1.0 };
+ deviceContext->OMSetBlendState(m_compositeBlendState, blendFactor, 0xffff);
+ }
+
+ params.invTexScale = (float4&)Vec2(1.0f / screenWidth, screenAspect / screenWidth);
+ params.clipPosToEye = (float4&)Vec2(tanf(fov*0.5f)*screenAspect, tanf(fov*0.5f));
+ params.color = (float4&)color;
+ params.ior = ior;
+ params.spotMin = m_spotMin;
+ params.spotMax = m_spotMax;
+ params.debug = debug;
+
+ params.lightPos = (const float3&)lightPos;
+ params.lightDir = (const float3&)-Normalize(lightTarget - lightPos);
+ params.lightTransform = (const XMMATRIX&)(ConvertToD3DProjection(lightTransform));
+
+ // Resolve MS back buffer/copy
+ if (m_msaaSamples > 1)
+ {
+ deviceContext->ResolveSubresource(m_fluidResolvedTarget, 0, m_appGraphCtxD3D11->m_backBuffer, 0, DXGI_FORMAT_R8G8B8A8_UNORM);
+ }
+ else
+ {
+ deviceContext->CopyResource(m_fluidResolvedTarget, m_appGraphCtxD3D11->m_backBuffer);
+ }
+
+ renderer.drawComposite(&params, m_fluidResolvedTargetSRV);
+
+ deviceContext->OMSetBlendState(nullptr, 0, 0xffff);
+}
+
+DiffuseRenderBuffers* DemoContextD3D11::createDiffuseRenderBuffers(int numParticles, bool& enableInterop)
+{
+ ID3D11Device* device = m_appGraphCtxD3D11->m_device;
+ DiffuseRenderBuffersD3D11* buffers = new DiffuseRenderBuffersD3D11;
+
+ buffers->m_numParticles = numParticles;
+ if (numParticles > 0)
+ {
+ {
+ D3D11_BUFFER_DESC bufDesc;
+ bufDesc.ByteWidth = numParticles * sizeof(Vec4);
+ bufDesc.Usage = D3D11_USAGE_DYNAMIC;
+ bufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ bufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ bufDesc.MiscFlags = 0;
+ if (enableInterop)
+ {
+ bufDesc.CPUAccessFlags = 0;
+ bufDesc.Usage = D3D11_USAGE_DEFAULT;
+ bufDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
+ }
+
+ device->CreateBuffer(&bufDesc, NULL, buffers->m_positions.ReleaseAndGetAddressOf());
+ device->CreateBuffer(&bufDesc, NULL, buffers->m_velocities.ReleaseAndGetAddressOf());
+ }
+
+ if (enableInterop)
+ {
+ extern NvFlexLibrary* g_flexLib;
+
+ buffers->m_positionsBuf = NvFlexRegisterD3DBuffer(g_flexLib, buffers->m_positions.Get(), numParticles, sizeof(Vec4));
+ buffers->m_velocitiesBuf = NvFlexRegisterD3DBuffer(g_flexLib, buffers->m_velocities.Get(), numParticles, sizeof(Vec4));
+
+ if (buffers->m_positionsBuf == nullptr ||
+ buffers->m_velocitiesBuf == nullptr)
+ enableInterop = false;
+ }
+ }
+
+ return reinterpret_cast<DiffuseRenderBuffers*>(buffers);
+}
+
+void DemoContextD3D11::destroyDiffuseRenderBuffers(DiffuseRenderBuffers* buffers)
+{
+ delete reinterpret_cast<DiffuseRenderBuffersD3D11*>(buffers);
+}
+
+void DemoContextD3D11::updateDiffuseRenderBuffers(DiffuseRenderBuffers* buffersIn, NvFlexSolver* solver)
+{
+ DiffuseRenderBuffersD3D11* buffers = reinterpret_cast<DiffuseRenderBuffersD3D11*>(buffersIn);
+ // diffuse particles
+ if (buffers->m_numParticles)
+ {
+ NvFlexGetDiffuseParticles(solver, buffers->m_positionsBuf, buffers->m_velocitiesBuf, nullptr);
+ }
+}
+
+void DemoContextD3D11::updateDiffuseRenderBuffers(DiffuseRenderBuffers* buffersIn, Vec4* diffusePositions, Vec4* diffuseVelocities, int numDiffuseParticles)
+{
+ DiffuseRenderBuffersD3D11& buffers = *reinterpret_cast<DiffuseRenderBuffersD3D11*>(buffersIn);
+ ID3D11DeviceContext* deviceContext = m_appGraphCtxD3D11->m_deviceContext;
+
+ D3D11_MAPPED_SUBRESOURCE res;
+
+ // vertices
+ if (diffusePositions)
+ {
+ deviceContext->Map(buffers.m_positions.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &res);
+ memcpy(res.pData, diffusePositions, sizeof(Vec4)*numDiffuseParticles);
+ deviceContext->Unmap(buffers.m_positions.Get(), 0);
+ }
+
+ if (diffuseVelocities)
+ {
+ deviceContext->Map(buffers.m_velocities.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &res);
+ memcpy(res.pData, diffuseVelocities, sizeof(Vec4)*numDiffuseParticles);
+ deviceContext->Unmap(buffers.m_velocities.Get(), 0);
+ }
+}
+
+void DemoContextD3D11::drawDiffuse(FluidRenderer* renderIn, const DiffuseRenderBuffers* buffersIn, int n, float radius, float screenWidth, float screenAspect, float fov, Vec4 color, Vec3 lightPos, Vec3 lightTarget, Matrix44 lightTransform, ShadowMap* shadowMap, float motionBlur, float inscatter, float outscatter, bool shadowEnabled, bool front)
+{
+ FluidRendererD3D11* render = (FluidRendererD3D11*)renderIn;
+ const DiffuseRenderBuffersD3D11& buffers = *reinterpret_cast<const DiffuseRenderBuffersD3D11*>(buffersIn);
+ if (n == 0)
+ return;
+
+ DiffuseDrawParamsD3D params;
+
+ params.model = (const XMMATRIX&)Matrix44::kIdentity;
+ params.view = (const XMMATRIX&)m_view;
+ params.projection = (const XMMATRIX&)m_proj;
+ params.diffuseRadius = screenWidth / screenAspect * (1.0f / (tanf(fov * 0.5f)));
+ params.diffuseScale = radius;
+ params.spotMin = m_spotMin;
+ params.spotMax = m_spotMax;
+ params.color = float4(1.0f, 1.0f, 1.0f, 1.0f);
+ params.motionScale = motionBlur;
+
+ // set shadow parameters
+ ShadowParamsD3D shadow;
+ RenderParamsUtilD3D::calcShadowParams(lightPos, lightTarget, lightTransform, m_shadowBias, &shadow);
+ params.lightTransform = shadow.lightTransform;
+ params.lightDir = shadow.lightDir;
+ params.lightPos = shadow.lightPos;
+ params.shadowMap = (ShadowMapD3D*)m_shadowMap;
+
+ memcpy(params.shadowTaps, shadow.shadowTaps, sizeof(shadow.shadowTaps));
+
+ m_diffuseRenderer->draw(&params, buffers.m_positions.Get(), buffers.m_velocities.Get(), n);
+
+ // reset depth stencil state
+ m_appGraphCtxD3D11->m_deviceContext->OMSetDepthStencilState(m_appGraphCtxD3D11->m_depthState, 0u);
+}
+
+int DemoContextD3D11::getNumDiffuseRenderParticles(DiffuseRenderBuffers* buffers)
+{
+ return reinterpret_cast<DiffuseRenderBuffersD3D11*>(buffers)->m_numParticles;
+}
+
+void DemoContextD3D11::beginLines()
+{
+}
+
+void DemoContextD3D11::drawLine(const Vec3& p, const Vec3& q, const Vec4& color)
+{
+ m_debugLineRender->addLine(p, q, color);
+}
+
+void DemoContextD3D11::endLines()
+{
+ // draw
+ Matrix44 projectionViewWorld = ((Matrix44&)(m_meshDrawParams.projection))*((Matrix44&)(m_meshDrawParams.view));
+
+ m_debugLineRender->flush(projectionViewWorld);
+}
+
+void DemoContextD3D11::startGpuWork() {}
+void DemoContextD3D11::endGpuWork() {}
+
+void DemoContextD3D11::flushGraphicsAndWait()
+{
+ ID3D11DeviceContext* deviceContext = m_appGraphCtxD3D11->m_deviceContext;
+
+ deviceContext->End(m_renderCompletionFence);
+ while (S_OK != deviceContext->GetData(m_renderCompletionFence, 0, 0, 0));
+}
+
+void* DemoContextD3D11::getGraphicsCommandQueue() { return NULL; }
+
+void DemoContextD3D11::drawImguiGraph()
+{
+ imguiGraphDraw();
+}