aboutsummaryrefslogtreecommitdiff
path: root/NvBlast/samples/SampleBase/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'NvBlast/samples/SampleBase/renderer')
-rw-r--r--NvBlast/samples/SampleBase/renderer/ConvexRenderMesh.cpp82
-rw-r--r--NvBlast/samples/SampleBase/renderer/ConvexRenderMesh.h34
-rw-r--r--NvBlast/samples/SampleBase/renderer/CustomRenderMesh.cpp96
-rw-r--r--NvBlast/samples/SampleBase/renderer/CustomRenderMesh.h41
-rw-r--r--NvBlast/samples/SampleBase/renderer/DebugRenderBuffer.h50
-rw-r--r--NvBlast/samples/SampleBase/renderer/Mesh.cpp13
-rw-r--r--NvBlast/samples/SampleBase/renderer/Mesh.h51
-rw-r--r--NvBlast/samples/SampleBase/renderer/PrimitiveRenderMesh.cpp205
-rw-r--r--NvBlast/samples/SampleBase/renderer/PrimitiveRenderMesh.h61
-rw-r--r--NvBlast/samples/SampleBase/renderer/RenderMaterial.cpp206
-rw-r--r--NvBlast/samples/SampleBase/renderer/RenderMaterial.h118
-rw-r--r--NvBlast/samples/SampleBase/renderer/RenderUtils.h78
-rw-r--r--NvBlast/samples/SampleBase/renderer/Renderable.cpp48
-rw-r--r--NvBlast/samples/SampleBase/renderer/Renderable.h128
-rw-r--r--NvBlast/samples/SampleBase/renderer/Renderer.cpp729
-rw-r--r--NvBlast/samples/SampleBase/renderer/Renderer.h248
-rw-r--r--NvBlast/samples/SampleBase/renderer/RendererHBAO.cpp81
-rw-r--r--NvBlast/samples/SampleBase/renderer/RendererHBAO.h40
-rw-r--r--NvBlast/samples/SampleBase/renderer/RendererShadow.cpp417
-rw-r--r--NvBlast/samples/SampleBase/renderer/RendererShadow.h82
-rw-r--r--NvBlast/samples/SampleBase/renderer/ResourceManager.cpp212
-rw-r--r--NvBlast/samples/SampleBase/renderer/ResourceManager.h93
-rw-r--r--NvBlast/samples/SampleBase/renderer/ShaderUtils.h99
-rw-r--r--NvBlast/samples/SampleBase/renderer/SkinnedRenderMesh.cpp217
-rw-r--r--NvBlast/samples/SampleBase/renderer/SkinnedRenderMesh.h82
25 files changed, 3511 insertions, 0 deletions
diff --git a/NvBlast/samples/SampleBase/renderer/ConvexRenderMesh.cpp b/NvBlast/samples/SampleBase/renderer/ConvexRenderMesh.cpp
new file mode 100644
index 0000000..074cc2d
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/ConvexRenderMesh.cpp
@@ -0,0 +1,82 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 "ConvexRenderMesh.h"
+#include "Renderer.h"
+#include "PxConvexMesh.h"
+
+
+struct Vertex
+{
+ PxVec3 position;
+ PxVec3 normal;
+};
+
+ConvexRenderMesh::ConvexRenderMesh(const PxConvexMesh* mesh)
+{
+ const uint32_t nbPolygons = mesh->getNbPolygons();
+ const uint8_t* indexBuffer = mesh->getIndexBuffer();
+ const PxVec3* meshVertices = mesh->getVertices();
+
+ uint32_t nbVerts = 0;
+ uint32_t nbFaces = 0;
+
+ for (uint32_t i = 0; i < nbPolygons; i++)
+ {
+ PxHullPolygon data;
+ mesh->getPolygonData(i, data);
+ uint32_t nbPolyVerts = data.mNbVerts;
+ nbVerts += nbPolyVerts;
+ nbFaces += (nbPolyVerts - 2) * 3;
+ }
+
+ std::vector<Vertex> vertices;
+ std::vector<uint16_t> faces;
+
+ vertices.resize(nbVerts);
+ faces.resize(nbFaces);
+
+ uint32_t vertCounter = 0;
+ uint32_t facesCounter = 0;
+ for (uint32_t i = 0; i < nbPolygons; i++)
+ {
+ PxHullPolygon data;
+ mesh->getPolygonData(i, data);
+
+ PxVec3 normal(data.mPlane[0], data.mPlane[1], data.mPlane[2]);
+
+ uint32_t vI0 = vertCounter;
+ for (uint32_t vI = 0; vI < data.mNbVerts; vI++)
+ {
+ vertices[vertCounter].position = meshVertices[indexBuffer[data.mIndexBase + vI]];
+ vertices[vertCounter].normal = normal;
+ vertCounter++;
+ }
+
+ for (uint32_t vI = 1; vI < uint32_t(data.mNbVerts) - 1; vI++)
+ {
+ faces[facesCounter++] = uint16_t(vI0);
+ faces[facesCounter++] = uint16_t(vI0 + vI + 1);
+ faces[facesCounter++] = uint16_t(vI0 + vI);
+ }
+ }
+
+ std::vector<D3D11_INPUT_ELEMENT_DESC> layout;
+ layout.push_back({ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 });
+ layout.push_back({ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 });
+
+ initialize(vertices.data(), (uint32_t)vertices.size(), sizeof(Vertex), layout, faces.data(), nbFaces);
+}
+
+
+ConvexRenderMesh::~ConvexRenderMesh()
+{
+}
+
diff --git a/NvBlast/samples/SampleBase/renderer/ConvexRenderMesh.h b/NvBlast/samples/SampleBase/renderer/ConvexRenderMesh.h
new file mode 100644
index 0000000..dfe8d8f
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/ConvexRenderMesh.h
@@ -0,0 +1,34 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 CONVEX_RENDER_MESH_H
+#define CONVEX_RENDER_MESH_H
+
+#include "CustomRenderMesh.h"
+
+namespace physx
+{
+class PxConvexMesh;
+}
+
+
+/**
+PxConvexMesh render mesh
+(this class relates to PhysX more then to Renderer)
+*/
+class ConvexRenderMesh : public CustomRenderMesh
+{
+public:
+ ConvexRenderMesh(const PxConvexMesh* mesh);
+ virtual ~ConvexRenderMesh();
+};
+
+
+#endif //CONVEX_RENDER_MESH_H \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/CustomRenderMesh.cpp b/NvBlast/samples/SampleBase/renderer/CustomRenderMesh.cpp
new file mode 100644
index 0000000..61ae9e0
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/CustomRenderMesh.cpp
@@ -0,0 +1,96 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 "CustomRenderMesh.h"
+
+
+CustomRenderMesh::CustomRenderMesh()
+ : m_indexBuffer(nullptr)
+{
+}
+
+CustomRenderMesh::CustomRenderMesh(const void* vertices, uint32_t numVertices, uint32_t vertexSize, std::vector<D3D11_INPUT_ELEMENT_DESC>& inputDesc, const uint16_t* faces, uint32_t numFaces)
+ : m_indexBuffer(nullptr)
+{
+ initialize(vertices, numVertices, vertexSize, inputDesc, faces, numFaces);
+}
+
+void CustomRenderMesh::initialize(const void* vertices, uint32_t numVertices, uint32_t vertexSize, std::vector<D3D11_INPUT_ELEMENT_DESC>& inputDesc, const uint16_t* faces, uint32_t numFaces)
+{
+ ID3D11Device* device = GetDeviceManager()->GetDevice();
+
+ m_inputDesc = inputDesc;
+ m_numVertices = numVertices;
+ m_vertexSize = vertexSize;
+ m_numFaces = numFaces;
+
+ // VB
+ {
+ D3D11_SUBRESOURCE_DATA vertexBufferData;
+
+ ZeroMemory(&vertexBufferData, sizeof(vertexBufferData));
+ vertexBufferData.pSysMem = vertices;
+
+ D3D11_BUFFER_DESC bufferDesc;
+
+ memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC));
+ bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ bufferDesc.ByteWidth = vertexSize * numVertices;
+ bufferDesc.CPUAccessFlags = 0;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
+
+ V(device->CreateBuffer(&bufferDesc, &vertexBufferData, &m_vertexBuffer));
+ }
+
+ // IB
+ if (faces != nullptr)
+ {
+ D3D11_SUBRESOURCE_DATA indexBufferData;
+
+ ZeroMemory(&indexBufferData, sizeof(indexBufferData));
+ indexBufferData.pSysMem = faces;
+
+ D3D11_BUFFER_DESC bufferDesc;
+
+ memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC));
+ bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+ bufferDesc.ByteWidth = sizeof(uint16_t) * numFaces;
+ bufferDesc.CPUAccessFlags = 0;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
+
+ V(device->CreateBuffer(&bufferDesc, &indexBufferData, &m_indexBuffer));
+ }
+}
+
+CustomRenderMesh::~CustomRenderMesh()
+{
+ SAFE_RELEASE(m_vertexBuffer);
+ SAFE_RELEASE(m_indexBuffer);
+}
+
+
+void CustomRenderMesh::render(ID3D11DeviceContext& context) const
+{
+ context.IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+
+ UINT strides[1] = { m_vertexSize };
+ UINT offsets[1] = { 0 };
+ context.IASetVertexBuffers(0, 1, &m_vertexBuffer, strides, offsets);
+
+ context.IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R16_UINT, 0);
+
+ if (m_indexBuffer)
+ context.DrawIndexed(m_numFaces, 0, 0);
+ else
+ context.Draw(m_numVertices, 0);
+}
+
diff --git a/NvBlast/samples/SampleBase/renderer/CustomRenderMesh.h b/NvBlast/samples/SampleBase/renderer/CustomRenderMesh.h
new file mode 100644
index 0000000..b0ddea1
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/CustomRenderMesh.h
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 CUSTOM_RENDER_MESH_H
+#define CUSTOM_RENDER_MESH_H
+
+#include "Renderable.h"
+
+
+class CustomRenderMesh : public IRenderMesh
+{
+public:
+ const std::vector<D3D11_INPUT_ELEMENT_DESC>& getInputElementDesc() const { return m_inputDesc; }
+ void render(ID3D11DeviceContext& context) const;
+
+ CustomRenderMesh(const void* vertices, uint32_t numVertices, uint32_t vertexSize, std::vector<D3D11_INPUT_ELEMENT_DESC>& inputDesc, const uint16_t* faces = nullptr, uint32_t numFaces = 0);
+ virtual ~CustomRenderMesh();
+
+protected:
+ CustomRenderMesh();
+ void initialize(const void* vertices, uint32_t numVertices, uint32_t vertexSize, std::vector<D3D11_INPUT_ELEMENT_DESC>& inputDesc, const uint16_t* faces, uint32_t numFaces);
+
+private:
+ ID3D11Buffer* m_vertexBuffer;
+ ID3D11Buffer* m_indexBuffer;
+ uint32_t m_numFaces;
+ uint32_t m_numVertices;
+ uint32_t m_vertexSize;
+
+ std::vector<D3D11_INPUT_ELEMENT_DESC> m_inputDesc;
+};
+
+
+#endif //CUSTOM_RENDER_MESH_H \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/DebugRenderBuffer.h b/NvBlast/samples/SampleBase/renderer/DebugRenderBuffer.h
new file mode 100644
index 0000000..7810733
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/DebugRenderBuffer.h
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 DEBUGRENDERBUFFER_H
+#define DEBUGRENDERBUFFER_H
+
+#include "PxRenderBuffer.h"
+#include <vector>
+
+using namespace physx;
+
+
+/**
+Simple PxRenderBuffer implementation for easy debug primitives adding
+*/
+class DebugRenderBuffer : public PxRenderBuffer
+{
+public:
+ ~DebugRenderBuffer() {}
+
+ virtual PxU32 getNbPoints() const { return 0; }
+ virtual const PxDebugPoint* getPoints() const { return nullptr; }
+
+ virtual PxU32 getNbLines() const { return static_cast<PxU32>(m_lines.size()); }
+ virtual const PxDebugLine* getLines() const { return m_lines.data(); }
+
+ virtual PxU32 getNbTriangles() const { return 0; }
+ virtual const PxDebugTriangle* getTriangles() const { return nullptr; }
+
+ virtual PxU32 getNbTexts() const { return 0; }
+ virtual const PxDebugText* getTexts() const { return nullptr; }
+
+ virtual void append(const PxRenderBuffer& other) {}
+ virtual void clear()
+ {
+ m_lines.clear();
+ }
+
+ std::vector<PxDebugLine> m_lines;
+};
+
+
+#endif //DEBUGRENDERBUFFER_H \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/Mesh.cpp b/NvBlast/samples/SampleBase/renderer/Mesh.cpp
new file mode 100644
index 0000000..cdf63f2
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/Mesh.cpp
@@ -0,0 +1,13 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 "Mesh.h"
+
diff --git a/NvBlast/samples/SampleBase/renderer/Mesh.h b/NvBlast/samples/SampleBase/renderer/Mesh.h
new file mode 100644
index 0000000..6951198
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/Mesh.h
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 MESH_H
+#define MESH_H
+
+#include <vector>
+#include "PxVec2.h"
+#include "PxVec3.h"
+
+
+class Mesh
+{
+ virtual uint32_t getVertexStride() = 0;
+ // ... TBD
+};
+
+/**
+SimpleMesh: position + normal + uv
+We use only this type everywhere, once other versions will be required we should generalize Mesh and refactor code.
+*/
+class SimpleMesh : public Mesh
+{
+public:
+
+ class Vertex
+ {
+ public:
+ physx::PxVec3 position;
+ physx::PxVec3 normal;
+ physx::PxVec2 uv;
+ };
+
+ virtual uint32_t getVertexStride() { return sizeof(Vertex); }
+
+ std::vector<Vertex> vertices;
+ std::vector<uint16_t> indices;
+
+ physx::PxVec3 extents;
+ physx::PxVec3 center;
+};
+
+
+#endif //MESH_H \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/PrimitiveRenderMesh.cpp b/NvBlast/samples/SampleBase/renderer/PrimitiveRenderMesh.cpp
new file mode 100644
index 0000000..329f47b
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/PrimitiveRenderMesh.cpp
@@ -0,0 +1,205 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 "PrimitiveRenderMesh.h"
+#include "Renderer.h"
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Base Mesh internal class
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+PrimitiveRenderMesh::PrimitiveRenderMesh(const float v[], UINT numVertices)
+{
+ std::vector<D3D11_INPUT_ELEMENT_DESC> layout;
+ layout.push_back({ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 });
+ layout.push_back({ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 });
+
+ initialize(v, numVertices, sizeof(float) * 6, layout, nullptr, 0);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Box Mesh
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+const float boxVertices[] =
+{
+ -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f,
+ 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f,
+ 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f,
+ 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f,
+ -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f,
+ -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f,
+
+ -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+ 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+ -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+ -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+
+ -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f,
+ -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f,
+ -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f,
+ -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f,
+ -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f,
+ -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f,
+
+ 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
+ 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f,
+ 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f,
+ 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f,
+ 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
+ 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
+
+ -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f,
+ 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f,
+ 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f,
+ 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f,
+ -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f,
+ -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f,
+
+ -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
+ -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
+ -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f
+};
+
+BoxRenderMesh::BoxRenderMesh() : PrimitiveRenderMesh(boxVertices, sizeof(boxVertices) / (6 * sizeof(boxVertices[0]))) {}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Plane Mesh
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+const float planeSize = 1.0f; // we use scaling instead
+const float planeTilesCount = 1000.0f;
+
+const float planeVertices[] =
+{
+ 0, planeSize, planeSize, 1.0f, 0.0f, 0.0f, planeTilesCount, planeTilesCount,
+ 0, planeSize, -planeSize, 1.0f, 0.0f, 0.0f, planeTilesCount, -planeTilesCount,
+ 0, -planeSize, -planeSize, 1.0f, 0.0f, 0.0f, -planeTilesCount, -planeTilesCount,
+ 0, -planeSize, -planeSize, 1.0f, 0.0f, 0.0f, -planeTilesCount, -planeTilesCount,
+ 0, -planeSize, planeSize, 1.0f, 0.0f, 0.0f, -planeTilesCount, planeTilesCount,
+ 0, planeSize, planeSize, 1.0f, 0.0f, 0.0f, planeTilesCount, planeTilesCount
+};
+
+PlaneRenderMesh::PlaneRenderMesh()
+{
+ std::vector<D3D11_INPUT_ELEMENT_DESC> layout;
+ layout.push_back({ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 });
+ layout.push_back({ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 });
+ layout.push_back({ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 });
+
+ initialize(planeVertices, sizeof(planeVertices) / (8 * sizeof(planeVertices[0])), sizeof(float) * 8, layout, nullptr, 0);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Sphere Mesh
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+const uint32_t g_numSlices = 8; // along lines of longitude
+const uint32_t g_numStacks = 16; // along lines of latitude
+
+const uint32_t g_numSphereVertices = (g_numSlices * 2 + 1)*(g_numStacks + 1);
+const uint32_t g_numSphereIndices = g_numSlices * 2 * g_numStacks * 6;
+
+const uint32_t g_numConeVertices = (g_numSlices * 2 + 1) * 2;
+const uint32_t g_numConeIndices = g_numSlices * 2 * 6;
+
+PxVec3 g_spherePositions[g_numSphereVertices];
+uint16_t g_sphereIndices[g_numSphereIndices];
+
+void generateSphereMesh(uint16_t slices, uint16_t stacks, PxVec3* positions, uint16_t* indices)
+{
+ const PxF32 thetaStep = PxPi / stacks;
+ const PxF32 phiStep = PxTwoPi / (slices * 2);
+
+ PxF32 theta = 0.0f;
+
+ // generate vertices
+ for (uint16_t y = 0; y <= stacks; ++y)
+ {
+ PxF32 phi = 0.0f;
+
+ PxF32 cosTheta = PxCos(theta);
+ PxF32 sinTheta = PxSin(theta);
+
+ for (uint16_t x = 0; x <= slices * 2; ++x)
+ {
+ PxF32 cosPhi = PxCos(phi);
+ PxF32 sinPhi = PxSin(phi);
+
+ PxVec3 p(cosPhi*sinTheta, cosTheta, sinPhi*sinTheta);
+
+ // write vertex
+ *(positions++) = p;
+
+ phi += phiStep;
+ }
+
+ theta += thetaStep;
+ }
+
+ const uint16_t numRingQuads = 2 * slices;
+ const uint16_t numRingVerts = 2 * slices + 1;
+
+ // add faces
+ for (uint16_t y = 0; y < stacks; ++y)
+ {
+ for (uint16_t i = 0; i < numRingQuads; ++i)
+ {
+ // add a quad
+ *(indices++) = (y + 0)*numRingVerts + i;
+ *(indices++) = (y + 1)*numRingVerts + i;
+ *(indices++) = (y + 1)*numRingVerts + i + 1;
+
+ *(indices++) = (y + 1)*numRingVerts + i + 1;
+ *(indices++) = (y + 0)*numRingVerts + i + 1;
+ *(indices++) = (y + 0)*numRingVerts + i;
+ }
+ }
+}
+
+
+struct SphereVertex
+{
+ PxVec3 position;
+ PxVec3 normal;
+};
+
+SphereRenderMesh::SphereRenderMesh()
+{
+ generateSphereMesh(g_numSlices, g_numStacks, g_spherePositions, g_sphereIndices);
+
+ std::vector<SphereVertex> vertices;
+ for (uint32_t i = 0; i < g_numSphereVertices; i++)
+ {
+ vertices.push_back({ g_spherePositions[i], g_spherePositions[i] });
+ }
+
+ std::vector<D3D11_INPUT_ELEMENT_DESC> layout;
+ layout.push_back({ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 });
+ layout.push_back({ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 });
+
+ initialize(vertices.data(), (uint32_t)vertices.size(), sizeof(SphereVertex), layout, g_sphereIndices, g_numSphereIndices);
+}
+
+
+SphereRenderMesh::~SphereRenderMesh()
+{
+}
diff --git a/NvBlast/samples/SampleBase/renderer/PrimitiveRenderMesh.h b/NvBlast/samples/SampleBase/renderer/PrimitiveRenderMesh.h
new file mode 100644
index 0000000..f72c191
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/PrimitiveRenderMesh.h
@@ -0,0 +1,61 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 PRIMITIVE_RENDER_MESH_H
+#define PRIMITIVE_RENDER_MESH_H
+
+#include "Utils.h"
+#include <DirectXMath.h>
+
+#include <vector>
+#include "Renderable.h"
+#include "CustomRenderMesh.h"
+
+
+class PrimitiveRenderMesh : public CustomRenderMesh
+{
+protected:
+ PrimitiveRenderMesh(const float v[], UINT numVertices);
+};
+
+class BoxRenderMesh : public PrimitiveRenderMesh
+{
+public:
+ BoxRenderMesh();
+};
+
+
+class PlaneRenderMesh : public CustomRenderMesh
+{
+public:
+ PlaneRenderMesh();
+};
+
+
+class SphereRenderMesh : public CustomRenderMesh
+{
+public:
+ SphereRenderMesh();
+ virtual ~SphereRenderMesh();
+};
+
+
+struct PrimitiveRenderMeshType
+{
+ enum Enum
+ {
+ Box,
+ Plane,
+ Sphere,
+ Count
+ };
+};
+
+#endif //PRIMITIVE_RENDER_MESH_H \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/RenderMaterial.cpp b/NvBlast/samples/SampleBase/renderer/RenderMaterial.cpp
new file mode 100644
index 0000000..cb40ec7
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/RenderMaterial.cpp
@@ -0,0 +1,206 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 "RenderMaterial.h"
+#include <DirectXMath.h>
+#include "ShaderUtils.h"
+#include "Renderer.h"
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// RenderMaterial
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+RenderMaterial::RenderMaterial(ResourceManager& resourceCallback, const char* shaderFileName,
+ const char* textureFileName, BlendMode blendMode)
+{
+ this->initialize(resourceCallback, shaderFileName, textureFileName, blendMode);
+}
+
+void RenderMaterial::initialize(ResourceManager& resourceCallback, const char* shaderFileName, const char* textureFileName, BlendMode blendMode)
+{
+ std::vector<std::string> v;
+ v.push_back(shaderFileName);
+ initialize(resourceCallback, v, textureFileName, blendMode);
+}
+
+void RenderMaterial::initialize(ResourceManager& resourceCallback, std::vector<std::string> shaderFileNames, const char* textureFileName, BlendMode blendMode)
+{
+ mTextureSRV = nullptr;
+ mTexture = nullptr;
+ mBlendState = nullptr;
+ mTextureFileName = textureFileName;
+
+ for (uint32_t i = 0; i < shaderFileNames.size(); i++)
+ {
+ const ShaderFileResource* resource = resourceCallback.requestShaderFile(shaderFileNames[i].c_str());
+ if (resource)
+ {
+ std::string shaderFilePath = resource->path;
+ mShaderFilePathes.push_back(shaderFilePath);
+ }
+ }
+ mShaderGroups.reserve(mShaderFilePathes.size());
+
+ if (!mTextureFileName.empty())
+ {
+ mTexture = resourceCallback.requestTexture(mTextureFileName.c_str());
+ }
+
+ setBlending(blendMode);
+
+ reload();
+}
+
+void RenderMaterial::releaseReloadableResources()
+{
+ for (std::vector<ShaderGroup*>::iterator it = mShaderGroups.begin(); it != mShaderGroups.end(); it++)
+ {
+ delete *it;
+ }
+ mShaderGroups.clear();
+
+ SAFE_RELEASE(mTextureSRV);
+}
+
+RenderMaterial::~RenderMaterial()
+{
+ releaseReloadableResources();
+ SAFE_RELEASE(mBlendState);
+}
+
+void RenderMaterial::setBlending(BlendMode blendMode)
+{
+ mBlendMode = blendMode;
+
+ SAFE_RELEASE(mBlendState);
+
+ D3D11_BLEND_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+
+ switch (blendMode)
+ {
+ case BLEND_NONE:
+ desc.RenderTarget[0].BlendEnable = FALSE;
+ desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
+ break;
+ case BLEND_ALPHA_BLENDING:
+ desc.AlphaToCoverageEnable = FALSE;
+ desc.IndependentBlendEnable = TRUE;
+ desc.RenderTarget[0].BlendEnable = TRUE;
+ desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
+ desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
+ desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
+ desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
+ desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
+ desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
+ desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
+ break;
+ case BLEND_ADDITIVE: // actually, is's additive by alpha
+ desc.AlphaToCoverageEnable = FALSE;
+ desc.IndependentBlendEnable = TRUE;
+ desc.RenderTarget[0].BlendEnable = TRUE;
+ desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
+ desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
+ desc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE;
+ desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
+ desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
+ desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
+ desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
+ break;
+ default:
+ PX_ALWAYS_ASSERT_MESSAGE("Unknown blend mode");
+ }
+
+ ID3D11Device* device = GetDeviceManager()->GetDevice();
+ V(device->CreateBlendState(&desc, &mBlendState));
+}
+
+void RenderMaterial::reload()
+{
+ releaseReloadableResources();
+
+ // load shaders
+ ID3D11Device* device = GetDeviceManager()->GetDevice();
+
+ for (std::vector<std::string>::iterator it = mShaderFilePathes.begin(); it != mShaderFilePathes.end(); it++)
+ {
+ const char* shaderFilePath = (*it).c_str();
+ ShaderGroup* shaderGroup = new ShaderGroup();
+ V(createShaderFromFile(device, shaderFilePath, "VS", &(shaderGroup->vs), shaderGroup->buffer));
+ createShaderFromFile(device, shaderFilePath, "PS", &shaderGroup->ps);
+ createShaderFromFile(device, shaderFilePath, "GS", &shaderGroup->gs);
+ mShaderGroups.push_back(shaderGroup);
+ }
+
+ // load texture
+ if (mTexture)
+ {
+ V(DirectX::CreateShaderResourceView(device, mTexture->image.GetImages(), mTexture->image.GetImageCount(),
+ mTexture->metaData, &mTextureSRV));
+ }
+}
+
+
+
+RenderMaterial::InstancePtr RenderMaterial::getMaterialInstance(const IRenderMesh* mesh)
+{
+ // look in cache
+ auto it = mRenderMeshToInstanceMap.find(mesh);
+ if (it != mRenderMeshToInstanceMap.end())
+ {
+ if (!(*it).second.expired())
+ {
+ return (*it).second.lock();
+ }
+ }
+
+ // create new
+ const std::vector<D3D11_INPUT_ELEMENT_DESC>& descs = mesh->getInputElementDesc();
+ RenderMaterial::InstancePtr instance = getMaterialInstance(&descs[0], (uint32_t)descs.size());
+ mRenderMeshToInstanceMap[mesh] = instance;
+ return instance;
+}
+
+RenderMaterial::InstancePtr RenderMaterial::getMaterialInstance(const D3D11_INPUT_ELEMENT_DESC* elementDescs, uint32_t numElements)
+{
+ ID3D11Device* device = GetDeviceManager()->GetDevice();
+
+ for (uint32_t i = 0; i < mShaderGroups.size(); i++)
+ {
+ if (mShaderGroups[i]->buffer == NULL)
+ continue;
+
+ ID3D11InputLayout* inputLayout = NULL;
+ device->CreateInputLayout(elementDescs, numElements, mShaderGroups[i]->buffer->GetBufferPointer(), mShaderGroups[i]->buffer->GetBufferSize(), &inputLayout);
+
+ if (inputLayout)
+ {
+ RenderMaterial::InstancePtr materialInstance(new Instance(*this, inputLayout, i));
+ return materialInstance;
+ }
+ }
+ PX_ALWAYS_ASSERT();
+ return NULL;
+}
+
+void RenderMaterial::Instance::bind(ID3D11DeviceContext& context, uint32_t slot, bool depthStencilOnly)
+{
+ mMaterial.mShaderGroups[mShaderNum]->Set(&context, !depthStencilOnly);
+
+ context.OMSetBlendState(mMaterial.mBlendState, nullptr, 0xFFFFFFFF);
+ context.PSSetShaderResources(slot, 1, &(mMaterial.mTextureSRV));
+ context.IASetInputLayout(mInputLayout);
+}
+
+bool RenderMaterial::Instance::isValid()
+{
+ return mMaterial.mShaderGroups.size() > 0 && mMaterial.mShaderGroups[mShaderNum]->IsValid();
+}
diff --git a/NvBlast/samples/SampleBase/renderer/RenderMaterial.h b/NvBlast/samples/SampleBase/renderer/RenderMaterial.h
new file mode 100644
index 0000000..a342459
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/RenderMaterial.h
@@ -0,0 +1,118 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 RENDER_MATERIAL_H
+#define RENDER_MATERIAL_H
+
+#include "Utils.h"
+#include "DirectXTex.h"
+
+#include <string>
+#include <vector>
+#include <list>
+#include <map>
+#include <memory>
+
+
+class IRenderMesh;
+class ResourceManager;
+struct TextureResource;
+
+
+class RenderMaterial
+{
+ public:
+
+ enum BlendMode
+ {
+ BLEND_NONE,
+ BLEND_ALPHA_BLENDING,
+ BLEND_ADDITIVE
+ };
+
+ RenderMaterial(ResourceManager& resourceProvider, const char* shaderFileName, const char* textureFileName = "", BlendMode blendMode = BLEND_NONE);
+ ~RenderMaterial();
+
+ void setBlending(BlendMode blendMode);
+ BlendMode getBlending() const { return mBlendMode; }
+
+ void reload();
+
+ class Instance
+ {
+ public:
+ Instance(RenderMaterial& material, ID3D11InputLayout* inputLayout, uint32_t shaderNum = 0) : mMaterial(material), mInputLayout(inputLayout), mShaderNum(shaderNum) {}
+ ~Instance() { SAFE_RELEASE(mInputLayout); }
+
+ bool isValid();
+ void bind(ID3D11DeviceContext& context, uint32_t slot, bool depthStencilOnly = false);
+ RenderMaterial& getMaterial() const { return mMaterial; }
+ private:
+ RenderMaterial& mMaterial;
+ ID3D11InputLayout* mInputLayout;
+ uint32_t mShaderNum;
+ };
+
+ typedef std::shared_ptr<Instance> InstancePtr;
+
+ InstancePtr getMaterialInstance(const IRenderMesh* mesh);
+ InstancePtr getMaterialInstance(const D3D11_INPUT_ELEMENT_DESC* elementDescs, uint32_t numElements);
+
+ private:
+ void initialize(ResourceManager& resourceCallback, const char* shaderFileName, const char* textureFileName, BlendMode blendMode);
+ void initialize(ResourceManager&resourceProvider, std::vector<std::string> shaderFileNames, const char* textureFileName, BlendMode blendMode);
+
+ void releaseReloadableResources();
+
+ std::string mShaderFileName;
+ std::string mTextureFileName;
+
+ struct ShaderGroup
+ {
+ ShaderGroup() : vs(nullptr), gs(nullptr), ps(nullptr), buffer(nullptr)
+ {
+ }
+ ~ShaderGroup()
+ {
+ Release();
+ }
+ void Release()
+ {
+ SAFE_RELEASE(vs);
+ SAFE_RELEASE(gs);
+ SAFE_RELEASE(ps);
+ SAFE_RELEASE(buffer);
+ }
+ void Set(ID3D11DeviceContext* c, bool setPixelShader = true)
+ {
+ c->VSSetShader(vs, nullptr, 0);
+ c->GSSetShader(gs, nullptr, 0);
+ c->PSSetShader(setPixelShader ? ps : nullptr, nullptr, 0);
+ }
+ bool IsValid()
+ {
+ return vs != nullptr;
+ }
+ ID3D11VertexShader* vs;
+ ID3D11GeometryShader* gs;
+ ID3D11PixelShader* ps;
+ ID3DBlob* buffer;
+ };
+
+ std::map<const IRenderMesh*, std::weak_ptr<Instance>> mRenderMeshToInstanceMap;
+ const TextureResource* mTexture;
+ ID3D11ShaderResourceView* mTextureSRV;
+ std::vector<std::string> mShaderFilePathes;
+ std::vector<ShaderGroup*> mShaderGroups;
+ ID3D11BlendState* mBlendState;
+ BlendMode mBlendMode;
+};
+
+#endif \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/RenderUtils.h b/NvBlast/samples/SampleBase/renderer/RenderUtils.h
new file mode 100644
index 0000000..12df9f2
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/RenderUtils.h
@@ -0,0 +1,78 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 RENDER_UTILS_H
+#define RENDER_UTILS_H
+
+#include "DirectXTex.h"
+#include <DirectXMath.h>
+#include "PxMat44.h"
+#include "PxVec3.h"
+#include "PxVec4.h"
+
+static DirectX::XMFLOAT4 getRandomPastelColor()
+{
+ float r = ((double)rand() / (RAND_MAX)) * 0.5f + 0.5f;
+ float g = ((double)rand() / (RAND_MAX)) * 0.5f + 0.5f;
+ float b = ((double)rand() / (RAND_MAX)) * 0.5f + 0.5f;
+ return DirectX::XMFLOAT4(r, g, b, 1.0f);
+}
+
+static physx::PxMat44 XMMATRIXToPxMat44(const DirectX::XMMATRIX& mat)
+{
+ physx::PxMat44 m;
+ memcpy(const_cast<float*>(m.front()), &mat.r[0], 4 * 4 * sizeof(float));
+ return m;
+}
+
+static DirectX::XMMATRIX PxMat44ToXMMATRIX(const physx::PxMat44& mat)
+{
+ return DirectX::XMMATRIX(mat.front());
+}
+
+static physx::PxVec4 XMVECTORToPxVec4(const DirectX::XMVECTOR& vec)
+{
+ DirectX::XMFLOAT4 f;
+ DirectX::XMStoreFloat4(&f, vec);
+ return physx::PxVec4(f.x, f.y, f.z, f.w);
+}
+
+static physx::PxVec3 XMFLOAT3ToPxVec3(const DirectX::XMFLOAT3& vec)
+{
+ return physx::PxVec3(vec.x, vec.y, vec.z);
+}
+
+static physx::PxVec4 XMFLOAT4ToPxVec4(const DirectX::XMFLOAT4& vec)
+{
+ return physx::PxVec4(vec.x, vec.y, vec.z, vec.w);
+}
+
+static uint32_t XMFLOAT4ToU32Color(const DirectX::XMFLOAT4& color)
+{
+ uint32_t c = 0;
+ c |= (int)(color.w * 255); c <<= 8;
+ c |= (int)(color.z * 255); c <<= 8;
+ c |= (int)(color.y * 255); c <<= 8;
+ c |= (int)(color.x * 255);
+ return c;
+}
+
+static DirectX::XMFLOAT4 XMFLOAT4Lerp(const DirectX::XMFLOAT4 v0, const DirectX::XMFLOAT4 v1, float val)
+{
+ DirectX::XMFLOAT4 v(
+ v0.x * (1 - val) + v1.x * val,
+ v0.y * (1 - val) + v1.y * val,
+ v0.z * (1 - val) + v1.z * val,
+ v0.w * (1 - val) + v1.w * val
+ );
+ return v;
+}
+
+#endif //RENDER_UTILS_H \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/Renderable.cpp b/NvBlast/samples/SampleBase/renderer/Renderable.cpp
new file mode 100644
index 0000000..340874b
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/Renderable.cpp
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 "Renderable.h"
+#include "Renderer.h"
+#include "RenderUtils.h"
+
+const DirectX::XMFLOAT4 DEFAULT_COLOR(0.5f, 0.5f, 0.5f, 1.0f);
+
+Renderable::Renderable(IRenderMesh& mesh, RenderMaterial& material) : m_mesh(mesh), m_scale(1, 1, 1), m_color(DEFAULT_COLOR), m_hidden(false), m_transform(PxIdentity)
+{
+ setMaterial(material);
+}
+
+void Renderable::setMaterial(RenderMaterial& material)
+{
+ m_materialInstance = material.getMaterialInstance(&m_mesh);
+}
+
+void Renderable::render(Renderer& renderer, bool depthStencilOnly) const
+{
+ if (!m_materialInstance->isValid())
+ {
+ PX_ALWAYS_ASSERT();
+ return;
+ }
+
+ m_materialInstance->bind(*renderer.m_context, 0, depthStencilOnly);
+
+ // setup object CB
+ {
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ renderer.m_context->Map(renderer.m_objectCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ Renderer::CBObject* objectBuffer = (Renderer::CBObject*)mappedResource.pData;
+ objectBuffer->world = PxMat44ToXMMATRIX(getModelMatrix());
+ objectBuffer->color = getColor();
+ renderer.m_context->Unmap(renderer.m_objectCB, 0);
+ }
+
+ m_mesh.render(*renderer.m_context);
+}
diff --git a/NvBlast/samples/SampleBase/renderer/Renderable.h b/NvBlast/samples/SampleBase/renderer/Renderable.h
new file mode 100644
index 0000000..f1faa52
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/Renderable.h
@@ -0,0 +1,128 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 RENDERABLE_H
+#define RENDERABLE_H
+
+#include "RenderMaterial.h"
+#include <DirectXMath.h>
+#include "PxMat44.h"
+#include "PxVec3.h"
+#include "PxVec4.h"
+
+using namespace physx;
+
+class Renderer;
+
+/**
+RenderMesh interface, used by Renderable
+*/
+class IRenderMesh
+{
+public:
+ virtual ~IRenderMesh() {}
+ virtual const std::vector<D3D11_INPUT_ELEMENT_DESC>& getInputElementDesc() const = 0;
+ virtual void render(ID3D11DeviceContext& context) const = 0;
+};
+
+/**
+Renderable, represents single object renderer by Renderer.
+Basically Renderable = RenderMaterial + RenderMesh
+*/
+class Renderable
+{
+public:
+ //////// public API ////////
+
+ void setMaterial(RenderMaterial& material);
+
+ PxMat44 getModelMatrix() const
+ {
+ return PxMat44(m_transform) * PxMat44(PxVec4(m_scale, 1));
+ }
+
+ void setTransform(PxTransform& transform)
+ {
+ m_transform = transform;
+ }
+
+ const PxTransform& getTransform() const
+ {
+ return m_transform;
+ }
+
+ void setScale(PxVec3 scale)
+ {
+ m_scale = scale;
+ }
+
+ const PxVec3& getScale() const
+ {
+ return m_scale;
+ }
+
+ void setColor(DirectX::XMFLOAT4 color)
+ {
+ m_color = color;
+ }
+ DirectX::XMFLOAT4 getColor() const
+ {
+ return m_color;
+ }
+
+ void setHidden(bool hidden)
+ {
+ m_hidden = hidden;
+ }
+
+ bool isHidden() const
+ {
+ return m_hidden;
+ }
+
+ bool isTransparent() const
+ {
+ return !(m_materialInstance->getMaterial().getBlending() == RenderMaterial::BLEND_NONE);
+ }
+
+ RenderMaterial& getMaterial() const { return m_materialInstance->getMaterial(); }
+
+private:
+ //////// methods used by Renderer ////////
+
+ friend class Renderer;
+
+ void render(Renderer& renderer) const
+ {
+ render(renderer, false);
+ }
+
+ void renderDepthStencilOnly(Renderer& renderer) const
+ {
+ render(renderer, true);
+ }
+
+ Renderable(IRenderMesh& mesh, RenderMaterial& material);
+
+ void render(Renderer& renderer, bool depthStencilOnly) const;
+
+
+ //////// internal data ////////
+
+ DirectX::XMFLOAT4 m_color;
+ PxTransform m_transform;
+ PxVec3 m_scale;
+
+ RenderMaterial::InstancePtr m_materialInstance;
+ IRenderMesh& m_mesh;
+ bool m_hidden;
+};
+
+#endif //RENDERABLE_H \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/Renderer.cpp b/NvBlast/samples/SampleBase/renderer/Renderer.cpp
new file mode 100644
index 0000000..94ea3c3
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/Renderer.cpp
@@ -0,0 +1,729 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 "Renderer.h"
+#include "RenderUtils.h"
+#include "UIHelpers.h"
+#include "SampleProfiler.h"
+
+#include "PxRenderBuffer.h"
+
+#include <set>
+
+
+const float CAMERA_CLIP_NEAR = 1.0f;
+const float CAMERA_CLIP_FAR = 1000.00f;
+
+const float CLEAR_SCENE_COLOR[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Renderer
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+Renderer::Renderer()
+: m_cameraCB(nullptr)
+, m_worldCB(nullptr)
+, m_objectCB(nullptr)
+, m_RSState(nullptr)
+, m_opaqueRenderDSState(nullptr)
+, m_transparencyRenderDSState(nullptr)
+, m_DSTexture(nullptr)
+, m_DSView(nullptr)
+, m_DSTextureSRV(nullptr)
+, m_pointSampler(nullptr)
+, m_linearSampler(nullptr)
+, m_wireframeMode(false)
+, m_debugPrimitiveVB(nullptr)
+, m_debugPrimitiveVBVerticesCount(0)
+, m_shadowEnabled(true)
+, m_HBAOEnabled(true)
+, m_visibleOpaqueRenderablesCount(0)
+, m_visibleTransparentRenderablesCount(0)
+{
+ m_worldCBData.ambientColor = DirectX::XMFLOAT3(0.21f, 0.21f, 0.22f);
+ m_worldCBData.pointLightColor = DirectX::XMFLOAT3(1.0f, 1.0f, 1.0f);
+ m_worldCBData.pointLightPos = DirectX::XMFLOAT3(0.0f, 30.0f, 12.0f);
+ m_worldCBData.dirLightColor = DirectX::XMFLOAT3(0.0f, 0.0f, 0.0f);
+ m_worldCBData.dirLightDir = DirectX::XMFLOAT3(-0.08f, -0.34f, -0.91f);
+ m_worldCBData.specularPower = 140.0f;
+ m_worldCBData.specularIntensity = 0.4f;
+
+ toggleCameraSpeed(false);
+}
+
+Renderer::~Renderer()
+{
+}
+
+void Renderer::initializeDefaultRSState()
+{
+ SAFE_RELEASE(m_RSState);
+ D3D11_RASTERIZER_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.CullMode = D3D11_CULL_FRONT;
+ desc.FillMode = m_wireframeMode ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID;
+ desc.AntialiasedLineEnable = FALSE;
+ desc.DepthBias = 0;
+ desc.DepthBiasClamp = 0;
+ desc.DepthClipEnable = TRUE;
+ desc.FrontCounterClockwise = FALSE;
+ desc.MultisampleEnable = TRUE;
+ desc.ScissorEnable = FALSE;
+ desc.SlopeScaledDepthBias = 0;
+
+ V(m_device->CreateRasterizerState(&desc, &m_RSState));
+}
+
+HRESULT Renderer::DeviceCreated(ID3D11Device* device)
+{
+ m_device = device;
+
+ // Camera constant buffer
+ {
+ D3D11_BUFFER_DESC buffer_desc;
+ ZeroMemory(&buffer_desc, sizeof(buffer_desc));
+ buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
+ buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ buffer_desc.ByteWidth = sizeof(CBCamera);
+ _ASSERT((buffer_desc.ByteWidth % 16) == 0);
+
+ V(device->CreateBuffer(&buffer_desc, nullptr, &m_cameraCB));
+ }
+
+ // World constant buffer
+ {
+ D3D11_BUFFER_DESC buffer_desc;
+ ZeroMemory(&buffer_desc, sizeof(buffer_desc));
+ buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
+ buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ buffer_desc.ByteWidth = sizeof(CBWorld);
+ _ASSERT((buffer_desc.ByteWidth % 16) == 0);
+
+ V(device->CreateBuffer(&buffer_desc, nullptr, &m_worldCB));
+ }
+
+ // Object constant buffer
+ {
+ D3D11_BUFFER_DESC buffer_desc;
+ ZeroMemory(&buffer_desc, sizeof(buffer_desc));
+ buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
+ buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ buffer_desc.ByteWidth = sizeof(CBObject);
+ _ASSERT((buffer_desc.ByteWidth % 16) == 0);
+
+ V(device->CreateBuffer(&buffer_desc, nullptr, &m_objectCB));
+ }
+
+ // Opaque Render Depth-Stencil state
+ {
+ D3D11_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.StencilEnable = FALSE;
+ desc.DepthEnable = TRUE;
+ desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
+
+ V(device->CreateDepthStencilState(&desc, &m_opaqueRenderDSState));
+ }
+
+ // Transparency Render Depth-Stencil state
+ {
+ D3D11_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.StencilEnable = FALSE;
+ desc.DepthEnable = TRUE;
+ desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
+ desc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
+
+ V(device->CreateDepthStencilState(&desc, &m_transparencyRenderDSState));
+ }
+
+ // Linear sampler
+ {
+ D3D11_SAMPLER_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
+ desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
+ desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
+ desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
+ desc.MaxAnisotropy = 1;
+ desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
+ desc.MinLOD = 0;
+ desc.MaxLOD = D3D11_FLOAT32_MAX;
+ V(device->CreateSamplerState(&desc, &m_linearSampler));
+ }
+
+ // Point sampler
+ {
+ D3D11_SAMPLER_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
+ desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
+ desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
+ desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
+ desc.MaxAnisotropy = 1;
+ desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
+ desc.MinLOD = 0;
+ desc.MaxLOD = D3D11_FLOAT32_MAX;
+ V(device->CreateSamplerState(&desc, &m_pointSampler));
+ }
+
+ // Rasterizer state
+ initializeDefaultRSState();
+
+ // init primitive render meshes
+ for (uint32_t i = 0; i < PrimitiveRenderMeshType::Count; i++)
+ {
+ m_primitiveRenderMeshes[i] = nullptr;
+ }
+
+ // init shadows
+ ID3D11DeviceContext* pd3dDeviceContext;
+ m_device->GetImmediateContext(&pd3dDeviceContext);
+ m_shadow.createResources(m_device, pd3dDeviceContext, &m_camera);
+
+ // init hbao
+ m_HBAO.createResources(m_device);
+
+ return S_OK;
+}
+
+void Renderer::DeviceDestroyed()
+{
+ SAFE_RELEASE(m_cameraCB);
+ SAFE_RELEASE(m_worldCB);
+ SAFE_RELEASE(m_objectCB);
+ SAFE_RELEASE(m_RSState);
+ SAFE_RELEASE(m_opaqueRenderDSState);
+ SAFE_RELEASE(m_transparencyRenderDSState);
+ SAFE_RELEASE(m_pointSampler);
+ SAFE_RELEASE(m_linearSampler);
+ SAFE_RELEASE(m_debugPrimitiveVB);
+ SAFE_RELEASE(m_DSTexture);
+ SAFE_RELEASE(m_DSView);
+ SAFE_RELEASE(m_DSTextureSRV);
+
+ for (uint32_t i = 0; i < PrimitiveRenderMeshType::Count; i++)
+ {
+ SAFE_DELETE(m_primitiveRenderMeshes[i]);
+ }
+}
+
+void Renderer::onInitialize()
+{
+ // search paths
+ m_resourceManager.addSearchDir("..\\..\\samples\\resources");
+ m_resourceManager.addSearchDir("..\\..\\..\\samples\\resources");
+ for (const std::string& d : getManager()->getConfig().additionalResourcesDir)
+ {
+ m_resourceManager.addSearchDir(d.c_str());
+ }
+
+ // debug primitive render material and input layout
+ {
+ m_debugPrimitiveRenderMaterial = new RenderMaterial(m_resourceManager, "debug_primitive", "");
+
+ D3D11_INPUT_ELEMENT_DESC layout[] = {
+ { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
+ };
+
+ m_debugPrimitiveRenderMaterialInstance = m_debugPrimitiveRenderMaterial->getMaterialInstance(layout, ARRAYSIZE(layout));
+ }
+}
+
+void Renderer::onTerminate()
+{
+ SAFE_DELETE(m_debugPrimitiveRenderMaterial);
+}
+
+void Renderer::BackBufferResized(ID3D11Device* /*device*/, const DXGI_SURFACE_DESC* sd)
+{
+ // Setup the camera's projection parameters
+ m_screenWidth = sd->Width;
+ m_screenHeight = sd->Height;
+ float fAspectRatio = m_screenWidth / m_screenHeight;
+ m_camera.SetProjParams(DirectX::XM_PIDIV4, fAspectRatio, CAMERA_CLIP_NEAR, CAMERA_CLIP_FAR);
+
+ SAFE_RELEASE(m_DSTexture);
+ SAFE_RELEASE(m_DSView);
+ SAFE_RELEASE(m_DSTextureSRV);
+
+ // create a new Depth-Stencil texture
+ {
+ D3D11_TEXTURE2D_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.Width = sd->Width;
+ desc.Height = sd->Height;
+ desc.MipLevels = 1;
+ desc.ArraySize = 1;
+ desc.Format = DXGI_FORMAT_R32_TYPELESS; // Use a typeless type here so that it can be both depth-stencil and shader resource.
+ desc.SampleDesc.Count = sd->SampleDesc.Count;
+ desc.SampleDesc.Quality = sd->SampleDesc.Quality;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+ V(m_device->CreateTexture2D(&desc, NULL, &m_DSTexture));
+ }
+
+ // create Depth-Stencil view
+ {
+ D3D11_DEPTH_STENCIL_VIEW_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.ViewDimension = sd->SampleDesc.Count > 1 ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;
+ desc.Format = DXGI_FORMAT_D32_FLOAT; // Make the view see this as D32_FLOAT instead of typeless
+ desc.Texture2D.MipSlice = 0;
+ V(m_device->CreateDepthStencilView(m_DSTexture, &desc, &m_DSView));
+ }
+
+ // create Depth-Stencil shader resource view
+ {
+ D3D11_SHADER_RESOURCE_VIEW_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.Format = DXGI_FORMAT_R32_FLOAT; // Make the shaders see this as R32_FLOAT instead of typeless
+ desc.ViewDimension = sd->SampleDesc.Count > 1 ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D;
+ desc.Texture2D.MipLevels = 1;
+ desc.Texture2D.MostDetailedMip = 0;
+ V(m_device->CreateShaderResourceView(m_DSTexture, &desc, &m_DSTextureSRV));
+ }
+
+ // setup viewport
+ m_viewport.Width = (FLOAT)sd->Width;
+ m_viewport.Height = (FLOAT)sd->Height;
+ m_viewport.MinDepth = 0;
+ m_viewport.MaxDepth = 1;
+ m_viewport.TopLeftX = 0;
+ m_viewport.TopLeftY = 0;
+
+ // setup shadows
+ m_shadow.setScreenResolution(0, sd->Width, sd->Height, sd->SampleDesc.Count, nullptr);
+}
+
+void Renderer::setAllConstantBuffers(ID3D11DeviceContext* ctx)
+{
+ ID3D11Buffer* cbs[3] = { m_cameraCB, m_worldCB, m_objectCB };
+ ctx->VSSetConstantBuffers(0, 3, cbs);
+ ctx->GSSetConstantBuffers(0, 3, cbs);
+ ctx->PSSetConstantBuffers(0, 3, cbs);
+}
+
+void Renderer::Render(ID3D11Device* /*device*/, ID3D11DeviceContext* ctx, ID3D11RenderTargetView* pRTV,
+ ID3D11DepthStencilView*)
+{
+ PROFILER_SCOPED_FUNCTION();
+
+ m_context = ctx;
+
+ ctx->ClearRenderTargetView(pRTV, CLEAR_SCENE_COLOR);
+ ctx->ClearDepthStencilView(m_DSView, D3D11_CLEAR_DEPTH, 1.0, 0);
+ ctx->RSSetViewports(1, &m_viewport);
+
+ // needed matrices
+ DirectX::XMMATRIX viewMatrix = m_camera.GetViewMatrix();
+ DirectX::XMMATRIX projMatrix = m_camera.GetProjMatrix();
+ DirectX::XMMATRIX projMatrixInv = DirectX::XMMatrixInverse(NULL, projMatrix);
+ DirectX::XMMATRIX viewProjMatrix = viewMatrix * projMatrix;
+
+ // Fill Camera constant buffer
+ {
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ ctx->Map(m_cameraCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ CBCamera* cameraBuffer = (CBCamera*)mappedResource.pData;
+ cameraBuffer->viewProjection = viewProjMatrix;
+ cameraBuffer->projectionInv = projMatrixInv;
+ DirectX::XMStoreFloat3(&(cameraBuffer->viewPos), m_camera.GetEyePt());
+ ctx->Unmap(m_cameraCB, 0);
+ }
+
+ // Fill World constant buffer
+ {
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ ctx->Map(m_worldCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ CBWorld* worldBuffer = (CBWorld*)mappedResource.pData;
+ memcpy(worldBuffer, &m_worldCBData, sizeof(m_worldCBData));
+ //worldBuffer->ambientColor = m_CBWorldData.ambientColor;
+ //worldBuffer->pointLightPos = m_CBWorldData.pointLightPos;
+ //worldBuffer->pointLightColor = m_CBWorldData.pointLightColor;
+ //worldBuffer->dirLightDir = m_CBWorldData.dirLightDir;
+ //worldBuffer->specularPower = m_CBWorldData.specularPower;
+ //worldBuffer->dirLightColor = m_CBWorldData.dirLightColor;
+ //worldBuffer->specularIntensity = m_CBWorldData.specularIntensity;
+ ctx->Unmap(m_worldCB, 0);
+ }
+
+ ctx->RSSetState(m_RSState);
+ ctx->PSSetSamplers(0, 1, &m_linearSampler);
+ ctx->PSSetSamplers(1, 1, &m_pointSampler);
+
+
+ if (m_shadowEnabled)
+ {
+ // render depth only
+ {
+ ctx->OMSetRenderTargets(0, nullptr, m_DSView);
+ ctx->OMSetDepthStencilState(m_opaqueRenderDSState, 0xFF);
+
+ // set constants buffers
+ setAllConstantBuffers(ctx);
+
+ for (auto it = m_renderables.begin(); it != m_renderables.end(); it++)
+ {
+ if (!(*it)->isTransparent() && !(*it)->isHidden())
+ (*it)->renderDepthStencilOnly(*this);
+ }
+ }
+
+ // render shadow map
+ m_shadow.renderShadowMaps(this);
+
+ // render shadow buffer
+ ctx->OMSetRenderTargets(0, nullptr, nullptr);
+ m_shadow.renderShadowBuffer(m_DSTextureSRV, nullptr);
+ }
+
+ // Opaque render
+ {
+ ctx->RSSetViewports(1, &m_viewport);
+ ctx->RSSetState(m_RSState);
+ ctx->OMSetRenderTargets(1, &pRTV, m_DSView);
+ ctx->OMSetDepthStencilState(m_opaqueRenderDSState, 0xFF);
+
+ // set constants buffers
+ setAllConstantBuffers(ctx);
+
+ // Fill Camera constant buffer
+ {
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ ctx->Map(m_cameraCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ CBCamera* cameraBuffer = (CBCamera*)mappedResource.pData;
+ cameraBuffer->viewProjection = viewProjMatrix;
+ cameraBuffer->projectionInv = projMatrixInv;
+ DirectX::XMStoreFloat3(&(cameraBuffer->viewPos), m_camera.GetEyePt());
+ ctx->Unmap(m_cameraCB, 0);
+ }
+
+ // Render opaque renderables
+ m_visibleOpaqueRenderablesCount = 0;
+ for (auto it = m_renderables.begin(); it != m_renderables.end(); it++)
+ {
+ if (!(*it)->isTransparent() && !(*it)->isHidden())
+ {
+ (*it)->render(*this);
+ m_visibleOpaqueRenderablesCount++;
+ }
+ }
+ }
+
+ // modulate shadows
+ if (m_shadowEnabled)
+ {
+ m_shadow.modulateShadowBuffer(pRTV);
+ }
+
+ // render AO
+ if (m_HBAOEnabled)
+ {
+ m_HBAO.renderAO(m_context, pRTV, m_DSTextureSRV, projMatrix);
+ }
+
+ ctx->RSSetViewports(1, &m_viewport);
+
+ // render debug render buffers
+ while (m_queuedRenderBuffers.size() > 0)
+ {
+ render(m_queuedRenderBuffers.back());
+ m_queuedRenderBuffers.pop_back();
+ }
+
+ // Transparency render
+ ctx->OMSetRenderTargets(1, &pRTV, m_DSView);
+ ctx->OMSetDepthStencilState(m_transparencyRenderDSState, 0xFF);
+
+ // depth as SRV isn't used now (uncommenting will produce a warning, probably need readonly depth?)
+ //ctx->PSSetShaderResources(1, 1, &mDSTextureSRV);
+
+ // Render transparent renderables
+ m_visibleTransparentRenderablesCount = 0;
+ for (auto it = m_renderables.begin(); it != m_renderables.end(); it++)
+ {
+ if ((*it)->isTransparent() && !(*it)->isHidden())
+ {
+ (*it)->render(*this);
+ m_visibleTransparentRenderablesCount++;
+ }
+ }
+
+ // shadows debug render
+ if (0)
+ {
+ m_shadow.displayMapFrustums(pRTV, m_DSView);
+ }
+
+ // Reset RT and SRV state
+ ID3D11ShaderResourceView* nullAttach[16] = { nullptr };
+ ctx->PSSetShaderResources(0, 16, nullAttach);
+ ctx->OMSetRenderTargets(0, nullptr, nullptr);
+}
+
+LRESULT Renderer::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ PX_UNUSED(hWnd);
+ PX_UNUSED(wParam);
+ PX_UNUSED(lParam);
+
+ if (uMsg == WM_KEYDOWN || uMsg == WM_KEYUP)
+ {
+ // Camera overspeed event
+ int iKeyPressed = static_cast<int>(wParam);
+ if (iKeyPressed == VK_SHIFT)
+ {
+ toggleCameraSpeed(uMsg == WM_KEYDOWN);
+ }
+ }
+
+ // Camera events
+ return m_camera.HandleMessages(hWnd, uMsg, wParam, lParam);
+}
+
+void Renderer::Animate(double fElapsedTimeSeconds)
+{
+ PROFILER_SCOPED_FUNCTION();
+
+ m_camera.FrameMove((float)fElapsedTimeSeconds);
+}
+
+void Renderer::renderDepthOnly(DirectX::XMMATRIX* viewProjectionSubstitute)
+{
+ // Fill Camera constant buffer
+ if (viewProjectionSubstitute)
+ {
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ m_context->Map(m_cameraCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ CBCamera* cameraBuffer = (CBCamera*)mappedResource.pData;
+ cameraBuffer->viewProjection = *viewProjectionSubstitute;
+ m_context->Unmap(m_cameraCB, 0);
+ }
+
+ // set constants buffers
+ setAllConstantBuffers(m_context);
+
+ // render
+ for (auto it = m_renderables.begin(); it != m_renderables.end(); it++)
+ {
+ if (!(*it)->isTransparent() && !(*it)->isHidden())
+ (*it)->renderDepthStencilOnly(*this);
+ }
+}
+
+void Renderer::render(const PxRenderBuffer* renderBuffer)
+{
+ // points
+ uint32_t pointsCount = renderBuffer->getNbPoints();
+ if (pointsCount > 0)
+ {
+ RenderDebugVertex* verts = new RenderDebugVertex[pointsCount];
+ const PxDebugPoint* points = renderBuffer->getPoints();
+ for (uint32_t i = 0; i < pointsCount; i++)
+ {
+ verts[i].mPos = points[i].pos;
+ verts[i].mColor = points[i].color;
+ }
+
+ renderDebugPrimitive(verts, pointsCount, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
+ delete[] verts;
+ }
+
+ // lines
+ uint32_t linesCount = renderBuffer->getNbLines();
+ if (linesCount > 0)
+ {
+ RenderDebugVertex* verts = new RenderDebugVertex[linesCount * 2];
+ const PxDebugLine* lines = renderBuffer->getLines();
+ for (uint32_t i = 0; i < linesCount; i++)
+ {
+ verts[i * 2].mPos = lines[i].pos0;
+ verts[i * 2].mColor = lines[i].color0;
+ verts[i * 2 + 1].mPos = lines[i].pos1;
+ verts[i * 2 + 1].mColor = lines[i].color1;
+ }
+
+ renderDebugPrimitive(verts, linesCount * 2, D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
+ delete[] verts;
+ }
+
+ // triangles
+ uint32_t trianglesCount = renderBuffer->getNbTriangles();
+ if (trianglesCount > 0)
+ {
+ RenderDebugVertex* verts = new RenderDebugVertex[trianglesCount * 3];
+ const PxDebugTriangle* triangles = renderBuffer->getTriangles();
+ for (uint32_t i = 0; i < trianglesCount; i++)
+ {
+ verts[i * 3].mPos = triangles[i].pos0;
+ verts[i * 3].mColor = triangles[i].color0;
+ verts[i * 3 + 1].mPos = triangles[i].pos1;
+ verts[i * 3 + 1].mColor = triangles[i].color1;
+ verts[i * 3 + 2].mPos = triangles[i].pos2;
+ verts[i * 3 + 2].mColor = triangles[i].color2;
+ }
+
+ renderDebugPrimitive(verts, trianglesCount * 3, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ delete[] verts;
+ }
+
+ // texts?
+ // ....
+}
+
+void Renderer::renderDebugPrimitive(const Renderer::RenderDebugVertex *vertices, uint32_t verticesCount, D3D11_PRIMITIVE_TOPOLOGY topology)
+{
+ m_context->IASetPrimitiveTopology(topology);
+
+ m_debugPrimitiveRenderMaterialInstance->bind(*m_context, 0);
+
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ m_context->Map(m_objectCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ CBObject* objectBuffer = (CBObject*)mappedResource.pData;
+
+ objectBuffer->world = PxMat44ToXMMATRIX(PxMat44(PxIdentity));
+
+ m_context->Unmap(m_objectCB, 0);
+
+ if (m_debugPrimitiveVBVerticesCount < verticesCount)
+ {
+ m_debugPrimitiveVBVerticesCount = verticesCount;
+ SAFE_RELEASE(m_debugPrimitiveVB);
+
+ D3D11_BUFFER_DESC bufferDesc;
+
+ memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC));
+ bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ bufferDesc.ByteWidth = sizeof(Renderer::RenderDebugVertex) * m_debugPrimitiveVBVerticesCount;
+ bufferDesc.CPUAccessFlags = 0;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.Usage = D3D11_USAGE_DEFAULT;
+
+ V(m_device->CreateBuffer(&bufferDesc, NULL, &m_debugPrimitiveVB));
+ }
+
+ CD3D11_BOX box(0, 0, 0, (LONG)(sizeof(Renderer::RenderDebugVertex) * verticesCount), 1, 1);
+ m_context->UpdateSubresource(m_debugPrimitiveVB, 0, &box, vertices, 0, 0);
+
+ ID3D11Buffer* pBuffers[1] = { m_debugPrimitiveVB };
+ UINT strides[1] = { sizeof(RenderDebugVertex) };
+ UINT offsets[1] = { 0 };
+ m_context->IASetVertexBuffers(0, 1, pBuffers, strides, offsets);
+
+ m_context->Draw(verticesCount, 0);
+}
+
+IRenderMesh* Renderer::getPrimitiveRenderMesh(PrimitiveRenderMeshType::Enum type)
+{
+ if (m_primitiveRenderMeshes[type] == NULL)
+ {
+ switch (type)
+ {
+ case PrimitiveRenderMeshType::Box:
+ m_primitiveRenderMeshes[type] = new BoxRenderMesh();
+ break;
+ case PrimitiveRenderMeshType::Plane:
+ m_primitiveRenderMeshes[type] = new PlaneRenderMesh();
+ break;
+ case PrimitiveRenderMeshType::Sphere:
+ m_primitiveRenderMeshes[type] = new SphereRenderMesh();
+ break;
+ default:
+ PX_ALWAYS_ASSERT_MESSAGE("Unsupported PxGeometryType");
+ return NULL;
+ }
+ }
+
+ return m_primitiveRenderMeshes[type];
+}
+
+
+Renderable* Renderer::createRenderable(IRenderMesh& mesh, RenderMaterial& material)
+{
+ Renderable* renderable = new Renderable(mesh, material);
+ m_renderables.emplace(renderable);
+ return renderable;
+}
+
+void Renderer::removeRenderable(Renderable* r)
+{
+ m_renderables.erase(m_renderables.find(r));
+ delete r;
+}
+
+void Renderer::toggleCameraSpeed(bool overspeed)
+{
+ m_camera.SetScalers(0.002f, overspeed ? 150.f : 25.f);
+}
+
+void Renderer::reloadShaders()
+{
+ // iterate Renderables materials and call reload()
+ std::set<RenderMaterial*> materials;
+ for (auto it = m_renderables.begin(); it != m_renderables.end(); it++)
+ {
+ materials.emplace(&((*it)->getMaterial()));
+ }
+ for (std::set<RenderMaterial*>::iterator it = materials.begin(); it != materials.end(); it++)
+ {
+ (*it)->reload();
+ }
+}
+
+void Renderer::drawUI()
+{
+ // Lighting
+ if (ImGui::TreeNode("Lighting"))
+ {
+ ImGui::ColorEdit3("Ambient Color", &(m_worldCBData.ambientColor.x));
+ ImGui::ColorEdit3("Point Light Color", &(m_worldCBData.pointLightColor.x));
+ ImGui::DragFloat3("Point Light Pos", &(m_worldCBData.pointLightPos.x));
+ ImGui::ColorEdit3("Dir Light Color", &(m_worldCBData.dirLightColor.x));
+ ImGui_DragFloat3Dir("Dir Light Dir", &(m_worldCBData.dirLightDir.x));
+ ImGui::DragFloat("Specular Power", &(m_worldCBData.specularPower), 1.0f, 1.0f, 500.0f);
+ ImGui::DragFloat("Specular Intensity", &(m_worldCBData.specularIntensity), 0.01f, 0.0f, 2.0f);
+
+ ImGui::TreePop();
+ }
+
+ // Shadow
+ if (ImGui::TreeNode("Shadow"))
+ {
+ ImGui::Checkbox("Shadows Enabled", &m_shadowEnabled);
+ if (m_shadowEnabled)
+ {
+ m_shadow.drawUI();
+ }
+
+ ImGui::TreePop();
+ }
+
+ // HBAO+
+ if (ImGui::TreeNode("HBAO+"))
+ {
+ ImGui::Checkbox("HBAO Enabled", &(m_HBAOEnabled));
+ if (m_HBAOEnabled)
+ {
+ m_HBAO.drawUI();
+ }
+
+ ImGui::TreePop();
+ }
+} \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/Renderer.h b/NvBlast/samples/SampleBase/renderer/Renderer.h
new file mode 100644
index 0000000..56e6e4a
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/Renderer.h
@@ -0,0 +1,248 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 RENDERER_H
+#define RENDERER_H
+
+#include "RenderMaterial.h"
+#include <DirectXMath.h>
+#include "XInput.h"
+#include "DXUTMisc.h"
+#include "DXUTCamera.h"
+#include "SampleManager.h"
+#include "Utils.h"
+#include "ResourceManager.h"
+#include "PrimitiveRenderMesh.h"
+#include "RendererShadow.h"
+#include "RendererHBAO.h"
+#include <unordered_set>
+
+class CFirstPersonCamera;
+class PhysXPrimitive;
+class RenderDebugImpl;
+
+namespace physx
+{
+class PxRenderBuffer;
+}
+
+
+/**
+3D World Renderer
+- use createRenderable() to add objects to render.
+- use queueRenderBuffer() every frame to render debug primitives.
+- contains ResourceManager to search for file and load resources.
+- contains RendererShadow and RendererHBAO, use them through getters to control shadows.
+*/
+class Renderer : public ISampleController
+{
+ friend class Renderable;
+
+ public:
+ //////// ctor ////////
+
+ Renderer();
+ ~Renderer();
+
+
+ //////// public API ////////
+
+ void reloadShaders();
+
+ bool getWireframeMode()
+ {
+ return m_wireframeMode;
+ }
+
+ void setWireframeMode(bool enabled)
+ {
+ if(m_wireframeMode != enabled)
+ {
+ m_wireframeMode = enabled;
+ initializeDefaultRSState();
+ }
+ }
+
+ IRenderMesh* getPrimitiveRenderMesh(PrimitiveRenderMeshType::Enum type);
+
+ Renderable* createRenderable(IRenderMesh& mesh, RenderMaterial& material);
+ void removeRenderable(Renderable* r);
+
+ void drawUI();
+
+
+ //////// public getters ////////
+
+ float getScreenWidth() const
+ {
+ return m_screenWidth;
+ }
+
+ float getScreenHeight() const
+ {
+ return m_screenHeight;
+ }
+
+ void queueRenderBuffer(const PxRenderBuffer* buffer)
+ {
+ m_queuedRenderBuffers.push_back(buffer);
+ }
+
+ ResourceManager& getResourceManager()
+ {
+ return m_resourceManager;
+ }
+
+ uint32_t getVisibleOpaqueRenderablesCount()
+ {
+ return m_visibleOpaqueRenderablesCount;
+ }
+
+ uint32_t getVisibleTransparentRenderablesCount()
+ {
+ return m_visibleTransparentRenderablesCount;
+ }
+
+ CFirstPersonCamera& getCamera()
+ {
+ return m_camera;
+ }
+
+
+ //////// public 'internal' methods ////////
+
+ // for internal usage (used by RenderShadows)
+ void renderDepthOnly(DirectX::XMMATRIX* viewProjectionSubstitute);
+
+ protected:
+
+ //////// controller callbacks ////////
+
+ virtual HRESULT DeviceCreated(ID3D11Device* pDevice);
+ virtual void DeviceDestroyed();
+ virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual void Animate(double fElapsedTimeSeconds);
+ virtual void onInitialize();
+ virtual void onTerminate();
+ virtual void BackBufferResized(ID3D11Device* pDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc);
+ virtual void Render(ID3D11Device* /*device*/, ID3D11DeviceContext* ctx, ID3D11RenderTargetView* pRTV,
+ ID3D11DepthStencilView* pDSV);
+
+ private:
+
+ //////// internal methods ////////
+
+ struct RenderDebugVertex
+ {
+ PxVec3 mPos;
+ uint32_t mColor;
+ };
+
+ void render(const PxRenderBuffer* renderBuffer);
+ void render(Renderable* renderable);
+ void renderDebugPrimitive(const RenderDebugVertex *vertices, uint32_t verticesCount, D3D11_PRIMITIVE_TOPOLOGY topology);
+ void initializeDefaultRSState();
+ void setAllConstantBuffers(ID3D11DeviceContext* ctx);
+ void toggleCameraSpeed(bool overspeed);
+
+
+ //////// constant buffers ////////
+
+ struct CBCamera
+ {
+ DirectX::XMMATRIX viewProjection;
+ DirectX::XMMATRIX projectionInv;
+ DirectX::XMFLOAT3 viewPos;
+ float unusedPad;
+ };
+ struct CBWorld
+ {
+ DirectX::XMFLOAT3 ambientColor;
+ float unusedPad1;
+ DirectX::XMFLOAT3 pointLightPos;
+ float unusedPad2;
+ DirectX::XMFLOAT3 pointLightColor;
+ float unusedPad3;
+ DirectX::XMFLOAT3 dirLightDir;
+ float specularPower;
+ DirectX::XMFLOAT3 dirLightColor;
+ float specularIntensity; // TODO: actually it's per object property
+ };
+ struct CBObject
+ {
+ DirectX::XMMATRIX world;
+ DirectX::XMFLOAT4 color;
+ };
+
+
+ //////// internal data ////////
+
+ // camera
+ CFirstPersonCamera m_camera;
+ float m_screenWidth;
+ float m_screenHeight;
+
+ // resources
+ ResourceManager m_resourceManager;
+
+ // additional render modules(libs)
+ RendererShadow m_shadow;
+ bool m_shadowEnabled;
+ RendererHBAO m_HBAO;
+ bool m_HBAOEnabled;
+
+ // DX11 common
+ ID3D11Device* m_device;
+ ID3D11DeviceContext* m_context;
+ D3D11_VIEWPORT m_viewport;
+
+ // DX11 states
+ ID3D11RasterizerState* m_RSState;
+ ID3D11DepthStencilState* m_opaqueRenderDSState;
+ ID3D11DepthStencilState* m_transparencyRenderDSState;
+
+ // DX11 samplers
+ ID3D11SamplerState* m_pointSampler;
+ ID3D11SamplerState* m_linearSampler;
+
+ // Depth Buffer
+ ID3D11Texture2D* m_DSTexture;
+ ID3D11DepthStencilView* m_DSView;
+ ID3D11ShaderResourceView* m_DSTextureSRV;
+
+ // Constant Buffers
+ ID3D11Buffer* m_cameraCB;
+ ID3D11Buffer* m_worldCB;
+ CBWorld m_worldCBData;
+ ID3D11Buffer* m_objectCB;
+
+ // toggles (options)
+ bool m_wireframeMode;
+
+ // renderables
+ std::unordered_set<Renderable*> m_renderables;
+
+ // primitive meshes cache
+ IRenderMesh* m_primitiveRenderMeshes[PrimitiveRenderMeshType::Count];
+
+ // stats
+ uint32_t m_visibleOpaqueRenderablesCount;
+ uint32_t m_visibleTransparentRenderablesCount;
+
+ // Debug Render
+ RenderMaterial* m_debugPrimitiveRenderMaterial;
+ RenderMaterial::InstancePtr m_debugPrimitiveRenderMaterialInstance;
+ ID3D11Buffer* m_debugPrimitiveVB;
+ uint32_t m_debugPrimitiveVBVerticesCount;
+ std::vector<const PxRenderBuffer*> m_queuedRenderBuffers;
+};
+
+
+#endif \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/RendererHBAO.cpp b/NvBlast/samples/SampleBase/renderer/RendererHBAO.cpp
new file mode 100644
index 0000000..5e20a49
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/RendererHBAO.cpp
@@ -0,0 +1,81 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 "RendererHBAO.h"
+#include "Renderer.h"
+#include "imgui.h"
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Renderer HBAO (wrapper for hbao+)
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+RendererHBAO::RendererHBAO()
+{
+ m_SSAOContext = NULL;
+
+ // default parameters
+ m_SSAOParameters.Radius = 2.0f;
+}
+
+
+RendererHBAO::~RendererHBAO()
+{
+ releaseResources();
+}
+
+
+void RendererHBAO::createResources(ID3D11Device *pd3dDevice)
+{
+ GFSDK_SSAO_Status status;
+ status = GFSDK_SSAO_CreateContext_D3D11(pd3dDevice, &m_SSAOContext, nullptr);
+ assert(status == GFSDK_SSAO_OK);
+}
+
+
+void RendererHBAO::releaseResources()
+{
+ if (m_SSAOContext != NULL)
+ {
+ m_SSAOContext->Release();
+ }
+}
+
+
+void RendererHBAO::renderAO(ID3D11DeviceContext *pd3dDeviceContext, ID3D11RenderTargetView* pRTV, ID3D11ShaderResourceView* pDepthSRV, DirectX::XMMATRIX& projMatrix)
+{
+ GFSDK_SSAO_InputData_D3D11 InputData;
+ InputData.DepthData.pFullResDepthTextureSRV = pDepthSRV;
+ InputData.DepthData.DepthTextureType = GFSDK_SSAO_HARDWARE_DEPTHS;
+ InputData.DepthData.MetersToViewSpaceUnits = 1.0f;
+ InputData.DepthData.ProjectionMatrix.Data = GFSDK_SSAO_Float4x4(reinterpret_cast<const GFSDK_SSAO_FLOAT*>(&(projMatrix.r[0])));
+ InputData.DepthData.ProjectionMatrix.Layout = GFSDK_SSAO_ROW_MAJOR_ORDER;
+
+ GFSDK_SSAO_Output_D3D11 Output;
+ Output.pRenderTargetView = pRTV;// m_pSceneRTs->ColorRTV;
+ Output.Blend.Mode = GFSDK_SSAO_MULTIPLY_RGB;
+
+ m_SSAOContext->RenderAO(pd3dDeviceContext, InputData, m_SSAOParameters, Output);
+}
+
+
+void RendererHBAO::drawUI()
+{
+ ImGui::DragFloat("Radius", &(m_SSAOParameters.Radius), 0.05f, 0.0f, 100.0f);
+ ImGui::DragFloat("Bias", &(m_SSAOParameters.Bias), 0.01f, 0.0f, 0.5f);
+ ImGui::DragFloat("NearAO", &(m_SSAOParameters.NearAO), 0.01f, 1.0f, 4.0f);
+ ImGui::DragFloat("FarAO", &(m_SSAOParameters.FarAO), 0.01, 1.0f, 4.0f);
+ ImGui::DragFloat("PowerExponent", &(m_SSAOParameters.PowerExponent), 0.01f, 1.0f, 8.0f);
+ ImGui::Checkbox("ForegroundAO Enabled", (bool*)&(m_SSAOParameters.ForegroundAO.Enable));
+ ImGui::DragFloat("ForegroundAO ViewDepth", &(m_SSAOParameters.ForegroundAO.ForegroundViewDepth), 0.01f, 0.0f, 100.0f);
+ ImGui::Checkbox("BackgroundAO Enabled", (bool*)&(m_SSAOParameters.BackgroundAO.Enable));
+ ImGui::DragFloat("BackgroundAO ViewDepth", &(m_SSAOParameters.BackgroundAO.BackgroundViewDepth), 0.01f, 0.0f, 100.0f);
+} \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/RendererHBAO.h b/NvBlast/samples/SampleBase/renderer/RendererHBAO.h
new file mode 100644
index 0000000..2478628
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/RendererHBAO.h
@@ -0,0 +1,40 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 RENDERER_HBAO_H
+#define RENDERER_HBAO_H
+
+#include <DirectXMath.h>
+#include "GFSDK_SSAO.h"
+
+
+class Renderer;
+
+class RendererHBAO
+{
+public:
+ RendererHBAO();
+ ~RendererHBAO();
+
+ void createResources(ID3D11Device *pd3dDevice);
+ void renderAO(ID3D11DeviceContext *pd3dDeviceContext, ID3D11RenderTargetView* pRTV, ID3D11ShaderResourceView* pDepthSRV, DirectX::XMMATRIX& projMatrix);
+
+ void drawUI();
+
+private:
+ void releaseResources();
+
+ GFSDK_SSAO_Parameters m_SSAOParameters;
+
+ GFSDK_SSAO_Context_D3D11* m_SSAOContext;
+};
+
+
+#endif \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/RendererShadow.cpp b/NvBlast/samples/SampleBase/renderer/RendererShadow.cpp
new file mode 100644
index 0000000..28a79e5
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/RendererShadow.cpp
@@ -0,0 +1,417 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 "RendererShadow.h"
+
+#include "XInput.h"
+#include "DXUTMisc.h"
+#include "DXUTCamera.h"
+#include "Renderer.h"
+#include "UIHelpers.h"
+
+#define CASCADES 1
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Renderer Shadows (wrapper for shadow_lib)
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+const float DEFAULT_LIGHT_SIZE = 3.0f;
+const DirectX::XMFLOAT3 DEFAULT_LIGHT_POS(-25, 25, 25);
+const DirectX::XMFLOAT3 DEFAULT_LIGHT_LOOK_AT(0, 0, 0);
+const DirectX::XMFLOAT3 DEFAULT_SHADOW_COLOR(0.25f, 0.25f, 0.25f);
+
+RendererShadow::RendererShadow()
+{
+ m_shadowLibContext = NULL;
+
+ m_PCSSEnabled = false;
+ m_lightSize = DEFAULT_LIGHT_SIZE;
+ m_lightPos = DEFAULT_LIGHT_POS;
+ m_lightLookAt = DEFAULT_LIGHT_LOOK_AT;
+ m_shadowColor = DEFAULT_SHADOW_COLOR;
+
+ m_worldSpaceBBox0.x = m_worldSpaceBBox0.y = m_worldSpaceBBox0.z = -100;
+ m_worldSpaceBBox1.x = m_worldSpaceBBox1.y = m_worldSpaceBBox1.z = 100;
+
+ // Penumbra params
+ m_PCSSParams.fMaxThreshold = 80.0f;
+ m_PCSSParams.fMaxClamp = 40.0f;
+ m_PCSSParams.fMinSizePercent = 3.0f;
+ m_PCSSParams.fMinWeightExponent = 5.0f;
+ m_PCSSParams.fMinWeightThresholdPercent = 20.0f;
+
+ m_softShadowTestScale = 0.002f;
+
+ memset(&m_shadowBufferSRV, 0, sizeof(m_shadowBufferSRV));
+
+ m_shadowMapHandle = NULL;
+ m_shadowBufferHandle = NULL;
+}
+
+
+RendererShadow::~RendererShadow()
+{
+ ReleaseResources();
+}
+
+
+void RendererShadow::createResources(ID3D11Device *pd3dDevice, ID3D11DeviceContext* context, CFirstPersonCamera* camera)
+{
+ m_camera = camera;
+
+#if !CASCADES
+ uint32_t shadowMapScale = 5;
+ uint32_t shadowMapWidth = 1024;
+ uint32_t shadowMapHeight = 1024;
+
+ // SM Desc
+ m_SMDesc.eViewType = GFSDK_ShadowLib_ViewType_Single;
+ m_SMDesc.eMapType = GFSDK_ShadowLib_MapType_Texture;
+#else
+
+ uint32_t shadowMapScale = 5;
+ uint32_t shadowMapWidth = 1024;
+ uint32_t shadowMapHeight = 1024;
+
+ // SM Desc
+ m_SMDesc.eViewType = GFSDK_ShadowLib_ViewType_Cascades_2;
+ m_SMDesc.eMapType = GFSDK_ShadowLib_MapType_TextureArray;
+#endif
+
+ m_SMDesc.uResolutionWidth = shadowMapWidth * shadowMapScale;
+ m_SMDesc.uResolutionHeight = shadowMapHeight * shadowMapScale;
+ m_SMDesc.uArraySize = m_SMDesc.eViewType;
+
+ for (int j = 0; j < GFSDK_ShadowLib_ViewType_Cascades_4; j++)
+ {
+ m_SMDesc.ViewLocation[j].uMapID = j;
+ m_SMDesc.ViewLocation[j].v2Origin.x = 0;
+ m_SMDesc.ViewLocation[j].v2Origin.y = 0;
+ m_SMDesc.ViewLocation[j].v2Dimension.x = shadowMapWidth * shadowMapScale;
+ m_SMDesc.ViewLocation[j].v2Dimension.y = shadowMapHeight * shadowMapScale;
+ }
+
+
+ // SM Render Params
+ m_SMRenderParams.iDepthBias = 1000;
+ m_SMRenderParams.fSlopeScaledDepthBias = 8;
+
+ // SB Render Params
+ m_SBRenderParams.eTechniqueType = GFSDK_ShadowLib_TechniqueType_PCSS;
+ m_SBRenderParams.eQualityType = GFSDK_ShadowLib_QualityType_High;
+
+ // DLL version
+ GFSDK_ShadowLib_Version DLLVersion;
+ GFSDK_ShadowLib_Status retCode = GFSDK_ShadowLib_GetDLLVersion(&DLLVersion);
+
+ // Header version
+ GFSDK_ShadowLib_Version headerVersion;
+ headerVersion.uMajor = GFSDK_SHADOWLIB_MAJOR_VERSION;
+ headerVersion.uMinor = GFSDK_SHADOWLIB_MINOR_VERSION;
+
+ // Do they match?
+ if (DLLVersion.uMajor == headerVersion.uMajor && DLLVersion.uMinor == headerVersion.uMinor)
+ {
+ GFSDK_ShadowLib_DeviceContext deviceAndContext;
+ deviceAndContext.pD3DDevice = pd3dDevice;
+ deviceAndContext.pDeviceContext = context;
+
+ retCode = GFSDK_ShadowLib_Create(&headerVersion, &m_shadowLibContext, &deviceAndContext, NULL);
+
+ if (retCode != GFSDK_ShadowLib_Status_Ok) assert(false);
+ }
+ else
+ {
+ assert(false);
+ }
+}
+
+
+void RendererShadow::ReleaseResources()
+{
+ SAFE_RELEASE(m_downsampledShadowMap.pTexture);
+ SAFE_RELEASE(m_downsampledShadowMap.pSRV);
+ SAFE_RELEASE(m_downsampledShadowMap.pRTV);
+
+ if (m_shadowLibContext != NULL)
+ {
+ m_shadowLibContext->Destroy();
+ m_shadowLibContext = NULL;
+ }
+}
+
+
+void RendererShadow::setScreenResolution(float FovyRad, UINT Width, UINT Height, UINT uSampleCount, ID3D11DepthStencilView* pReadOnlyDSV)
+{
+ changeShadowSettings(Width, Height, uSampleCount, pReadOnlyDSV);
+}
+
+
+void RendererShadow::changeShadowSettings(UINT Width, UINT Height, UINT uSampleCount, ID3D11DepthStencilView* pReadOnlyDSV)
+{
+ m_SBDesc.uResolutionWidth = Width;
+ m_SBDesc.uResolutionHeight = Height;
+ m_SBDesc.uSampleCount = uSampleCount;
+ m_SBDesc.ReadOnlyDSV.pDSV = pReadOnlyDSV;
+
+ reloadBuffers();
+}
+
+void RendererShadow::reloadBuffers()
+{
+ {
+ m_shadowLibContext->RemoveMap(&m_shadowMapHandle);
+
+ if (m_SMDesc.eMapType == GFSDK_ShadowLib_MapType_Texture &&
+ m_SMDesc.eViewType == GFSDK_ShadowLib_ViewType_Single &&
+ m_SBRenderParams.eTechniqueType == GFSDK_ShadowLib_TechniqueType_PCSS)
+ {
+ m_SMDesc.bDownsample = true;
+ }
+
+ m_shadowLibContext->AddMap(&m_SMDesc, &m_shadowMapHandle);
+ }
+
+ if (m_SMDesc.eMapType == GFSDK_ShadowLib_MapType_Texture && m_SMDesc.eViewType == GFSDK_ShadowLib_ViewType_Single)
+ {
+ m_downsampledShadowMap.uWidth = m_SMDesc.uResolutionWidth >> 1;
+ m_downsampledShadowMap.uHeight = m_SMDesc.uResolutionHeight >> 1;
+ m_downsampledShadowMap.uSampleCount = 1;
+ m_downsampledShadowMap.Format = DXGI_FORMAT_R32_FLOAT;
+ SAFE_RELEASE(m_downsampledShadowMap.pTexture);
+ SAFE_RELEASE(m_downsampledShadowMap.pSRV);
+ SAFE_RELEASE(m_downsampledShadowMap.pRTV);
+ m_shadowLibContext->DevModeCreateTexture2D(&m_downsampledShadowMap);
+ }
+
+ m_shadowLibContext->RemoveBuffer(&m_shadowBufferHandle);
+ m_shadowLibContext->AddBuffer(&m_SBDesc, &m_shadowBufferHandle);
+}
+
+
+
+//--------------------------------------------------------------------------------------
+// Data passed to the shadow map render function
+//--------------------------------------------------------------------------------------
+struct ShadowMapRenderFunctionParams
+{
+ Renderer* renderer;
+};
+static ShadowMapRenderFunctionParams s_RenderParams;
+
+//--------------------------------------------------------------------------------------
+// Shadow map render function
+//--------------------------------------------------------------------------------------
+static void ShadowMapRenderFunction(void* pParams, gfsdk_float4x4* pViewProj)
+{
+ ShadowMapRenderFunctionParams* pRP = (ShadowMapRenderFunctionParams*)pParams;
+
+ DirectX::XMMATRIX viewProjection;
+ memcpy(&viewProjection, &pViewProj->_11, sizeof(gfsdk_float4x4));
+
+ pRP->renderer->renderDepthOnly(&viewProjection);
+}
+
+void RendererShadow::renderShadowMaps(Renderer* renderer)
+{
+ // select technique
+ GFSDK_ShadowLib_TechniqueType technique = m_SBRenderParams.eTechniqueType;
+ m_SBRenderParams.eTechniqueType = m_PCSSEnabled ? GFSDK_ShadowLib_TechniqueType_PCSS : GFSDK_ShadowLib_TechniqueType_PCF;
+ if (technique != m_SBRenderParams.eTechniqueType)
+ reloadBuffers();
+
+
+ DirectX::XMMATRIX viewMatrix = m_camera->GetViewMatrix();
+ DirectX::XMMATRIX projMatrix = m_camera->GetProjMatrix();
+
+ memcpy(&m_SMRenderParams.m4x4EyeViewMatrix, &viewMatrix.r[0], sizeof(gfsdk_float4x4));
+ memcpy(&m_SMRenderParams.m4x4EyeProjectionMatrix, &projMatrix.r[0], sizeof(gfsdk_float4x4));
+
+ // TODO: (better world space bbox needed)
+ m_SMRenderParams.v3WorldSpaceBBox[0] = m_worldSpaceBBox0;
+ m_SMRenderParams.v3WorldSpaceBBox[1] = m_worldSpaceBBox1;
+
+ m_SMRenderParams.LightDesc.eLightType = GFSDK_ShadowLib_LightType_Directional;
+ memcpy(&m_SMRenderParams.LightDesc.v3LightPos, &m_lightPos.x, sizeof(gfsdk_float3));
+ memcpy(&m_SMRenderParams.LightDesc.v3LightLookAt, &m_lightLookAt.x, sizeof(gfsdk_float3));
+ m_SMRenderParams.LightDesc.fLightSize = m_lightSize;
+ m_SMRenderParams.LightDesc.bLightFalloff = false;
+
+ // Scene specific setup for the shadow map phase that follows
+ s_RenderParams.renderer = renderer;
+ m_SMRenderParams.fnpDrawFunction = GFSDK_ShadowLib_FunctionPointer(ShadowMapRenderFunction);
+ m_SMRenderParams.pDrawFunctionParams = &s_RenderParams;
+
+ // render shadow map
+ m_shadowLibContext->RenderMap(m_shadowMapHandle, &m_SMRenderParams);
+}
+
+
+void RendererShadow::renderShadowBuffer(ID3D11ShaderResourceView* pDepthStencilSRV, ID3D11ShaderResourceView* pResolvedDepthStencilSRV)
+{
+ if (m_SBRenderParams.eTechniqueType == GFSDK_ShadowLib_TechniqueType_PCSS &&
+ m_SMDesc.eMapType == GFSDK_ShadowLib_MapType_Texture &&
+ m_SMDesc.eViewType == GFSDK_ShadowLib_ViewType_Single)
+ {
+ m_tempResources.pDownsampledShadowMap = &m_downsampledShadowMap;
+ m_shadowLibContext->SetTempResources(&m_tempResources);
+ }
+
+ m_SBRenderParams.PCSSPenumbraParams = m_PCSSParams;
+ m_SBRenderParams.fSoftShadowTestScale = m_softShadowTestScale;
+
+ m_shadowLibContext->ClearBuffer(m_shadowBufferHandle);
+
+ m_SBRenderParams.DepthBufferDesc.DepthStencilSRV.pSRV = pDepthStencilSRV;
+
+ m_shadowLibContext->RenderBuffer(m_shadowMapHandle, m_shadowBufferHandle, &m_SBRenderParams);
+
+ m_shadowLibContext->FinalizeBuffer(m_shadowBufferHandle, &m_shadowBufferSRV);
+}
+
+
+void RendererShadow::modulateShadowBuffer(ID3D11RenderTargetView* pOutputRTV)
+{
+ GFSDK_ShadowLib_RenderTargetView ColorRTV;
+ ColorRTV.pRTV = pOutputRTV;
+
+ gfsdk_float3 v3ShadowColor = { m_shadowColor.x, m_shadowColor.y, m_shadowColor.z };
+ m_shadowLibContext->ModulateBuffer(m_shadowBufferHandle, &ColorRTV, v3ShadowColor, GFSDK_ShadowLib_ModulateBufferMask_RGB);
+}
+
+
+void RendererShadow::displayShadowMaps(ID3D11RenderTargetView* pOutputRTV, UINT Width, UINT Height)
+{
+ GFSDK_ShadowLib_RenderTargetView ColorRTV;
+ ColorRTV.pRTV = pOutputRTV;
+
+ float fMapResW = (float)m_SMDesc.uResolutionWidth;
+ float fMapResH = (float)m_SMDesc.uResolutionHeight;
+
+ float fWidthScale = Width / ((float)m_SMDesc.uArraySize * fMapResW);
+ fWidthScale = (fWidthScale > 1.0f) ? (1.0f) : (fWidthScale);
+
+ float fOneFifth = (float)Height / (5.0f);
+ float fHeightScale = fOneFifth / fMapResH;
+ fHeightScale = (fHeightScale > 1.0f) ? (1.0f) : (fHeightScale);
+
+ float fScale = (fHeightScale < fWidthScale) ? (fHeightScale) : (fWidthScale);
+
+ fMapResW = floorf(fMapResW * fScale);
+ fMapResH = floorf(fMapResH * fScale);
+
+ for (unsigned int j = 0; j < (unsigned int)m_SMDesc.uArraySize; j++)
+ {
+ m_shadowLibContext->DevModeDisplayMap(m_shadowBufferHandle,
+ &ColorRTV,
+ m_shadowMapHandle,
+ j,
+ j * (unsigned int)fMapResW + j,
+ Height - (unsigned int)fMapResH,
+ fScale);
+ }
+}
+
+
+void RendererShadow::displayMapFrustums(ID3D11RenderTargetView* pOutputRTV, ID3D11DepthStencilView* pDSV)
+{
+ gfsdk_float3 v3Color;
+ v3Color.x = 1.0f;
+ v3Color.y = 0.0f;
+ v3Color.z = 0.0f;
+
+ GFSDK_ShadowLib_RenderTargetView ColorRTV;
+ ColorRTV.pRTV = pOutputRTV;
+
+ GFSDK_ShadowLib_DepthStencilView DSV;
+ DSV.pDSV = pDSV;
+
+ unsigned int NumViews;
+ NumViews = m_SMDesc.eViewType;
+
+ for (unsigned int j = 0; j < NumViews; j++)
+ {
+ switch (j)
+ {
+ case 0:
+ v3Color.x = 1.0f;
+ v3Color.y = 0.0f;
+ v3Color.z = 0.0f;
+ break;
+ case 1:
+ v3Color.x = 0.0f;
+ v3Color.y = 1.0f;
+ v3Color.z = 0.0f;
+ break;
+ case 2:
+ v3Color.x = 0.0f;
+ v3Color.y = 0.0f;
+ v3Color.z = 1.0f;
+ break;
+ case 3:
+ v3Color.x = 1.0f;
+ v3Color.y = 1.0f;
+ v3Color.z = 0.0f;
+ break;
+ }
+
+ m_shadowLibContext->DevModeDisplayMapFrustum(m_shadowBufferHandle,
+ &ColorRTV,
+ &DSV,
+ m_shadowMapHandle,
+ j,
+ v3Color);
+ }
+}
+
+
+void RendererShadow::displayShadowBuffer(ID3D11RenderTargetView* pOutputRTV)
+{
+ gfsdk_float2 v2Scale;
+ v2Scale.x = 1.0f;
+ v2Scale.y = 1.0f;
+
+ GFSDK_ShadowLib_RenderTargetView ColorRTV;
+ ColorRTV.pRTV = pOutputRTV;
+
+ m_shadowLibContext->DevModeDisplayBuffer(m_shadowBufferHandle,
+ &ColorRTV,
+ v2Scale,
+ NULL);
+}
+
+
+void RendererShadow::toggleDisplayCascades(bool bToggle)
+{
+ m_shadowLibContext->DevModeToggleDebugCascadeShader(m_shadowBufferHandle,
+ bToggle);
+}
+
+
+void RendererShadow::drawUI()
+{
+ ImGui::Checkbox("PCSS", &m_PCSSEnabled);
+ ImGui::ColorEdit3("Shadow Color", &(m_shadowColor.x));
+ ImGui::DragFloat("Light Size", &m_lightSize, 0.05f, 0.0f, 100.0f);
+ ImGui::DragFloat3("Light Position", &(m_lightPos.x));
+ ImGui_DragFloat3Dir("Light LookAt", &(m_lightLookAt.x));
+ ImGui::DragFloat("SoftShadowTestScale", &(m_softShadowTestScale), 0.0001f, 0.0f, 10.0f);
+ if (m_PCSSEnabled)
+ {
+ ImGui::DragFloat("PCSS: fMaxClamp", &(m_PCSSParams.fMaxClamp), 0.001f, 0.0f, 100.0f);
+ ImGui::DragFloat("PCSS: fMaxThreshold", &(m_PCSSParams.fMaxThreshold), 0.001f, 0.0f, 100.0f);
+ ImGui::DragFloat("PCSS: fMinSizePercent", &(m_PCSSParams.fMinSizePercent), 0.001f, 0.0f, 100.0f);
+ ImGui::DragFloat("PCSS: fMinWeightExponent", &(m_PCSSParams.fMinWeightExponent), 0.001f, 0.0f, 100.0f);
+ ImGui::DragFloat("PCSS: fMinWeightThresholdPercent", &(m_PCSSParams.fMinWeightThresholdPercent), 0.001f, 0.0f, 100.0f);
+ ImGui::DragFloat("PCSS: fBlockerSearchDitherPercent", &(m_PCSSParams.fBlockerSearchDitherPercent), 0.001f, 0.0f, 100.0f);
+ ImGui::DragFloat("PCSS: fFilterDitherPercent", &(m_PCSSParams.fFilterDitherPercent), 0.001f, 0.0f, 100.0f);
+ }
+} \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/RendererShadow.h b/NvBlast/samples/SampleBase/renderer/RendererShadow.h
new file mode 100644
index 0000000..cc81c67
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/RendererShadow.h
@@ -0,0 +1,82 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 RENDERER_SHADOW_H
+#define RENDERER_SHADOW_H
+
+#include <DirectXMath.h>
+#include "Utils.h"
+#include "gfsdk_shadowlib.h"
+
+#include <string>
+
+
+class CFirstPersonCamera;
+class Renderer;
+
+class RendererShadow
+{
+public:
+ RendererShadow();
+ ~RendererShadow();
+
+ void createResources(ID3D11Device *pd3dDevice, ID3D11DeviceContext* context, CFirstPersonCamera* camera);
+
+ void setScreenResolution(float FovyRad, UINT Width, UINT Height, UINT uSampleCount, ID3D11DepthStencilView* pReadOnlyDSV);
+ void changeShadowSettings(UINT Width, UINT Height, UINT uSampleCount, ID3D11DepthStencilView* pReadOnlyDSV);
+ void renderShadowMaps(Renderer* renderer);
+ void renderShadowBuffer(ID3D11ShaderResourceView* pDepthStencilSRV, ID3D11ShaderResourceView* pResolvedDepthStencilSRV);
+ void modulateShadowBuffer(ID3D11RenderTargetView* pOutputRTV);
+ void displayShadowMaps(ID3D11RenderTargetView* pOutputRTV, UINT Width, UINT Height);
+ void displayMapFrustums(ID3D11RenderTargetView* pOutputRTV, ID3D11DepthStencilView* pDSV);
+ void displayShadowBuffer(ID3D11RenderTargetView* pOutputRTV);
+ void toggleDisplayCascades(bool bToggle);
+
+
+ void drawUI();
+
+private:
+ void reloadBuffers();
+ void ReleaseResources();
+
+
+ GFSDK_ShadowLib_Context* m_shadowLibContext;
+
+ GFSDK_ShadowLib_ShaderResourceView m_shadowBufferSRV;
+
+ GFSDK_ShadowLib_Map* m_shadowMapHandle;
+ GFSDK_ShadowLib_MapDesc m_SMDesc;
+ GFSDK_ShadowLib_BufferDesc m_SBDesc;
+ GFSDK_ShadowLib_MapRenderParams m_SMRenderParams;
+
+ GFSDK_ShadowLib_Buffer* m_shadowBufferHandle;
+ GFSDK_ShadowLib_BufferRenderParams m_SBRenderParams;
+
+ GFSDK_ShadowLib_TempResources m_tempResources;
+ GFSDK_ShadowLib_Texture2D m_downsampledShadowMap;
+
+ CFirstPersonCamera* m_camera;
+
+ // params
+ bool m_PCSSEnabled;
+ float m_lightSize;
+ DirectX::XMFLOAT3 m_lightPos;
+ DirectX::XMFLOAT3 m_lightLookAt;
+ DirectX::XMFLOAT3 m_shadowColor;
+ GFSDK_ShadowLib_PCSSPenumbraParams m_PCSSParams;
+ float m_softShadowTestScale;
+
+ gfsdk_float3 m_worldSpaceBBox0;
+ gfsdk_float3 m_worldSpaceBBox1;
+
+};
+
+
+#endif \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/ResourceManager.cpp b/NvBlast/samples/SampleBase/renderer/ResourceManager.cpp
new file mode 100644
index 0000000..f8a4b7b
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/ResourceManager.cpp
@@ -0,0 +1,212 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 "ResourceManager.h"
+#include "PxAssert.h"
+#include "PsString.h"
+#include "Utils.h"
+
+#include <windows.h>
+
+
+using namespace physx;
+
+#define PATH_MAX_LEN 512
+
+
+ResourceManager::ResourceManager()
+{
+ // search for root folder by default
+ addSearchDir(".");
+}
+
+const ShaderFileResource* ResourceManager::requestShaderFile(const char* name)
+{
+ const Resource* resource = requestResource(eSHADER_FILE, name);
+ return resource != nullptr ? static_cast<const ShaderFileResource*>(resource) : nullptr;
+}
+
+const TextureResource* ResourceManager::requestTexture(const char* name)
+{
+ const Resource* resource = requestResource(eTEXTURE, name);
+ return resource != nullptr ? static_cast<const TextureResource*>(resource) : nullptr;
+}
+
+const Resource* ResourceManager::requestResource(ResourceType type, const char* name)
+{
+ // search in loaded
+ std::pair<ResourceType, std::string> key(type, name);
+ auto val = m_loadedResources.find(key);
+ if (val != m_loadedResources.end())
+ {
+ return val->second.get();
+ }
+
+ std::shared_ptr<Resource> resource;
+ if (type == eSHADER_FILE)
+ {
+ char path[PATH_MAX_LEN];
+ const char* exts[] = { "hlsl" };
+ if (findFile(name, std::vector<const char*>(exts, exts + sizeof(exts) / sizeof(exts[0])), path))
+ {
+ resource = std::shared_ptr<Resource>(new ShaderFileResource(path));
+ }
+ else
+ {
+ PX_ALWAYS_ASSERT_MESSAGE(name);
+ }
+ }
+ else if (type == eTEXTURE)
+ {
+ char path[PATH_MAX_LEN];
+ const char* exts[] = { "dds", "tga" };
+ if (findFile(name, std::vector<const char*>(exts, exts + sizeof(exts) / sizeof(exts[0])), path))
+ {
+ std::shared_ptr<TextureResource> textureResource(new TextureResource());
+ WCHAR wPath[MAX_PATH];
+ MultiByteToWideChar(CP_ACP, 0, path, -1, wPath, MAX_PATH);
+ wPath[MAX_PATH - 1] = 0;
+
+ const char* ext = strext(path);
+ if (::strcmp(ext, "dds") == 0)
+ {
+ V(DirectX::LoadFromDDSFile(wPath, DirectX::DDS_FLAGS_NONE, &textureResource->metaData,
+ textureResource->image));
+ }
+ else if (::strcmp(ext, "tga") == 0)
+ {
+ V(DirectX::LoadFromTGAFile(wPath, &textureResource->metaData,
+ textureResource->image));
+ }
+ else
+ {
+ PX_ALWAYS_ASSERT_MESSAGE("Unsupported texture extension");
+ }
+ resource = textureResource;
+ }
+ }
+
+ if (resource.get())
+ {
+ m_loadedResources.emplace(key, resource);
+ return resource.get();
+ }
+ else
+ {
+ PX_ALWAYS_ASSERT_MESSAGE(name);
+ return nullptr;
+ }
+}
+
+bool dirExists(const char* dir)
+{
+ DWORD ftyp = GetFileAttributesA(dir);
+ if (ftyp == INVALID_FILE_ATTRIBUTES)
+ return false; // something is wrong with path!
+
+ if (ftyp & FILE_ATTRIBUTE_DIRECTORY)
+ return true; // this is a directory!
+
+ return false; // this is not a directory!
+}
+
+bool ResourceManager::addSearchDir(const char* dir, bool recursive)
+{
+ if (dirExists(dir))
+ {
+ m_searchDirs.push_back(SearchDir(dir, recursive));
+ return true;
+ }
+ return false;
+}
+
+
+ResourceManager::~ResourceManager()
+{
+}
+
+
+bool ResourceManager::findFileInDir(std::string fileNameFull, const char* path, bool recursive, char* foundPath)
+{
+ WIN32_FIND_DATAA ffd;
+ char tmp[PATH_MAX_LEN];
+ shdfnd::snprintf(tmp, sizeof(tmp), "%s\\*", path);
+ HANDLE hFind = FindFirstFileA(tmp, &ffd);
+
+ if(INVALID_HANDLE_VALUE == hFind)
+ {
+ return NULL;
+ }
+
+ do
+ {
+ if (0 == shdfnd::strcmp(".", ffd.cFileName) || 0 == shdfnd::strcmp("..", ffd.cFileName))
+ continue;
+
+ if(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ shdfnd::snprintf(tmp, sizeof(tmp), "%s\\%s", path, ffd.cFileName);
+ if(findFileInDir(fileNameFull, tmp, recursive, foundPath))
+ return true;
+ }
+ else if (shdfnd::stricmp(ffd.cFileName, fileNameFull.c_str()) == 0)
+ {
+ shdfnd::snprintf(foundPath, PATH_MAX_LEN, "%s\\%s", path, ffd.cFileName);
+ return true;
+ }
+ } while(FindNextFileA(hFind, &ffd) != 0);
+ // release handle
+ FindClose(hFind);
+ return false;
+}
+
+bool ResourceManager::findFile(std::string fileName, const std::vector<const char*>& exts, char* foundPath)
+{
+ std::string fileNameOnly = fileName;
+ size_t ind = fileNameOnly.find_last_of('/');
+ if (ind > 0)
+ fileNameOnly = fileNameOnly.substr(ind + 1);
+
+ for(size_t i = 0; i < m_searchDirs.size(); i++)
+ {
+ const SearchDir& searchDir = m_searchDirs[i];
+
+ for(size_t j = 0; j < exts.size(); j++)
+ {
+ const char* ext = exts[j];
+ const uint32_t fileMaxLen = 128;
+ char fileNameFull[fileMaxLen] = { 0 };
+
+ physx::shdfnd::snprintf(fileNameFull, fileMaxLen, "%s.%s", fileNameOnly.c_str(), ext);
+ if(findFileInDir(fileNameFull, searchDir.path.c_str(), searchDir.recursive, foundPath))
+ return true;
+ }
+
+ if (findFileInDir(fileNameOnly.c_str(), searchDir.path.c_str(), searchDir.recursive, foundPath))
+ return true;
+ }
+ return false;
+}
+
+bool ResourceManager::findFile(std::string fileName, std::string& foundPath)
+{
+ std::vector<const char*> exts;
+ char path[PATH_MAX_LEN];
+ if (findFile(fileName, exts, path))
+ {
+ foundPath = path;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
diff --git a/NvBlast/samples/SampleBase/renderer/ResourceManager.h b/NvBlast/samples/SampleBase/renderer/ResourceManager.h
new file mode 100644
index 0000000..6a9b8cd
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/ResourceManager.h
@@ -0,0 +1,93 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 RESOURCE_MANAGER_H
+#define RESOURCE_MANAGER_H
+
+#include <vector>
+#include <string>
+#include <map>
+#include <memory>
+#include "DirectXTex.h"
+
+
+struct Resource
+{
+private:
+ Resource& operator = (const Resource&);
+};
+
+
+struct ShaderFileResource : public Resource
+{
+ ShaderFileResource(const std::string& p) : path(p) {}
+ std::string path;
+};
+
+
+struct TextureResource : public Resource
+{
+ DirectX::TexMetadata metaData;
+ DirectX::ScratchImage image;
+};
+
+
+/**
+ResourceManager used to look for files in provided dirs (see addSearchDir). Also it loads resources and caches them.
+*/
+class ResourceManager
+{
+public:
+ //////// ctor ////////
+
+ ResourceManager();
+ ~ResourceManager();
+
+ //////// public API ////////
+
+ bool addSearchDir(const char* dir, bool recursive = true);
+
+ const ShaderFileResource* requestShaderFile(const char* name);
+
+ const TextureResource* requestTexture(const char* name);
+
+ bool findFile(std::string fileName, std::string& foundPath);
+
+ bool findFile(std::string fileName, const std::vector<const char*>& exts, char* foundPath);
+
+
+private:
+ //////// internal methods ////////
+
+ enum ResourceType
+ {
+ eSHADER_FILE,
+ eTEXTURE
+ };
+
+ const Resource* requestResource(ResourceType type, const char* name);
+
+ bool findFileInDir(std::string fileNameFull, const char* path, bool recursive, char* foundPath);
+
+ struct SearchDir
+ {
+ SearchDir(std::string path_, bool recursive_) : path(path_), recursive(recursive_) {}
+
+ std::string path;
+ bool recursive;
+ };
+
+
+ //////// internal data ////////
+
+ std::vector<SearchDir> m_searchDirs;
+ std::map<std::pair<ResourceType, std::string>, std::shared_ptr<Resource>> m_loadedResources;
+};
+#endif \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/ShaderUtils.h b/NvBlast/samples/SampleBase/renderer/ShaderUtils.h
new file mode 100644
index 0000000..778c811
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/ShaderUtils.h
@@ -0,0 +1,99 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 SHADER_UTILS_H
+#define SHADER_UTILS_H
+
+#include "Utils.h"
+#include <d3dcompiler.h>
+
+
+static HRESULT CompileShaderFromFile(const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel,
+ ID3DBlob** ppBlobOut)
+{
+ HRESULT hr = S_OK;
+ ID3DBlob* pErrorBlob = NULL;
+
+ WCHAR wFileName[MAX_PATH];
+ MultiByteToWideChar(CP_ACP, 0, szFileName, -1, wFileName, MAX_PATH);
+ wFileName[MAX_PATH - 1] = 0;
+ hr = D3DCompileFromFile(wFileName, NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, szEntryPoint, szShaderModel, D3D10_SHADER_ENABLE_STRICTNESS, 0,
+ ppBlobOut, &pErrorBlob);
+ if(FAILED(hr))
+ {
+ OutputDebugStringA((char*)pErrorBlob->GetBufferPointer());
+ SAFE_RELEASE(pErrorBlob);
+ return hr;
+ }
+ SAFE_RELEASE(pErrorBlob);
+
+ return S_OK;
+}
+
+static HRESULT createShader(ID3D11Device* pDev, const void* pData, size_t len, ID3D11VertexShader** ppShd, bool)
+{
+ return pDev->CreateVertexShader(pData, len, nullptr, ppShd);
+}
+
+static HRESULT createShader(ID3D11Device* pDev, const void* pData, size_t len, ID3D11GeometryShader** ppShd,
+ bool forceFast)
+{
+ PX_UNUSED(forceFast);
+ return pDev->CreateGeometryShader(pData, len, nullptr, ppShd);
+}
+
+static HRESULT createShader(ID3D11Device* pDev, const void* pData, size_t len, ID3D11PixelShader** ppShd, bool)
+{
+ return pDev->CreatePixelShader(pData, len, nullptr, ppShd);
+}
+
+static const char* shaderModel(ID3D11VertexShader**)
+{
+ return "vs_5_0";
+}
+
+static const char* shaderModel(ID3D11GeometryShader**)
+{
+ return "gs_5_0";
+}
+
+static const char* shaderModel(ID3D11PixelShader**)
+{
+ return "ps_5_0";
+}
+
+// Give back the shader buffer blob for use in CreateVertexLayout. Caller must release the blob.
+template <class S>
+static HRESULT createShaderFromFile(ID3D11Device* pDev, const char* szFileName, LPCSTR szEntryPoint, S** ppShd,
+ ID3DBlob*& pShaderBuffer, bool forceFast = false)
+{
+ HRESULT hr = CompileShaderFromFile(szFileName, szEntryPoint, shaderModel(ppShd), &pShaderBuffer);
+ if(SUCCEEDED(hr) && pShaderBuffer)
+ {
+ const void* shaderBufferData = pShaderBuffer->GetBufferPointer();
+ const UINT shaderBufferSize = pShaderBuffer->GetBufferSize();
+ createShader(pDev, shaderBufferData, shaderBufferSize, ppShd, forceFast);
+ }
+ return hr;
+}
+
+// Overloaded, same as above but don't give back the shader buffer blob.
+template <class S>
+static HRESULT createShaderFromFile(ID3D11Device* pDev, const char* szFileName, LPCSTR szEntryPoint, S** ppShd,
+ bool forceFast = false)
+{
+ ID3DBlob* pShaderBuffer = NULL;
+ HRESULT hr = createShaderFromFile(pDev, szFileName, szEntryPoint, ppShd, pShaderBuffer, forceFast);
+ SAFE_RELEASE(pShaderBuffer);
+ return hr;
+}
+
+
+#endif //SHADER_UTILS_H \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/SkinnedRenderMesh.cpp b/NvBlast/samples/SampleBase/renderer/SkinnedRenderMesh.cpp
new file mode 100644
index 0000000..c575d6c
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/SkinnedRenderMesh.cpp
@@ -0,0 +1,217 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 "SkinnedRenderMesh.h"
+#include "Renderer.h"
+
+SkinnedRenderMesh::SkinnedRenderMesh(const std::vector<const SimpleMesh*>& meshes)
+{
+ PX_ASSERT_WITH_MESSAGE(meshes.size() <= MeshesCountMax, "meshes.size() have to be <= SkinnedRenderMesh::MeshesCountMax");
+
+ m_device = GetDeviceManager()->GetDevice();
+
+ // input element desc setup
+ m_inputDesc.push_back({ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 });
+ m_inputDesc.push_back({ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 });
+ m_inputDesc.push_back({ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 });
+ m_inputDesc.push_back({ "TEXCOORD", 1, DXGI_FORMAT_R32_UINT, 1, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 });
+
+ // reserve VB
+ uint32_t verticesTotal = 0;
+ std::for_each(meshes.begin(), meshes.end(), [&](const SimpleMesh* c) { verticesTotal += (uint32_t)c->vertices.size(); });
+ std::vector<SimpleMesh::Vertex> vertexBuffer;
+ vertexBuffer.reserve(verticesTotal);
+
+ // reserve IB
+ uint32_t indicesTotal = 0;
+ std::for_each(meshes.begin(), meshes.end(), [&](const SimpleMesh* c) { indicesTotal += (uint32_t)c->indices.size(); });
+ m_indices.reserve(indicesTotal);
+
+ // fill VB, IB, MeshInfo
+ m_meshesInfo.resize(meshes.size());
+ for (uint32_t meshIndex = 0; meshIndex < meshes.size(); ++meshIndex)
+ {
+ const SimpleMesh* mesh = meshes[meshIndex];
+ MeshInfo& meshInfo = m_meshesInfo[meshIndex];
+
+ meshInfo.firstVertex = (uint32_t)vertexBuffer.size();
+ vertexBuffer.insert(vertexBuffer.end(), mesh->vertices.begin(), mesh->vertices.end());
+ meshInfo.verticesCount = (uint32_t)mesh->vertices.size();
+
+ meshInfo.firstIndex = (uint32_t)m_indices.size();
+ uint32_t indexOffset = meshInfo.firstVertex;
+ for (uint32_t index : mesh->indices)
+ {
+ m_indices.push_back((uint32_t)index + indexOffset);
+ }
+ meshInfo.indicesCount = (uint32_t)mesh->indices.size();
+ }
+
+ // vertex buffer
+ {
+ D3D11_SUBRESOURCE_DATA vertexBufferData;
+
+ ZeroMemory(&vertexBufferData, sizeof(vertexBufferData));
+ vertexBufferData.pSysMem = vertexBuffer.data();
+
+ D3D11_BUFFER_DESC bufferDesc;
+
+ memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC));
+ bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ bufferDesc.ByteWidth = (uint32_t)(sizeof(SimpleMesh::Vertex) * vertexBuffer.size());
+ bufferDesc.CPUAccessFlags = 0;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
+
+ V(m_device->CreateBuffer(&bufferDesc, &vertexBufferData, &m_vertexBuffer));
+ }
+
+ // bone index buffer
+ {
+ D3D11_BUFFER_DESC bufferDesc;
+
+ memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC));
+ bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ bufferDesc.ByteWidth = (uint32_t)(sizeof(uint32_t) * vertexBuffer.size());
+ bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+
+ V(m_device->CreateBuffer(&bufferDesc, nullptr, &m_boneIndexBuffer));
+ }
+
+ // index buffer
+ {
+ D3D11_BUFFER_DESC bufferDesc;
+
+ memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC));
+ bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+ bufferDesc.ByteWidth = (uint32_t)(sizeof(uint32_t) * m_indices.size());
+ bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+
+ V(m_device->CreateBuffer(&bufferDesc, nullptr, &m_indexBuffer));
+ }
+
+ // bone texture
+ {
+ D3D11_TEXTURE2D_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.Width = 4;
+ desc.Height = (uint32_t)meshes.size();
+ desc.MipLevels = 1;
+ desc.ArraySize = 1;
+ desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ desc.Usage = D3D11_USAGE_DYNAMIC;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+
+ V(m_device->CreateTexture2D(&desc, nullptr, &m_boneTexture));
+ }
+
+ // bone texture SRV
+ {
+ D3D11_SHADER_RESOURCE_VIEW_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
+ desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ desc.Texture2D.MipLevels = 1;
+ desc.Texture2D.MostDetailedMip = 0;
+ V(m_device->CreateShaderResourceView(m_boneTexture, &desc, &m_boneTextureSRV));
+ }
+}
+
+SkinnedRenderMesh::~SkinnedRenderMesh()
+{
+ SAFE_RELEASE(m_vertexBuffer);
+ SAFE_RELEASE(m_boneIndexBuffer);
+ SAFE_RELEASE(m_indexBuffer);
+ SAFE_RELEASE(m_boneTexture);
+ SAFE_RELEASE(m_boneTextureSRV);
+}
+
+void SkinnedRenderMesh::updateVisibleMeshes(const std::vector<uint32_t>& visibleMeshes)
+{
+ ID3D11DeviceContext* context;
+ m_device->GetImmediateContext(&context);
+
+ // update bone index buffer
+ {
+ D3D11_MAPPED_SUBRESOURCE mappedRead;
+ V(context->Map(m_boneIndexBuffer, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead));
+
+ uint32_t* boneIndexBuffer = (uint32_t*)mappedRead.pData;
+ for (uint32_t i = 0; i < visibleMeshes.size(); ++i)
+ {
+ const MeshInfo& info = m_meshesInfo[visibleMeshes[i]];
+ for (uint32_t v = info.firstVertex; v < info.firstVertex + info.verticesCount; ++v)
+ {
+ boneIndexBuffer[v] = i;
+ }
+ }
+
+ context->Unmap(m_boneIndexBuffer, 0);
+ }
+
+ // update index buffer
+ {
+ D3D11_MAPPED_SUBRESOURCE mappedRead;
+ V(context->Map(m_indexBuffer, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead));
+
+ uint32_t* indexBuffer = (uint32_t*)mappedRead.pData;
+ uint32_t indexCount = 0;
+ for (uint32_t meshIndex : visibleMeshes)
+ {
+ const MeshInfo& info = m_meshesInfo[meshIndex];
+ memcpy(indexBuffer + indexCount, &m_indices[info.firstIndex], info.indicesCount * sizeof(uint32_t));
+ indexCount += info.indicesCount;
+ }
+ context->Unmap(m_indexBuffer, 0);
+ m_indexCount = indexCount;
+ PX_ASSERT(m_indexCount % 3 == 0);
+ }
+}
+
+void SkinnedRenderMesh::updateVisibleMeshTransforms(std::vector<PxMat44>& transforms)
+{
+ ID3D11DeviceContext* context;
+ m_device->GetImmediateContext(&context);
+
+ // update bone transform texture
+ {
+ D3D11_MAPPED_SUBRESOURCE mappedRead;
+ V(context->Map(m_boneTexture, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead));
+ for (uint32_t i = 0; i < transforms.size(); ++i)
+ {
+ std::memcpy((uint8_t*)mappedRead.pData + i * mappedRead.RowPitch, &transforms[i], sizeof(PxMat44));
+ }
+ context->Unmap(m_boneTexture, 0);
+ }
+}
+
+void SkinnedRenderMesh::render(ID3D11DeviceContext& context) const
+{
+ context.IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+
+ UINT strides[2] = { sizeof(SimpleMesh::Vertex), sizeof(uint32_t) };
+ UINT offsets[2] = { 0 };
+ ID3D11Buffer* buffers[2] = { m_vertexBuffer, m_boneIndexBuffer };
+ context.IASetVertexBuffers(0, 2, buffers, strides, offsets);
+
+ context.IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0);
+
+ context.VSSetShaderResources(1, 1, &m_boneTextureSRV);
+
+ context.DrawIndexed(m_indexCount, 0, 0);
+} \ No newline at end of file
diff --git a/NvBlast/samples/SampleBase/renderer/SkinnedRenderMesh.h b/NvBlast/samples/SampleBase/renderer/SkinnedRenderMesh.h
new file mode 100644
index 0000000..2f690d8
--- /dev/null
+++ b/NvBlast/samples/SampleBase/renderer/SkinnedRenderMesh.h
@@ -0,0 +1,82 @@
+/*
+* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, 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 SKINNED_RENDER_MESH_H
+#define SKINNED_RENDER_MESH_H
+
+#include "Utils.h"
+#include <DirectXMath.h>
+
+#include <vector>
+#include "Renderable.h"
+#include "Mesh.h"
+
+/**
+SkinnedRenderMesh:
+ bonde indices are passed as vertex input,
+ bone transforms are stored in texture
+ max bone meshes count: SkinnedRenderMesh::MeshesCountMax
+*/
+class SkinnedRenderMesh : public IRenderMesh
+{
+public:
+ //////// ctor ////////
+
+ SkinnedRenderMesh(const std::vector<const SimpleMesh*>& meshes);
+ ~SkinnedRenderMesh();
+
+
+ //////// const ////////
+
+ static const uint32_t MeshesCountMax = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+
+
+ //////// public API ////////
+
+ void updateVisibleMeshes(const std::vector<uint32_t>& visibleMeshes);
+ void updateVisibleMeshTransforms(std::vector<PxMat44>& transforms);
+
+
+ //////// IRenderMesh implementation ////////
+
+ virtual const std::vector<D3D11_INPUT_ELEMENT_DESC>& getInputElementDesc() const { return m_inputDesc; }
+ virtual void render(ID3D11DeviceContext& context) const;
+
+private:
+ //////// internal data ////////
+
+ struct MeshInfo
+ {
+ uint32_t firstIndex;
+ uint32_t indicesCount;
+
+ uint32_t firstVertex;
+ uint32_t verticesCount;
+ };
+
+ std::vector<D3D11_INPUT_ELEMENT_DESC> m_inputDesc;
+
+ ID3D11Device* m_device;
+
+ ID3D11Buffer* m_vertexBuffer;
+ ID3D11Buffer* m_boneIndexBuffer;
+ ID3D11Buffer* m_indexBuffer;
+ ID3D11Texture2D* m_boneTexture;
+ ID3D11ShaderResourceView* m_boneTextureSRV;
+
+ uint32_t m_indexCount;
+
+ std::vector<MeshInfo> m_meshesInfo;
+ std::vector<uint32_t> m_indices;
+};
+
+
+
+#endif //SKINNED_RENDER_MESH_H \ No newline at end of file