BsRendererUtility.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  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. #include "BsGpuParams.h"
  11. #include "BsGpuParamDesc.h"
  12. namespace BansheeEngine
  13. {
  14. RendererUtility::RendererUtility()
  15. {
  16. VertexDataDescPtr vertexDesc = bs_shared_ptr_new<VertexDataDesc>();
  17. vertexDesc->addVertElem(VET_FLOAT3, VES_POSITION);
  18. vertexDesc->addVertElem(VET_FLOAT2, VES_TEXCOORD);
  19. mFullScreenQuadMesh = MeshCore::create(4, 6, vertexDesc);
  20. }
  21. RendererUtility::~RendererUtility()
  22. {
  23. }
  24. void RendererUtility::setPass(const SPtr<MaterialCore>& material, UINT32 passIdx)
  25. {
  26. RenderAPICore& rs = RenderAPICore::instance();
  27. SPtr<PassCore> pass = material->getPass(passIdx);
  28. SPtr<PassParametersCore> passParams = material->getPassParameters(passIdx);
  29. struct StageData
  30. {
  31. GpuProgramType type;
  32. bool enable;
  33. SPtr<GpuParamsCore> params;
  34. SPtr<GpuProgramCore> program;
  35. };
  36. const UINT32 numStages = 6;
  37. StageData stages[numStages] =
  38. {
  39. {
  40. GPT_VERTEX_PROGRAM, pass->hasVertexProgram(),
  41. passParams->mVertParams, pass->getVertexProgram()
  42. },
  43. {
  44. GPT_FRAGMENT_PROGRAM, pass->hasFragmentProgram(),
  45. passParams->mFragParams, pass->getFragmentProgram()
  46. },
  47. {
  48. GPT_GEOMETRY_PROGRAM, pass->hasGeometryProgram(),
  49. passParams->mGeomParams, pass->getGeometryProgram()
  50. },
  51. {
  52. GPT_HULL_PROGRAM, pass->hasHullProgram(),
  53. passParams->mHullParams, pass->getHullProgram()
  54. },
  55. {
  56. GPT_DOMAIN_PROGRAM, pass->hasDomainProgram(),
  57. passParams->mDomainParams, pass->getDomainProgram()
  58. },
  59. {
  60. GPT_COMPUTE_PROGRAM, pass->hasComputeProgram(),
  61. passParams->mComputeParams, pass->getComputeProgram()
  62. }
  63. };
  64. for (UINT32 i = 0; i < numStages; i++)
  65. {
  66. const StageData& stage = stages[i];
  67. if (stage.enable)
  68. {
  69. rs.bindGpuProgram(stage.program);
  70. rs.setGpuParams(stage.type, stage.params);
  71. }
  72. else
  73. rs.unbindGpuProgram(stage.type);
  74. }
  75. // Set up non-texture related pass settings
  76. if (pass->getBlendState() != nullptr)
  77. rs.setBlendState(pass->getBlendState());
  78. else
  79. rs.setBlendState(BlendStateCore::getDefault());
  80. if (pass->getDepthStencilState() != nullptr)
  81. rs.setDepthStencilState(pass->getDepthStencilState(), pass->getStencilRefValue());
  82. else
  83. rs.setDepthStencilState(DepthStencilStateCore::getDefault(), pass->getStencilRefValue());
  84. if (pass->getRasterizerState() != nullptr)
  85. rs.setRasterizerState(pass->getRasterizerState());
  86. else
  87. rs.setRasterizerState(RasterizerStateCore::getDefault());
  88. }
  89. void RendererUtility::setPassParams(const SPtr<MaterialCore>& material, UINT32 passIdx)
  90. {
  91. const SPtr<PassParametersCore>& passParams = material->getPassParameters(passIdx);
  92. RenderAPICore& rs = RenderAPICore::instance();
  93. struct StageData
  94. {
  95. GpuProgramType type;
  96. SPtr<GpuParamsCore> params;
  97. };
  98. const UINT32 numStages = 6;
  99. StageData stages[numStages] =
  100. {
  101. { GPT_VERTEX_PROGRAM, passParams->mVertParams },
  102. { GPT_FRAGMENT_PROGRAM, passParams->mFragParams },
  103. { GPT_GEOMETRY_PROGRAM, passParams->mGeomParams },
  104. { GPT_HULL_PROGRAM, passParams->mHullParams },
  105. { GPT_DOMAIN_PROGRAM, passParams->mDomainParams },
  106. { GPT_COMPUTE_PROGRAM, passParams->mComputeParams }
  107. };
  108. for (UINT32 i = 0; i < numStages; i++)
  109. {
  110. const StageData& stage = stages[i];
  111. SPtr<GpuParamsCore> params = stage.params;
  112. if (params == nullptr)
  113. continue;
  114. const GpuParamDesc& paramDesc = params->getParamDesc();
  115. for (auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
  116. {
  117. SPtr<SamplerStateCore> samplerState = params->getSamplerState(iter->second.slot);
  118. if (samplerState == nullptr)
  119. rs.setSamplerState(stage.type, iter->second.slot, SamplerStateCore::getDefault());
  120. else
  121. rs.setSamplerState(stage.type, iter->second.slot, samplerState);
  122. }
  123. for (auto iter = paramDesc.textures.begin(); iter != paramDesc.textures.end(); ++iter)
  124. {
  125. SPtr<TextureCore> texture = params->getTexture(iter->second.slot);
  126. if (!params->isLoadStoreTexture(iter->second.slot))
  127. {
  128. if (texture == nullptr)
  129. rs.setTexture(stage.type, iter->second.slot, false, nullptr);
  130. else
  131. rs.setTexture(stage.type, iter->second.slot, true, texture);
  132. }
  133. else
  134. {
  135. const TextureSurface& surface = params->getLoadStoreSurface(iter->second.slot);
  136. if (texture == nullptr)
  137. rs.setLoadStoreTexture(stage.type, iter->second.slot, false, nullptr, surface);
  138. else
  139. rs.setLoadStoreTexture(stage.type, iter->second.slot, true, texture, surface);
  140. }
  141. }
  142. rs.setConstantBuffers(stage.type, params);
  143. }
  144. }
  145. void RendererUtility::draw(const SPtr<MeshCoreBase>& mesh, const SubMesh& subMesh)
  146. {
  147. RenderAPICore& rs = RenderAPICore::instance();
  148. const MeshProperties& meshProps = mesh->getProperties();
  149. std::shared_ptr<VertexData> vertexData = mesh->getVertexData();
  150. rs.setVertexDeclaration(vertexData->vertexDeclaration);
  151. auto& vertexBuffers = vertexData->getBuffers();
  152. if (vertexBuffers.size() > 0)
  153. {
  154. SPtr<VertexBufferCore> buffers[MAX_BOUND_VERTEX_BUFFERS];
  155. UINT32 endSlot = 0;
  156. UINT32 startSlot = MAX_BOUND_VERTEX_BUFFERS;
  157. for (auto iter = vertexBuffers.begin(); iter != vertexBuffers.end(); ++iter)
  158. {
  159. if (iter->first >= MAX_BOUND_VERTEX_BUFFERS)
  160. BS_EXCEPT(InvalidParametersException, "Buffer index out of range");
  161. startSlot = std::min(iter->first, startSlot);
  162. endSlot = std::max(iter->first, endSlot);
  163. }
  164. for (auto iter = vertexBuffers.begin(); iter != vertexBuffers.end(); ++iter)
  165. {
  166. buffers[iter->first - startSlot] = iter->second;
  167. }
  168. rs.setVertexBuffers(startSlot, buffers, endSlot - startSlot + 1);
  169. }
  170. rs.setDrawOperation(subMesh.drawOp);
  171. SPtr<IndexBufferCore> indexBuffer = mesh->getIndexBuffer();
  172. UINT32 indexCount = subMesh.indexCount;
  173. rs.setIndexBuffer(indexBuffer);
  174. rs.drawIndexed(subMesh.indexOffset + mesh->getIndexOffset(), indexCount, mesh->getVertexOffset(), vertexData->vertexCount);
  175. mesh->_notifyUsedOnGPU();
  176. }
  177. void RendererUtility::drawScreenQuad(const ViewportCore& viewport, const Rect2& uv, const Vector2I& textureSize)
  178. {
  179. // Note: Consider drawing the quad using a single large triangle for possibly better performance
  180. Rect2I viewArea = viewport.getArea();
  181. Vector3 vertices[4];
  182. vertices[0] = Vector3((float)viewArea.x, (float)viewArea.y, 0.0f);
  183. vertices[1] = Vector3((float)viewArea.x + (float)viewArea.width, (float)viewArea.y, 0.0f);
  184. vertices[2] = Vector3((float)viewArea.x, (float)viewArea.y + (float)viewArea.height, 0.0f);
  185. vertices[3] = Vector3((float)viewArea.x + (float)viewArea.width, (float)viewArea.y + (float)viewArea.height, 0.0f);
  186. Vector2 uvs[4];
  187. uvs[0] = Vector2(uv.x, uv.y);
  188. uvs[1] = Vector2(uv.x + uv.width, uv.y);
  189. uvs[2] = Vector2(uv.x, uv.y + uv.height);
  190. uvs[3] = Vector2(uv.x + uv.width, uv.y + uv.height);
  191. auto targetProps = viewport.getTarget()->getProperties();;
  192. RenderAPICore& rapi = RenderAPICore::instance();
  193. for (int i = 0; i < 4; i++)
  194. {
  195. vertices[i].x = -1.0f + 2.0f * (vertices[i].x + rapi.getHorizontalTexelOffset()) / targetProps.getWidth();
  196. vertices[i].y = 1.0f - 2.0f * (vertices[i].y + rapi.getVerticalTexelOffset()) / targetProps.getHeight();
  197. uvs[i].x /= (float)textureSize.x;
  198. uvs[i].y /= (float)textureSize.y;
  199. }
  200. SPtr<VertexDataDesc> vertexDesc = mFullScreenQuadMesh->getVertexDesc();
  201. MeshDataPtr meshData = bs_shared_ptr_new<MeshData>(4, 6, vertexDesc);
  202. auto vecIter = meshData->getVec3DataIter(VES_POSITION);
  203. for (UINT32 i = 0; i < 4; i++)
  204. vecIter.addValue(vertices[i]);
  205. auto uvIter = meshData->getVec2DataIter(VES_TEXCOORD);
  206. for (UINT32 i = 0; i < 4; i++)
  207. uvIter.addValue(uvs[i]);
  208. auto indices = meshData->getIndices32();
  209. indices[0] = 0;
  210. indices[1] = 1;
  211. indices[2] = 2;
  212. indices[3] = 1;
  213. indices[4] = 3;
  214. indices[5] = 2;
  215. mFullScreenQuadMesh->writeSubresource(0, *meshData, true, false);
  216. draw(mFullScreenQuadMesh, mFullScreenQuadMesh->getProperties().getSubMesh());
  217. }
  218. RendererUtility& gRendererUtility()
  219. {
  220. return RendererUtility::instance();
  221. }
  222. }