// 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) { const auto d = (ImageData *) _image; m_atlasSize.x += d->Width; if (d->Height > m_atlasSize.y) m_atlasSize.y = d->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) { const auto d = (ImageData *) _image; for (INT32 y = 0; y < d->Height; y++) ia_memcpy(&pixels[(atlasCursor + (y * m_atlasSize.x)) * 4], &d->Pixels[y * d->Width * 4], d->Width * 4); m_texCoordMap[_image] = Vec2(((FLOAT32) atlasCursor) / ((FLOAT32) m_atlasSize.x), 0.0f); atlasCursor += d->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 Handle _image, IN INT32 tileIndexX, IN INT32 tileIndexY, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset) { const auto d = (ImageData *) _image; const auto &t = m_texCoordMap[_image]; const auto pX = ((tileIndexX + uvOffset.x) * ((FLOAT32) d->TileWidth)) * m_inverseAtlasSize.x; const auto pY = ((tileIndexY + uvOffset.y) * ((FLOAT32) d->TileHeight)) * m_inverseAtlasSize.y; auto texCoords = Vec4(t.x + pX, t.y + pY, d->TileWidth * m_inverseAtlasSize.x, d->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