BsStaticRenderableHandler.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsStaticRenderableHandler.h"
  4. #include "BsShader.h"
  5. #include "BsGpuParams.h"
  6. #include "BsRenderBeast.h"
  7. #include "BsMaterial.h"
  8. namespace BansheeEngine
  9. {
  10. StaticRenderableHandler::StaticRenderableHandler()
  11. { }
  12. void StaticRenderableHandler::initializeRenderElem(RenderableElement& element)
  13. {
  14. element.rendererData = PerObjectData();
  15. PerObjectData* rendererData = any_cast_unsafe<PerObjectData>(&element.rendererData);
  16. SPtr<ShaderCore> shader = element.material->getShader();
  17. if (shader == nullptr)
  18. {
  19. LOGWRN("Missing shader on material.");
  20. return;
  21. }
  22. const Map<String, SHADER_PARAM_BLOCK_DESC>& paramBlockDescs = shader->getParamBlocks();
  23. String perFrameBlockName;
  24. String perCameraBlockName;
  25. String perObjectBlockName;
  26. for (auto& paramBlockDesc : paramBlockDescs)
  27. {
  28. if (paramBlockDesc.second.rendererSemantic == RBS_PerFrame)
  29. perFrameBlockName = paramBlockDesc.second.name;
  30. else if (paramBlockDesc.second.rendererSemantic == RBS_PerCamera)
  31. perCameraBlockName = paramBlockDesc.second.name;
  32. else if (paramBlockDesc.second.rendererSemantic == RBS_PerObject)
  33. perObjectBlockName = paramBlockDesc.second.name;
  34. }
  35. UINT32 numPasses = element.material->getNumPasses();
  36. for (UINT32 i = 0; i < numPasses; i++)
  37. {
  38. SPtr<PassParametersCore> passParams = element.material->getPassParameters(i);
  39. for (UINT32 j = 0; j < PassParametersCore::NUM_PARAMS; j++)
  40. {
  41. SPtr<GpuParamsCore> gpuParams = passParams->getParamByIdx(j);
  42. if (gpuParams == nullptr)
  43. continue;
  44. const GpuParamDesc& paramsDesc = gpuParams->getParamDesc();
  45. if (perFrameBlockName != "")
  46. {
  47. auto findIter = paramsDesc.paramBlocks.find(perFrameBlockName);
  48. if (findIter != paramsDesc.paramBlocks.end())
  49. {
  50. // TODO - We only compare block sizes but not actual contents. Should I check them too?
  51. // Probably shouldn't concern myself with that here, instead check that on a higher level.
  52. if (findIter->second.blockSize == mPerFrameParams.getDesc().blockSize)
  53. {
  54. UINT32 slotIdx = findIter->second.slot;
  55. element.rendererBuffers.push_back(RenderableElement::BufferBindInfo(i, j, slotIdx, mPerFrameParams.getBuffer()));
  56. }
  57. }
  58. }
  59. if (perCameraBlockName != "")
  60. {
  61. auto findIter = paramsDesc.paramBlocks.find(perCameraBlockName);
  62. if (findIter != paramsDesc.paramBlocks.end())
  63. {
  64. if (findIter->second.blockSize == mPerCameraParams.getDesc().blockSize)
  65. {
  66. UINT32 slotIdx = findIter->second.slot;
  67. element.rendererBuffers.push_back(RenderableElement::BufferBindInfo(i, j, slotIdx, mPerCameraParams.getBuffer()));
  68. }
  69. }
  70. }
  71. if (perObjectBlockName != "")
  72. {
  73. auto findIter = paramsDesc.paramBlocks.find(perObjectBlockName);
  74. if (findIter != paramsDesc.paramBlocks.end())
  75. {
  76. if (findIter->second.blockSize == mPerObjectParams.getDesc().blockSize)
  77. {
  78. UINT32 slotIdx = findIter->second.slot;
  79. rendererData->perObjectBuffers.push_back(RenderableElement::BufferBindInfo(i, j, slotIdx, mPerObjectParams.getBuffer()));
  80. }
  81. }
  82. }
  83. }
  84. }
  85. }
  86. void StaticRenderableHandler::bindPerObjectBuffers(const RenderableElement& element)
  87. {
  88. const PerObjectData* rendererData = any_cast_unsafe<PerObjectData>(&element.rendererData);
  89. for (auto& perObjectBuffer : rendererData->perObjectBuffers)
  90. {
  91. SPtr<GpuParamsCore> params = element.material->getPassParameters(perObjectBuffer.passIdx)->getParamByIdx(perObjectBuffer.paramsIdx);
  92. params->setParamBlockBuffer(perObjectBuffer.slotIdx, perObjectBuffer.buffer);
  93. }
  94. }
  95. void StaticRenderableHandler::updatePerFrameBuffers(float time)
  96. {
  97. mPerFrameParams.gTime.set(time);
  98. }
  99. void StaticRenderableHandler::updatePerCameraBuffers(const CameraShaderData& cameraData)
  100. {
  101. mPerCameraParams.gViewDir.set(cameraData.viewDir);
  102. mPerCameraParams.gViewOrigin.set(cameraData.viewOrigin);
  103. mPerCameraParams.gMatView.set(cameraData.view);
  104. mPerCameraParams.gMatProj.set(cameraData.proj);
  105. mPerCameraParams.gMatViewProj.set(cameraData.viewProj);
  106. mPerCameraParams.gMatInvProj.set(cameraData.invProj);
  107. mPerCameraParams.gMatInvViewProj.set(cameraData.invViewProj);
  108. mPerCameraParams.gMatScreenToWorld.set(cameraData.screenToWorld);
  109. mPerCameraParams.gDeviceZToWorldZ.set(cameraData.deviceZToWorldZ);
  110. mPerCameraParams.gClipToUVScaleOffset.set(cameraData.clipToUVScaleOffset);
  111. }
  112. void StaticRenderableHandler::updatePerObjectBuffers(RenderableElement& element, const RenderableShaderData& data, const Matrix4& wvpMatrix)
  113. {
  114. // TODO - If I kept all the values in the same structure maybe a simple memcpy directly into the constant buffer would be better (i.e. faster)?
  115. mPerObjectParams.gMatWorld.set(data.worldTransform);
  116. mPerObjectParams.gMatInvWorld.set(data.invWorldTransform);
  117. mPerObjectParams.gMatWorldNoScale.set(data.worldNoScaleTransform);
  118. mPerObjectParams.gMatInvWorldNoScale.set(data.invWorldNoScaleTransform);
  119. mPerObjectParams.gWorldDeterminantSign.set(data.worldDeterminantSign);
  120. mPerObjectParams.gMatWorldViewProj.set(wvpMatrix);
  121. }
  122. }