RenderCore
This commit is contained in:
82
Src/RenderCore/imp/cpp/TextureAtlas.cpp
Normal file
82
Src/RenderCore/imp/cpp/TextureAtlas.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <RenderCore/TextureAtlas.hpp>
|
||||
|
||||
namespace ia::iae
|
||||
{
|
||||
RDC_TextureAtlas::RDC_TextureAtlas(IN CONST Vector<Handle> &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
|
||||
Reference in New Issue
Block a user