BsRendererUtility.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #include "BsRendererUtility.h"
  2. #include "BsRenderAPI.h"
  3. #include "BsMesh.h"
  4. #include "BsVertexDataDesc.h"
  5. #include "BsMaterial.h"
  6. #include "BsPass.h"
  7. #include "BsBlendState.h"
  8. #include "BsDepthStencilState.h"
  9. #include "BsRasterizerState.h"
  10. namespace BansheeEngine
  11. {
  12. RendererUtility::RendererUtility()
  13. {
  14. VertexDataDescPtr vertexDesc = bs_shared_ptr_new<VertexDataDesc>();
  15. vertexDesc->addVertElem(VET_FLOAT3, VES_POSITION);
  16. vertexDesc->addVertElem(VET_FLOAT2, VES_TEXCOORD);
  17. mFullScreenQuadMesh = MeshCore::create(4, 6, vertexDesc);
  18. }
  19. RendererUtility::~RendererUtility()
  20. {
  21. }
  22. void RendererUtility::setPass(const SPtr<MaterialCore>& material, UINT32 passIdx)
  23. {
  24. RenderAPICore& rs = RenderAPICore::instance();
  25. SPtr<PassCore> pass = material->getPass(passIdx);
  26. SPtr<PassParametersCore> passParams = material->getPassParameters(passIdx);
  27. struct StageData
  28. {
  29. GpuProgramType type;
  30. bool enable;
  31. SPtr<GpuParamsCore> params;
  32. SPtr<GpuProgramCore> program;
  33. };
  34. const UINT32 numStages = 6;
  35. StageData stages[numStages] =
  36. {
  37. {
  38. GPT_VERTEX_PROGRAM, pass->hasVertexProgram(),
  39. passParams->mVertParams, pass->getVertexProgram()
  40. },
  41. {
  42. GPT_FRAGMENT_PROGRAM, pass->hasFragmentProgram(),
  43. passParams->mFragParams, pass->getFragmentProgram()
  44. },
  45. {
  46. GPT_GEOMETRY_PROGRAM, pass->hasGeometryProgram(),
  47. passParams->mGeomParams, pass->getGeometryProgram()
  48. },
  49. {
  50. GPT_HULL_PROGRAM, pass->hasHullProgram(),
  51. passParams->mHullParams, pass->getHullProgram()
  52. },
  53. {
  54. GPT_DOMAIN_PROGRAM, pass->hasDomainProgram(),
  55. passParams->mDomainParams, pass->getDomainProgram()
  56. },
  57. {
  58. GPT_COMPUTE_PROGRAM, pass->hasComputeProgram(),
  59. passParams->mComputeParams, pass->getComputeProgram()
  60. }
  61. };
  62. for (UINT32 i = 0; i < numStages; i++)
  63. {
  64. const StageData& stage = stages[i];
  65. if (stage.enable)
  66. {
  67. rs.bindGpuProgram(stage.program);
  68. rs.setGpuParams(stage.type, stage.params);
  69. }
  70. else
  71. rs.unbindGpuProgram(stage.type);
  72. }
  73. // Set up non-texture related pass settings
  74. if (pass->getBlendState() != nullptr)
  75. rs.setBlendState(pass->getBlendState());
  76. else
  77. rs.setBlendState(BlendStateCore::getDefault());
  78. if (pass->getDepthStencilState() != nullptr)
  79. rs.setDepthStencilState(pass->getDepthStencilState(), pass->getStencilRefValue());
  80. else
  81. rs.setDepthStencilState(DepthStencilStateCore::getDefault(), pass->getStencilRefValue());
  82. if (pass->getRasterizerState() != nullptr)
  83. rs.setRasterizerState(pass->getRasterizerState());
  84. else
  85. rs.setRasterizerState(RasterizerStateCore::getDefault());
  86. }
  87. void RendererUtility::draw(const SPtr<MeshCoreBase>& mesh, const SubMesh& subMesh)
  88. {
  89. RenderAPICore& rs = RenderAPICore::instance();
  90. const MeshProperties& meshProps = mesh->getProperties();
  91. std::shared_ptr<VertexData> vertexData = mesh->getVertexData();
  92. rs.setVertexDeclaration(vertexData->vertexDeclaration);
  93. auto& vertexBuffers = vertexData->getBuffers();
  94. if (vertexBuffers.size() > 0)
  95. {
  96. SPtr<VertexBufferCore> buffers[MAX_BOUND_VERTEX_BUFFERS];
  97. UINT32 endSlot = 0;
  98. UINT32 startSlot = MAX_BOUND_VERTEX_BUFFERS;
  99. for (auto iter = vertexBuffers.begin(); iter != vertexBuffers.end(); ++iter)
  100. {
  101. if (iter->first >= MAX_BOUND_VERTEX_BUFFERS)
  102. BS_EXCEPT(InvalidParametersException, "Buffer index out of range");
  103. startSlot = std::min(iter->first, startSlot);
  104. endSlot = std::max(iter->first, endSlot);
  105. }
  106. for (auto iter = vertexBuffers.begin(); iter != vertexBuffers.end(); ++iter)
  107. {
  108. buffers[iter->first - startSlot] = iter->second;
  109. }
  110. rs.setVertexBuffers(startSlot, buffers, endSlot - startSlot + 1);
  111. }
  112. rs.setDrawOperation(subMesh.drawOp);
  113. SPtr<IndexBufferCore> indexBuffer = mesh->getIndexBuffer();
  114. UINT32 indexCount = subMesh.indexCount;
  115. rs.setIndexBuffer(indexBuffer);
  116. rs.drawIndexed(subMesh.indexOffset + mesh->getIndexOffset(), indexCount, mesh->getVertexOffset(), vertexData->vertexCount);
  117. mesh->_notifyUsedOnGPU();
  118. }
  119. void RendererUtility::drawScreenQuad(const ViewportCore& viewport, const Rect2& uv, const Vector2I& textureSize)
  120. {
  121. // Note: Consider drawing the quad using a single large triangle for possibly better performance
  122. Rect2I viewArea = viewport.getArea();
  123. Vector3 vertices[4];
  124. vertices[0] = Vector3((float)viewArea.x, (float)viewArea.y, 0.0f);
  125. vertices[1] = Vector3((float)viewArea.x + (float)viewArea.width, (float)viewArea.y, 0.0f);
  126. vertices[2] = Vector3((float)viewArea.x, (float)viewArea.y + (float)viewArea.height, 0.0f);
  127. vertices[3] = Vector3((float)viewArea.x + (float)viewArea.width, (float)viewArea.y + (float)viewArea.height, 0.0f);
  128. Vector2 uvs[4];
  129. uvs[0] = Vector2(uv.x, uv.y);
  130. uvs[1] = Vector2(uv.x + uv.width, uv.y);
  131. uvs[2] = Vector2(uv.x, uv.y + uv.height);
  132. uvs[3] = Vector2(uv.x + uv.width, uv.y + uv.height);
  133. auto targetProps = viewport.getTarget()->getProperties();;
  134. RenderAPICore& rapi = RenderAPICore::instance();
  135. for (int i = 0; i < 4; i++)
  136. {
  137. vertices[i].x = -1.0f + 2.0f * (vertices[i].x + rapi.getHorizontalTexelOffset()) / targetProps.getWidth();
  138. vertices[i].y = 1.0f - 2.0f * (vertices[i].y + rapi.getVerticalTexelOffset()) / targetProps.getHeight();
  139. uvs[i].x /= (float)textureSize.x;
  140. uvs[i].y /= (float)textureSize.y;
  141. }
  142. SPtr<VertexDataDesc> vertexDesc = mFullScreenQuadMesh->getVertexDesc();
  143. MeshDataPtr meshData = bs_shared_ptr_new<MeshData>(4, 6, vertexDesc);
  144. auto vecIter = meshData->getVec3DataIter(VES_POSITION);
  145. for (UINT32 i = 0; i < 4; i++)
  146. vecIter.addValue(vertices[i]);
  147. auto uvIter = meshData->getVec2DataIter(VES_TEXCOORD);
  148. for (UINT32 i = 0; i < 4; i++)
  149. uvIter.addValue(uvs[i]);
  150. auto indices = meshData->getIndices32();
  151. indices[0] = 0;
  152. indices[1] = 1;
  153. indices[2] = 2;
  154. indices[3] = 1;
  155. indices[4] = 3;
  156. indices[5] = 2;
  157. mFullScreenQuadMesh->writeSubresource(0, *meshData, true, false);
  158. draw(mFullScreenQuadMesh, mFullScreenQuadMesh->getProperties().getSubMesh());
  159. }
  160. RendererUtility& gRendererUtility()
  161. {
  162. return RendererUtility::instance();
  163. }
  164. }