This commit is contained in:
Isuru Samarathunga
2025-10-15 09:27:19 +05:30
parent 0f557eb010
commit f742dcfaff
8 changed files with 87 additions and 58 deletions

View File

@ -31,6 +31,7 @@ namespace ia::iae
VOID TextureComponent::Draw() VOID TextureComponent::Draw()
{ {
const auto t = Engine::GetImageExtent(m_texture); const auto t = Engine::GetImageExtent(m_texture);
const auto t2 = Engine::GetImageOriginalExtent(m_texture);
m_textureExtent = {t.x, t.y}; m_textureExtent = {t.x, t.y};
m_drawnSize = m_node->GetScale() * m_textureExtent * m_scaleOffset; m_drawnSize = m_node->GetScale() * m_textureExtent * m_scaleOffset;
@ -40,7 +41,7 @@ namespace ia::iae
Engine::SetRenderState_ColorOverlay(m_colorOverlay); Engine::SetRenderState_ColorOverlay(m_colorOverlay);
Engine::SetRenderState_TextureOffset(m_textureOffset); Engine::SetRenderState_TextureOffset(m_textureOffset);
Engine::SetRenderState_CameraRelative(m_isCameraRelative); Engine::SetRenderState_CameraRelative(m_isCameraRelative);
Engine::SetRenderState_Transform(m_node->GetPosition() + m_positionOffset, m_drawnSize, m_node->GetRotation() + m_rotationOffset, m_node->Layer(), m_node->SortIndex()); Engine::SetRenderState_Transform(m_node->GetPosition() + m_positionOffset, m_node->GetScale() * Vec2{t2.x, t2.y} * m_scaleOffset, m_node->GetRotation() + m_rotationOffset, m_node->Layer(), m_node->SortIndex());
Engine::DrawGeometry(Engine::GetGeometry_Quad()); Engine::DrawGeometry(Engine::GetGeometry_Quad());
} }

View File

@ -96,7 +96,8 @@ namespace ia::iae
{ {
const auto data = File::ReadToVector(path.c_str()); const auto data = File::ReadToVector(path.c_str());
const auto handle = CreateImage(name, data.data(), data.size()); const auto handle = CreateImage(name, data.data(), data.size());
return (resizeToWidth && resizeToHeight) ? ResizeImage(handle, resizeToWidth, resizeToHeight) : handle; const auto extent = GetImageExtent(handle);
return (resizeToWidth && resizeToHeight) ? RescaleImage(handle, {(FLOAT32)resizeToWidth/(FLOAT32)extent.x, (FLOAT32)resizeToHeight/(FLOAT32)extent.y}) : handle;
} }
Handle Engine::CreateSoundFromFile(IN CONST String &name, IN CONST String &path) Handle Engine::CreateSoundFromFile(IN CONST String &name, IN CONST String &path)
@ -105,9 +106,9 @@ namespace ia::iae
return CreateSound(name, data.data(), data.size()); return CreateSound(name, data.data(), data.size());
} }
Handle Engine::ResizeImage(IN CONST String &name, IN INT32 newWidth, IN INT32 newHeight) Handle Engine::RescaleImage(IN CONST String &name, IN Vec2 factor)
{ {
return ResizeImage(GetImage(name), newWidth, newHeight); return RescaleImage(GetImage(name), factor);
} }
String Engine::GetUniqueResourceName() String Engine::GetUniqueResourceName()

View File

@ -29,9 +29,9 @@ namespace ia::iae
SDL_GPUSamplerCreateInfo createInfo{.min_filter = SDL_GPU_FILTER_LINEAR, SDL_GPUSamplerCreateInfo createInfo{.min_filter = SDL_GPU_FILTER_LINEAR,
.mag_filter = SDL_GPU_FILTER_LINEAR, .mag_filter = SDL_GPU_FILTER_LINEAR,
.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_LINEAR, .mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_LINEAR,
.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_REPEAT, .address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_REPEAT, .address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
.address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_REPEAT, .address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
.enable_anisotropy = false}; .enable_anisotropy = false};
g_linearClampSampler = SDL_CreateGPUSampler(Renderer::GetDevice(), &createInfo); g_linearClampSampler = SDL_CreateGPUSampler(Renderer::GetDevice(), &createInfo);

View File

@ -288,7 +288,7 @@ namespace ia::iae
s_fragmentUniform.FlippedV = s_state.FlippedV; s_fragmentUniform.FlippedV = s_state.FlippedV;
s_fragmentUniform.TextureOffset = s_state.TextureOffset; s_fragmentUniform.TextureOffset = s_state.TextureOffset;
SDL_GPUTextureSamplerBinding textureBinding{.texture = s_state.ActiveTexture, SDL_GPUTextureSamplerBinding textureBinding{.texture = s_state.ActiveTexture,
.sampler = GPUResourceManager::GetSampler_LinearRepeat()}; .sampler = ((s_state.TextureOffset.x <= FLOAT32_EPSILON) && (s_state.TextureOffset.y <= FLOAT32_EPSILON)) ? GPUResourceManager::GetSampler_LinearClamp() : GPUResourceManager::GetSampler_LinearRepeat()};
SDL_BindGPUFragmentSamplers(s_state.ActiveRenderPass, 0, &textureBinding, 1); SDL_BindGPUFragmentSamplers(s_state.ActiveRenderPass, 0, &textureBinding, 1);
SDL_PushGPUFragmentUniformData(s_state.ActiveCommandBuffer, 0, &s_fragmentUniform, sizeof(s_fragmentUniform)); SDL_PushGPUFragmentUniformData(s_state.ActiveCommandBuffer, 0, &s_fragmentUniform, sizeof(s_fragmentUniform));

View File

@ -28,11 +28,9 @@
namespace ia::iae namespace ia::iae
{ {
Vector<SDL_GPUTexture *> ResourceManager::s_imageHandles;
Map<String, Handle> ResourceManager::s_images; Map<String, Handle> ResourceManager::s_images;
Map<String, Handle> ResourceManager::s_sounds; Map<String, Handle> ResourceManager::s_sounds;
Map<Handle, UINT64> ResourceManager::s_imageExtents; Vector<ResourceManager::ImageResource> ResourceManager::s_imageHandles;
Map<Handle, UINT64> ResourceManager::s_nonScaledImageExtents;
VOID ResourceManager::Initialize() VOID ResourceManager::Initialize()
{ {
@ -47,7 +45,7 @@ namespace ia::iae
VOID ResourceManager::Terminate() VOID ResourceManager::Terminate()
{ {
for (const auto &t : s_images) for (const auto &t : s_images)
GPUResourceManager::DestroyTexture(s_imageHandles[t->Value]); GPUResourceManager::DestroyTexture(s_imageHandles[t->Value].Handle);
for (const auto &t : s_sounds) for (const auto &t : s_sounds)
AudioManager::DestoryAudio(t->Value); AudioManager::DestoryAudio(t->Value);
} }
@ -65,11 +63,15 @@ namespace ia::iae
{ {
const auto texture = GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER, width, height, rgbaData, const auto texture = GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER, width, height, rgbaData,
SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM); SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM);
s_imageHandles.pushBack(texture); s_imageHandles.pushBack(ImageResource{.OriginalWidth = width,
.OriginalHeight = height,
.OriginalPixelData = new UINT8[width * height * 4],
.Width = width,
.Height = height,
.Handle = texture});
ia_memcpy(s_imageHandles.back().OriginalPixelData, rgbaData, width * height * 4);
Handle handle = s_imageHandles.size() - 1; Handle handle = s_imageHandles.size() - 1;
s_images[name] = handle; s_images[name] = handle;
s_imageExtents[handle] = (((UINT64) width) << 32) | height;
s_nonScaledImageExtents[handle] = s_imageExtents[handle];
return handle; return handle;
} }
@ -114,8 +116,8 @@ namespace ia::iae
VOID ResourceManager::DestroyImage(IN Handle image) VOID ResourceManager::DestroyImage(IN Handle image)
{ {
GPUResourceManager::DestroyTexture(s_imageHandles[image]); GPUResourceManager::DestroyTexture(s_imageHandles[image].Handle);
s_imageHandles[image] = nullptr; s_imageHandles[image] = {};
} }
VOID ResourceManager::DestroySound(IN Handle sound) VOID ResourceManager::DestroySound(IN Handle sound)
@ -125,23 +127,38 @@ namespace ia::iae
IVec2 ResourceManager::GetImageExtent(IN Handle image) IVec2 ResourceManager::GetImageExtent(IN Handle image)
{ {
const auto t = s_imageExtents[image]; const auto t = s_imageHandles[image];
return {(INT32) (t >> 32), (INT32) t}; return {t.Width, t.Height};
} }
Handle ResourceManager::ResizeImage(IN Handle image, IN INT32 newWidth, IN INT32 newHeight) IVec2 ResourceManager::GetImageOriginalExtent(IN Handle image)
{ {
const auto currentExtent = GetImageExtent(image); const auto t = s_imageHandles[image];
const auto pixelData = return {t.OriginalWidth, t.OriginalHeight};
GPUResourceManager::GetTexturePixelData(s_imageHandles[image], currentExtent.x, currentExtent.y); }
Handle ResourceManager::RescaleImage(IN Handle image, IN Vec2 factor)
{
if (!s_imageHandles[image].OriginalPixelData)
return image;
const auto newWidth = (INT32) (s_imageHandles[image].OriginalWidth * factor.x);
const auto newHeight = (INT32) (s_imageHandles[image].OriginalHeight * factor.y);
if (!newWidth || !newHeight ||
((newWidth <= s_imageHandles[image].OriginalWidth) && (newHeight <= s_imageHandles[image].OriginalHeight)))
return image;
const auto newPixelData = const auto newPixelData =
stbir_resize_uint8_linear(pixelData.data(), currentExtent.x, currentExtent.y, currentExtent.x * 4, nullptr, stbir_resize_uint8_linear(s_imageHandles[image].OriginalPixelData, s_imageHandles[image].OriginalWidth,
newWidth, newHeight, newWidth * 4, stbir_pixel_layout::STBIR_RGBA); 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, newWidth, newHeight, const auto texture = GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER, newWidth, newHeight,
newPixelData, SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM); newPixelData, SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM);
s_imageExtents[image] = (((UINT64) newWidth) << 32) | newHeight; GPUResourceManager::DestroyTexture(s_imageHandles[image].Handle);
GPUResourceManager::DestroyTexture(s_imageHandles[image]); s_imageHandles[image].Handle = texture;
s_imageHandles[image] = texture; s_imageHandles[image].Width = newWidth;
s_imageHandles[image].Height = newHeight;
free(newPixelData); free(newPixelData);
return image; return image;
} }
@ -153,24 +170,24 @@ namespace ia::iae
const auto h = unitHeight * unitCountY; const auto h = unitHeight * unitCountY;
Vector<SDL_GPUTexture *> textures; Vector<SDL_GPUTexture *> textures;
for (const auto &t : images) for (const auto &t : images)
textures.pushBack(s_imageHandles[t]); textures.pushBack(s_imageHandles[t].Handle);
const auto texture = const auto texture =
GPUResourceManager::CombineTextures(textures.data(), unitWidth, unitHeight, unitCountX, unitCountY); GPUResourceManager::CombineTextures(textures.data(), unitWidth, unitHeight, unitCountX, unitCountY);
s_imageHandles.pushBack(texture); s_imageHandles.pushBack(ImageResource{.OriginalWidth = w,
.OriginalHeight = h,
.OriginalPixelData = nullptr,
.Width = w,
.Height = h,
.Handle = texture});
Handle handle = s_imageHandles.size() - 1; Handle handle = s_imageHandles.size() - 1;
s_images[Engine::GetUniqueResourceName()] = handle; s_images[Engine::GetUniqueResourceName()] = handle;
s_imageExtents[handle] = (((UINT64) w) << 32) | h;
s_nonScaledImageExtents[handle] = s_imageExtents[handle];
return handle; return handle;
} }
VOID ResourceManager::RescaleAllImages(IN FLOAT32 factorX, IN FLOAT32 factorY) VOID ResourceManager::RescaleAllImages(IN Vec2 factor)
{ {
for (auto &t : s_images) for (auto &t : s_images)
{ t->Value = RescaleImage(t->Value, factor);
const auto p = s_nonScaledImageExtents[t->Value];
t->Value = ResizeImage(t->Value, ((INT32) (p >> 32)) * factorX, ((INT32) p) * factorY);
}
} }
} // namespace ia::iae } // namespace ia::iae
@ -216,14 +233,19 @@ namespace ia::iae
return ResourceManager::GetImageExtent(image); return ResourceManager::GetImageExtent(image);
} }
Handle Engine::ResizeImage(IN Handle image, IN INT32 newWidth, IN INT32 newHeight) IVec2 Engine::GetImageOriginalExtent(IN Handle image)
{ {
return ResourceManager::ResizeImage(image, newWidth, newHeight); return ResourceManager::GetImageOriginalExtent(image);
} }
VOID Engine::RescaleAllImages(IN FLOAT32 factorX, IN FLOAT32 factorY) Handle Engine::RescaleImage(IN Handle image, IN Vec2 factor)
{ {
ResourceManager::RescaleAllImages(factorX, factorY); return ResourceManager::RescaleImage(image, factor);
}
VOID Engine::RescaleAllImages(IN Vec2 factor)
{
ResourceManager::RescaleAllImages(factor);
} }
Handle Engine::CombineImages(IN CONST Vector<Handle> &images, IN INT32 unitWidth, IN INT32 unitHeight, Handle Engine::CombineImages(IN CONST Vector<Handle> &images, IN INT32 unitWidth, IN INT32 unitHeight,

View File

@ -76,19 +76,20 @@ namespace ia::iae
std::string result; std::string result;
std::string::const_iterator search_start(text.cbegin()); std::string::const_iterator search_start(text.cbegin());
SIZE_T t1 = 0, t2 = 0; SIZE_T t = 0;
while (std::regex_search(search_start, text.cend(), match, std::regex(pattern.c_str()))) while (std::regex_search(search_start, text.cend(), match, std::regex(pattern.c_str())))
{ {
for(SIZE_T i = 1; i < match.size(); i++) for(SIZE_T i = 1; i < match.size(); i++)
{ {
result += text.substr(t1, match.position(i) - t1); const auto p = match.position(i) + (search_start - text.cbegin());
result += std::string(groupTransformer(i - 1, match.str(i).c_str()).c_str()); const auto l = match.length(i);
t1 = match.position(i); result += text.substr(t, p - t);
t2 = match.str(i).length(); result += groupTransformer(i - 1, text.substr(p, l).c_str()).c_str();
t = p + l;
} }
result += text.substr(match.suffix().first - text.begin() - 1); search_start = text.cbegin() + t;
search_start = match.suffix().first;
} }
result += text.substr(t, text.size() - t);
return result.c_str(); return result.c_str();
} }

View File

@ -26,9 +26,13 @@ namespace ia::iae
{ {
struct ImageResource struct ImageResource
{ {
INT32 OriginalWidth{};
INT32 OriginalHeight{};
PUINT8 OriginalPixelData{};
INT32 Width{}; INT32 Width{};
INT32 Height{}; INT32 Height{};
SDL_GPUTexture *Texture{}; SDL_GPUTexture *Handle{};
}; };
public: public:
@ -47,22 +51,21 @@ namespace ia::iae
STATIC VOID DestroyImage(IN Handle image); STATIC VOID DestroyImage(IN Handle image);
STATIC VOID DestroySound(IN Handle sound); STATIC VOID DestroySound(IN Handle sound);
STATIC IVec2 GetImageExtent(IN Handle image); STATIC IVec2 GetImageExtent(IN Handle image);
STATIC VOID RescaleAllImages(IN FLOAT32 factorX, IN FLOAT32 factorY); STATIC IVec2 GetImageOriginalExtent(IN Handle image);
STATIC Handle ResizeImage(IN Handle image, IN INT32 newWidth, IN INT32 newHeight); STATIC VOID RescaleAllImages(IN Vec2 factor);
STATIC Handle RescaleImage(IN Handle image, IN Vec2 factor);
STATIC Handle CombineImages(IN CONST Vector<Handle> &images, IN INT32 unitWidth, IN INT32 unitHeight, STATIC Handle CombineImages(IN CONST Vector<Handle> &images, IN INT32 unitWidth, IN INT32 unitHeight,
IN INT32 unitCountX, IN INT32 unitCountY); IN INT32 unitCountX, IN INT32 unitCountY);
public: public:
STATIC SDL_GPUTexture *GetTextureFromImage(IN Handle image) STATIC SDL_GPUTexture *GetTextureFromImage(IN Handle image)
{ {
return s_imageHandles[image]; return s_imageHandles[image].Handle;
} }
private: private:
STATIC Vector<SDL_GPUTexture *> s_imageHandles;
STATIC Map<String, Handle> s_images; STATIC Map<String, Handle> s_images;
STATIC Map<String, Handle> s_sounds; STATIC Map<String, Handle> s_sounds;
STATIC Map<Handle, UINT64> s_imageExtents; STATIC Vector<ImageResource> s_imageHandles;
STATIC Map<Handle, UINT64> s_nonScaledImageExtents;
}; };
} // namespace ia::iae } // namespace ia::iae

View File

@ -82,9 +82,10 @@ namespace ia::iae
STATIC VOID DestroyImage(IN Handle image); STATIC VOID DestroyImage(IN Handle image);
STATIC VOID DestroySound(IN Handle sound); STATIC VOID DestroySound(IN Handle sound);
STATIC IVec2 GetImageExtent(IN Handle image); STATIC IVec2 GetImageExtent(IN Handle image);
STATIC Handle ResizeImage(IN Handle image, IN INT32 newWidth, IN INT32 newHeight); STATIC IVec2 GetImageOriginalExtent(IN Handle image);
STATIC Handle ResizeImage(IN CONST String &name, IN INT32 newWidth, IN INT32 newHeight); STATIC Handle RescaleImage(IN Handle image, IN Vec2 factor);
STATIC VOID RescaleAllImages(IN FLOAT32 factorX, IN FLOAT32 factorY); STATIC Handle RescaleImage(IN CONST String &name, IN Vec2 factor);
STATIC VOID RescaleAllImages(IN Vec2 factor);
STATIC Handle CombineImages(IN CONST Vector<Handle> &images, IN INT32 unitWidth, IN INT32 unitHeight, STATIC Handle CombineImages(IN CONST Vector<Handle> &images, IN INT32 unitWidth, IN INT32 unitHeight,
IN INT32 unitCountX, IN INT32 unitCountY); IN INT32 unitCountX, IN INT32 unitCountY);