#include "Dx9TextureLoader.h" #include namespace { void CopyMipLevel(image::Texture& texture, const int currentMipLevel, const int faceCount, const uint8_t*& currentDataOffset) { for (auto currentFace = 0; currentFace < faceCount; currentFace++) { const auto mipSize = texture.GetSizeOfMipLevel(currentMipLevel); memcpy(texture.GetBufferForMipLevel(currentMipLevel, currentFace), currentDataOffset, mipSize); currentDataOffset += mipSize; } } } // namespace namespace image { Dx9TextureLoader::Dx9TextureLoader() : m_format(oat::D3DFMT_UNKNOWN), m_type(TextureType::T_2D), m_has_mip_maps(false), m_mip_map_order(MipMapDataOrder::LargestToSmallest), m_width(1u), m_height(1u), m_depth(1u) { } const ImageFormat* Dx9TextureLoader::GetFormatForDx9Format() const { for (const auto* i : format::ALL) { if (i->GetD3DFormat() == m_format) return i; } return nullptr; } Dx9TextureLoader& Dx9TextureLoader::Format(const oat::D3DFORMAT format) { m_format = format; return *this; } Dx9TextureLoader& Dx9TextureLoader::Type(const TextureType textureType) { m_type = textureType; return *this; } Dx9TextureLoader& Dx9TextureLoader::HasMipMaps(const bool hasMipMaps) { m_has_mip_maps = hasMipMaps; return *this; } Dx9TextureLoader& Dx9TextureLoader::MipMapOrder(const MipMapDataOrder mipMapOrder) { m_mip_map_order = mipMapOrder; return *this; } Dx9TextureLoader& Dx9TextureLoader::Width(const unsigned width) { m_width = width; return *this; } Dx9TextureLoader& Dx9TextureLoader::Height(const unsigned height) { m_height = height; return *this; } Dx9TextureLoader& Dx9TextureLoader::Depth(const unsigned depth) { m_depth = depth; return *this; } std::unique_ptr Dx9TextureLoader::LoadTexture(const void* data) { const auto* format = GetFormatForDx9Format(); if (format == nullptr) return nullptr; std::unique_ptr texture; switch (m_type) { case TextureType::T_2D: texture = std::make_unique(format, m_width, m_height, m_has_mip_maps); break; case TextureType::T_3D: texture = std::make_unique(format, m_width, m_height, m_depth, m_has_mip_maps); break; case TextureType::T_CUBE: texture = std::make_unique(format, m_width, m_width, m_has_mip_maps); break; default: return nullptr; } texture->Allocate(); const auto mipMapCount = m_has_mip_maps ? texture->GetMipMapCount() : 1; const auto faceCount = m_type == TextureType::T_CUBE ? 6 : 1; auto* currentDataOffset = static_cast(data); if (m_mip_map_order == MipMapDataOrder::LargestToSmallest) { for (auto currentMipLevel = 0; currentMipLevel < mipMapCount; currentMipLevel++) CopyMipLevel(*texture, currentMipLevel, faceCount, currentDataOffset); } else { for (auto currentMipLevel = mipMapCount - 1; currentMipLevel >= 0; currentMipLevel--) CopyMipLevel(*texture, currentMipLevel, faceCount, currentDataOffset); } return texture; } } // namespace image