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