TileSet
This commit is contained in:
@ -19,8 +19,6 @@
|
||||
|
||||
namespace ia::iae
|
||||
{
|
||||
STATIC Vector<Handle> TileTextures;
|
||||
|
||||
TileMapComponent::TileMapComponent(IN Node2D *node) : TextureComponent(node)
|
||||
{
|
||||
}
|
||||
@ -45,30 +43,38 @@ namespace ia::iae
|
||||
TextureComponent::FixedUpdate();
|
||||
}
|
||||
|
||||
VOID TileMapComponent::BeginGridSetup(IN INT32 tileWidth, IN INT32 tileHeight, IN INT32 tileCountX,
|
||||
IN INT32 tileCountY)
|
||||
VOID TileMapComponent::Setup(IN InitializerList<TileEntryDesc> tileDescs, IN INT32 tileWidth, IN INT32 tileHeight,
|
||||
IN INT32 tileCountX, IN INT32 tileCountY)
|
||||
{
|
||||
Vector<Handle> textures;
|
||||
|
||||
m_tileWidth = tileWidth;
|
||||
m_tileHeight = tileHeight;
|
||||
m_tileCountX = tileCountX;
|
||||
m_tileCountY = tileCountY;
|
||||
TileTextures.resize(m_tileCountX * m_tileCountY);
|
||||
}
|
||||
|
||||
VOID TileMapComponent::SetupGridTile(IN INT32 index, IN Handle texture)
|
||||
{
|
||||
TileTextures[index] = texture;
|
||||
}
|
||||
m_tileEntries.reset();
|
||||
m_tileEntries.reserve(tileDescs.size());
|
||||
for (const auto &td : tileDescs)
|
||||
{
|
||||
const auto tileSet = (TileSet*)Engine::GetTileSet(td.TileSetName);
|
||||
textures.pushBack(tileSet->GetTileTexture(td.TileIndex));
|
||||
m_tileEntries.pushBack(TileEntry{.IsWalkable = td.IsWalkable});
|
||||
}
|
||||
|
||||
VOID TileMapComponent::SetupGridTile(IN INT32 x, IN INT32 y, IN Handle texture)
|
||||
{
|
||||
TileTextures[x + y * m_tileCountX] = texture;
|
||||
}
|
||||
|
||||
VOID TileMapComponent::EndGridSetup()
|
||||
{
|
||||
m_mapTexture = Engine::CombineImages(TileTextures, m_tileWidth, m_tileHeight, m_tileCountX, m_tileCountY);
|
||||
if(m_mapTexture != INVALID_HANDLE)
|
||||
Engine::DestroyImage(m_mapTexture);
|
||||
m_mapTexture = Engine::CombineImages(textures, m_tileWidth, m_tileHeight, m_tileCountX, m_tileCountY);
|
||||
SetTexture(m_mapTexture);
|
||||
TileTextures.reset();
|
||||
}
|
||||
|
||||
BOOL TileMapComponent::CanWalkX(IN Vec2 pixelPosition, IN FLOAT32 d)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL TileMapComponent::CanWalkY(IN Vec2 pixelPosition, IN FLOAT32 d)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
} // namespace ia::iae
|
||||
@ -74,7 +74,9 @@ namespace ia::iae
|
||||
|
||||
Vec2 Engine::CalculatePercentPosition(IN Vec2 percent)
|
||||
{
|
||||
return Vec2{Renderer::s_activeSceneDesignViewport.x/100.0f, Renderer::s_activeSceneDesignViewport.y/100.0f} * percent;
|
||||
return Vec2{Renderer::s_activeSceneDesignViewport.x / 100.0f,
|
||||
Renderer::s_activeSceneDesignViewport.y / 100.0f} *
|
||||
percent;
|
||||
}
|
||||
|
||||
Direction Engine::GetVectorPointingDirection(IN Vec2 v)
|
||||
@ -121,6 +123,12 @@ namespace ia::iae
|
||||
return CreateSound(name, data.data(), data.size());
|
||||
}
|
||||
|
||||
Handle Engine::CreateTileSetFromFile(IN CONST String &name, IN CONST String &path, IN INT32 tileWidth,
|
||||
IN INT32 tileHeight)
|
||||
{
|
||||
return CreateTileSet(name, CreateImageFromFile(name, path), tileWidth, tileHeight);
|
||||
}
|
||||
|
||||
Handle Engine::RescaleImage(IN CONST String &name, IN Vec2 factor)
|
||||
{
|
||||
return ResourceManager::RescaleImage(GetImage(name), factor);
|
||||
|
||||
@ -86,7 +86,7 @@ namespace ia::iae
|
||||
IVec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
|
||||
IVec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
|
||||
static_cast<UINT32>(face->glyph->advance.x) >> 6,
|
||||
GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, face->glyph->bitmap.width, face->glyph->bitmap.rows, GLYPH_PIXEL_DATA.data()),
|
||||
GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, face->glyph->bitmap.width, face->glyph->bitmap.rows, face->glyph->bitmap.width, GLYPH_PIXEL_DATA.data()),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -64,10 +64,11 @@ namespace ia::iae
|
||||
}
|
||||
|
||||
SDL_GPUTexture *GPUResourceManager::CreateTexture(IN SDL_GPUTextureUsageFlags usage, IN INT32 width,
|
||||
IN INT32 height, IN PCUINT8 rgbaData,
|
||||
IN INT32 height, IN INT32 stride, IN PCUINT8 rgbaData,
|
||||
IN SDL_GPUTextureFormat format, IN BOOL generateMipmaps)
|
||||
{
|
||||
const auto mipLevels = 1;//generateMipmaps ? ia_max((UINT32)(floor(log2(ia_max(width, height))) + 1), (UINT32)1) : (UINT32)1;
|
||||
const auto mipLevels =
|
||||
1; // generateMipmaps ? ia_max((UINT32)(floor(log2(ia_max(width, height))) + 1), (UINT32)1) : (UINT32)1;
|
||||
|
||||
STATIC Vector<UINT8> TMP_COLOR_BUFFER;
|
||||
|
||||
@ -87,15 +88,33 @@ namespace ia::iae
|
||||
}
|
||||
if (rgbaData)
|
||||
{
|
||||
TMP_COLOR_BUFFER.reset();
|
||||
TMP_COLOR_BUFFER.resize(width * height * 4);
|
||||
for (SIZE_T i = 0; i < TMP_COLOR_BUFFER.size() >> 2; i++)
|
||||
|
||||
if (stride == width)
|
||||
{
|
||||
const auto a = static_cast<FLOAT32>(rgbaData[i * 4 + 3]) / 255.0f;
|
||||
TMP_COLOR_BUFFER[i * 4 + 0] = static_cast<UINT8>(rgbaData[i * 4 + 0] * a);
|
||||
TMP_COLOR_BUFFER[i * 4 + 1] = static_cast<UINT8>(rgbaData[i * 4 + 1] * a);
|
||||
TMP_COLOR_BUFFER[i * 4 + 2] = static_cast<UINT8>(rgbaData[i * 4 + 2] * a);
|
||||
TMP_COLOR_BUFFER[i * 4 + 3] = rgbaData[i * 4 + 3];
|
||||
for (SIZE_T i = 0; i < TMP_COLOR_BUFFER.size() >> 2; i++)
|
||||
{
|
||||
const auto a = static_cast<FLOAT32>(rgbaData[i * 4 + 3]) / 255.0f;
|
||||
TMP_COLOR_BUFFER[i * 4 + 0] = static_cast<UINT8>(rgbaData[i * 4 + 0] * a);
|
||||
TMP_COLOR_BUFFER[i * 4 + 1] = static_cast<UINT8>(rgbaData[i * 4 + 1] * a);
|
||||
TMP_COLOR_BUFFER[i * 4 + 2] = static_cast<UINT8>(rgbaData[i * 4 + 2] * a);
|
||||
TMP_COLOR_BUFFER[i * 4 + 3] = rgbaData[i * 4 + 3];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(INT32 y = 0; y < height; y++)
|
||||
{
|
||||
for(INT32 x = 0; x < width; x++)
|
||||
{
|
||||
const auto p = &rgbaData[(x + y * stride) * 4];
|
||||
const auto a = static_cast<FLOAT32>(p[3]) / 255.0f;
|
||||
TMP_COLOR_BUFFER[(x + y * width) * 4 + 0] = static_cast<UINT8>(p[0] * a);
|
||||
TMP_COLOR_BUFFER[(x + y * width) * 4 + 1] = static_cast<UINT8>(p[1] * a);
|
||||
TMP_COLOR_BUFFER[(x + y * width) * 4 + 2] = static_cast<UINT8>(p[2] * a);
|
||||
TMP_COLOR_BUFFER[(x + y * width) * 4 + 3] = p[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_GPUTransferBufferCreateInfo stagingBufferCreateInfo{.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD,
|
||||
|
||||
@ -30,6 +30,7 @@ namespace ia::iae
|
||||
{
|
||||
Map<String, Handle> ResourceManager::s_images;
|
||||
Map<String, Handle> ResourceManager::s_sounds;
|
||||
Map<String, RefPtr<TileSet>> ResourceManager::s_tileSets;
|
||||
Vector<ResourceManager::ImageResource> ResourceManager::s_imageHandles;
|
||||
|
||||
VOID ResourceManager::Initialize()
|
||||
@ -59,11 +60,12 @@ namespace ia::iae
|
||||
return result;
|
||||
}
|
||||
|
||||
Handle ResourceManager::CreateImage(IN CONST String &name, IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height)
|
||||
Handle ResourceManager::CreateImage(IN CONST String &name, IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height,
|
||||
IN INT32 stride)
|
||||
{
|
||||
const auto texture =
|
||||
GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, width,
|
||||
height, rgbaData, SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM, true);
|
||||
const auto texture = GPUResourceManager::CreateTexture(
|
||||
SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, width, height,
|
||||
(stride == -1) ? width : stride, rgbaData, SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM, true);
|
||||
s_imageHandles.pushBack(ImageResource{.OriginalWidth = width,
|
||||
.OriginalHeight = height,
|
||||
.OriginalPixelData = new UINT8[width * height * 4],
|
||||
@ -154,8 +156,8 @@ namespace ia::iae
|
||||
s_imageHandles[image].OriginalHeight, s_imageHandles[image].OriginalWidth * 4,
|
||||
nullptr, newWidth, newHeight, newWidth * 4, stbir_pixel_layout::STBIR_RGBA);
|
||||
const auto texture = GPUResourceManager::CreateTexture(
|
||||
SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, newWidth, newHeight, newPixelData,
|
||||
SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM, true);
|
||||
SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, newWidth, newHeight, newWidth,
|
||||
newPixelData, SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM, true);
|
||||
GPUResourceManager::DestroyTexture(s_imageHandles[image].Handle);
|
||||
s_imageHandles[image].Handle = texture;
|
||||
s_imageHandles[image].Width = newWidth;
|
||||
@ -198,6 +200,44 @@ namespace ia::iae
|
||||
for (auto &t : s_images)
|
||||
t->Value = RescaleImage(t->Value, factor);
|
||||
}
|
||||
|
||||
Handle ResourceManager::CreateTileSet(IN CONST String &name, IN Handle image, IN INT32 tileWidth,
|
||||
IN INT32 tileHeight)
|
||||
{
|
||||
Vector<Handle> tileImages;
|
||||
|
||||
const auto extent = GetImageExtent(image);
|
||||
for (INT32 y = 0; y < extent.y; y += tileHeight)
|
||||
{
|
||||
for (INT32 x = 0; x < extent.x; x += tileWidth)
|
||||
{
|
||||
const auto w = s_imageHandles[image].OriginalWidth;
|
||||
tileImages.pushBack(CreateImage(BuildString(name, "_Tile", x, y),
|
||||
&s_imageHandles[image].OriginalPixelData[(x + y * w) * 4], tileWidth,
|
||||
tileHeight, w));
|
||||
}
|
||||
}
|
||||
|
||||
return CreateTileSet(name, tileImages, tileWidth, tileHeight);
|
||||
}
|
||||
|
||||
Handle ResourceManager::CreateTileSet(IN CONST String &name, IN CONST Vector<Handle> &images, IN INT32 tileWidth,
|
||||
IN INT32 tileHeight)
|
||||
{
|
||||
auto result = MakeRefPtr<TileSet>(images, tileWidth, tileHeight);
|
||||
s_tileSets[name] = result;
|
||||
return (Handle) (result.get());
|
||||
}
|
||||
|
||||
Handle ResourceManager::GetTileSet(IN CONST String &name)
|
||||
{
|
||||
return (Handle) (s_tileSets[name].get());
|
||||
}
|
||||
|
||||
VOID ResourceManager::DestroyTileSet(IN CONST String &name)
|
||||
{
|
||||
s_tileSets[name].reset();
|
||||
}
|
||||
} // namespace ia::iae
|
||||
|
||||
namespace ia::iae
|
||||
@ -262,4 +302,25 @@ namespace ia::iae
|
||||
{
|
||||
return ResourceManager::CombineImages(images, unitWidth, unitHeight, unitCountX, unitCountY);
|
||||
}
|
||||
|
||||
Handle Engine::CreateTileSet(IN CONST String &name, IN Handle image, IN INT32 tileWidth, IN INT32 tileHeight)
|
||||
{
|
||||
return ResourceManager::CreateTileSet(name, image, tileWidth, tileHeight);
|
||||
}
|
||||
|
||||
Handle Engine::CreateTileSet(IN CONST String &name, IN CONST Vector<Handle> &images, IN INT32 tileWidth,
|
||||
IN INT32 tileHeight)
|
||||
{
|
||||
return ResourceManager::CreateTileSet(name, images, tileWidth, tileHeight);
|
||||
}
|
||||
|
||||
Handle Engine::GetTileSet(IN CONST String &name)
|
||||
{
|
||||
return ResourceManager::GetTileSet(name);
|
||||
}
|
||||
|
||||
VOID Engine::DestroyTileSet(IN CONST String &name)
|
||||
{
|
||||
ResourceManager::DestroyTileSet(name);
|
||||
}
|
||||
} // namespace ia::iae
|
||||
29
Engine/Src/Imp/CPP/TileSet.cpp
Normal file
29
Engine/Src/Imp/CPP/TileSet.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
// 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 <IAEngine/TileSet.hpp>
|
||||
|
||||
namespace ia::iae
|
||||
{
|
||||
TileSet::TileSet(IN CONST Vector<Handle> &images, IN INT32 tileWidth, IN INT32 tileHeight)
|
||||
: m_images(images), m_tileWidth(tileWidth), m_tileHeight(tileHeight)
|
||||
{
|
||||
}
|
||||
|
||||
TileSet::~TileSet()
|
||||
{
|
||||
}
|
||||
} // namespace ia::iae
|
||||
Reference in New Issue
Block a user