diff --git a/engine/modules/engine/render/include/render/renderapi.h b/engine/modules/engine/render/include/render/renderapi.h index b722935..dc9d5aa 100644 --- a/engine/modules/engine/render/include/render/renderapi.h +++ b/engine/modules/engine/render/include/render/renderapi.h @@ -25,5 +25,8 @@ namespace api { virtual void DrawStaticMesh(Mesh& mesh) = 0; virtual void LoadShader(Shader& shader) = 0; + + virtual void BeginFrame() = 0; + virtual void EndFrame() = 0; }; } \ No newline at end of file diff --git a/engine/modules/render/vulkan/include/vkn/backend.h b/engine/modules/render/vulkan/include/vkn/backend.h index 730835b..45dda86 100644 --- a/engine/modules/render/vulkan/include/vkn/backend.h +++ b/engine/modules/render/vulkan/include/vkn/backend.h @@ -12,7 +12,12 @@ namespace vkn { ~Backend(); template Worker* InitWorker(Name name, VkCommandPoolCreateFlags flag); - + Instance& GetInstance() { + return *mInstance; + } + Device& GetDevice() { + return *mDevice; + } public: static struct BufferWorker* TransferWorker; static struct CommandWorker* RenderWorker; diff --git a/engine/modules/render/vulkan/include/vkn/vulkan_api.h b/engine/modules/render/vulkan/include/vkn/vulkan_api.h index 5483aaa..1ef01ec 100644 --- a/engine/modules/render/vulkan/include/vkn/vulkan_api.h +++ b/engine/modules/render/vulkan/include/vkn/vulkan_api.h @@ -25,5 +25,15 @@ namespace vkn { void DrawStaticMesh(Mesh& mesh)override; void LoadShader(Shader& shader)override; + + void BeginFrame()override; + void EndFrame()override; + + Backend& GetBackend() { + return backend; + } + static VulkanAPI* Ptr() { + return (VulkanAPI*)api::RenderAPI::Ptr(); + } }; } \ No newline at end of file diff --git a/engine/modules/render/vulkan/include/vkn/vulkan_window.h b/engine/modules/render/vulkan/include/vkn/vulkan_window.h index e375955..599fe48 100644 --- a/engine/modules/render/vulkan/include/vkn/vulkan_window.h +++ b/engine/modules/render/vulkan/include/vkn/vulkan_window.h @@ -2,9 +2,34 @@ #include "type.h" #include "render/window.h" namespace vkn { + class Device; + struct VulkanWindowArgs { + uint32_t frames; + uint32_t width; + uint32_t height; + VkFormat imageFormat; + VkColorSpaceKHR imageColorSpace; + VkPresentModeKHR presentMode; + VkImageUsageFlags imageUsage; + uint32_t maxFrameInFlightCount; + VkExtent2D EnableImageExtent2D(VkSurfaceCapabilitiesKHR& capabilities); + static VulkanWindowArgs Default(); + }; + class VulkanSwapchain { + private: + Device& mDevice; + VkSwapchainKHR mPtr; + int mFrames; + //pmr::vector mSurfaces{GlobalPool()}; + pmr::vector mFences{ GlobalPool() }; + pmr::vector mSemaphores{ GlobalPool() }; + public: + VulkanSwapchain(Device& device, VkSurfaceKHR surface, VulkanWindowArgs& args); + + }; class VulkanWindow : public api::Window { private: - VkSurfaceKHR mSurfaceKHR; + VulkanSwapchain* mSwapchain; public: void* operator new(size_t size) { return ::operator new(size, GlobalPool()); @@ -12,9 +37,8 @@ namespace vkn { void operator delete(void* p) {} public: using api::Window::Window; - void CreateRender(); + void CreateRender(VulkanWindowArgs& args); static VulkanWindow* Ptr() { - //return dynamic_cast(api::Window::Ptr()); return (VulkanWindow*)api::Window::Ptr(); } }; diff --git a/engine/modules/render/vulkan/src/thread/buffer_worker.cpp b/engine/modules/render/vulkan/src/thread/buffer_worker.cpp index 86bf32d..1f70a8b 100644 --- a/engine/modules/render/vulkan/src/thread/buffer_worker.cpp +++ b/engine/modules/render/vulkan/src/thread/buffer_worker.cpp @@ -1,6 +1,7 @@ #include "vkn/thread/buffer_worker.h" #include "vkn/wrapper/queue.h" #include "vkn/wrapper/device.h" +#define VMA_IMPLEMENTATION #include "vma/vk_mem_alloc.h" #include "zlog.h" namespace vkn { diff --git a/engine/modules/render/vulkan/src/vulkan_api.cpp b/engine/modules/render/vulkan/src/vulkan_api.cpp index b4306e8..331a3b6 100644 --- a/engine/modules/render/vulkan/src/vulkan_api.cpp +++ b/engine/modules/render/vulkan/src/vulkan_api.cpp @@ -46,4 +46,12 @@ namespace vkn { void VulkanAPI::LoadShader(Shader& shader) { } + void VulkanAPI::BeginFrame() + { + + } + void VulkanAPI::EndFrame() + { + + } } diff --git a/engine/modules/render/vulkan/src/vulkan_window.cpp b/engine/modules/render/vulkan/src/vulkan_window.cpp index 1c8f9d1..346aee2 100644 --- a/engine/modules/render/vulkan/src/vulkan_window.cpp +++ b/engine/modules/render/vulkan/src/vulkan_window.cpp @@ -1,7 +1,81 @@ #include "vkn/vulkan_window.h" +#include "vkn/wrapper/device.h" +#include "vkn/wrapper/instance.h" +#include "vkn/vulkan_api.h" +#include "vkn/backend.h" +#include "zlog.h" +#include +#include namespace vkn { - void VulkanWindow::CreateRender() + void VulkanWindow::CreateRender(VulkanWindowArgs& args) { - + VulkanAPI* api = VulkanAPI::Ptr(); + Backend& backend = api->GetBackend(); + VkInstance instance = backend.GetInstance().Ptr(); + VkSurfaceKHR surface; + if (!SDL_Vulkan_CreateSurface(mPtr, instance, &surface)) { + zlog::error("SDL_Vulkan_CreateSurface failed! {}", SDL_GetError()); + } + args.width = mWidth; + args.height = mHeight; + mSwapchain = new (GlobalPool()) VulkanSwapchain(backend.GetDevice(), surface, args); + } + VulkanSwapchain::VulkanSwapchain(Device& device, VkSurfaceKHR surface, VulkanWindowArgs& args) + : mDevice(device) + { + VkSurfaceCapabilitiesKHR capabilities{}; + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device.GetPhysical(), surface, &capabilities); + VkExtent2D image_extent = args.EnableImageExtent2D(capabilities); + VkSwapchainCreateInfoKHR swapchain_create_info = { + VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,// VkStructureType sType + nullptr, // const void * pNext + 0, // VkSwapchainCreateFlagsKHR flags + surface, // VkSurfaceKHR surface + (uint32_t)args.frames, // uint32_t minImageCount + args.imageFormat, // VkFormat imageFormat + args.imageColorSpace, // VkColorSpaceKHR imageColorSpace + image_extent, // VkExtent2D imageExtent + 1, // uint32_t imageArrayLayers + args.imageUsage, // VkImageUsageFlags imageUsage + VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode imageSharingMode + 0, // uint32_t queueFamilyIndexCount + nullptr, // const uint32_t * pQueueFamilyIndices + capabilities.currentTransform, // VkSurfaceTransformFlagBitsKHR preTransform + VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, // VkCompositeAlphaFlagBitsKHR compositeAlpha + args.presentMode, // VkPresentModeKHR presentMode + VK_TRUE, // VkBool32 clipped + VK_NULL_HANDLE // VkSwapchainKHR oldSwapchain + }; + VkResult result = vkCreateSwapchainKHR(device.Ptr(), &swapchain_create_info, nullptr, &mPtr); + if (result != VK_SUCCESS) { + zlog::error("Failed to create swap chain."); + } + pmr::vector swapchain_images{FramePool()}; + + mFrames = args.frames; + } + VkExtent2D VulkanWindowArgs::EnableImageExtent2D(VkSurfaceCapabilitiesKHR& capabilities) + { + VkExtent2D image_extent{ width , height }; + if (capabilities.currentExtent.width != 0xFFFFFFFF) + { + image_extent = capabilities.currentExtent; + } + else + { + image_extent.width = std::clamp(image_extent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width); + image_extent.height = std::clamp(image_extent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height); + } + return image_extent; + } + VulkanWindowArgs VulkanWindowArgs::Default() + { + return { + .imageFormat = VK_FORMAT_B8G8R8A8_SRGB, + .imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, + .presentMode = VK_PRESENT_MODE_MAILBOX_KHR, + .imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + .maxFrameInFlightCount = 2 + }; } } \ No newline at end of file diff --git a/game/zworld/src/zworld.cpp b/game/zworld/src/zworld.cpp index c962bb9..ebc25f3 100644 --- a/game/zworld/src/zworld.cpp +++ b/game/zworld/src/zworld.cpp @@ -19,14 +19,7 @@ void ZWorldModule::MainLoop() { bool running = true; SDL_Event event_; - auto win = Window::Ptr(); - auto ptr = Window::Ptr()->GetPtr(); - SDL_Renderer* renderer = SDL_CreateRenderer(ptr, -1, SDL_RENDERER_ACCELERATED); - if (!renderer) { - std::cerr << "无法创建渲染器: " << SDL_GetError() << std::endl; - SDL_DestroyWindow(ptr); - SDL_Quit(); - } + auto RenderAPI = RenderAPI::Ptr(); while (running) { // 处理事件 while (SDL_PollEvent(&event_)) { @@ -34,18 +27,7 @@ void ZWorldModule::MainLoop() running = false; } } - - // 清除屏幕 - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // 黑色 - SDL_RenderClear(renderer); - - // 绘制一个红色矩形 - SDL_Rect rect = { 200, 150, 400, 300 }; - SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); // 红色 - SDL_RenderFillRect(renderer, &rect); - - // 显示渲染内容 - SDL_RenderPresent(renderer); + RenderAPI->BeginFrame(); + RenderAPI->EndFrame(); } - }