| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #pragma once
- #include "BsCorePrerequisites.h"
- #include "BsRTTIType.h"
- #include "BsTexture.h"
- #include "BsMath.h"
- #include "BsCoreThread.h"
- #include "BsRenderAPI.h"
- #include "BsTextureManager.h"
- #include "BsPixelData.h"
- namespace BansheeEngine
- {
- /** @cond RTTI */
- /** @addtogroup RTTI-Impl-Core
- * @{
- */
- class BS_CORE_EXPORT TextureRTTI : public RTTIType<Texture, Resource, TextureRTTI>
- {
- private:
- BS_BEGIN_RTTI_MEMBERS
- BS_RTTI_MEMBER_PLAIN(mSize, 0)
- BS_RTTI_MEMBER_PLAIN_NAMED(height, mProperties.mDesc.height, 2)
- BS_RTTI_MEMBER_PLAIN_NAMED(width, mProperties.mDesc.width, 3)
- BS_RTTI_MEMBER_PLAIN_NAMED(depth, mProperties.mDesc.depth, 4)
- BS_RTTI_MEMBER_PLAIN_NAMED(numMips, mProperties.mDesc.numMips, 5)
- BS_RTTI_MEMBER_PLAIN_NAMED(hwGamma, mProperties.mDesc.hwGamma, 6)
- BS_RTTI_MEMBER_PLAIN_NAMED(numSamples, mProperties.mDesc.numSamples, 7)
- BS_RTTI_MEMBER_PLAIN_NAMED(type, mProperties.mDesc.type, 9)
- BS_RTTI_MEMBER_PLAIN_NAMED(format, mProperties.mDesc.format, 10)
- BS_END_RTTI_MEMBERS
- INT32& getUsage(Texture* obj) { return obj->mProperties.mDesc.usage; }
- void setUsage(Texture* obj, INT32& val)
- {
- // Render target and depth stencil texture formats are for in-memory use only
- // and don't make sense when serialized
- if (val == TU_DEPTHSTENCIL || val == TU_RENDERTARGET)
- obj->mProperties.mDesc.usage = TU_STATIC;
- else
- obj->mProperties.mDesc.usage = val;
- }
- #define BS_ADD_PLAINFIELD(name, id, parentType) \
- addPlainField(#name, id##, &##parentType##::get##name, &##parentType##::Set##name);
- SPtr<PixelData> getPixelData(Texture* obj, UINT32 idx)
- {
- UINT32 face = (size_t)Math::floor(idx / (float)(obj->mProperties.getNumMipmaps() + 1));
- UINT32 mipmap = idx % (obj->mProperties.getNumMipmaps() + 1);
- UINT32 subresourceIdx = obj->mProperties.mapToSubresourceIdx(face, mipmap);
- SPtr<PixelData> pixelData = obj->mProperties.allocateSubresourceBuffer(subresourceIdx);
- obj->readSubresource(gCoreAccessor(), subresourceIdx, pixelData);
- gCoreAccessor().submitToCoreThread(true);
- return pixelData;
- }
- void setPixelData(Texture* obj, UINT32 idx, SPtr<PixelData> data)
- {
- Vector<SPtr<PixelData>>* pixelData = any_cast<Vector<SPtr<PixelData>>*>(obj->mRTTIData);
- (*pixelData)[idx] = data;
- }
- UINT32 getPixelDataArraySize(Texture* obj)
- {
- return obj->mProperties.getNumFaces() * (obj->mProperties.getNumMipmaps() + 1);
- }
- void setPixelDataArraySize(Texture* obj, UINT32 size)
- {
- Vector<SPtr<PixelData>>* pixelData = any_cast<Vector<SPtr<PixelData>>*>(obj->mRTTIData);
- pixelData->resize(size);
- }
- public:
- TextureRTTI()
- :mInitMembers(this)
- {
- addPlainField("mUsage", 11, &TextureRTTI::getUsage, &TextureRTTI::setUsage);
- addReflectablePtrArrayField("mPixelData", 12, &TextureRTTI::getPixelData, &TextureRTTI::getPixelDataArraySize,
- &TextureRTTI::setPixelData, &TextureRTTI::setPixelDataArraySize, RTTI_Flag_SkipInReferenceSearch);
- }
- void onDeserializationStarted(IReflectable* obj, const UnorderedMap<String, UINT64>& params) override
- {
- Texture* texture = static_cast<Texture*>(obj);
- texture->mRTTIData = bs_new<Vector<SPtr<PixelData>>>();
- }
- void onDeserializationEnded(IReflectable* obj, const UnorderedMap<String, UINT64>& params) override
- {
- Texture* texture = static_cast<Texture*>(obj);
- if(texture->mRTTIData.empty())
- return;
- TextureProperties& texProps = texture->mProperties;
- // Update pixel format if needed as it's possible the original texture was saved using some other render API
- // that has an unsupported format.
- PixelFormat originalFormat = texProps.getFormat();
- PixelFormat validFormat = TextureManager::instance().getNativeFormat(
- texProps.getTextureType(), texProps.getFormat(), texProps.getUsage(), texProps.isHardwareGammaEnabled());
- Vector<SPtr<PixelData>>* pixelData = any_cast<Vector<SPtr<PixelData>>*>(texture->mRTTIData);
- if (originalFormat != validFormat)
- {
- texProps.mDesc.format = validFormat;
- for (size_t i = 0; i < pixelData->size(); i++)
- {
- SPtr<PixelData> origData = pixelData->at(i);
- SPtr<PixelData> newData = PixelData::create(origData->getWidth(), origData->getHeight(), origData->getDepth(), validFormat);
- PixelUtil::bulkPixelConversion(*origData, *newData);
- (*pixelData)[i] = newData;
- }
- }
- // A bit clumsy initializing with already set values, but I feel its better than complicating things and storing the values
- // in mRTTIData.
- texture->initialize();
- for(size_t i = 0; i < pixelData->size(); i++)
- {
- UINT32 face = (size_t)Math::floor(i / (float)(texProps.getNumMipmaps() + 1));
- UINT32 mipmap = i % (texProps.getNumMipmaps() + 1);
- UINT32 subresourceIdx = texProps.mapToSubresourceIdx(face, mipmap);
- texture->writeSubresource(gCoreAccessor(), subresourceIdx, pixelData->at(i), false);
- }
- bs_delete(pixelData);
- texture->mRTTIData = nullptr;
- }
- const String& getRTTIName() override
- {
- static String name = "Texture";
- return name;
- }
- UINT32 getRTTIId() override
- {
- return TID_Texture;
- }
- SPtr<IReflectable> newRTTIObject() override
- {
- return TextureManager::instance()._createEmpty();
- }
- };
- /** @} */
- /** @endcond */
- }
|