diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /APEX_1.4/samples_v2/SampleBase/ApexRenderResources.cpp | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'APEX_1.4/samples_v2/SampleBase/ApexRenderResources.cpp')
| -rw-r--r-- | APEX_1.4/samples_v2/SampleBase/ApexRenderResources.cpp | 814 |
1 files changed, 814 insertions, 0 deletions
diff --git a/APEX_1.4/samples_v2/SampleBase/ApexRenderResources.cpp b/APEX_1.4/samples_v2/SampleBase/ApexRenderResources.cpp new file mode 100644 index 00000000..dddd0279 --- /dev/null +++ b/APEX_1.4/samples_v2/SampleBase/ApexRenderResources.cpp @@ -0,0 +1,814 @@ +/* +* 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 "ApexRenderResources.h" + +#include "RenderDataFormat.h" +#include <sstream> + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Helper functions +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static DXGI_FORMAT getD3DFormat(RenderDataFormat::Enum format) +{ + DXGI_FORMAT d3dFormat; + switch(format) + { + case RenderDataFormat::FLOAT1: + d3dFormat = DXGI_FORMAT_R32_FLOAT; + break; + case RenderDataFormat::FLOAT2: + d3dFormat = DXGI_FORMAT_R32G32_FLOAT; + break; + case RenderDataFormat::FLOAT3: + d3dFormat = DXGI_FORMAT_R32G32B32_FLOAT; + break; + case RenderDataFormat::FLOAT4: + d3dFormat = DXGI_FORMAT_R32G32B32A32_FLOAT; + break; + case RenderDataFormat::B8G8R8A8: + d3dFormat = DXGI_FORMAT_B8G8R8A8_UNORM; + break; + case RenderDataFormat::UINT1: + case RenderDataFormat::UBYTE4: + case RenderDataFormat::R8G8B8A8: + d3dFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + break; + case RenderDataFormat::USHORT1: + d3dFormat = DXGI_FORMAT_R16_UINT; + break; + case RenderDataFormat::USHORT2: + d3dFormat = DXGI_FORMAT_R16G16_UINT; + break; + case RenderDataFormat::USHORT3: + case RenderDataFormat::USHORT4: + d3dFormat = DXGI_FORMAT_R16G16B16A16_UINT; + break; + default: + d3dFormat = DXGI_FORMAT_UNKNOWN; + } + PX_ASSERT((d3dFormat != DXGI_FORMAT_UNKNOWN) && "Invalid DIRECT3D11 vertex type."); + return d3dFormat; +} + +static void getD3DUsage(RenderVertexSemantic::Enum semantic, LPCSTR& usageName, uint8_t& usageIndex) +{ + usageIndex = 0; + if(semantic >= RenderVertexSemantic::TEXCOORD0 && semantic <= RenderVertexSemantic::TEXCOORD3) + { + usageName = "TEXCOORD"; + usageIndex = (uint8_t)(semantic - RenderVertexSemantic::TEXCOORD0); + } + else + { + switch(semantic) + { + case RenderVertexSemantic::POSITION: + usageName = "POSITION"; + break; + case RenderVertexSemantic::NORMAL: + usageName = "NORMAL"; + break; + case RenderVertexSemantic::TANGENT: + usageName = "TANGENT"; + break; + case RenderVertexSemantic::COLOR: + usageName = "COLOR"; + break; + case RenderVertexSemantic::BONE_INDEX: + usageName = "TEXCOORD"; + usageIndex = 5; + break; + case RenderVertexSemantic::BONE_WEIGHT: + usageName = "TEXCOORD"; + usageIndex = 6; + break; + case RenderVertexSemantic::DISPLACEMENT_TEXCOORD: + usageName = "TEXCOORD"; + usageIndex = 7; + break; + case RenderVertexSemantic::DISPLACEMENT_FLAGS: + usageName = "TEXCOORD"; + usageIndex = 8; + break; + default: + usageName = "POSITION"; + } + } +} + +static void getD3DUsage(RenderSpriteSemantic::Enum semantic, LPCSTR& usageName, uint8_t& usageIndex) +{ + usageIndex = 0; + switch (semantic) + { + case RenderSpriteSemantic::POSITION: + usageName = "POSITION"; + break; + case RenderSpriteSemantic::COLOR: + usageName = "COLOR"; + break; + case RenderSpriteSemantic::VELOCITY: + usageName = "NORMAL"; + break; + case RenderSpriteSemantic::SCALE: + usageName = "TANGENT"; + break; + case RenderSpriteSemantic::LIFE_REMAIN: + usageName = "TEXCOORD"; + usageIndex = 0; + break; + case RenderSpriteSemantic::DENSITY: + usageName = "TEXCOORD"; + usageIndex = 1; + break; + case RenderSpriteSemantic::SUBTEXTURE: + usageName = "TEXCOORD"; + usageIndex = 2; + break; + case RenderSpriteSemantic::ORIENTATION: + usageName = "TEXCOORD"; + usageIndex = 3; + break; + default: + PX_ALWAYS_ASSERT(); + usageName = "POSITION"; + break; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SampleApexRendererVertexBuffer +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +SampleApexRendererVertexBuffer::SampleApexRendererVertexBuffer(ID3D11Device& d3dDevice, + const apex::UserRenderVertexBufferDesc& desc) +: mDevice(d3dDevice) +{ + uint32_t stride = 0; + uint8_t pointer = 0; + for(uint32_t i = 0; i < apex::RenderVertexSemantic::NUM_SEMANTICS; i++) + { + apex::RenderDataFormat::Enum apexFormat = desc.buffersRequest[i]; + + mDataFormat[i] = apexFormat; + stride += RenderDataFormat::getFormatDataSize(apexFormat); + + mPointers[i] = pointer; + pointer += (uint8_t)RenderDataFormat::getFormatDataSize(apexFormat); + } + + mStride = stride; + mVerticesCount = desc.maxVerts; + + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.ByteWidth = (UINT)(desc.maxVerts * mStride); + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + + V(mDevice.CreateBuffer(&bufferDesc, NULL, &mVertexBuffer)); +} + +SampleApexRendererVertexBuffer::~SampleApexRendererVertexBuffer(void) +{ + if(mVertexBuffer) + { + mVertexBuffer->Release(); + mVertexBuffer = NULL; + } +} + +void SampleApexRendererVertexBuffer::addVertexElements(uint32_t streamIndex, + std::vector<D3D11_INPUT_ELEMENT_DESC>& vertexElements) const +{ + uint32_t offset = 0; + + for(uint32_t i = 0; i < apex::RenderVertexSemantic::NUM_SEMANTICS; i++) + { + apex::RenderVertexSemantic::Enum semantic = (apex::RenderVertexSemantic::Enum)i; + + if(mDataFormat[i] != RenderDataFormat::UNSPECIFIED) + { + uint8_t d3dUsageIndex = 0; + LPCSTR d3dUsageName = ""; + getD3DUsage(semantic, d3dUsageName, d3dUsageIndex); + + D3D11_INPUT_ELEMENT_DESC element; + element.SemanticName = d3dUsageName; + element.SemanticIndex = d3dUsageIndex; + element.Format = getD3DFormat(mDataFormat[i]); + element.InputSlot = streamIndex; + element.AlignedByteOffset = offset; + element.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + element.InstanceDataStepRate = 0; + + vertexElements.push_back(element); + + offset += (uint32_t)RenderDataFormat::getFormatDataSize(mDataFormat[i]); + } + } +} + +void SampleApexRendererVertexBuffer::writeBuffer(const apex::RenderVertexBufferData& data, uint32_t firstVertex, + uint32_t numVerts) +{ + ID3D11DeviceContext* context; + mDevice.GetImmediateContext(&context); + + D3D11_MAPPED_SUBRESOURCE mappedRead; + V(context->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead)); + + for(uint32_t i = 0; i < apex::RenderVertexSemantic::NUM_SEMANTICS; i++) + { + apex::RenderVertexSemantic::Enum apexSemantic = (apex::RenderVertexSemantic::Enum)i; + const apex::RenderSemanticData& semanticData = data.getSemanticData(apexSemantic); + if(semanticData.data) + { + const void* srcData = semanticData.data; + const uint32_t srcStride = semanticData.stride; + + void* dstData = ((uint8_t*)mappedRead.pData) + firstVertex * mStride + mPointers[i]; + + for(uint32_t j = 0; j < numVerts; j++) + { + memcpy(dstData, srcData, srcStride); + dstData = ((uint8_t*)dstData) + mStride; + srcData = ((uint8_t*)srcData) + srcStride; + } + } + } + + context->Unmap(mVertexBuffer, 0); +} + +void SampleApexRendererVertexBuffer::bind(ID3D11DeviceContext& context, uint32_t streamID, uint32_t firstVertex) +{ + ID3D11Buffer* pBuffers[1] = { mVertexBuffer }; + UINT strides[1] = { mStride }; + UINT offsets[1] = { firstVertex * mStride }; + context.IASetVertexBuffers(streamID, 1, pBuffers, strides, offsets); +} + +void SampleApexRendererVertexBuffer::unbind(ID3D11DeviceContext& context, uint32_t streamID) +{ + ID3D11Buffer* pBuffers[1] = { NULL }; + UINT strides[1] = { 0 }; + UINT offsets[1] = { 0 }; + context.IASetVertexBuffers(streamID, 1, pBuffers, strides, offsets); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SampleApexRendererIndexBuffer +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +SampleApexRendererIndexBuffer::SampleApexRendererIndexBuffer(ID3D11Device& d3dDevice, + const apex::UserRenderIndexBufferDesc& desc) +: mDevice(d3dDevice) +{ + mIndicesCount = desc.maxIndices; + mStride = RenderDataFormat::getFormatDataSize(desc.format); + + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + bufferDesc.ByteWidth = (UINT)(RenderDataFormat::getFormatDataSize(desc.format) * desc.maxIndices); + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + + V(mDevice.CreateBuffer(&bufferDesc, NULL, &mIndexBuffer)); + + mFormat = (desc.format == RenderDataFormat::USHORT1 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT); +} + +SampleApexRendererIndexBuffer::~SampleApexRendererIndexBuffer(void) +{ + if(mIndexBuffer) + { + mIndexBuffer->Release(); + mIndexBuffer = NULL; + } +} + +void SampleApexRendererIndexBuffer::writeBuffer(const void* srcData, uint32_t srcStride, uint32_t firstDestElement, + uint32_t numElements) +{ + ID3D11DeviceContext* context; + mDevice.GetImmediateContext(&context); + + D3D11_MAPPED_SUBRESOURCE mappedRead; + V(context->Map(mIndexBuffer, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead)); + + ::memcpy(static_cast<char*>(mappedRead.pData) + firstDestElement * mStride, srcData, mStride * numElements); + + context->Unmap(mIndexBuffer, 0); +} + +void SampleApexRendererIndexBuffer::bind(ID3D11DeviceContext& context) +{ + context.IASetIndexBuffer(mIndexBuffer, mFormat, 0); +} + +void SampleApexRendererIndexBuffer::unbind(ID3D11DeviceContext& context) +{ + context.IASetIndexBuffer(NULL, DXGI_FORMAT(), 0); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SampleApexRendererBoneBuffer +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +SampleApexRendererBoneBuffer::SampleApexRendererBoneBuffer(ID3D11Device& d3dDevice, + const apex::UserRenderBoneBufferDesc& desc) +: mDevice(d3dDevice) +{ + mMaxBones = desc.maxBones; + mBones = NULL; + mBones = new PxMat44[mMaxBones]; + + { + D3D11_TEXTURE2D_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Width = 4; + desc.Height = mMaxBones; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.CPUAccessFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + + D3D11_SUBRESOURCE_DATA subData; + memset(&subData, 0, sizeof(D3D11_SUBRESOURCE_DATA)); + subData.pSysMem = mBones; + subData.SysMemPitch = desc.Width * sizeof(unsigned int); + subData.SysMemSlicePitch = 0; + + V(mDevice.CreateTexture2D(&desc, &subData, &mTexture)); + } + + { + 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(mDevice.CreateShaderResourceView(mTexture, &desc, &mShaderResourceView)); + } +} + +SampleApexRendererBoneBuffer::~SampleApexRendererBoneBuffer(void) +{ + if(mBones) + { + delete[] mBones; + } + + if(mTexture) + { + mTexture->Release(); + } + + if(mShaderResourceView) + { + mShaderResourceView->Release(); + } +} + +void SampleApexRendererBoneBuffer::writeBuffer(const apex::RenderBoneBufferData& data, uint32_t firstBone, + uint32_t numBones) +{ + const apex::RenderSemanticData& semanticData = data.getSemanticData(apex::RenderBoneSemantic::POSE); + if(!semanticData.data) + return; + + const void* srcData = semanticData.data; + const uint32_t srcStride = semanticData.stride; + for(uint32_t i = 0; i < numBones; i++) + { + mBones[firstBone + i] = PxMat44(*((const PxMat44*)srcData)); + srcData = ((uint8_t*)srcData) + srcStride; + } + + ID3D11DeviceContext* context; + mDevice.GetImmediateContext(&context); + + CD3D11_BOX box(0, (LONG)firstBone, 0, 4, (LONG)(firstBone + numBones), 1); + context->UpdateSubresource(mTexture, 0, &box, mBones, 16 * 4, 16 * 4 * mMaxBones); +} + +void SampleApexRendererBoneBuffer::bind(uint32_t slot) +{ + ID3D11DeviceContext* context; + mDevice.GetImmediateContext(&context); + + context->VSSetShaderResources(slot, 1, &mShaderResourceView); + context->PSSetShaderResources(slot, 1, &mShaderResourceView); +} + +void SampleApexRendererBoneBuffer::unbind() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SampleApexRendererSpriteBuffer +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +SampleApexRendererSpriteBuffer::SampleApexRendererSpriteBuffer(ID3D11Device& d3dDevice, const nvidia::apex::UserRenderSpriteBufferDesc& desc) +: mDevice(d3dDevice) +{ + for (uint32_t i = 0; i < apex::RenderSpriteLayoutElement::NUM_SEMANTICS; i++) + { + if (desc.semanticOffsets[i] != static_cast<uint32_t>(-1)) + { + mDataFormat[i] = RenderSpriteLayoutElement::getSemanticFormat((apex::RenderSpriteLayoutElement::Enum)i); + } + else + { + mDataFormat[i] = RenderDataFormat::UNSPECIFIED; + } + } + + mStride = desc.stride; + + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.ByteWidth = (UINT)(desc.maxSprites * mStride); + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + + V(mDevice.CreateBuffer(&bufferDesc, NULL, &mVertexBuffer)); +} + +SampleApexRendererSpriteBuffer::~SampleApexRendererSpriteBuffer(void) +{ + if (mVertexBuffer) + { + mVertexBuffer->Release(); + mVertexBuffer = NULL; + } +} + +void SampleApexRendererSpriteBuffer::addVertexElements(uint32_t streamIndex, + std::vector<D3D11_INPUT_ELEMENT_DESC>& vertexElements) const +{ + uint32_t offset = 0; + + for (uint32_t i = 0; i < apex::RenderSpriteLayoutElement::NUM_SEMANTICS; i++) + { + apex::RenderSpriteSemantic::Enum semantic = RenderSpriteLayoutElement::getSemantic((apex::RenderSpriteLayoutElement::Enum)i); + + if (mDataFormat[i] != RenderDataFormat::UNSPECIFIED) + { + uint8_t d3dUsageIndex = 0; + LPCSTR d3dUsageName = ""; + getD3DUsage(semantic, d3dUsageName, d3dUsageIndex); + + D3D11_INPUT_ELEMENT_DESC element; + element.SemanticName = d3dUsageName; + element.SemanticIndex = d3dUsageIndex; + element.Format = getD3DFormat(mDataFormat[i]); + element.InputSlot = streamIndex; + element.AlignedByteOffset = offset; + element.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + element.InstanceDataStepRate = 0; + + vertexElements.push_back(element); + + offset += (uint32_t)RenderDataFormat::getFormatDataSize(mDataFormat[i]); + } + } +} + +void SampleApexRendererSpriteBuffer::writeBuffer(const void* srcData, uint32_t firstSprite, uint32_t numSprites) +{ + ID3D11DeviceContext* context; + mDevice.GetImmediateContext(&context); + + D3D11_MAPPED_SUBRESOURCE mappedRead; + V(context->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead)); + + ::memcpy(static_cast<char*>(mappedRead.pData) + firstSprite * mStride, srcData, mStride * numSprites); + + context->Unmap(mVertexBuffer, 0); +} + +void SampleApexRendererSpriteBuffer::writeTexture(uint32_t textureId, uint32_t numSprites, const void* srcData, size_t srcSize) +{ + PX_ALWAYS_ASSERT(); + PX_UNUSED(textureId); + PX_UNUSED(numSprites); + PX_UNUSED(srcData); + PX_UNUSED(srcSize); +} + +void SampleApexRendererSpriteBuffer::bind(ID3D11DeviceContext& context, uint32_t streamID, uint32_t firstVertex) +{ + ID3D11Buffer* pBuffers[1] = { mVertexBuffer }; + UINT strides[1] = { mStride }; + UINT offsets[1] = { firstVertex * mStride }; + context.IASetVertexBuffers(streamID, 1, pBuffers, strides, offsets); +} + +void SampleApexRendererSpriteBuffer::unbind(ID3D11DeviceContext& context, uint32_t streamID) +{ + ID3D11Buffer* pBuffers[1] = { NULL }; + UINT strides[1] = { 0 }; + UINT offsets[1] = { 0 }; + context.IASetVertexBuffers(streamID, 1, pBuffers, strides, offsets); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SampleApexRendererInstanceBuffer +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +SampleApexRendererInstanceBuffer::SampleApexRendererInstanceBuffer(ID3D11Device& d3dDevice, const nvidia::apex::UserRenderInstanceBufferDesc& desc) + : mDevice(d3dDevice) +{ + for (uint32_t i = 0; i < apex::RenderInstanceLayoutElement::NUM_SEMANTICS; i++) + { + if (desc.semanticOffsets[i] != static_cast<uint32_t>(-1)) + { + RenderDataFormat::Enum dataFormat = RenderInstanceLayoutElement::getSemanticFormat((apex::RenderInstanceLayoutElement::Enum)i); + if (dataFormat == RenderDataFormat::FLOAT3x3) + { + mDataFormat.push_back(RenderDataFormat::FLOAT3); + mDataFormat.push_back(RenderDataFormat::FLOAT3); + mDataFormat.push_back(RenderDataFormat::FLOAT3); + } + else + { + mDataFormat.push_back(dataFormat); + } + } + else + { + } + } + + mStride = desc.stride; + + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.ByteWidth = (UINT)(desc.maxInstances * mStride); + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + + V(mDevice.CreateBuffer(&bufferDesc, NULL, &mInstanceBuffer)); +} + +SampleApexRendererInstanceBuffer::~SampleApexRendererInstanceBuffer(void) +{ + if (mInstanceBuffer) + { + mInstanceBuffer->Release(); + mInstanceBuffer = NULL; + } +} + +void SampleApexRendererInstanceBuffer::addVertexElements(uint32_t streamIndex, + std::vector<D3D11_INPUT_ELEMENT_DESC>& vertexElements) const +{ + uint32_t offset = 0; + + for (uint32_t i = 0; i < mDataFormat.size(); i++) + { + RenderDataFormat::Enum dataFormat = mDataFormat[i]; + + D3D11_INPUT_ELEMENT_DESC element; + element.SemanticName = "TEXCOORD"; + element.SemanticIndex = 9 + i; + element.Format = getD3DFormat(dataFormat); + element.InputSlot = streamIndex; + element.AlignedByteOffset = offset; + element.InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA; + element.InstanceDataStepRate = 1; + + vertexElements.push_back(element); + + offset += (uint32_t)RenderDataFormat::getFormatDataSize(dataFormat); + } +} + +void SampleApexRendererInstanceBuffer::writeBuffer(const void* srcData, uint32_t firstInstance, uint32_t numInstances) +{ + ID3D11DeviceContext* context; + mDevice.GetImmediateContext(&context); + + D3D11_MAPPED_SUBRESOURCE mappedRead; + V(context->Map(mInstanceBuffer, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead)); + + ::memcpy(static_cast<char*>(mappedRead.pData) + firstInstance * mStride, srcData, mStride * numInstances); + + context->Unmap(mInstanceBuffer, 0); +} + +void SampleApexRendererInstanceBuffer::bind(ID3D11DeviceContext& context, uint32_t streamID, uint32_t firstVertex) +{ + ID3D11Buffer* pBuffers[1] = { mInstanceBuffer }; + UINT strides[1] = { mStride }; + UINT offsets[1] = { firstVertex * mStride }; + context.IASetVertexBuffers(streamID, 1, pBuffers, strides, offsets); +} + +void SampleApexRendererInstanceBuffer::unbind(ID3D11DeviceContext& context, uint32_t streamID) +{ + ID3D11Buffer* pBuffers[1] = { NULL }; + UINT strides[1] = { 0 }; + UINT offsets[1] = { 0 }; + context.IASetVertexBuffers(streamID, 1, pBuffers, strides, offsets); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SampleApexRendererMesh +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +SampleApexRendererMesh::SampleApexRendererMesh(ID3D11Device& d3dDevice, const apex::UserRenderResourceDesc& desc) +: mDevice(d3dDevice) +{ + mVertexBuffers = NULL; + mNumVertexBuffers = 0; + mIndexBuffer = NULL; + mSpriteBuffer = NULL; + mInstanceBuffer = NULL; + mMaterialInstance = NULL; + + mBoneBuffer = NULL; + + mNumVertexBuffers = desc.numVertexBuffers; + if(mNumVertexBuffers > 0) + { + mVertexBuffers = new SampleApexRendererVertexBuffer* [mNumVertexBuffers]; + for(uint32_t i = 0; i < mNumVertexBuffers; i++) + { + mVertexBuffers[i] = static_cast<SampleApexRendererVertexBuffer*>(desc.vertexBuffers[i]); + } + } + + if (desc.indexBuffer) + mIndexBuffer = static_cast<SampleApexRendererIndexBuffer*>(desc.indexBuffer); + + if (desc.boneBuffer) + mBoneBuffer = static_cast<SampleApexRendererBoneBuffer*>(desc.boneBuffer); + + if (desc.spriteBuffer) + mSpriteBuffer = static_cast<SampleApexRendererSpriteBuffer*>(desc.spriteBuffer); + + if (desc.instanceBuffer) + mInstanceBuffer = static_cast<SampleApexRendererInstanceBuffer*>(desc.instanceBuffer); + + mCullMode = desc.cullMode; + mPrimitiveTopology = desc.primitives == RenderPrimitiveType::POINT_SPRITES ? D3D_PRIMITIVE_TOPOLOGY_POINTLIST : + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + + setVertexBufferRange(desc.firstVertex, desc.numVerts); + setIndexBufferRange(desc.firstIndex, desc.numIndices); + setBoneBufferRange(desc.firstBone, desc.numBones); + setSpriteBufferRange(desc.firstSprite, desc.numSprites); + setInstanceBufferRange(desc.firstInstance, desc.numInstances); + + if (desc.material) + setMaterial(desc.material); +} + +void SampleApexRendererMesh::setMaterial(void* material) +{ + ApexRenderMaterial* renderMaterial = static_cast<ApexRenderMaterial*>(material); + if (mMaterial != renderMaterial) + { + mMaterial = renderMaterial; + + std::vector<D3D11_INPUT_ELEMENT_DESC> descs; + + for (uint32_t i = 0; i < mNumVertexBuffers; i++) + { + mVertexBuffers[i]->addVertexElements(i, descs); + } + + if (mSpriteBuffer) + mSpriteBuffer->addVertexElements(0, descs); + + if (mInstanceBuffer) + mInstanceBuffer->addVertexElements(mNumVertexBuffers, descs); + + mMaterialInstance = renderMaterial->getMaterialInstance(&descs[0], (uint32_t)descs.size()); + } +} + +SampleApexRendererMesh::~SampleApexRendererMesh(void) +{ + if(mVertexBuffers) + { + delete[] mVertexBuffers; + } +} + +void SampleApexRendererMesh::setVertexBufferRange(uint32_t firstVertex, uint32_t numVerts) +{ + mFirstVertex = firstVertex; + mNumVertices = numVerts; +} + +void SampleApexRendererMesh::setIndexBufferRange(uint32_t firstIndex, uint32_t numIndices) +{ + mFirstIndex = firstIndex; + mNumIndices = numIndices; +} + +void SampleApexRendererMesh::setBoneBufferRange(uint32_t firstBone, uint32_t numBones) +{ + mFirstBone = firstBone; + mNumBones = numBones; +} + +void SampleApexRendererMesh::setInstanceBufferRange(uint32_t firstInstance, uint32_t numInstances) +{ + mFirstInstance = firstInstance; + mNumInstances = numInstances; +} + +void SampleApexRendererMesh::setSpriteBufferRange(uint32_t firstSprite, uint32_t numSprites) +{ + mFirstSprite = firstSprite; + mNumSprites = numSprites; +} + +void SampleApexRendererMesh::render(const apex::RenderContext& c) +{ + PX_UNUSED(c); + if (mMaterialInstance == NULL || !mMaterialInstance->isValid()) + return; + + ID3D11DeviceContext* context; + mDevice.GetImmediateContext(&context); + + for(uint32_t i = 0; i < mNumVertexBuffers; i++) + { + mVertexBuffers[i]->bind(*context, i, 0); + } + + if (mIndexBuffer) + mIndexBuffer->bind(*context); + + mMaterialInstance->bind(*context, 0); + + if (mBoneBuffer) + mBoneBuffer->bind(1); + + if (mSpriteBuffer) + mSpriteBuffer->bind(*context, mNumVertexBuffers, mFirstSprite); + + if (mInstanceBuffer) + mInstanceBuffer->bind(*context, mNumVertexBuffers, mFirstInstance); + + context->IASetPrimitiveTopology(mPrimitiveTopology); + + if (mIndexBuffer && mInstanceBuffer) + context->DrawIndexedInstanced(mNumIndices, mNumInstances, mFirstIndex, 0, mFirstInstance); + else if (mIndexBuffer) + context->DrawIndexed(mNumIndices, mFirstIndex, 0); + else if (mInstanceBuffer) + context->DrawInstanced(mNumVertices, mNumInstances, mFirstVertex, mFirstInstance); + else if (mSpriteBuffer) + context->Draw(mNumSprites, mFirstSprite); + + for(uint32_t i = 0; i < mNumVertexBuffers; i++) + { + mVertexBuffers[i]->unbind(*context, i); + } + + if (mIndexBuffer) + mIndexBuffer->unbind(*context); + + if (mInstanceBuffer) + mInstanceBuffer->unbind(*context, 0); + + if (mSpriteBuffer) + mSpriteBuffer->unbind(*context, 0); + + if (mBoneBuffer != NULL) + mBoneBuffer->unbind(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |