// IAEngine: 2D Game Engine by IA
// Copyright (C) 2025 IASoft (PVT) LTD (oss@iasoft.dev)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
#include
namespace ia::iae
{
RDC_TextureAtlas::RDC_TextureAtlas(IN CONST Vector &images)
{
if (images.empty())
return;
m_atlasSize.x = 0;
m_atlasSize.y = 0;
for (const auto &image : images)
{
m_atlasSize.x += image->Width;
if (image->Height > m_atlasSize.y)
m_atlasSize.y = image->Height;
}
m_inverseAtlasSize = {1.0f / ((FLOAT32) m_atlasSize.x), 1.0f / ((FLOAT32) m_atlasSize.y)};
const auto pixels = new UINT8[m_atlasSize.x * m_atlasSize.y * 4];
INT32 atlasCursor{0};
for (const auto &image : images)
{
for (INT32 y = 0; y < image->Height; y++)
ia_memcpy(&pixels[(atlasCursor + (y * m_atlasSize.x)) * 4], &image->Pixels[y * image->Width * 4], image->Width * 4);
m_texCoordMap[(Handle)(image)] = Vec2(((FLOAT32) atlasCursor) / ((FLOAT32) m_atlasSize.x), 0.0f);
atlasCursor += image->Width;
}
m_texture = new RDC_Texture(RDC_Texture::EType::SAMPLED, m_atlasSize.x, m_atlasSize.y);
m_texture->SetImageData(pixels);
delete[] pixels;
}
RDC_TextureAtlas::~RDC_TextureAtlas()
{
delete m_texture;
}
Vec4 RDC_TextureAtlas::GetTextureCoordinates(IN ImageView* imageView, IN INT32 tileIndexX, IN INT32 tileIndexY, IN BOOL flipH,
IN BOOL flipV, IN Vec2 uvOffset)
{
const auto &t = m_texCoordMap[(Handle)(imageView->ImagePtr)];
const auto pX = ((tileIndexX + uvOffset.x) * ((FLOAT32) imageView->TileWidth)) * m_inverseAtlasSize.x;
const auto pY = ((tileIndexY + uvOffset.y) * ((FLOAT32) imageView->TileHeight)) * m_inverseAtlasSize.y;
auto texCoords = Vec4(t.x + pX, t.y + pY, imageView->TileWidth * m_inverseAtlasSize.x,
imageView->TileHeight * m_inverseAtlasSize.y);
if (flipH)
{
texCoords.x += texCoords.z;
texCoords.z *= -1;
}
if (flipV)
{
texCoords.y += texCoords.w;
texCoords.w *= -1;
}
return texCoords;
}
} // namespace ia::iae