CmD3D11VertexDeclaration.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include "CmD3D11VertexDeclaration.h"
  2. #include "CmD3D11Mappings.h"
  3. #include "CmD3D11Device.h"
  4. #include "CmD3D11HLSLProgram.h"
  5. #include "CmException.h"
  6. namespace CamelotEngine
  7. {
  8. D3D11VertexDeclaration::D3D11VertexDeclaration()
  9. :VertexDeclaration()
  10. {
  11. }
  12. D3D11VertexDeclaration::~D3D11VertexDeclaration()
  13. {
  14. for(auto iter = mLayoutPerDevice.begin(); iter != mLayoutPerDevice.end(); ++iter)
  15. {
  16. if(iter->second != nullptr)
  17. iter->second->Release();
  18. }
  19. }
  20. const VertexElement& D3D11VertexDeclaration::addElement(unsigned short source, UINT32 offset, VertexElementType theType,
  21. VertexElementSemantic semantic, unsigned short index)
  22. {
  23. mNeedsRebuild = true;
  24. return VertexDeclaration::addElement(source, offset, theType, semantic, index);
  25. }
  26. const VertexElement& D3D11VertexDeclaration::insertElement(unsigned short atPosition,
  27. unsigned short source, UINT32 offset, VertexElementType theType,
  28. VertexElementSemantic semantic, unsigned short index)
  29. {
  30. mNeedsRebuild = true;
  31. return VertexDeclaration::insertElement(atPosition, source, offset, theType, semantic, index);
  32. }
  33. void D3D11VertexDeclaration::removeElement(unsigned short elem_index)
  34. {
  35. VertexDeclaration::removeElement(elem_index);
  36. mNeedsRebuild = true;
  37. }
  38. void D3D11VertexDeclaration::removeElement(VertexElementSemantic semantic, unsigned short index)
  39. {
  40. VertexDeclaration::removeElement(semantic, index);
  41. mNeedsRebuild = true;
  42. }
  43. void D3D11VertexDeclaration::removeAllElements(void)
  44. {
  45. VertexDeclaration::removeAllElements();
  46. mNeedsRebuild = true;
  47. }
  48. void D3D11VertexDeclaration::modifyElement(unsigned short elem_index, unsigned short source, UINT32 offset, VertexElementType theType,
  49. VertexElementSemantic semantic, unsigned short index)
  50. {
  51. VertexDeclaration::modifyElement(elem_index, source, offset, theType, semantic, index);
  52. mNeedsRebuild = true;
  53. }
  54. ID3D11InputLayout* D3D11VertexDeclaration::getD3DLayout(D3D11Device& device, D3D11HLSLProgram& programToBindTo)
  55. {
  56. if(!mNeedsRebuild)
  57. {
  58. auto iterFind = mLayoutPerDevice.find(&device);
  59. if(iterFind == mLayoutPerDevice.end())
  60. mNeedsRebuild = true;
  61. }
  62. if(mNeedsRebuild)
  63. {
  64. size_t numElements = programToBindTo.getNumInputs();
  65. D3D11_INPUT_ELEMENT_DESC* declElements = new D3D11_INPUT_ELEMENT_DESC[numElements];
  66. ZeroMemory(declElements, sizeof(D3D11_INPUT_ELEMENT_DESC) * numElements);
  67. unsigned int idx;
  68. for (idx = 0; idx < numElements; ++idx)
  69. {
  70. const D3D11_SIGNATURE_PARAMETER_DESC& inputDesc = programToBindTo.getInputParamDesc(idx);
  71. VertexElementList::const_iterator i, iend;
  72. iend = mElementList.end();
  73. bool found = false;
  74. for (i = mElementList.begin(); i != iend; ++i)
  75. {
  76. LPCSTR semanticName = D3D11Mappings::get(i->getSemantic());
  77. UINT semanticIndex = i->getIndex();
  78. if(strcmp(semanticName, inputDesc.SemanticName) == 0
  79. && semanticIndex == inputDesc.SemanticIndex)
  80. {
  81. found = true;
  82. break;
  83. }
  84. }
  85. if(!found)
  86. {
  87. CM_EXCEPT(RenderingAPIException, "Shader signature doesn't match the vertex declaration!");
  88. }
  89. declElements[idx].SemanticName = inputDesc.SemanticName;
  90. declElements[idx].SemanticIndex = inputDesc.SemanticIndex;
  91. declElements[idx].Format = D3D11Mappings::get(i->getType());
  92. declElements[idx].InputSlot = i->getSource();
  93. declElements[idx].AlignedByteOffset = static_cast<WORD>(i->getOffset());
  94. declElements[idx].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  95. declElements[idx].InstanceDataStepRate = 0;
  96. DWORD dwShaderFlags = 0;
  97. const HLSLMicroCode& microCode = programToBindTo.getMicroCode();
  98. ID3D11InputLayout* inputLayout = nullptr;
  99. HRESULT hr = device.getD3D11Device()->CreateInputLayout(
  100. declElements,
  101. programToBindTo.getNumInputs(),
  102. &microCode[0],
  103. microCode.size(),
  104. &inputLayout );
  105. if (FAILED(hr)|| device.hasError())
  106. {
  107. String errorDescription = device.getErrorDescription();
  108. CM_EXCEPT(RenderingAPIException, "Unable to set D3D11 vertex declaration" + errorDescription);
  109. }
  110. mLayoutPerDevice[&device] = inputLayout;
  111. }
  112. }
  113. return mLayoutPerDevice[&device];
  114. }
  115. }