#pragma once #include "drape/texture.hpp" #include #include namespace dp { template class DynamicTexture : public Texture { using Base = Texture; public: ~DynamicTexture() override { ASSERT(m_indexer == nullptr, ()); } ref_ptr FindResource(Key const & key, bool & newResource) override { ASSERT(m_indexer != nullptr, ()); if (key.GetType() != TResourceType) return nullptr; return m_indexer->MapResource(static_cast(key), newResource); } void Create(ref_ptr context, Params const & params) override { ASSERT(Base::IsPowerOfTwo(params.m_width, params.m_height), (params.m_width, params.m_height)); Base::Create(context, params); } void Create(ref_ptr context, Params const & params, ref_ptr data) override { ASSERT(Base::IsPowerOfTwo(params.m_width, params.m_height), (params.m_width, params.m_height)); Base::Create(context, params, data); } void UpdateState(ref_ptr context) override { // Create texture before first uploading. if (!m_isInitialized) { std::vector initData(m_params.m_width * m_params.m_height * GetBytesPerPixel(m_params.m_format), 0); Create(context, m_params, initData.data()); m_isInitialized = true; } ASSERT(m_indexer != nullptr, ()); Bind(context); m_indexer->UploadResources(context, make_ref(this)); } TextureFormat GetFormat() const override { return m_params.m_format; } uint32_t GetWidth() const override { return m_params.m_width; } uint32_t GetHeight() const override { return m_params.m_height; } float GetS(uint32_t x) const override { return static_cast(x) / m_params.m_width; } float GetT(uint32_t y) const override { return static_cast(y) / m_params.m_height; } uint32_t GetID() const override { return m_isInitialized ? Texture::GetID() : 0; } void Bind(ref_ptr context) const override { if (m_isInitialized) Texture::Bind(context); } void SetFilter(TextureFilter filter) override { if (m_isInitialized) Texture::SetFilter(filter); } protected: DynamicTexture() : m_isInitialized(false) {} struct DynamicTextureParams { m2::PointU m_size; dp::TextureFormat m_format = dp::TextureFormat::Unspecified; TextureFilter m_filter = dp::TextureFilter::Nearest; bool m_usePixelBuffer = false; }; void Init(ref_ptr allocator, ref_ptr indexer, DynamicTextureParams const & params) { m_indexer = indexer; m_params.m_allocator = allocator; m_params.m_width = params.m_size.x; m_params.m_height = params.m_size.y; m_params.m_format = params.m_format; m_params.m_filter = params.m_filter; m_params.m_usePixelBuffer = params.m_usePixelBuffer; m_params.m_isMutable = true; } void Reset() { m_indexer = nullptr; } ref_ptr m_indexer; Texture::Params m_params; std::atomic m_isInitialized; }; } // namespace dp