CmD3D11RenderUtility.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. #include "CmD3D11RenderUtility.h"
  2. #include "CmD3D11Device.h"
  3. #include "CmVector3.h"
  4. #include "CmColor.h"
  5. #include "CmRect.h"
  6. namespace CamelotFramework
  7. {
  8. struct ClearVertex
  9. {
  10. Vector3 pos;
  11. UINT32 col;
  12. };
  13. D3D11RenderUtility::D3D11RenderUtility(D3D11Device* device)
  14. :mDevice(device), mClearQuadIB(nullptr), mClearQuadVB(nullptr),
  15. mClearQuadIL(nullptr), mClearQuadVS(nullptr), mClearQuadPS(nullptr)
  16. {
  17. }
  18. D3D11RenderUtility::~D3D11RenderUtility()
  19. {
  20. SAFE_RELEASE(mClearQuadPS);
  21. SAFE_RELEASE(mClearQuadVS);
  22. SAFE_RELEASE(mClearQuadIL);
  23. SAFE_RELEASE(mClearQuadIB);
  24. SAFE_RELEASE(mClearQuadVB);
  25. // TODO - Clear up all resources
  26. }
  27. void D3D11RenderUtility::drawClearQuad(float clipLeft, float clipWidth, float clipTop, float clipHeight,
  28. UINT32 clearBuffers, const Color& color, float depth, UINT16 stencil)
  29. {
  30. // TODO - Set up states
  31. // TODO - Make sure to apply proper states depending on "clearBuffers" flags. Don't forget about stencil
  32. // TODO - How smart it is to update buffer right before drawing it!? (cache the clip area)
  33. ClearVertex vertexData[4];
  34. vertexData[0].pos = Vector3(clipLeft, clipTop, depth);
  35. vertexData[1].pos = Vector3(clipLeft + clipWidth, clipTop, depth);
  36. vertexData[2].pos = Vector3(clipLeft, clipTop + clipHeight, depth);
  37. vertexData[3].pos = Vector3(clipLeft + clipWidth, clipTop + clipHeight, depth);
  38. vertexData[0].col = color.getAsBGRA();
  39. vertexData[1].col = color.getAsBGRA();
  40. vertexData[2].col = color.getAsBGRA();
  41. vertexData[3].col = color.getAsBGRA();
  42. mDevice->getImmediateContext()->UpdateSubresource(mClearQuadVB, 0, nullptr, vertexData, 0, sizeof(vertexData));
  43. mDevice->getImmediateContext()->VSSetShader(mClearQuadVS, nullptr, 0);
  44. mDevice->getImmediateContext()->PSSetShader(mClearQuadPS, nullptr, 0);
  45. ID3D11Buffer* buffers[1];
  46. buffers[0] = mClearQuadVB;
  47. UINT32 strides[1] = { sizeof(ClearVertex) };
  48. UINT32 offsets[1] = { 0 };
  49. mDevice->getImmediateContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
  50. mDevice->getImmediateContext()->IASetIndexBuffer(mClearQuadIB, DXGI_FORMAT_R16_UINT, 0);
  51. mDevice->getImmediateContext()->IASetVertexBuffers(0, 1, buffers, strides, offsets);
  52. mDevice->getImmediateContext()->IASetInputLayout(mClearQuadIL);
  53. mDevice->getImmediateContext()->DrawIndexed(4, 0, 0);
  54. }
  55. void D3D11RenderUtility::initClearQuadResources()
  56. {
  57. String vsShaderCode = " \
  58. void main( \
  59. in float3 inPos : POSITION, \
  60. in float4 color : COLOR0, \
  61. out float4 oPosition : SV_Position, \
  62. out float4 oColor : COLOR0) \
  63. { \
  64. oPosition = float4(inPos.xyz, 1); \
  65. oColor = color; \
  66. } \
  67. ";
  68. String psShaderCode = "float4 ps_main(in float4 inPos : SV_Position, float4 color : COLOR) : SV_Target \
  69. { return color; }";
  70. HRESULT hr;
  71. ID3DBlob* microcode = nullptr;
  72. ID3DBlob* errors = nullptr;
  73. // Compile pixel shader
  74. hr = D3DCompile(psShaderCode.c_str(), psShaderCode.size(), nullptr, nullptr, nullptr, "main", "ps_4_0",
  75. D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR, 0, &microcode, &errors);
  76. if (FAILED(hr))
  77. {
  78. String message = "Cannot assemble D3D11 high-level shader. Errors:\n" +
  79. String(static_cast<const char*>(errors->GetBufferPointer()));
  80. SAFE_RELEASE(errors);
  81. CM_EXCEPT(RenderingAPIException, message);
  82. }
  83. SAFE_RELEASE(errors);
  84. hr = mDevice->getD3D11Device()->CreatePixelShader(static_cast<DWORD*>(microcode->GetBufferPointer()),
  85. microcode->GetBufferSize(), mDevice->getClassLinkage(), &mClearQuadPS);
  86. if (FAILED(hr))
  87. {
  88. SAFE_RELEASE(microcode);
  89. CM_EXCEPT(RenderingAPIException, "Cannot create D3D11 high-level shader.");
  90. }
  91. // Compile vertex shader
  92. hr = D3DCompile(vsShaderCode.c_str(), vsShaderCode.size(), nullptr, nullptr, nullptr, "main", "vs_4_0",
  93. D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR, 0, &microcode, &errors);
  94. if (FAILED(hr))
  95. {
  96. String message = "Cannot assemble D3D11 high-level shader. Errors:\n" +
  97. String(static_cast<const char*>(errors->GetBufferPointer()));
  98. SAFE_RELEASE(errors);
  99. CM_EXCEPT(RenderingAPIException, message);
  100. }
  101. SAFE_RELEASE(errors);
  102. hr = mDevice->getD3D11Device()->CreateVertexShader(static_cast<DWORD*>(microcode->GetBufferPointer()),
  103. microcode->GetBufferSize(), mDevice->getClassLinkage(), &mClearQuadVS);
  104. if (FAILED(hr))
  105. {
  106. SAFE_RELEASE(microcode);
  107. CM_EXCEPT(RenderingAPIException, "Cannot create D3D11 high-level shader.");
  108. }
  109. // Create input layout
  110. D3D11_INPUT_ELEMENT_DESC* declElements = cm_newN<D3D11_INPUT_ELEMENT_DESC, ScratchAlloc>(2);
  111. ZeroMemory(declElements, sizeof(D3D11_INPUT_ELEMENT_DESC) * 2);
  112. declElements[0].SemanticName = "POSITION";
  113. declElements[0].SemanticIndex = 0;
  114. declElements[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
  115. declElements[0].InputSlot = 0;
  116. declElements[0].AlignedByteOffset = 0;
  117. declElements[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  118. declElements[0].InstanceDataStepRate = 0;
  119. declElements[1].SemanticName = "COLOR";
  120. declElements[1].SemanticIndex = 0;
  121. declElements[1].Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  122. declElements[1].InputSlot = 0;
  123. declElements[1].AlignedByteOffset = sizeof(float) * 3;
  124. declElements[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  125. declElements[1].InstanceDataStepRate = 0;
  126. hr = mDevice->getD3D11Device()->CreateInputLayout(declElements, 2, microcode->GetBufferPointer(),
  127. microcode->GetBufferSize(), &mClearQuadIL);
  128. cm_deleteN<ScratchAlloc>(declElements, 2);
  129. if (FAILED(hr))
  130. {
  131. CM_EXCEPT(RenderingAPIException, "Cannot create D3D11 input layout.");
  132. }
  133. // Create vertex buffer
  134. D3D11_BUFFER_DESC mVBDesc;
  135. mVBDesc.ByteWidth = sizeof(float) * 3 + sizeof(UINT32);
  136. mVBDesc.MiscFlags = 0;
  137. mVBDesc.StructureByteStride = 0;
  138. mVBDesc.Usage = D3D11_USAGE_DEFAULT;
  139. mVBDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
  140. mVBDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
  141. ClearVertex vertexData[4];
  142. vertexData[0].pos = Vector3(0, 0, 0);
  143. vertexData[1].pos = Vector3(0, 0, 0);
  144. vertexData[2].pos = Vector3(0, 0, 0);
  145. vertexData[3].pos = Vector3(0, 0, 0);
  146. vertexData[0].col = Color::White.getAsBGRA();
  147. vertexData[1].col = Color::White.getAsBGRA();
  148. vertexData[2].col = Color::White.getAsBGRA();
  149. vertexData[3].col = Color::White.getAsBGRA();
  150. D3D11_SUBRESOURCE_DATA vertexSubresourceData;
  151. vertexSubresourceData.pSysMem = vertexData;
  152. hr = mDevice->getD3D11Device()->CreateBuffer(&mVBDesc, &vertexSubresourceData, &mClearQuadVB);
  153. if (FAILED(hr) || mDevice->hasError())
  154. {
  155. String msg = mDevice->getErrorDescription();
  156. CM_EXCEPT(RenderingAPIException, "Cannot create D3D11 buffer: " + msg);
  157. }
  158. // Create index buffer
  159. D3D11_BUFFER_DESC mIBDesc;
  160. mIBDesc.ByteWidth = sizeof(UINT16) * 4;
  161. mIBDesc.MiscFlags = 0;
  162. mIBDesc.StructureByteStride = 0;
  163. mIBDesc.Usage = D3D11_USAGE_DEFAULT;
  164. mIBDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
  165. mIBDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
  166. UINT16 indexData[6];
  167. indexData[0] = 0;
  168. indexData[1] = 1;
  169. indexData[2] = 2;
  170. indexData[3] = 1;
  171. indexData[4] = 3;
  172. indexData[5] = 2;
  173. D3D11_SUBRESOURCE_DATA indexSubresourceData;
  174. indexSubresourceData.pSysMem = indexData;
  175. hr = mDevice->getD3D11Device()->CreateBuffer(&mIBDesc, &indexSubresourceData, &mClearQuadIB);
  176. if (FAILED(hr) || mDevice->hasError())
  177. {
  178. String msg = mDevice->getErrorDescription();
  179. CM_EXCEPT(RenderingAPIException, "Cannot create D3D11 buffer: " + msg);
  180. }
  181. }
  182. }