Cleanup 2/2

This commit is contained in:
Isuru Samarathunga
2025-11-05 16:23:50 +05:30
parent 7d6e8ef695
commit 80dc50d279
14 changed files with 275 additions and 74 deletions

View File

@ -14,4 +14,4 @@ add_executable(IAE_Editor ${SRC_FILES})
target_include_directories(IAE_Editor PRIVATE imp/hpp) target_include_directories(IAE_Editor PRIVATE imp/hpp)
target_link_libraries(IAE_Editor PRIVATE RenderCore) target_link_libraries(IAE_Editor PRIVATE IAEngine)

View File

@ -14,9 +14,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <IAEngine/IAEngine.hpp>
#include <RenderCore/RenderCore.hpp> #include <RenderCore/RenderCore.hpp>
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <Vendor/imgui/backends/imgui_impl_sdl3.h> #include <Vendor/imgui/backends/imgui_impl_sdl3.h>
#include <Vendor/imgui/backends/imgui_impl_sdlgpu3.h> #include <Vendor/imgui/backends/imgui_impl_sdlgpu3.h>
#include <Vendor/imgui/imgui.h> #include <Vendor/imgui/imgui.h>
@ -25,11 +27,14 @@ namespace ia::iae
{ {
ImDrawData *g_imDrawData{}; ImDrawData *g_imDrawData{};
SDL_Window *g_windowHandle{}; EXTERN Vec2 g_designViewport;
EXTERN SDL_Window *g_windowHandle;
INT32 Run(IN INT32 argc, IN PCCHAR argv[]) INT32 Run(IN INT32 argc, IN PCCHAR argv[])
{ {
INT32 frameCounter{0};
IVec2 windowExtent{800, 600}; IVec2 windowExtent{800, 600};
g_designViewport = windowExtent;
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMEPAD)) if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMEPAD))
THROW_UNKNOWN("Failed to intialize SDL: ", SDL_GetError()); THROW_UNKNOWN("Failed to intialize SDL: ", SDL_GetError());
@ -40,15 +45,15 @@ namespace ia::iae
SDL_MaximizeWindow(g_windowHandle); SDL_MaximizeWindow(g_windowHandle);
SDL_GetWindowSizeInPixels(g_windowHandle, &windowExtent.x, &windowExtent.y); SDL_GetWindowSizeInPixels(g_windowHandle, &windowExtent.x, &windowExtent.y);
RDC::Initialize(windowExtent, g_windowHandle, true); IAEngine::__Initialize();
const auto mainScale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
auto gamePreviewTexture = new RDC_Texture(RDC_Texture::EType::SAMPLED, 800, 600); auto gamePreviewTexture = new RDC_Texture(RDC_Texture::EType::SAMPLED, 800, 600);
const auto mainScale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
ImGui::CreateContext(); ImGui::CreateContext();
auto& imGUIIO = ImGui::GetIO(); auto &imGUIIO = ImGui::GetIO();
imGUIIO.IniFilename = nullptr; imGUIIO.IniFilename = nullptr;
imGUIIO.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; imGUIIO.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
imGUIIO.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; imGUIIO.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
@ -71,9 +76,18 @@ namespace ia::iae
SDL_PollEvent(&event); SDL_PollEvent(&event);
if (event.type == SDL_EVENT_QUIT) if (event.type == SDL_EVENT_QUIT)
break; break;
IAEngine::__ProcessEvent(&event);
IAEngine::__Update();
ImGui_ImplSDL3_ProcessEvent(&event); ImGui_ImplSDL3_ProcessEvent(&event);
RDC::RenderToTexture(gamePreviewTexture->GetHandle()); frameCounter++;
if (frameCounter >= 60)
{
frameCounter = 0;
IAEngine::__FixedUpdate();
}
IAEngine::__RenderToTexture(gamePreviewTexture->GetHandle());
ImGui_ImplSDLGPU3_NewFrame(); ImGui_ImplSDLGPU3_NewFrame();
ImGui_ImplSDL3_NewFrame(); ImGui_ImplSDL3_NewFrame();
@ -122,7 +136,7 @@ namespace ia::iae
delete gamePreviewTexture; delete gamePreviewTexture;
RDC::Terminate(); IAEngine::__Terminate();
SDL_DestroyWindow(g_windowHandle); SDL_DestroyWindow(g_windowHandle);
@ -133,4 +147,36 @@ namespace ia::iae
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
return ia::iae::Run(argc, (const char **) argv); return ia::iae::Run(argc, (const char **) argv);
}
#include <IAEngine/LibInterface.hpp>
C_DECL(GameRequestedConfig *Game_GetConfigRequest())
{
return nullptr;
}
C_DECL(VOID Game_OnInitialize())
{
}
C_DECL(VOID Game_OnTerminate())
{
}
C_DECL(VOID Game_OnDebugDraw())
{
RDC::DrawRect({10, 10}, {700, 500}, {1.0f, 0.0f, 0.0f, 1.0f});
}
C_DECL(VOID Game_OnFixedUpdate())
{
}
C_DECL(VOID Game_OnUpdate(IN FLOAT32 deltaTime))
{
}
C_DECL(VOID Game_OnResize(IN INT32 newWidth, IN INT32 newHeight))
{
} }

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
//#include <EmbeddedResources.hpp> // #include <EmbeddedResources.hpp>
#include <GameData.hpp> #include <GameData.hpp>
#include <IAEngine/LibInterface.hpp> #include <IAEngine/LibInterface.hpp>
@ -77,6 +77,8 @@ namespace ia::iae
BOOL g_isDebugMode = false; BOOL g_isDebugMode = false;
#endif #endif
BOOL g_isHeadlessMode = false;
INT32 Run(IN CONST String &name, IN CONST String &packageName, IN CONST String &developerName, INT32 Run(IN CONST String &name, IN CONST String &packageName, IN CONST String &developerName,
IN CONST String &publisherName, IN IA_VERSION_TYPE version) IN CONST String &publisherName, IN IA_VERSION_TYPE version)
{ {
@ -111,9 +113,9 @@ namespace ia::iae
const auto gameVersion = g_gameVersion; const auto gameVersion = g_gameVersion;
SDL_SetAppMetadata(g_gameName.c_str(), IA_STRINGIFY_VERSION(gameVersion).c_str(), g_gamePackageName.c_str()); SDL_SetAppMetadata(g_gameName.c_str(), IA_STRINGIFY_VERSION(gameVersion).c_str(), g_gamePackageName.c_str());
//EmbeddedResources::Initialize(); // EmbeddedResources::Initialize();
IAEngine::Initialize(); IAEngine::__Initialize();
SDL_Event event{}; SDL_Event event{};
while (true) while (true)
@ -121,23 +123,22 @@ namespace ia::iae
SDL_PollEvent(&event); SDL_PollEvent(&event);
if (event.type == SDL_EVENT_QUIT) if (event.type == SDL_EVENT_QUIT)
break; break;
IAEngine::ProcessEvent(&event); IAEngine::__ProcessEvent(&event);
IAEngine::Update(); IAEngine::__Update();
frameCounter++; frameCounter++;
if (frameCounter >= 60) if (frameCounter >= 60)
{ {
frameCounter = 0; frameCounter = 0;
IAEngine::FixedUpdate(); IAEngine::__FixedUpdate();
} }
IAEngine::Draw(); IAEngine::__RenderToWindow();
IAEngine::DebugDraw();
} }
IAEngine::Terminate(); IAEngine::__Terminate();
//EmbeddedResources::Terminate(); // EmbeddedResources::Terminate();
SDL_DestroyWindow(g_windowHandle); SDL_DestroyWindow(g_windowHandle);
@ -149,8 +150,10 @@ namespace ia::iae
namespace ia::iae namespace ia::iae
{ {
VOID IAEngine::Initialize() VOID IAEngine::__Initialize()
{ {
g_isHeadlessMode = false;
RDC::Initialize(IVec2{g_designViewport.x, g_designViewport.y}, g_windowHandle, g_isDebugMode); RDC::Initialize(IVec2{g_designViewport.x, g_designViewport.y}, g_windowHandle, g_isDebugMode);
GameData::Initialize(); GameData::Initialize();
@ -161,7 +164,22 @@ namespace ia::iae
Game_OnInitialize(); Game_OnInitialize();
} }
VOID IAEngine::Terminate() VOID IAEngine::__InitializeHeadless()
{
g_isHeadlessMode = true;
if(!g_designViewport.x || !g_designViewport.y)
g_designViewport = {800, 600};
GameData::Initialize();
ChangeActiveScene(GameData::GetEntryScene() ? GameData::GetEntryScene()
: CreateScene({g_designViewport.x, g_designViewport.y}));
Game_OnInitialize();
}
VOID IAEngine::__Terminate()
{ {
Game_OnTerminate(); Game_OnTerminate();
@ -173,13 +191,25 @@ namespace ia::iae
DestroyResource(i); DestroyResource(i);
} }
VOID IAEngine::Draw() VOID IAEngine::__RenderToWindow()
{ {
g_activeScene->OnDraw(); g_activeScene->OnDraw();
RDC::RenderToWindow(); RDC::RenderToWindow();
g_activeScene->OnDebugDraw();
Game_OnDebugDraw();
} }
VOID IAEngine::Update() VOID IAEngine::__RenderToTexture(IN PVOID textureHandle)
{
g_activeScene->OnDraw();
RDC::RenderToTexture((SDL_GPUTexture *) textureHandle);
g_activeScene->OnDebugDraw();
Game_OnDebugDraw();
}
VOID IAEngine::__Update()
{ {
FLOAT32 deltaTime = 0; FLOAT32 deltaTime = 0;
@ -187,19 +217,13 @@ namespace ia::iae
Game_OnUpdate(deltaTime); Game_OnUpdate(deltaTime);
} }
VOID IAEngine::FixedUpdate() VOID IAEngine::__FixedUpdate()
{ {
g_activeScene->OnFixedUpdate(); g_activeScene->OnFixedUpdate();
Game_OnFixedUpdate(); Game_OnFixedUpdate();
} }
VOID IAEngine::DebugDraw() VOID IAEngine::__ProcessEvent(IN PVOID _event)
{
g_activeScene->OnDebugDraw();
Game_OnDebugDraw();
}
VOID IAEngine::ProcessEvent(IN PVOID _event)
{ {
const auto event = (SDL_Event *) _event; const auto event = (SDL_Event *) _event;
} }
@ -213,8 +237,8 @@ namespace ia::iae
auto pixels = stbi_load(path, &w, &h, &n, STBI_rgb_alpha); auto pixels = stbi_load(path, &w, &h, &n, STBI_rgb_alpha);
if (!pixels) if (!pixels)
THROW_INVALID_DATA(path); THROW_INVALID_DATA(path);
const auto t = RDC::CreateImage(pixels, w, h, tileWidth == -1 ? 1 : w / tileWidth, const auto t =
tileHeight == -1 ? 1 : h / tileHeight); RDC::CreateImage(pixels, w, h, tileWidth == -1 ? 1 : w / tileWidth, tileHeight == -1 ? 1 : h / tileHeight);
stbi_image_free(pixels); stbi_image_free(pixels);
return t; return t;
} }
@ -345,8 +369,7 @@ namespace ia::iae
IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset) IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset)
{ {
const auto t = static_cast<Resource_Texture *>(g_resources[tileSheet]); const auto t = static_cast<Resource_Texture *>(g_resources[tileSheet]);
RDC::DrawSpriteTopLeft(t->Texture, tileIndexX, tileIndexY, position, scale, rotation, flipH, flipV, RDC::DrawSpriteTopLeft(t->Texture, tileIndexX, tileIndexY, position, scale, rotation, flipH, flipV, uvOffset);
uvOffset);
} }
VOID IAEngine::DrawSprite(IN Handle sprite, IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, VOID IAEngine::DrawSprite(IN Handle sprite, IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH,
@ -360,8 +383,8 @@ namespace ia::iae
IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset) IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset)
{ {
const auto t = static_cast<Resource_SpriteSheet *>(g_resources[spriteSheet]); const auto t = static_cast<Resource_SpriteSheet *>(g_resources[spriteSheet]);
RDC::DrawSpriteTopLeft(t->Texture, frameIndex, animationIndex, position, scale, rotation, flipH, RDC::DrawSpriteTopLeft(t->Texture, frameIndex, animationIndex, position, scale, rotation, flipH, flipV,
flipV, uvOffset); uvOffset);
} }
} // namespace ia::iae } // namespace ia::iae

View File

@ -62,18 +62,14 @@ namespace ia::iae
IN Vec2 scale = {1.0f, 1.0f}, IN FLOAT32 rotation = 0.0f, IN BOOL flipH = false, IN Vec2 scale = {1.0f, 1.0f}, IN FLOAT32 rotation = 0.0f, IN BOOL flipH = false,
IN BOOL flipV = false, IN Vec2 uvOffset = {}); IN BOOL flipV = false, IN Vec2 uvOffset = {});
private: public:
STATIC VOID Initialize(); STATIC VOID __Initialize();
STATIC VOID Terminate(); STATIC VOID __InitializeHeadless();
STATIC VOID Draw(); STATIC VOID __Terminate();
STATIC VOID Update(); STATIC VOID __RenderToWindow();
STATIC VOID FixedUpdate(); STATIC VOID __RenderToTexture(IN PVOID textureHandle);
STATIC VOID DebugDraw(); STATIC VOID __Update();
STATIC VOID ProcessEvent(IN PVOID event); STATIC VOID __FixedUpdate();
STATIC VOID __ProcessEvent(IN PVOID event);
friend INT32 Run(IN CONST String &name, IN CONST String &packageName, IN CONST String &developerName,
IN CONST String &publisherName, IN IA_VERSION_TYPE version);
friend class Scene;
}; };
} // namespace ia::iae } // namespace ia::iae

View File

@ -9,7 +9,7 @@ struct SpriteInstanceData
}; };
layout (location = 0) in vec2 inPosition; layout (location = 0) in vec2 inPosition;
layout (location = 1) in vec2 inTexCoord; layout (location = 1) in vec4 inTexCoord;
layout(location = 0) out vec2 outTexCoord; layout(location = 0) out vec2 outTexCoord;
layout(location = 1) out vec4 outVertexColor; layout(location = 1) out vec4 outVertexColor;
@ -29,6 +29,7 @@ void main()
{ {
SpriteInstanceData spriteData = sboSpriteData.data[gl_InstanceIndex]; SpriteInstanceData spriteData = sboSpriteData.data[gl_InstanceIndex];
gl_Position = uboPerScene.projection * uboPerFrame.view * spriteData.Transform * vec4(inPosition, 0.0f, 1.0f); gl_Position = uboPerScene.projection * uboPerFrame.view * spriteData.Transform * vec4(inPosition, 0.0f, 1.0f);
outTexCoord = vec2(spriteData.TexCoords) + vec2(spriteData.TexCoords.z, spriteData.TexCoords.w) * inTexCoord; vec4 t = spriteData.TexCoords * inTexCoord;
outTexCoord = vec2(t.x + t.z, t.y + t.w);
outVertexColor = spriteData.Color; outVertexColor = spriteData.Color;
} }

View File

@ -0,0 +1,13 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec4 inVertexColor;
layout(location = 0) out vec4 outColor;
void main()
{
outColor = inVertexColor;
if(outColor.w < 0.1)
discard;
}

View File

@ -0,0 +1,20 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout (location = 0) in vec2 inPosition;
layout (location = 1) in vec4 inVertexColor;
layout(location = 0) out vec4 outVertexColor;
layout(set = 1, binding = 0) uniform UBO_Vertex_PerScene {
mat4 projection;
} uboPerScene;
layout(set = 1, binding = 1) uniform UBO_Vertex_PerFrame {
mat4 view;
} uboPerFrame;
void main()
{
gl_Position = uboPerScene.projection * uboPerFrame.view * vec4(inPosition, 0.0f, 1.0f);
outVertexColor = inVertexColor;
}

File diff suppressed because one or more lines are too long

View File

@ -19,7 +19,7 @@
namespace ia::iae namespace ia::iae
{ {
RDC_Pipeline::RDC_Pipeline(IN SDL_GPUTextureFormat renderTargetFormat, IN CONST StageDesc &vertexStageDesc, RDC_Pipeline::RDC_Pipeline(IN SDL_GPUTextureFormat renderTargetFormat, IN CONST StageDesc &vertexStageDesc,
IN CONST StageDesc &pixelStageDesc, IN BOOL enableVertexBuffer) IN CONST StageDesc &pixelStageDesc, IN SDL_GPUPrimitiveType primitiveType, IN BOOL enableVertexBuffer)
{ {
SDL_GPUShader *vertexShader{}; SDL_GPUShader *vertexShader{};
SDL_GPUShader *pixelShader{}; SDL_GPUShader *pixelShader{};
@ -69,7 +69,7 @@ namespace ia::iae
SDL_GPUVertexAttribute vertexAttributes[] = { SDL_GPUVertexAttribute vertexAttributes[] = {
{.location = 0, .buffer_slot = 0, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2, .offset = 0}, {.location = 0, .buffer_slot = 0, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2, .offset = 0},
{.location = 1, .buffer_slot = 0, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2, .offset = sizeof(Vec2)}}; {.location = 1, .buffer_slot = 0, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4, .offset = sizeof(Vec2)}};
SDL_GPUGraphicsPipelineCreateInfo createInfo = { SDL_GPUGraphicsPipelineCreateInfo createInfo = {
.vertex_shader = vertexShader, .vertex_shader = vertexShader,
@ -77,8 +77,8 @@ namespace ia::iae
.vertex_input_state = SDL_GPUVertexInputState{.vertex_buffer_descriptions = &vertexBufferDesc, .vertex_input_state = SDL_GPUVertexInputState{.vertex_buffer_descriptions = &vertexBufferDesc,
.num_vertex_buffers = enableVertexBuffer ? (UINT32) 1 : 0, .num_vertex_buffers = enableVertexBuffer ? (UINT32) 1 : 0,
.vertex_attributes = vertexAttributes, .vertex_attributes = vertexAttributes,
.num_vertex_attributes = enableVertexBuffer ? (UINT32) 2 : 0}, .num_vertex_attributes = enableVertexBuffer ? (UINT32)2 : 0},
.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, .primitive_type = primitiveType,
.rasterizer_state = SDL_GPURasterizerState{.fill_mode = SDL_GPU_FILLMODE_FILL, .rasterizer_state = SDL_GPURasterizerState{.fill_mode = SDL_GPU_FILLMODE_FILL,
.cull_mode = SDL_GPU_CULLMODE_NONE, .cull_mode = SDL_GPU_CULLMODE_NONE,
.front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE, .front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE,

View File

@ -26,19 +26,30 @@ namespace ia::iae
Mat4 RDC::s_projectionMatrix; Mat4 RDC::s_projectionMatrix;
SDL_Window *RDC::s_windowHandle; SDL_Window *RDC::s_windowHandle;
Handle RDC::s_quadGeometry; Handle RDC::s_quadGeometry;
RDC_Pipeline *RDC::s_primitiveDrawPipeline;
RDC_Pipeline *RDC::s_dynamicSpritePipeline; RDC_Pipeline *RDC::s_dynamicSpritePipeline;
SDL_GPUSampler *RDC::s_linearClampSampler; SDL_GPUSampler *RDC::s_linearClampSampler;
SDL_GPUSampler *RDC::s_linearRepeatSampler; SDL_GPUSampler *RDC::s_linearRepeatSampler;
Vec2 RDC::s_cameraPosition{}; Vec2 RDC::s_cameraPosition{};
IVec2 RDC::s_viewportExtent; IVec2 RDC::s_viewportExtent;
RDC_Texture *RDC::s_defaultTexture{};
RDC_TextureAtlas *RDC::s_staticSpriteAtlas{}; RDC_TextureAtlas *RDC::s_staticSpriteAtlas{};
RDC_TextureAtlas *RDC::s_dynamicSpriteAtlas{}; RDC_TextureAtlas *RDC::s_dynamicSpriteAtlas{};
INT32 RDC::s_spriteInstanceCount{};
RDC_HostVisibleBuffer *RDC::s_primitiveInstanceBuffer{};
RDC_HostVisibleBuffer *RDC::s_staticSpriteInstanceBuffer{}; RDC_HostVisibleBuffer *RDC::s_staticSpriteInstanceBuffer{};
RDC_HostVisibleBuffer *RDC::s_dynamicSpriteInstanceBuffer{}; RDC_HostVisibleBuffer *RDC::s_dynamicSpriteInstanceBuffer{};
RDC_Texture *RDC::s_defaultTexture{};
INT32 RDC::s_spriteInstanceCount{};
RDC_SpriteInstanceData RDC::s_spriteInstances[RDC::MAX_SPRITE_COUNT]; RDC_SpriteInstanceData RDC::s_spriteInstances[RDC::MAX_SPRITE_COUNT];
INT32 RDC::s_primitiveInstanceCount{};
GeometryVertex RDC::s_primitiveInstances[RDC::MAX_PRIMITIVE_COUNT];
VOID RDC::Initialize(IN IVec2 viewportExtent, IN SDL_Window *windowHandle, IN BOOL isDebugMode) VOID RDC::Initialize(IN IVec2 viewportExtent, IN SDL_Window *windowHandle, IN BOOL isDebugMode)
{ {
EmbeddedResources::Initialize(); EmbeddedResources::Initialize();
@ -69,7 +80,11 @@ namespace ia::iae
delete s_defaultTexture; delete s_defaultTexture;
delete s_staticSpriteAtlas; delete s_staticSpriteAtlas;
delete s_dynamicSpriteAtlas; delete s_dynamicSpriteAtlas;
delete s_primitiveDrawPipeline;
delete s_dynamicSpritePipeline; delete s_dynamicSpritePipeline;
delete s_primitiveInstanceBuffer;
delete s_staticSpriteInstanceBuffer; delete s_staticSpriteInstanceBuffer;
delete s_dynamicSpriteInstanceBuffer; delete s_dynamicSpriteInstanceBuffer;
@ -85,11 +100,12 @@ namespace ia::iae
glm::orthoLH(0.0f, (FLOAT32) s_viewportExtent.x, (FLOAT32) s_viewportExtent.y, 0.0f, -1.0f, 1.0f); glm::orthoLH(0.0f, (FLOAT32) s_viewportExtent.x, (FLOAT32) s_viewportExtent.y, 0.0f, -1.0f, 1.0f);
} }
VOID RDC::Render(IN SDL_GPURenderPass* renderPass, IN SDL_GPUCommandBuffer* commandBuffer) VOID RDC::Render(IN SDL_GPURenderPass *renderPass, IN SDL_GPUCommandBuffer *commandBuffer)
{ {
s_dynamicSpritePipeline->Bind(renderPass); s_dynamicSpritePipeline->Bind(renderPass);
SDL_PushGPUVertexUniformData(commandBuffer, 0, &s_projectionMatrix, sizeof(Mat4)); SDL_PushGPUVertexUniformData(commandBuffer, 0, &s_projectionMatrix, sizeof(Mat4));
SDL_PushGPUVertexUniformData(commandBuffer, 1, &s_viewMatrix, sizeof(Mat4)); SDL_PushGPUVertexUniformData(commandBuffer, 1, &s_viewMatrix, sizeof(Mat4));
SDL_GPUTextureSamplerBinding textureBinding{.texture = s_dynamicSpriteAtlas SDL_GPUTextureSamplerBinding textureBinding{.texture = s_dynamicSpriteAtlas
? s_dynamicSpriteAtlas->GetTexture()->GetHandle() ? s_dynamicSpriteAtlas->GetTexture()->GetHandle()
: s_defaultTexture->GetHandle(), : s_defaultTexture->GetHandle(),
@ -98,13 +114,27 @@ namespace ia::iae
RDC_Device::BindGeometry(renderPass, s_quadGeometry); RDC_Device::BindGeometry(renderPass, s_quadGeometry);
if (s_spriteInstanceCount) if (s_spriteInstanceCount)
{ {
const auto spriteInstanceBuffer = s_dynamicSpriteInstanceBuffer->GetHandle(); const auto buffer = s_dynamicSpriteInstanceBuffer->GetHandle();
s_dynamicSpriteInstanceBuffer->CopyFrom(s_spriteInstances, s_dynamicSpriteInstanceBuffer->CopyFrom(s_spriteInstances,
sizeof(RDC_SpriteInstanceData) * s_spriteInstanceCount); sizeof(RDC_SpriteInstanceData) * s_spriteInstanceCount);
SDL_BindGPUVertexStorageBuffers(renderPass, 0, &spriteInstanceBuffer, 1); SDL_BindGPUVertexStorageBuffers(renderPass, 0, &buffer, 1);
SDL_DrawGPUIndexedPrimitives(renderPass, 6, s_spriteInstanceCount, 0, 0, 0); SDL_DrawGPUIndexedPrimitives(renderPass, 6, s_spriteInstanceCount, 0, 0, 0);
} }
s_spriteInstanceCount = 0; s_spriteInstanceCount = 0;
s_primitiveDrawPipeline->Bind(renderPass);
SDL_PushGPUVertexUniformData(commandBuffer, 0, &s_projectionMatrix, sizeof(Mat4));
SDL_PushGPUVertexUniformData(commandBuffer, 1, &s_viewMatrix, sizeof(Mat4));
if (s_primitiveInstanceCount)
{
s_primitiveInstanceBuffer->CopyFrom(s_primitiveInstances,
sizeof(GeometryVertex) * s_primitiveInstanceCount);
SDL_GPUBufferBinding bufferBindings[] = {{.buffer = s_primitiveInstanceBuffer->GetHandle(), .offset = 0}};
SDL_BindGPUVertexBuffers(renderPass, 0, &bufferBindings[0], 1);
SDL_DrawGPUPrimitives(renderPass, s_primitiveInstanceCount << 1, 1, 0, 0);
}
s_primitiveInstanceCount = 0;
} }
VOID RDC::RenderToWindow() VOID RDC::RenderToWindow()
@ -192,6 +222,27 @@ namespace ia::iae
.Color = {1.0f, 1.0f, 1.0f, 1.0f}}; .Color = {1.0f, 1.0f, 1.0f, 1.0f}};
return _s; return _s;
} }
VOID RDC::DrawLine(IN Vec2 start, IN Vec2 end, IN Vec4 color)
{
s_primitiveInstances[s_primitiveInstanceCount++] = {start, color};
s_primitiveInstances[s_primitiveInstanceCount++] = { end, color };
}
VOID RDC::DrawRect(IN Vec2 start, IN Vec2 end, IN Vec4 color)
{
s_primitiveInstances[s_primitiveInstanceCount++] = {start, color};
s_primitiveInstances[s_primitiveInstanceCount++] = {Vec2{end.x, start.y}, color};
s_primitiveInstances[s_primitiveInstanceCount++] = {Vec2{end.x, start.y}, color};
s_primitiveInstances[s_primitiveInstanceCount++] = {end, color};
s_primitiveInstances[s_primitiveInstanceCount++] = {end, color};
s_primitiveInstances[s_primitiveInstanceCount++] = {Vec2{start.x, end.y}, color};
s_primitiveInstances[s_primitiveInstanceCount++] = {Vec2{start.x, end.y}, color};
s_primitiveInstances[s_primitiveInstanceCount++] = {start, color};
}
} // namespace ia::iae } // namespace ia::iae
namespace ia::iae namespace ia::iae
@ -271,6 +322,7 @@ namespace ia::iae
{ {
s_dynamicSpriteInstanceBuffer = s_dynamicSpriteInstanceBuffer =
new RDC_HostVisibleBuffer(RDC_Buffer::EType::STORAGE, sizeof(s_spriteInstances)); new RDC_HostVisibleBuffer(RDC_Buffer::EType::STORAGE, sizeof(s_spriteInstances));
s_primitiveInstanceBuffer = new RDC_HostVisibleBuffer(RDC_Buffer::EType::VERTEX, sizeof(s_primitiveInstances));
} }
VOID RDC::InitializeTextures() VOID RDC::InitializeTextures()
@ -286,6 +338,22 @@ namespace ia::iae
VOID RDC::InitializePipelines() VOID RDC::InitializePipelines()
{ {
s_primitiveDrawPipeline =
new RDC_Pipeline(RDC_Device::GetSwapchainTextureFormat(),
RDC_Pipeline::StageDesc{
.SourceData = EmbeddedResources::GetResource("Shaders/PrimitiveDraw.vert"),
.SamplerCount = 0,
.UniformBufferCount = 2,
.StorageBufferCount = 0,
},
RDC_Pipeline::StageDesc{
.SourceData = EmbeddedResources::GetResource("Shaders/PrimitiveDraw.frag"),
.SamplerCount = 0,
.UniformBufferCount = 0,
.StorageBufferCount = 0,
},
SDL_GPU_PRIMITIVETYPE_LINELIST, true);
s_dynamicSpritePipeline = s_dynamicSpritePipeline =
new RDC_Pipeline(RDC_Device::GetSwapchainTextureFormat(), new RDC_Pipeline(RDC_Device::GetSwapchainTextureFormat(),
RDC_Pipeline::StageDesc{ RDC_Pipeline::StageDesc{
@ -300,17 +368,17 @@ namespace ia::iae
.UniformBufferCount = 0, .UniformBufferCount = 0,
.StorageBufferCount = 0, .StorageBufferCount = 0,
}, },
true); SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, true);
} }
VOID RDC::InitializeGeometries() VOID RDC::InitializeGeometries()
{ {
s_quadGeometry = RDC_Device::CreateGeometry( s_quadGeometry = RDC_Device::CreateGeometry(
{ {
{glm::vec2{0, 1}, glm::vec2{0, 1}}, {glm::vec2{0.0f, 1.0f}, glm::vec4{1.0f, 1.0f, 0.0f, 1.0f}},
{glm::vec2{1, 1}, glm::vec2{1, 1}}, {glm::vec2{1.0f, 1.0f}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}},
{glm::vec2{1, 0}, glm::vec2{1, 0}}, {glm::vec2{1.0f, 0.0f}, glm::vec4{1.0f, 1.0f, 1.0f, 0.0f}},
{glm::vec2{0, 0}, glm::vec2{0, 0}}, {glm::vec2{0.0f, 0.0f}, glm::vec4{1.0f, 1.0f, 0.0f, 0.0f}},
}, },
{0, 1, 2, 2, 3, 0}); {0, 1, 2, 2, 3, 0});
} }

View File

@ -24,7 +24,7 @@ namespace ia::iae
: (UINT32) 1) : (UINT32) 1)
{ {
SDL_GPUTextureCreateInfo createInfo{.type = SDL_GPU_TEXTURETYPE_2D, SDL_GPUTextureCreateInfo createInfo{.type = SDL_GPU_TEXTURETYPE_2D,
.format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM, .format = RDC_Device::GetSwapchainTextureFormat(),
.width = (UINT32) width, .width = (UINT32) width,
.height = (UINT32) height, .height = (UINT32) height,
.layer_count_or_depth = 1, .layer_count_or_depth = 1,
@ -54,6 +54,10 @@ namespace ia::iae
TMP_COLOR_BUFFER.resize(m_width * m_height * 4); TMP_COLOR_BUFFER.resize(m_width * m_height * 4);
const auto swapchainFormat = RDC_Device::GetSwapchainTextureFormat();
const auto swapRB = (swapchainFormat == SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM) ||
(swapchainFormat == SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM_SRGB);
if (stride == -1) if (stride == -1)
{ {
for (SIZE_T i = 0; i < TMP_COLOR_BUFFER.size() >> 2; i++) for (SIZE_T i = 0; i < TMP_COLOR_BUFFER.size() >> 2; i++)
@ -63,6 +67,9 @@ namespace ia::iae
TMP_COLOR_BUFFER[i * 4 + 1] = static_cast<UINT8>(rgbaData[i * 4 + 1] * 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 + 2] = static_cast<UINT8>(rgbaData[i * 4 + 2] * a);
TMP_COLOR_BUFFER[i * 4 + 3] = rgbaData[i * 4 + 3]; TMP_COLOR_BUFFER[i * 4 + 3] = rgbaData[i * 4 + 3];
if (swapRB)
std::swap(TMP_COLOR_BUFFER[i * 4 + 0], TMP_COLOR_BUFFER[i * 4 + 2]);
} }
} }
else else
@ -77,6 +84,9 @@ namespace ia::iae
TMP_COLOR_BUFFER[(x + y * m_width) * 4 + 1] = static_cast<UINT8>(p[1] * a); TMP_COLOR_BUFFER[(x + y * m_width) * 4 + 1] = static_cast<UINT8>(p[1] * a);
TMP_COLOR_BUFFER[(x + y * m_width) * 4 + 2] = static_cast<UINT8>(p[2] * a); TMP_COLOR_BUFFER[(x + y * m_width) * 4 + 2] = static_cast<UINT8>(p[2] * a);
TMP_COLOR_BUFFER[(x + y * m_width) * 4 + 3] = p[3]; TMP_COLOR_BUFFER[(x + y * m_width) * 4 + 3] = p[3];
if (swapRB)
std::swap(TMP_COLOR_BUFFER[(x + y * m_width) * 4 + 0],
TMP_COLOR_BUFFER[(x + y * m_width) * 4 + 0]);
} }
} }
} }

View File

@ -24,7 +24,7 @@ namespace ia::iae
struct GeometryVertex struct GeometryVertex
{ {
Vec2 Position; Vec2 Position;
Vec2 TexCoords; Vec4 TexCoords_Color;
}; };
class RDC_Device class RDC_Device

View File

@ -32,11 +32,12 @@ namespace ia::iae
}; };
public: public:
RDC_Pipeline(IN SDL_GPUTextureFormat renderTargetFormat, IN CONST StageDesc &vertexStageDesc, IN CONST StageDesc &pixelStageDesc, RDC_Pipeline(IN SDL_GPUTextureFormat renderTargetFormat, IN CONST StageDesc &vertexStageDesc,
IN CONST StageDesc &pixelStageDesc, IN SDL_GPUPrimitiveType primitiveType,
IN BOOL enableVertexBuffer); IN BOOL enableVertexBuffer);
~RDC_Pipeline(); ~RDC_Pipeline();
VOID Bind(IN SDL_GPURenderPass* renderPass); VOID Bind(IN SDL_GPURenderPass *renderPass);
public: public:
SDL_GPUGraphicsPipeline *GetHandle() CONST SDL_GPUGraphicsPipeline *GetHandle() CONST

View File

@ -38,6 +38,7 @@ namespace ia::iae
{ {
public: public:
STATIC CONSTEXPR INT32 MAX_SPRITE_COUNT = 100000; STATIC CONSTEXPR INT32 MAX_SPRITE_COUNT = 100000;
STATIC CONSTEXPR INT32 MAX_PRIMITIVE_COUNT = 100000;
public: public:
STATIC VOID Initialize(IN IVec2 viewportExtent, IN SDL_Window *windowHandle, IN BOOL isDebugMode); STATIC VOID Initialize(IN IVec2 viewportExtent, IN SDL_Window *windowHandle, IN BOOL isDebugMode);
@ -57,6 +58,9 @@ namespace ia::iae
STATIC Vec2 DrawSpriteCentered(IN Handle image, IN INT32 tileIndexX, IN INT32 tileIndexY, STATIC Vec2 DrawSpriteCentered(IN Handle image, IN INT32 tileIndexX, IN INT32 tileIndexY,
IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH = false, IN BOOL flipV = false, IN Vec2 uvOffset = {}); IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH = false, IN BOOL flipV = false, IN Vec2 uvOffset = {});
STATIC VOID DrawLine(IN Vec2 start, IN Vec2 end, IN Vec4 color);
STATIC VOID DrawRect(IN Vec2 start, IN Vec2 end, IN Vec4 color);
STATIC Handle CreateImage(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height, IN INT32 tileCountX = 1, STATIC Handle CreateImage(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height, IN INT32 tileCountX = 1,
IN INT32 tileCountY = 1); IN INT32 tileCountY = 1);
STATIC VOID DestroyImage(IN Handle image); STATIC VOID DestroyImage(IN Handle image);
@ -74,20 +78,29 @@ namespace ia::iae
private: private:
STATIC Mat4 s_viewMatrix; STATIC Mat4 s_viewMatrix;
STATIC IVec2 s_viewportExtent;
STATIC Mat4 s_projectionMatrix;
STATIC Vec2 s_cameraPosition; STATIC Vec2 s_cameraPosition;
STATIC Handle s_quadGeometry; STATIC Handle s_quadGeometry;
STATIC IVec2 s_viewportExtent;
STATIC Mat4 s_projectionMatrix;
STATIC SDL_Window *s_windowHandle; STATIC SDL_Window *s_windowHandle;
STATIC RDC_Texture* s_defaultTexture;
STATIC RDC_Pipeline *s_primitiveDrawPipeline;
STATIC RDC_Pipeline *s_dynamicSpritePipeline; STATIC RDC_Pipeline *s_dynamicSpritePipeline;
STATIC SDL_GPUSampler *s_linearClampSampler; STATIC SDL_GPUSampler *s_linearClampSampler;
STATIC SDL_GPUSampler *s_linearRepeatSampler; STATIC SDL_GPUSampler *s_linearRepeatSampler;
STATIC RDC_TextureAtlas *s_staticSpriteAtlas; STATIC RDC_TextureAtlas *s_staticSpriteAtlas;
STATIC RDC_TextureAtlas *s_dynamicSpriteAtlas; STATIC RDC_TextureAtlas *s_dynamicSpriteAtlas;
STATIC RDC_HostVisibleBuffer* s_primitiveInstanceBuffer;
STATIC RDC_HostVisibleBuffer* s_staticSpriteInstanceBuffer; STATIC RDC_HostVisibleBuffer* s_staticSpriteInstanceBuffer;
STATIC RDC_HostVisibleBuffer* s_dynamicSpriteInstanceBuffer; STATIC RDC_HostVisibleBuffer* s_dynamicSpriteInstanceBuffer;
STATIC INT32 s_spriteInstanceCount; STATIC INT32 s_spriteInstanceCount;
STATIC RDC_Texture* s_defaultTexture;
STATIC RDC_SpriteInstanceData s_spriteInstances[MAX_SPRITE_COUNT]; STATIC RDC_SpriteInstanceData s_spriteInstances[MAX_SPRITE_COUNT];
STATIC INT32 s_primitiveInstanceCount;
STATIC GeometryVertex s_primitiveInstances[MAX_PRIMITIVE_COUNT];
}; };
} // namespace ia::iae } // namespace ia::iae