diff --git a/Engine/Src/Imp/CPP/Renderer/Renderer.cpp b/Engine/Src/Imp/CPP/Renderer/Renderer.cpp index bf8ce73..39490e2 100644 --- a/Engine/Src/Imp/CPP/Renderer/Renderer.cpp +++ b/Engine/Src/Imp/CPP/Renderer/Renderer.cpp @@ -38,10 +38,10 @@ namespace ia::iae Pipeline *Renderer::s_geometryPipeline{}; Pipeline *Renderer::s_postprocessPipeline{}; + Renderer::Geometry *Renderer::s_quadGeometry{}; + VOID Renderer::Initialize() { - SDL_GetWindowSizeInPixels(g_windowHandle, &s_screenWidth, &s_screenHeight); - if (!(s_gpuDevice = SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV, Engine::IsDebugMode(), nullptr))) THROW_UNKNOWN("Failed to create the SDL GPU Device: ", SDL_GetError()); @@ -53,16 +53,8 @@ namespace ia::iae GPUResourceManager::Initialize(); - // Initialize Render Targets - s_renderTargetSceneDepth = - GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET, s_screenWidth, s_screenHeight, - nullptr, SDL_GPU_TEXTUREFORMAT_D16_UNORM); - s_renderTargetSceneColor = GPUResourceManager::CreateTexture( - SDL_GPU_TEXTUREUSAGE_COLOR_TARGET | SDL_GPU_TEXTUREUSAGE_SAMPLER, s_screenWidth, s_screenHeight, nullptr, - SDL_GetGPUSwapchainTextureFormat(s_gpuDevice, g_windowHandle)); - s_renderTargetDebugDrawColor = GPUResourceManager::CreateTexture( - SDL_GPU_TEXTUREUSAGE_COLOR_TARGET | SDL_GPU_TEXTUREUSAGE_SAMPLER, s_screenWidth, s_screenHeight, nullptr, - SDL_GetGPUSwapchainTextureFormat(s_gpuDevice, g_windowHandle)); + SDL_GetWindowSizeInPixels(g_windowHandle, &s_screenWidth, &s_screenHeight); + OnScreenResize(s_screenWidth, s_screenHeight); // Initialize Pipelines s_geometryPipeline = new Pipeline( @@ -96,9 +88,6 @@ namespace ia::iae DebugDraw::Initialize(); - s_state.ProjectionMatrix = - glm::orthoLH(0.0f, (FLOAT32) s_screenWidth, (FLOAT32) s_screenHeight, 0.0f, -2097152.0f, 2097152.0f); - s_state.ColorTargetInfo.clear_color = SDL_FColor{0.33f, 0.33f, 0.33f, 1.0f}; s_state.ColorTargetInfo.load_op = SDL_GPU_LOADOP_CLEAR; s_state.ColorTargetInfo.store_op = SDL_GPU_STOREOP_STORE; @@ -110,12 +99,23 @@ namespace ia::iae s_state.DepthStencilTargetInfo.store_op = SDL_GPU_STOREOP_STORE; s_state.DepthStencilTargetInfo.stencil_load_op = SDL_GPU_LOADOP_CLEAR; s_state.DepthStencilTargetInfo.stencil_store_op = SDL_GPU_STOREOP_STORE; + + s_quadGeometry = CreateGeometry( + { + {glm::vec3{0, 1, 0}, glm::vec2{0, 1}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}}, + {glm::vec3{1, 1, 0}, glm::vec2{1, 1}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}}, + {glm::vec3{1, 0, 0}, glm::vec2{1, 0}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}}, + {glm::vec3{0, 0, 0}, glm::vec2{0, 0}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}}, + }, + {0, 1, 2, 2, 3, 0}); } VOID Renderer::Terminate() { SDL_WaitForGPUIdle(s_gpuDevice); + DestroyGeometry(s_quadGeometry); + DebugDraw::Terminate(); delete s_geometryPipeline; @@ -133,6 +133,8 @@ namespace ia::iae VOID Renderer::BeginFrame() { + STATIC Mat4 IdentityMatrix(1.0f); + if (!(s_state.ActiveCommandBuffer = SDL_AcquireGPUCommandBuffer(s_gpuDevice))) THROW_UNKNOWN("Failed to acquire SDL GPU command buffer: ", SDL_GetError()); @@ -143,7 +145,10 @@ namespace ia::iae SDL_BindGPUGraphicsPipeline(s_state.ActiveRenderPass, s_geometryPipeline->GetHandle()); SDL_PushGPUVertexUniformData(s_state.ActiveCommandBuffer, 0, &s_state.ProjectionMatrix, sizeof(Mat4)); - //SDL_PushGPUVertexUniformData(s_state.ActiveCommandBuffer, 1, s_state.ActiveCamera->GetMatrix(), sizeof(Mat4)); + SDL_PushGPUVertexUniformData( + s_state.ActiveCommandBuffer, 1, + (s_state.ActiveCamera && !s_state.CameraRelative) ? s_state.ActiveCamera->GetMatrix() : &IdentityMatrix, + sizeof(Mat4)); } VOID Renderer::EndFrame() @@ -185,13 +190,84 @@ namespace ia::iae VOID Renderer::OnScreenResize(IN INT32 newWidth, IN INT32 newHeight) { + s_screenWidth = newWidth; + s_screenHeight = newHeight; + if (s_renderTargetSceneDepth) + GPUResourceManager::DestroyTexture(s_renderTargetSceneDepth); + if (s_renderTargetSceneColor) + GPUResourceManager::DestroyTexture(s_renderTargetSceneColor); + if (s_renderTargetDebugDrawColor) + GPUResourceManager::DestroyTexture(s_renderTargetDebugDrawColor); + + s_renderTargetSceneDepth = + GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET, s_screenWidth, s_screenHeight, + nullptr, SDL_GPU_TEXTUREFORMAT_D16_UNORM); + s_renderTargetSceneColor = GPUResourceManager::CreateTexture( + SDL_GPU_TEXTUREUSAGE_COLOR_TARGET | SDL_GPU_TEXTUREUSAGE_SAMPLER, s_screenWidth, s_screenHeight, nullptr, + SDL_GetGPUSwapchainTextureFormat(s_gpuDevice, g_windowHandle)); + s_renderTargetDebugDrawColor = GPUResourceManager::CreateTexture( + SDL_GPU_TEXTUREUSAGE_COLOR_TARGET | SDL_GPU_TEXTUREUSAGE_SAMPLER, s_screenWidth, s_screenHeight, nullptr, + SDL_GetGPUSwapchainTextureFormat(s_gpuDevice, g_windowHandle)); + + s_state.ProjectionMatrix = + glm::orthoLH(0.0f, (FLOAT32) s_screenWidth, (FLOAT32) s_screenHeight, 0.0f, -2097152.0f, 2097152.0f); } SDL_GPUTextureFormat Renderer::GetRenderTargetFormat() { return SDL_GetGPUSwapchainTextureFormat(s_gpuDevice, g_windowHandle); } + + Renderer::Geometry *Renderer::CreateGeometry(IN CONST Vector &vertices, + IN CONST Vector &indices) + { + const auto mesh = new Geometry(); + mesh->VertexBuffer = GPUResourceManager::CreateDeviceLocalBuffer( + SDL_GPU_BUFFERUSAGE_VERTEX, vertices.data(), static_cast(vertices.size() * sizeof(vertices[0]))); + mesh->IndexBuffer = GPUResourceManager::CreateDeviceLocalBuffer( + SDL_GPU_BUFFERUSAGE_INDEX, indices.data(), static_cast(indices.size() * sizeof(indices[0]))); + mesh->IndexCount = static_cast(indices.size()); + return mesh; + } + + VOID Renderer::DestroyGeometry(IN Geometry *handle) + { + delete handle; + } + + VOID Renderer::DrawGeometry(IN Geometry *handle) + { +#pragma pack(push, 1) + + STATIC struct + { + INT32 FlippedH{false}; + INT32 FlippedV{false}; + Vec2 TextureOffset{0.0f, 0.0f}; + glm::vec4 ColorOverlay{1.0f, 1.0f, 1.0f, 1.0f}; + } s_fragmentUniform{}; + +#pragma pack(pop) + + s_fragmentUniform.ColorOverlay = Vec4(s_state.ColorOverlay.R / 255.0f, s_state.ColorOverlay.G / 255.0f, + s_state.ColorOverlay.B / 255.0f, s_state.ColorOverlay.A / 255.0f); + s_fragmentUniform.FlippedH = s_state.FlippedH; + s_fragmentUniform.FlippedV = s_state.FlippedV; + s_fragmentUniform.TextureOffset = s_state.TextureOffset; + SDL_GPUTextureSamplerBinding textureBinding{.texture = s_state.ActiveTexture, + .sampler = GPUResourceManager::GetSampler_LinearRepeat()}; + SDL_BindGPUFragmentSamplers(s_state.ActiveRenderPass, 0, &textureBinding, 1); + SDL_PushGPUFragmentUniformData(s_state.ActiveCommandBuffer, 0, &s_fragmentUniform, sizeof(s_fragmentUniform)); + + SDL_SetGPUScissor(s_state.ActiveRenderPass, &s_state.Scissor); + + SDL_GPUBufferBinding bufferBindings[] = {{.buffer = handle->VertexBuffer, .offset = 0}, + {.buffer = handle->IndexBuffer, .offset = 0}}; + SDL_BindGPUVertexBuffers(s_state.ActiveRenderPass, 0, bufferBindings, 1); + SDL_BindGPUIndexBuffer(s_state.ActiveRenderPass, &bufferBindings[1], SDL_GPU_INDEXELEMENTSIZE_32BIT); + SDL_DrawGPUIndexedPrimitives(s_state.ActiveRenderPass, handle->IndexCount, 1, 0, 0, 0); + } } // namespace ia::iae namespace ia::iae @@ -203,15 +279,17 @@ namespace ia::iae Handle Engine::CreateGeometry(IN CONST Vector &vertices, IN CONST Vector &indices) { - return INVALID_HANDLE; + return (Handle) Renderer::CreateGeometry(vertices, indices); } VOID Engine::DestroyGeometry(IN Handle geometry) { + Renderer::DestroyGeometry((Renderer::Geometry *) geometry); } VOID Engine::DrawGeometry(IN Handle handle) { + Renderer::DrawGeometry((Renderer::Geometry *) handle); } VOID Engine::SetRenderState_Scissor(IN IVec4 rect) @@ -247,11 +325,35 @@ namespace ia::iae VOID Engine::SetRenderState_Texture(IN Handle image) { - Renderer::s_state.ActiveTexture = image; + Renderer::s_state.ActiveTexture = (SDL_GPUTexture *) image; } VOID Engine::SetRenderState_Transform(IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN UINT8 layer, IN INT16 sortIndex) { + IA_ASSERT(sortIndex <= 0x1FFF); + + if (Renderer::s_state.YSortingEnabled) + sortIndex += static_cast(position.y); + + Renderer::s_state.ModelMatrix = + glm::translate(glm::mat4(1.0f), glm::vec3{position.x, position.y, + static_cast((layer << 13) | (sortIndex & 0x1FFF))}); + Renderer::s_state.ModelMatrix = + glm::rotate(Renderer::s_state.ModelMatrix, rotation, glm::vec3(0.0f, 0.0f, 1.0f)); + Renderer::s_state.ModelMatrix = glm::scale(Renderer::s_state.ModelMatrix, glm::vec3{scale.x, scale.y, 1.0f}); + + SDL_PushGPUVertexUniformData(Renderer::s_state.ActiveCommandBuffer, 2, &Renderer::s_state.ModelMatrix, + sizeof(Mat4)); + } + + VOID Engine::SetRenderState_YSortingEnabled(IN BOOL value) + { + Renderer::s_state.YSortingEnabled = value; + } + + Handle Engine::GetGeometry_Quad() + { + return (Handle)Renderer::s_quadGeometry; } } // namespace ia::iae \ No newline at end of file diff --git a/Engine/Src/Imp/HPP/Renderer/Renderer.hpp b/Engine/Src/Imp/HPP/Renderer/Renderer.hpp index 0ace78f..8cbf148 100644 --- a/Engine/Src/Imp/HPP/Renderer/Renderer.hpp +++ b/Engine/Src/Imp/HPP/Renderer/Renderer.hpp @@ -24,7 +24,7 @@ namespace ia::iae class Renderer { public: - struct Mesh + struct Geometry { INT32 IndexCount{}; SDL_GPUBuffer *IndexBuffer; @@ -36,11 +36,11 @@ namespace ia::iae BOOL FlippedH{false}; BOOL FlippedV{false}; BOOL CameraRelative{true}; - BOOL ScissorEnabled{false}; + BOOL YSortingEnabled{false}; Color ColorOverlay{}; Vec2 TextureOffset{0.0f, 0.0f}; SDL_Rect Scissor{0, 0, 0, 0}; - Handle ActiveTexture{INVALID_HANDLE}; + SDL_GPUTexture* ActiveTexture{nullptr}; Mat4 ModelMatrix{1.0f}; Mat4 ProjectionMatrix{1.0f}; @@ -63,6 +63,11 @@ namespace ia::iae STATIC VOID OnScreenResize(IN INT32 newWidth, IN INT32 newHeight); public: + STATIC Geometry* CreateGeometry(IN CONST Vector &vertices, IN CONST Vector &indices); + STATIC VOID DestroyGeometry(IN Geometry* handle); + + STATIC VOID DrawGeometry(IN Geometry* handle); + STATIC SDL_GPUTextureFormat GetRenderTargetFormat(); STATIC SDL_GPUDevice *GetDevice() @@ -80,6 +85,7 @@ namespace ia::iae STATIC SDL_GPUTexture *s_renderTargetDebugDrawColor; STATIC Pipeline* s_geometryPipeline; STATIC Pipeline* s_postprocessPipeline; + STATIC Geometry* s_quadGeometry; friend class Engine; }; diff --git a/Engine/Src/Inc/IAEngine/Engine.hpp b/Engine/Src/Inc/IAEngine/Engine.hpp index cfc7238..b89444a 100644 --- a/Engine/Src/Inc/IAEngine/Engine.hpp +++ b/Engine/Src/Inc/IAEngine/Engine.hpp @@ -38,6 +38,7 @@ namespace ia::iae STATIC VOID DestroyPhysicsBody(IN Handle body); // Renderer Functions + STATIC Handle GetGeometry_Quad(); STATIC Handle CreateGeometry(IN CONST Vector& vertices, IN CONST Vector& indices); STATIC VOID DestroyGeometry(IN Handle geometry); STATIC VOID DrawGeometry(IN Handle handle); @@ -48,6 +49,7 @@ namespace ia::iae STATIC VOID SetRenderState_FlippedH(IN BOOL value); STATIC VOID SetRenderState_FlippedV(IN BOOL value); STATIC VOID SetRenderState_TextureOffset(IN Vec2 off); + STATIC VOID SetRenderState_YSortingEnabled(IN BOOL value); STATIC VOID SetRenderState_ColorOverlay(IN Color color); STATIC VOID SetRenderState_CameraRelative(IN BOOL value); STATIC VOID SetRenderState_Texture(IN Handle image);