BsTextureRTTI.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #pragma once
  2. #include "BsCorePrerequisites.h"
  3. #include "BsRTTIType.h"
  4. #include "BsTexture.h"
  5. #include "BsManagedDataBlock.h"
  6. #include "BsMath.h"
  7. #include "BsCoreApplication.h"
  8. #include "BsCoreThread.h"
  9. #include "BsRenderSystem.h"
  10. #include "BsTextureManager.h"
  11. #include "BsPixelData.h"
  12. namespace BansheeEngine
  13. {
  14. class BS_CORE_EXPORT TextureRTTI : public RTTIType<Texture, Resource, TextureRTTI>
  15. {
  16. private:
  17. BS_SETGET_MEMBER(mSize, UINT32, Texture)
  18. BS_SETGET_MEMBER(mHeight, UINT32, Texture)
  19. BS_SETGET_MEMBER(mWidth, UINT32, Texture)
  20. BS_SETGET_MEMBER(mDepth, UINT32, Texture)
  21. BS_SETGET_MEMBER(mNumMipmaps, UINT32, Texture)
  22. BS_SETGET_MEMBER(mHwGamma, bool, Texture)
  23. BS_SETGET_MEMBER(mMultisampleCount, UINT32, Texture)
  24. BS_SETGET_MEMBER(mMultisampleHint, String, Texture)
  25. BS_SETGET_MEMBER(mTextureType, TextureType, Texture)
  26. BS_SETGET_MEMBER(mFormat, PixelFormat, Texture)
  27. INT32& getUsage(Texture* obj) { return obj->mUsage; }
  28. void setUsage(Texture* obj, INT32& val)
  29. {
  30. // Render target and depth stencil texture formats are for in-memory use only
  31. // and don't make sense when serialized
  32. if (val == TU_DEPTHSTENCIL || val == TU_RENDERTARGET)
  33. obj->mUsage = TU_STATIC;
  34. else
  35. obj->mUsage = val;
  36. }
  37. #define BS_ADD_PLAINFIELD(name, id, parentType) \
  38. addPlainField(#name, id##, &##parentType##::get##name, &##parentType##::Set##name);
  39. PixelDataPtr getPixelData(Texture* obj, UINT32 idx)
  40. {
  41. UINT32 face = (size_t)Math::floor(idx / (float)(obj->getNumMipmaps() + 1));
  42. UINT32 mipmap = idx % (obj->getNumMipmaps() + 1);
  43. UINT32 subresourceIdx = obj->mapToSubresourceIdx(face, mipmap);
  44. PixelDataPtr pixelData = obj->allocateSubresourceBuffer(subresourceIdx);
  45. GpuResourcePtr sharedTexPtr = std::static_pointer_cast<GpuResource>(obj->getThisPtr());
  46. // We want the data right away so queue directly to main core thread queue and block until we get it
  47. pixelData->_lock();
  48. gCoreThread().queueReturnCommand(
  49. std::bind(&RenderSystem::readSubresource, RenderSystem::instancePtr(), sharedTexPtr, subresourceIdx,
  50. std::static_pointer_cast<GpuResourceData>(pixelData), std::placeholders::_1), true);
  51. return pixelData;
  52. }
  53. void setPixelData(Texture* obj, UINT32 idx, PixelDataPtr data)
  54. {
  55. Vector<PixelDataPtr>* pixelData = any_cast<Vector<PixelDataPtr>*>(obj->mRTTIData);
  56. (*pixelData)[idx] = data;
  57. }
  58. UINT32 getPixelDataArraySize(Texture* obj)
  59. {
  60. return obj->getNumFaces() * (obj->getNumMipmaps() + 1);
  61. }
  62. void setPixelDataArraySize(Texture* obj, UINT32 size)
  63. {
  64. Vector<PixelDataPtr>* pixelData = any_cast<Vector<PixelDataPtr>*>(obj->mRTTIData);
  65. pixelData->resize(size);
  66. }
  67. public:
  68. TextureRTTI()
  69. {
  70. BS_ADD_PLAINFIELD(mSize, 0, TextureRTTI)
  71. BS_ADD_PLAINFIELD(mHeight, 2, TextureRTTI)
  72. BS_ADD_PLAINFIELD(mWidth, 3, TextureRTTI)
  73. BS_ADD_PLAINFIELD(mDepth, 4, TextureRTTI)
  74. BS_ADD_PLAINFIELD(mNumMipmaps, 5, TextureRTTI)
  75. BS_ADD_PLAINFIELD(mHwGamma, 6, TextureRTTI)
  76. BS_ADD_PLAINFIELD(mMultisampleCount, 7, TextureRTTI)
  77. BS_ADD_PLAINFIELD(mMultisampleHint, 8, TextureRTTI)
  78. BS_ADD_PLAINFIELD(mTextureType, 9, TextureRTTI)
  79. BS_ADD_PLAINFIELD(mFormat, 10, TextureRTTI)
  80. addPlainField("mUsage", 11, &TextureRTTI::getUsage, &TextureRTTI::setUsage);
  81. addReflectablePtrArrayField("mPixelData", 12, &TextureRTTI::getPixelData, &TextureRTTI::getPixelDataArraySize,
  82. &TextureRTTI::setPixelData, &TextureRTTI::setPixelDataArraySize);
  83. }
  84. virtual void onDeserializationStarted(IReflectable* obj)
  85. {
  86. Texture* texture = static_cast<Texture*>(obj);
  87. texture->mRTTIData = bs_new<Vector<PixelDataPtr>, PoolAlloc>();
  88. }
  89. virtual void onDeserializationEnded(IReflectable* obj)
  90. {
  91. Texture* texture = static_cast<Texture*>(obj);
  92. if(texture->mRTTIData.empty())
  93. return;
  94. // A bit clumsy initializing with already set values, but I feel its better than complicating things and storing the values
  95. // in mRTTIData.
  96. texture->initialize(texture->getTextureType(), texture->getWidth(), texture->getHeight(), texture->getDepth(),
  97. texture->getNumMipmaps(), texture->getFormat(), texture->getUsage(), texture->isHardwareGammaEnabled(),
  98. texture->getMultisampleCount(), texture->getMultisampleHint());
  99. Vector<PixelDataPtr>* pixelData = any_cast<Vector<PixelDataPtr>*>(texture->mRTTIData);
  100. for(size_t i = 0; i < pixelData->size(); i++)
  101. {
  102. UINT32 face = (size_t)Math::floor(i / (float)(texture->getNumMipmaps() + 1));
  103. UINT32 mipmap = i % (texture->getNumMipmaps() + 1);
  104. UINT32 subresourceIdx = texture->mapToSubresourceIdx(face, mipmap);
  105. GpuResourcePtr sharedTexPtr = std::static_pointer_cast<GpuResource>(texture->getThisPtr());
  106. pixelData->at(i)->_lock();
  107. gCoreThread().queueReturnCommand(std::bind(&RenderSystem::writeSubresource, RenderSystem::instancePtr(),
  108. sharedTexPtr, subresourceIdx, pixelData->at(i), false, std::placeholders::_1));
  109. }
  110. bs_delete<PoolAlloc>(pixelData);
  111. texture->mRTTIData = nullptr;
  112. }
  113. virtual const String& getRTTIName()
  114. {
  115. static String name = "Texture";
  116. return name;
  117. }
  118. virtual UINT32 getRTTIId()
  119. {
  120. return TID_Texture;
  121. }
  122. virtual std::shared_ptr<IReflectable> newRTTIObject()
  123. {
  124. return TextureManager::instance()._createEmpty();
  125. }
  126. };
  127. }