This commit is contained in:
Isuru Samarathunga
2025-09-15 20:28:22 +05:30
parent 6974a647f5
commit 829ca638cb
13 changed files with 170 additions and 57 deletions

View File

@ -16,7 +16,7 @@ namespace ia::iae::game
{
scene = Engine::CreateScene();
scene->YSortingEnabled() = true;
Engine::ChangeScene(scene);
Engine::ChangeScene(scene.get());
g_player = MakeRefPtr<Node>();
{

View File

@ -24,23 +24,42 @@ namespace ia::iae
{
}
Handle AtlasRendererComponent::AddTexture(IN RefPtr<Texture> texture)
AtlasRendererComponent::~AtlasRendererComponent()
{
m_textures.pushBack(texture);
return m_textures.size() - 1;
m_bakedGPUTexture.reset();
}
VOID AtlasRendererComponent::SetGrid(IN CONST TileGrid &grid)
VOID AtlasRendererComponent::SetGrid(IN INT32 tileWidth, IN INT32 tileHeight, IN INT32 tileCountX,
IN INT32 tileCountY)
{
m_tileGrid = grid;
m_tileGrid.m_tileTextures.resize(grid.TileCountX * grid.TileCountY);
for (auto &t : m_tileGrid.m_tileTextures)
t = INVALID_HANDLE;
m_tileGrid = {};
m_tileGrid.TileWidth = tileWidth;
m_tileGrid.TileHeight = tileHeight;
m_tileGrid.TileCountX = tileCountX;
m_tileGrid.TileCountY = tileCountY;
m_tileGrid.m_tileTextures.resize(m_tileGrid.TileCountX * m_tileGrid.TileCountY);
}
VOID AtlasRendererComponent::SetGridTileTexture(IN INT32 x, IN INT32 y, IN Handle textureHandle)
VOID AtlasRendererComponent::SetGridTileTexture(IN INT32 index, IN Texture texture)
{
m_tileGrid.m_tileTextures[x + (y * m_tileGrid.TileCountX)] = textureHandle;
m_tileGrid.m_tileTextures[index] = texture;
}
VOID AtlasRendererComponent::SetGridTileTexture(IN INT32 x, IN INT32 y, IN Texture texture)
{
m_tileGrid.m_tileTextures[x + (y * m_tileGrid.TileCountX)] = texture;
}
VOID AtlasRendererComponent::BakeGrid()
{
CONST INT32 w = m_tileGrid.TileWidth * m_tileGrid.TileCountX, h = m_tileGrid.TileHeight * m_tileGrid.TileCountY;
Vector<Handle> handles;
handles.resize(m_tileGrid.TileCountX * m_tileGrid.TileCountY);
for (SIZE_T i = 0; i < handles.size(); i++)
handles[i] = m_tileGrid.m_tileTextures[i].GetHandle();
m_bakedGPUTexture = GPUTexture::GridCombine(handles.data(), m_tileGrid.TileCountX, m_tileGrid.TileCountY,
m_tileGrid.TileWidth, m_tileGrid.TileHeight);
m_bakedTexture = Texture(m_bakedGPUTexture->GetHandle(), w, h);
}
VOID AtlasRendererComponent::Update()
@ -49,18 +68,7 @@ namespace ia::iae
VOID AtlasRendererComponent::Draw()
{
glm::vec3 p{m_node->GetPosition().x, m_node->GetPosition().y, m_node->GetPosition().z};
for (INT32 y = 0; y < m_tileGrid.TileCountY; y++)
{
for (INT32 x = 0; x < m_tileGrid.TileCountX; x++)
{
const auto t = m_tileGrid.m_tileTextures[x + (y * m_tileGrid.TileCountX)];
if (t != INVALID_HANDLE)
m_textures[t]->Draw(m_node->SortOffset(), p + m_tileGrid.Position, {1.0f, 1.0f, 1.0f}, 0.0f, false, false, {1.0f, 1.0f, 1.0f, 1.0f});
p.x += m_tileGrid.TileWidth;
}
p.x = m_node->GetPosition().x;
p.y += m_tileGrid.TileHeight;
}
m_bakedTexture.Draw(m_node->SortOffset(), m_node->GetPosition() + m_tileGrid.Position, {1.0f, 1.0f, 1.0f}, 0.0f,
false, false, {1.0f, 1.0f, 1.0f, 1.0f});
}
} // namespace ia::iae

View File

@ -41,8 +41,7 @@ namespace ia::iae
SDL_Window *g_windowHandle{};
Vector<RefPtr<GPUTexture>> g_gpuTextureRefs;
RefPtr<Scene> g_activeScene;
Scene* g_activeScene;
BOOL Engine::Initialize(IN CONST InitConfig &config)
{
@ -140,14 +139,14 @@ namespace ia::iae
g_activeScene->Draw();
}
VOID Engine::ChangeScene(IN RefPtr<Scene> scene)
VOID Engine::ChangeScene(IN Scene* scene)
{
g_activeScene = scene;
}
Scene* Engine::GetActiveScene()
Scene *Engine::GetActiveScene()
{
return g_activeScene.get();
return g_activeScene;
}
} // namespace ia::iae
@ -181,6 +180,35 @@ namespace ia::iae
return Texture(t->GetHandle(), width, height);
}
Vector<Texture> Engine::CreateTextures(IN CONST Vector<UINT8> &encodedData, IN INT32 textureCount)
{
return CreateTextures(encodedData.data(), encodedData.size(), textureCount);
}
Vector<Texture> Engine::CreateTextures(IN PCUINT8 encodedData, IN SIZE_T encodedDataSize, IN INT32 textureCount)
{
SIZE_T offset{0};
Vector<Texture> result;
INT32 w, h, nrChannels;
for (INT32 i = 0; i < textureCount; i++)
{
SIZE_T readSize{};
const auto pixels = stbi_load_from_memory(&encodedData[offset], encodedDataSize - offset, &w, &h,
&nrChannels, STBI_rgb_alpha, readSize);
if (!pixels)
THROW_INVALID_DATA("Failed to decode the provided image data");
result.pushBack(CreateTexture((PCUINT8) pixels, w, h));
STBI_FREE(pixels);
offset += readSize;
if (offset >= encodedDataSize)
{
IA_RELEASE_ASSERT(i == (textureCount - 1));
break;
}
}
return result;
}
Sound Engine::CreateSound(IN PCUINT8 audioData, IN SIZE_T audioDataSize)
{
return Audio::CreateSound(audioData, audioDataSize);

View File

@ -20,6 +20,12 @@
namespace ia::iae
{
Node::~Node()
{
for (auto &c : m_components)
c.reset();
}
VOID Node::OnAdded(IN Scene *scene)
{
m_scene = scene;

View File

@ -28,16 +28,14 @@ namespace ia::iae
{
if (g_defaultSampler)
return;
SDL_GPUSamplerCreateInfo createInfo{
.min_filter = SDL_GPU_FILTER_LINEAR,
SDL_GPUSamplerCreateInfo createInfo{.min_filter = SDL_GPU_FILTER_LINEAR,
.mag_filter = SDL_GPU_FILTER_LINEAR,
.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_LINEAR,
.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
.address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
.max_anisotropy = 1.0f,
.enable_anisotropy = true
};
.enable_anisotropy = true};
g_defaultSampler = SDL_CreateGPUSampler(g_gpuDevice, &createInfo);
}
@ -59,8 +57,8 @@ namespace ia::iae
SDL_GPUTextureCreateInfo createInfo{.type = SDL_GPU_TEXTURETYPE_2D,
.format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM,
.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER,
.width = (UINT32)width,
.height = (UINT32)height,
.width = (UINT32) width,
.height = (UINT32) height,
.layer_count_or_depth = 1,
.num_levels = 1};
@ -72,7 +70,7 @@ namespace ia::iae
}
SDL_GPUTransferBufferCreateInfo stagingBufferCreateInfo{.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD,
.size = (UINT32)width * (UINT32)height * 4};
.size = (UINT32) width * (UINT32) height * 4};
const auto stagingBuffer = SDL_CreateGPUTransferBuffer(g_gpuDevice, &stagingBufferCreateInfo);
const auto mappedPtr = SDL_MapGPUTransferBuffer(g_gpuDevice, stagingBuffer, false);
SDL_memcpy(mappedPtr, rgbaData, width * height * 4);
@ -81,7 +79,7 @@ namespace ia::iae
const auto cmdBuffer = SDL_AcquireGPUCommandBuffer(g_gpuDevice);
const auto copyPass = SDL_BeginGPUCopyPass(cmdBuffer);
SDL_GPUTextureTransferInfo transferInfo{.transfer_buffer = stagingBuffer, .offset = 0};
SDL_GPUTextureRegion region{.texture = handle, .w = (UINT32)width, .h = (UINT32)height, .d = 1};
SDL_GPUTextureRegion region{.texture = handle, .w = (UINT32) width, .h = (UINT32) height, .d = 1};
SDL_UploadToGPUTexture(copyPass, &transferInfo, &region, false);
SDL_EndGPUCopyPass(copyPass);
SDL_SubmitGPUCommandBuffer(cmdBuffer);
@ -92,6 +90,47 @@ namespace ia::iae
return res;
}
RefPtr<GPUTexture> GPUTexture::GridCombine(IN Handle *handles, IN INT32 unitCountX, IN INT32 unitCountY,
IN INT32 unitSizeX, IN INT32 unitSizeY)
{
const auto res = MakeRefPtr<GPUTexture>();
SDL_GPUTextureCreateInfo createInfo{.type = SDL_GPU_TEXTURETYPE_2D,
.format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM,
.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER,
.width = (UINT32) unitCountX * unitSizeX,
.height = (UINT32) unitCountY * unitSizeY,
.layer_count_or_depth = 1,
.num_levels = 1};
SDL_GPUTexture *handle{};
if (!(handle = SDL_CreateGPUTexture(g_gpuDevice, &createInfo)))
{
IAE_LOG_ERROR("Failed to create a SDL GPU Texture");
return nullptr;
}
const auto cmdBuffer = SDL_AcquireGPUCommandBuffer(g_gpuDevice);
const auto copyPass = SDL_BeginGPUCopyPass(cmdBuffer);
for (INT32 y = 0; y < unitCountY; y++)
{
for (INT32 x = 0; x < unitCountX; x++)
{
SDL_GPUTextureLocation src{.texture = (SDL_GPUTexture *) handles[x + (y * unitCountX)], .x = 0, .y = 0};
SDL_GPUTextureLocation dst{.texture = handle, .x = (UINT32)(x * unitSizeX), .y = (UINT32)(y * unitSizeY)};
SDL_CopyGPUTextureToTexture(copyPass, &src, &dst, unitSizeX, unitSizeY, 1, false);
}
}
SDL_EndGPUCopyPass(copyPass);
SDL_SubmitGPUCommandBuffer(cmdBuffer);
res->m_handle = (Handle) handle;
return res;
}
GPUTexture::~GPUTexture()
{
if (m_handle)

View File

@ -18,6 +18,12 @@
namespace ia::iae
{
Scene::~Scene()
{
for (auto &n : m_nodes)
n.reset();
}
VOID Scene::Draw()
{
for (auto &n : m_nodes)

View File

@ -1433,6 +1433,15 @@ STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, i
return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
}
STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp, size_t& readSize)
{
stbi__context s;
stbi__start_mem(&s,buffer,len);
const auto data = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
readSize = s.img_buffer - s.img_buffer_original;
return data;
}
STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
{
stbi__context s;

View File

@ -17,6 +17,7 @@
#pragma once
#include <IAEngine/Components/Component.hpp>
#include <IAEngine/Rendering/GPUTexture.hpp>
#include <IAEngine/Texture.hpp>
namespace ia::iae
@ -33,19 +34,21 @@ namespace ia::iae
INT32 TileCountX{};
INT32 TileCountY{};
Vector<Handle> m_tileTextures{};
private:
Vector<Texture> m_tileTextures{};
friend class AtlasRendererComponent;
};
public:
AtlasRendererComponent(IN Node *node);
~AtlasRendererComponent();
public:
Handle AddTexture(IN RefPtr<Texture> texture);
VOID SetGrid(IN CONST TileGrid &grid);
VOID SetGridTileTexture(IN INT32 x, IN INT32 y, IN Handle textureHandle);
VOID SetGrid(IN INT32 tileWidth, IN INT32 tileHeight, IN INT32 tileCountX, IN INT32 tileCountY);
VOID SetGridTileTexture(IN INT32 index, IN Texture texture);
VOID SetGridTileTexture(IN INT32 x, IN INT32 y, IN Texture texture);
VOID BakeGrid();
public:
VOID Draw();
@ -53,6 +56,7 @@ namespace ia::iae
private:
TileGrid m_tileGrid{};
Vector<RefPtr<Texture>> m_textures;
Texture m_bakedTexture{};
RefPtr<GPUTexture> m_bakedGPUTexture{};
};
} // namespace ia::iae

View File

@ -47,7 +47,7 @@ namespace ia::iae
STATIC VOID EndFrame();
STATIC BOOL ShouldClose();
STATIC VOID ChangeScene(IN RefPtr<Scene> scene);
STATIC VOID ChangeScene(IN Scene* scene);
STATIC Scene* GetActiveScene();
public:
@ -56,6 +56,8 @@ namespace ia::iae
STATIC Texture CreateTexture(IN CONST Vector<UINT8> &encodedData);
STATIC Texture CreateTexture(IN PCUINT8 encodedData, IN SIZE_T encodedDataSize);
STATIC Texture CreateTexture(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height);
STATIC Vector<Texture> CreateTextures(IN CONST Vector<UINT8> &encodedData, IN INT32 textureCount);
STATIC Vector<Texture> CreateTextures(IN PCUINT8 encodedData, IN SIZE_T encodedDataSize, IN INT32 textureCount);
STATIC Sound CreateSound(IN CONST Vector<UINT8> &audioData);
STATIC Sound CreateSound(IN PCUINT8 audioData, IN SIZE_T audioDataSize);

View File

@ -27,6 +27,8 @@ namespace ia::iae
class Node : public Transform<Node>
{
public:
~Node();
VIRTUAL VOID OnAdded(IN Scene *scene);
VIRTUAL VOID OnRemoved();

View File

@ -32,6 +32,8 @@ namespace ia::iae
STATIC RefPtr<GPUTexture> Create(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height);
STATIC RefPtr<GPUTexture> GridCombine(IN Handle* handles, IN INT32 unitCountX, IN INT32 unitCountY, IN INT32 unitSizeX, IN INT32 unitSizeY);
public:
Handle GetHandle() CONST
{

View File

@ -23,6 +23,8 @@ namespace ia::iae
class Scene
{
public:
~Scene();
VOID Draw();
VOID Update();

View File

@ -28,18 +28,23 @@ namespace ia::iae
~Texture();
public:
VOID Draw(IN FLOAT32 sortOffset, IN CONST glm::vec3 &position, IN CONST glm::vec3 &scale, IN FLOAT32 rotation, IN BOOL flipH,
IN BOOL flipV, IN CONST glm::vec4 &colorOverlay) CONST;
VOID Draw(IN FLOAT32 sortOffset, IN CONST glm::vec3 &position, IN CONST glm::vec3 &scale, IN FLOAT32 rotation,
IN BOOL flipH, IN BOOL flipV, IN CONST glm::vec4 &colorOverlay) CONST;
public:
Handle GetHandle() CONST
{
return m_handle;
}
INT32 GetWidth() CONST
{
return (INT32)m_size.x;
return (INT32) m_size.x;
}
INT32 GetHeight() CONST
{
return (INT32)m_size.y;
return (INT32) m_size.y;
}
private: