BsMultiRenderTexture.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #include "BsMultiRenderTexture.h"
  2. #include "BsTexture.h"
  3. #include "BsException.h"
  4. #include "BsDebug.h"
  5. #include "BsCoreThread.h"
  6. #include "BsTextureManager.h"
  7. namespace BansheeEngine
  8. {
  9. void MultiRenderTextureProperties::copyToBuffer(UINT8* buffer) const
  10. {
  11. *(MultiRenderTextureProperties*)buffer = *this;
  12. }
  13. void MultiRenderTextureProperties::copyFromBuffer(UINT8* buffer)
  14. {
  15. *this = *(MultiRenderTextureProperties*)buffer;
  16. }
  17. UINT32 MultiRenderTextureProperties::getSize() const
  18. {
  19. return sizeof(MultiRenderTextureProperties);
  20. }
  21. MultiRenderTextureCore::MultiRenderTextureCore(MultiRenderTexture* parent, MultiRenderTextureProperties* properties, const MULTI_RENDER_TEXTURE_DESC& desc)
  22. :RenderTargetCore(parent, properties), mDesc(desc)
  23. { }
  24. MultiRenderTextureCore::~MultiRenderTextureCore()
  25. { }
  26. void MultiRenderTextureCore::initialize()
  27. {
  28. RenderTargetCore::initialize();
  29. mColorSurfaces.resize(BS_MAX_MULTIPLE_RENDER_TARGETS);
  30. for (size_t i = 0; i < mDesc.colorSurfaces.size(); i++)
  31. {
  32. if (mDesc.colorSurfaces[i].texture != nullptr)
  33. {
  34. if (i >= BS_MAX_MULTIPLE_RENDER_TARGETS)
  35. {
  36. LOGWRN("Render texture index is larger than the maximum number of supported render targets. Index: " + toString((int)i) +
  37. ". Max. number of render targets: " + toString(BS_MAX_MULTIPLE_RENDER_TARGETS));
  38. continue;
  39. }
  40. TexturePtr texture = mDesc.colorSurfaces[i].texture;
  41. if (texture->getUsage() != TU_RENDERTARGET)
  42. BS_EXCEPT(InvalidParametersException, "Provided texture is not created with render target usage.");
  43. mColorSurfaces[i] = Texture::requestView(texture, mDesc.colorSurfaces[i].mipLevel, 1,
  44. mDesc.colorSurfaces[i].face, 1, GVU_RENDERTARGET);
  45. }
  46. }
  47. if (mDesc.depthStencilSurface.texture != nullptr)
  48. {
  49. TexturePtr texture = mDesc.depthStencilSurface.texture;
  50. if (texture->getUsage() != TU_DEPTHSTENCIL)
  51. BS_EXCEPT(InvalidParametersException, "Provided texture is not created with depth stencil usage.");
  52. mDepthStencilSurface = Texture::requestView(texture, mDesc.depthStencilSurface.mipLevel, 1,
  53. mDesc.depthStencilSurface.face, 1, GVU_DEPTHSTENCIL);
  54. }
  55. throwIfBuffersDontMatch();
  56. }
  57. void MultiRenderTextureCore::destroy()
  58. {
  59. for (auto iter = mColorSurfaces.begin(); iter != mColorSurfaces.end(); ++iter)
  60. {
  61. if (*iter != nullptr)
  62. Texture::releaseView(*iter);
  63. }
  64. if (mDepthStencilSurface != nullptr)
  65. Texture::releaseView(mDepthStencilSurface);
  66. RenderTargetCore::destroy();
  67. }
  68. void MultiRenderTextureCore::throwIfBuffersDontMatch() const
  69. {
  70. TextureViewPtr firstSurfaceDesc = nullptr;
  71. for(size_t i = 0; i < mColorSurfaces.size(); i++)
  72. {
  73. if(mColorSurfaces[i] == nullptr)
  74. continue;
  75. if(firstSurfaceDesc == nullptr)
  76. {
  77. firstSurfaceDesc = mColorSurfaces[i];
  78. continue;
  79. }
  80. if(mColorSurfaces[i]->getTexture()->getWidth() != firstSurfaceDesc->getTexture()->getWidth() ||
  81. mColorSurfaces[i]->getTexture()->getHeight() != firstSurfaceDesc->getTexture()->getHeight() ||
  82. mColorSurfaces[i]->getTexture()->getMultisampleCount() != firstSurfaceDesc->getTexture()->getMultisampleCount())
  83. {
  84. String errorInfo = "\nWidth: " + toString(mColorSurfaces[i]->getTexture()->getWidth()) + "/" + toString(firstSurfaceDesc->getTexture()->getWidth());
  85. errorInfo += "\nHeight: " + toString(mColorSurfaces[i]->getTexture()->getHeight()) + "/" + toString(firstSurfaceDesc->getTexture()->getHeight());
  86. errorInfo += "\nMultisample Count: " + toString(mColorSurfaces[i]->getTexture()->getMultisampleCount()) + "/" + toString(firstSurfaceDesc->getTexture()->getMultisampleCount());
  87. BS_EXCEPT(InvalidParametersException, "Provided texture and depth stencil buffer don't match!" + errorInfo);
  88. }
  89. }
  90. if(firstSurfaceDesc == nullptr)
  91. return;
  92. if(firstSurfaceDesc->getTexture()->getTextureType() != TEX_TYPE_2D)
  93. BS_EXCEPT(NotImplementedException, "Render textures are currently only implemented for 2D surfaces.");
  94. if((firstSurfaceDesc->getFirstArraySlice() + firstSurfaceDesc->getNumArraySlices()) >= firstSurfaceDesc->getTexture()->getNumFaces())
  95. {
  96. BS_EXCEPT(InvalidParametersException, "Provided number of faces is out of range. Face: " +
  97. toString(firstSurfaceDesc->getFirstArraySlice() + firstSurfaceDesc->getNumArraySlices()) + ". Max num faces: " + toString(firstSurfaceDesc->getTexture()->getNumFaces()));
  98. }
  99. if(firstSurfaceDesc->getMostDetailedMip() >= firstSurfaceDesc->getTexture()->getNumMipmaps())
  100. {
  101. BS_EXCEPT(InvalidParametersException, "Provided number of mip maps is out of range. Mip level: " +
  102. toString(firstSurfaceDesc->getMostDetailedMip()) + ". Max num mipmaps: " + toString(firstSurfaceDesc->getTexture()->getNumMipmaps()));
  103. }
  104. if(mDepthStencilSurface == nullptr)
  105. return;
  106. if(mDepthStencilSurface->getTexture()->getWidth() != firstSurfaceDesc->getTexture()->getWidth() ||
  107. mDepthStencilSurface->getTexture()->getHeight() != firstSurfaceDesc->getTexture()->getHeight() ||
  108. mDepthStencilSurface->getTexture()->getMultisampleCount() != firstSurfaceDesc->getTexture()->getMultisampleCount())
  109. {
  110. String errorInfo = "\nWidth: " + toString(mDepthStencilSurface->getTexture()->getWidth()) + "/" + toString(firstSurfaceDesc->getTexture()->getWidth());
  111. errorInfo += "\nHeight: " + toString(mDepthStencilSurface->getTexture()->getHeight()) + "/" + toString(firstSurfaceDesc->getTexture()->getHeight());
  112. errorInfo += "\nMultisample Count: " + toString(mDepthStencilSurface->getTexture()->getMultisampleCount()) + "/" + toString(firstSurfaceDesc->getTexture()->getMultisampleCount());
  113. BS_EXCEPT(InvalidParametersException, "Provided texture and depth stencil buffer don't match!" + errorInfo);
  114. }
  115. }
  116. void MultiRenderTextureCore::copyToMemory(PixelData &dst, FrameBuffer buffer)
  117. {
  118. throw std::exception("The method or operation is not implemented.");
  119. }
  120. MultiRenderTexture* MultiRenderTextureCore::getNonCore() const
  121. {
  122. return static_cast<MultiRenderTexture*>(mParent);
  123. }
  124. void MultiRenderTexture::initialize(const MULTI_RENDER_TEXTURE_DESC& desc)
  125. {
  126. mDesc = desc;
  127. mProperties = createProperties();
  128. MultiRenderTextureProperties* properties = static_cast<MultiRenderTextureProperties*>(mProperties);
  129. for (size_t i = 0; i < desc.colorSurfaces.size(); i++)
  130. {
  131. TexturePtr texture = desc.colorSurfaces[i].texture;
  132. if (texture != nullptr)
  133. {
  134. properties->mWidth = texture->getWidth();
  135. properties->mHeight = texture->getWidth();
  136. properties->mColorDepth = BansheeEngine::PixelUtil::getNumElemBits(texture->getFormat());
  137. properties->mActive = true;
  138. properties->mHwGamma = texture->isHardwareGammaEnabled();
  139. properties->mMultisampleCount = texture->getMultisampleCount();
  140. properties->mIsWindow = false;
  141. properties->mRequiresTextureFlipping = requiresTextureFlipping();
  142. break;
  143. }
  144. }
  145. RenderTarget::initialize();
  146. }
  147. const MultiRenderTextureProperties& MultiRenderTexture::getProperties() const
  148. {
  149. THROW_IF_CORE_THREAD;
  150. return static_cast<const MultiRenderTextureProperties&>(RenderTarget::getProperties());
  151. }
  152. MultiRenderTextureCore* MultiRenderTexture::getCore() const
  153. {
  154. return static_cast<MultiRenderTextureCore*>(mCoreSpecific);
  155. }
  156. MultiRenderTexturePtr MultiRenderTexture::create(const MULTI_RENDER_TEXTURE_DESC& desc)
  157. {
  158. return TextureManager::instance().createMultiRenderTexture(desc);
  159. }
  160. }