CmMultiRenderTexture.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include "CmMultiRenderTexture.h"
  2. #include "CmTexture.h"
  3. #include "CmException.h"
  4. namespace CamelotEngine
  5. {
  6. MultiRenderTexture::MultiRenderTexture()
  7. {
  8. mSurfaces.resize(CM_MAX_MULTIPLE_RENDER_TARGETS);
  9. }
  10. void MultiRenderTexture::setColorSurface(UINT32 surfaceIdx, TexturePtr texture, UINT32 face, UINT32 numFaces, UINT32 mipLevel)
  11. {
  12. if(surfaceIdx < 0 || surfaceIdx >= CM_MAX_MULTIPLE_RENDER_TARGETS)
  13. CM_EXCEPT(InvalidParametersException, "Invalid surface index. 0 <= " + toString(surfaceIdx) + " < CM_MAX_MULTIPLE_RENDER_TARGETS");
  14. if(texture != nullptr && texture->getUsage() != TU_RENDERTARGET)
  15. CM_EXCEPT(InvalidParametersException, "Provided texture is not created with render target usage.");
  16. mSurfaces[surfaceIdx].texture = texture;
  17. if(texture == nullptr)
  18. {
  19. setColorSurfaceImpl(surfaceIdx, texture, face, numFaces, mipLevel);
  20. return;
  21. }
  22. mPriority = CM_REND_TO_TEX_RT_GROUP;
  23. mWidth = texture->getWidth();
  24. mHeight = texture->getWidth();
  25. mColorDepth = CamelotEngine::PixelUtil::getNumElemBits(texture->getFormat());
  26. mActive = true;
  27. mHwGamma = texture->isHardwareGammaEnabled();
  28. mFSAA = texture->getFSAA();
  29. mFSAAHint = texture->getFSAAHint();
  30. mSurfaces[surfaceIdx].format = texture->getFormat();
  31. mSurfaces[surfaceIdx].face = face;
  32. mSurfaces[surfaceIdx].numFaces = numFaces;
  33. mSurfaces[surfaceIdx].mipLevel = mipLevel;
  34. throwIfBuffersDontMatch();
  35. setColorSurfaceImpl(surfaceIdx, texture, face, numFaces, mipLevel);
  36. }
  37. void MultiRenderTexture::setDepthStencilSurface(TexturePtr depthStencilSurface)
  38. {
  39. if(depthStencilSurface != nullptr && depthStencilSurface->getUsage() != TU_DEPTHSTENCIL)
  40. CM_EXCEPT(InvalidParametersException, "Provided texture is not created with depth stencil usage.");
  41. mDepthStencilSurface = depthStencilSurface;
  42. throwIfBuffersDontMatch();
  43. setDepthStencilImpl(depthStencilSurface);
  44. }
  45. void MultiRenderTexture::throwIfBuffersDontMatch() const
  46. {
  47. const SurfaceDesc* firstSurfaceDesc = nullptr;
  48. for(size_t i = 0; i < mSurfaces.size(); i++)
  49. {
  50. if(mSurfaces[i].texture == nullptr)
  51. continue;
  52. if(firstSurfaceDesc == nullptr)
  53. {
  54. firstSurfaceDesc = &mSurfaces[i];
  55. continue;
  56. }
  57. if(mSurfaces[i].texture->getWidth() != firstSurfaceDesc->texture->getWidth() ||
  58. mSurfaces[i].texture->getHeight() != firstSurfaceDesc->texture->getHeight() ||
  59. mSurfaces[i].texture->getFSAA() != firstSurfaceDesc->texture->getFSAA() ||
  60. mSurfaces[i].texture->getFSAAHint() != firstSurfaceDesc->texture->getFSAAHint())
  61. {
  62. String errorInfo = "\nWidth: " + toString(mSurfaces[i].texture->getWidth()) + "/" + toString(firstSurfaceDesc->texture->getWidth());
  63. errorInfo += "\nHeight: " + toString(mSurfaces[i].texture->getHeight()) + "/" + toString(firstSurfaceDesc->texture->getHeight());
  64. errorInfo += "\nFSAA: " + toString(mSurfaces[i].texture->getFSAA()) + "/" + toString(firstSurfaceDesc->texture->getFSAA());
  65. errorInfo += "\nFSAAHint: " + mSurfaces[i].texture->getFSAAHint() + "/" + firstSurfaceDesc->texture->getFSAAHint();
  66. CM_EXCEPT(InvalidParametersException, "Provided texture and depth stencil buffer don't match!" + errorInfo);
  67. }
  68. }
  69. if(firstSurfaceDesc == nullptr)
  70. return;
  71. if(firstSurfaceDesc->texture->getTextureType() != TEX_TYPE_2D)
  72. CM_EXCEPT(NotImplementedException, "Render textures are currently only implemented for 2D surfaces.");
  73. if((firstSurfaceDesc->face + firstSurfaceDesc->numFaces) >= firstSurfaceDesc->texture->getNumFaces())
  74. {
  75. CM_EXCEPT(InvalidParametersException, "Provided number of faces is out of range. Face: " +
  76. toString(firstSurfaceDesc->face + firstSurfaceDesc->numFaces) + ". Max num faces: " + toString(firstSurfaceDesc->texture->getNumFaces()));
  77. }
  78. if(firstSurfaceDesc->mipLevel >= firstSurfaceDesc->texture->getNumMipmaps())
  79. {
  80. CM_EXCEPT(InvalidParametersException, "Provided number of mip maps is out of range. Mip level: " +
  81. toString(firstSurfaceDesc->mipLevel) + ". Max num mipmaps: " + toString(firstSurfaceDesc->texture->getNumMipmaps()));
  82. }
  83. if(mDepthStencilSurface == nullptr)
  84. return;
  85. if(mDepthStencilSurface->getWidth() != firstSurfaceDesc->texture->getWidth() ||
  86. mDepthStencilSurface->getHeight() != firstSurfaceDesc->texture->getHeight() ||
  87. mDepthStencilSurface->getFSAA() != firstSurfaceDesc->texture->getFSAA() ||
  88. mDepthStencilSurface->getFSAAHint() != firstSurfaceDesc->texture->getFSAAHint())
  89. {
  90. String errorInfo = "\nWidth: " + toString(mDepthStencilSurface->getWidth()) + "/" + toString(firstSurfaceDesc->texture->getWidth());
  91. errorInfo += "\nHeight: " + toString(mDepthStencilSurface->getHeight()) + "/" + toString(firstSurfaceDesc->texture->getHeight());
  92. errorInfo += "\nFSAA: " + toString(mDepthStencilSurface->getFSAA()) + "/" + toString(firstSurfaceDesc->texture->getFSAA());
  93. errorInfo += "\nFSAAHint: " + mDepthStencilSurface->getFSAAHint() + "/" + firstSurfaceDesc->texture->getFSAAHint();
  94. CM_EXCEPT(InvalidParametersException, "Provided texture and depth stencil buffer don't match!" + errorInfo);
  95. }
  96. }
  97. void MultiRenderTexture::copyContentsToMemory( const PixelData &dst, FrameBuffer buffer /*= FB_AUTO */ )
  98. {
  99. throw std::exception("The method or operation is not implemented.");
  100. }
  101. }