BsRenderer.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #include "BsRenderer.h"
  2. #include "BsCoreThread.h"
  3. #include "BsRenderSystem.h"
  4. #include "BsMaterialProxy.h"
  5. #include "BsMeshProxy.h"
  6. #include "BsMesh.h"
  7. #include "BsBlendState.h"
  8. #include "BsDepthStencilState.h"
  9. #include "BsRasterizerState.h"
  10. namespace BansheeEngine
  11. {
  12. void Renderer::setPass(const MaterialProxy& material, UINT32 passIdx)
  13. {
  14. THROW_IF_NOT_CORE_THREAD;
  15. RenderSystem& rs = RenderSystem::instance();
  16. const MaterialProxyPass& pass = material.passes[passIdx];
  17. if (pass.vertexProg)
  18. {
  19. rs.bindGpuProgram(pass.vertexProg);
  20. rs.bindGpuParams(GPT_VERTEX_PROGRAM, material.params[pass.vertexProgParamsIdx]);
  21. }
  22. else
  23. rs.unbindGpuProgram(GPT_VERTEX_PROGRAM);
  24. if (pass.fragmentProg)
  25. {
  26. rs.bindGpuProgram(pass.fragmentProg);
  27. rs.bindGpuParams(GPT_FRAGMENT_PROGRAM, material.params[pass.fragmentProgParamsIdx]);
  28. }
  29. else
  30. rs.unbindGpuProgram(GPT_FRAGMENT_PROGRAM);
  31. if (pass.geometryProg)
  32. {
  33. rs.bindGpuProgram(pass.geometryProg);
  34. rs.bindGpuParams(GPT_GEOMETRY_PROGRAM, material.params[pass.geometryProgParamsIdx]);
  35. }
  36. else
  37. rs.unbindGpuProgram(GPT_GEOMETRY_PROGRAM);
  38. if (pass.hullProg)
  39. {
  40. rs.bindGpuProgram(pass.hullProg);
  41. rs.bindGpuParams(GPT_HULL_PROGRAM, material.params[pass.hullProgParamsIdx]);
  42. }
  43. else
  44. rs.unbindGpuProgram(GPT_HULL_PROGRAM);
  45. if (pass.domainProg)
  46. {
  47. rs.bindGpuProgram(pass.domainProg);
  48. rs.bindGpuParams(GPT_DOMAIN_PROGRAM, material.params[pass.domainProgParamsIdx]);
  49. }
  50. else
  51. rs.unbindGpuProgram(GPT_DOMAIN_PROGRAM);
  52. if (pass.computeProg)
  53. {
  54. rs.bindGpuProgram(pass.computeProg);
  55. rs.bindGpuParams(GPT_COMPUTE_PROGRAM, material.params[pass.computeProgParamsIdx]);
  56. }
  57. else
  58. rs.unbindGpuProgram(GPT_COMPUTE_PROGRAM);
  59. // TODO - Try to limit amount of state changes, if previous state is already the same
  60. // Set up non-texture related pass settings
  61. if (pass.blendState != nullptr)
  62. rs.setBlendState(pass.blendState.getInternalPtr());
  63. else
  64. rs.setBlendState(BlendState::getDefault());
  65. if (pass.depthStencilState != nullptr)
  66. rs.setDepthStencilState(pass.depthStencilState.getInternalPtr(), pass.stencilRefValue);
  67. else
  68. rs.setDepthStencilState(DepthStencilState::getDefault(), pass.stencilRefValue);
  69. if (pass.rasterizerState != nullptr)
  70. rs.setRasterizerState(pass.rasterizerState.getInternalPtr());
  71. else
  72. rs.setRasterizerState(RasterizerState::getDefault());
  73. }
  74. void Renderer::draw(const MeshProxy& meshProxy)
  75. {
  76. THROW_IF_NOT_CORE_THREAD;
  77. RenderSystem& rs = RenderSystem::instance();
  78. MeshBasePtr mesh;
  79. if (!meshProxy.mesh.expired())
  80. mesh = meshProxy.mesh.lock();
  81. else
  82. return;
  83. std::shared_ptr<VertexData> vertexData = mesh->_getVertexData();
  84. rs.setVertexDeclaration(vertexData->vertexDeclaration);
  85. auto vertexBuffers = vertexData->getBuffers();
  86. if (vertexBuffers.size() > 0)
  87. {
  88. VertexBufferPtr buffers[MAX_BOUND_VERTEX_BUFFERS];
  89. UINT32 endSlot = 0;
  90. UINT32 startSlot = MAX_BOUND_VERTEX_BUFFERS;
  91. for (auto iter = vertexBuffers.begin(); iter != vertexBuffers.end(); ++iter)
  92. {
  93. if (iter->first >= MAX_BOUND_VERTEX_BUFFERS)
  94. BS_EXCEPT(InvalidParametersException, "Buffer index out of range");
  95. startSlot = std::min(iter->first, startSlot);
  96. endSlot = std::max(iter->first, endSlot);
  97. }
  98. for (auto iter = vertexBuffers.begin(); iter != vertexBuffers.end(); ++iter)
  99. {
  100. buffers[iter->first - startSlot] = iter->second;
  101. }
  102. rs.setVertexBuffers(startSlot, buffers, endSlot - startSlot + 1);
  103. }
  104. SubMesh subMesh = meshProxy.subMesh;
  105. rs.setDrawOperation(subMesh.drawOp);
  106. IndexBufferPtr indexBuffer = mesh->_getIndexBuffer();
  107. UINT32 indexCount = subMesh.indexCount;
  108. if (indexCount == 0)
  109. indexCount = indexBuffer->getNumIndices();
  110. rs.setIndexBuffer(indexBuffer);
  111. rs.drawIndexed(subMesh.indexOffset + mesh->_getIndexOffset(), indexCount, mesh->_getVertexOffset(), vertexData->vertexCount);
  112. mesh->_notifyUsedOnGPU();
  113. }
  114. }