Skip to content

Commit

Permalink
Imgui window now pops up.
Browse files Browse the repository at this point in the history
  • Loading branch information
bbrown683 committed Jul 16, 2023
1 parent 814403c commit 7f4df58
Show file tree
Hide file tree
Showing 12 changed files with 193 additions and 67 deletions.
61 changes: 61 additions & 0 deletions graphics/cmd.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,66 @@ public:
commandBuffer = std::move(device.allocateCommandBuffersUnique(commandBufferInfo).front());
}

void BeginRender(CVulkanFrame frame, CVulkanRender render) {
Begin();

// Transition image for drawing.
vk::ImageMemoryBarrier colorAttachmentBarrier;
colorAttachmentBarrier.setImage(frame.image);
colorAttachmentBarrier.setDstAccessMask(vk::AccessFlagBits::eColorAttachmentWrite);
colorAttachmentBarrier.setOldLayout(vk::ImageLayout::eUndefined);
colorAttachmentBarrier.setNewLayout(vk::ImageLayout::eColorAttachmentOptimal);
colorAttachmentBarrier.setSubresourceRange(vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1));

commandBuffer->pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eColorAttachmentOutput, {}, nullptr, nullptr, colorAttachmentBarrier);

vk::Rect2D renderArea({}, frame.extent);
vk::RenderingInfo renderingInfo;
renderingInfo.setRenderArea(renderArea);
renderingInfo.setLayerCount(1);
renderingInfo.setColorAttachments(render.colorAttachments);
renderingInfo.setPDepthAttachment(render.depthAttachments.data());
renderingInfo.setPStencilAttachment(render.stencilAttachments.data());

commandBuffer->beginRendering(renderingInfo);

vk::Viewport viewport(0.0f, 0.0f, static_cast<float>(frame.extent.width), static_cast<float>(frame.extent.height), 0.0f, 1.0f);
commandBuffer->setViewport(0, viewport);
commandBuffer->setScissor(0, renderArea);
}

void EndRender(CVulkanFrame frame) {
commandBuffer->endRendering();

// Transition image for presentation.
vk::ImageMemoryBarrier presentImageBarrier;
presentImageBarrier.setImage(frame.image);
presentImageBarrier.setSrcAccessMask(vk::AccessFlagBits::eColorAttachmentWrite);
presentImageBarrier.setOldLayout(vk::ImageLayout::eColorAttachmentOptimal);
presentImageBarrier.setNewLayout(vk::ImageLayout::ePresentSrcKHR);
presentImageBarrier.setSubresourceRange(vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1));

commandBuffer->pipelineBarrier(vk::PipelineStageFlagBits::eColorAttachmentOutput, vk::PipelineStageFlagBits::eBottomOfPipe, {}, nullptr, nullptr, presentImageBarrier);

End();
}

void Draw(CVulkanDraw draw) {
commandBuffer->bindPipeline(vk::PipelineBindPoint::eGraphics, draw.pipeline);
commandBuffer->bindVertexBuffers(0, draw.vertexBuffers, draw.vertexBufferOffsets);
if(draw.indicesCount > 0) {
commandBuffer->bindIndexBuffer(draw.indexBuffer, draw.indexBufferOffset, vk::IndexType::eUint16);
commandBuffer->drawIndexed(draw.indicesCount, 1, 0, 0, 0);
} else {
commandBuffer->draw(draw.verticesCount, 1, 0, 0);
}
}

void Draw(ImDrawData* drawData) {
ImGui_ImplVulkan_RenderDrawData(drawData, *commandBuffer);
}

/*
void Render(CVulkanFrame frame, CVulkanRender render) {
Begin();
Expand Down Expand Up @@ -66,6 +126,7 @@ public:
End();
}
*/

void CopyBuffer(CVulkanBuffer* srcBuffer, CVulkanBuffer* dstBuffer, vk::BufferCopy regions) {
Begin();
Expand Down
13 changes: 6 additions & 7 deletions graphics/device.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export class CVulkanDevice {
uint32_t graphicsQueueIndex;
uint32_t computeQueueIndex;
uint32_t transferQueueIndex;
friend class CVulkanDeviceDeleter;
public:
CVulkanDevice(vk::PhysicalDevice physicalDevice) : physicalDevice(physicalDevice) {
availableLayers = physicalDevice.enumerateDeviceLayerProperties();
Expand Down Expand Up @@ -115,16 +114,16 @@ public:
return enabledExtensions;
}

CVulkanQueue GetGraphicsQueue() {
return CVulkanQueue(*device, graphicsQueueIndex);
std::unique_ptr<CVulkanQueue> GetGraphicsQueue() {
return std::make_unique<CVulkanQueue>(*device, graphicsQueueIndex);
}

CVulkanQueue GetComputeQueue() {
return CVulkanQueue(*device, computeQueueIndex);
std::unique_ptr<CVulkanQueue> GetComputeQueue() {
return std::make_unique<CVulkanQueue>(*device, computeQueueIndex);
}

CVulkanQueue GetTransferQueue() {
return CVulkanQueue(*device, transferQueueIndex);
std::unique_ptr<CVulkanQueue> GetTransferQueue() {
return std::make_unique<CVulkanQueue>(*device, transferQueueIndex);
}

CVulkanGraphicsPipeline CreateGraphicsPipeline(std::string vertexShaderFile, std::string fragmentShaderFile, vk::Format colorFormat) {
Expand Down
35 changes: 12 additions & 23 deletions graphics/mesh.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ export class CVulkanMeshLoader {
CVulkanDevice* device;
CVulkanQueue* queue;
CVulkanCommandPool* commandPool;
CVulkanCommandBuffer* commandBuffer;
std::shared_ptr<CVulkanCommandBuffer> commandBuffer;
public:
CVulkanMeshLoader(CVulkanDevice* device, CVulkanQueue* queue, CVulkanCommandPool* commandPool, CVulkanCommandBuffer* commandBuffer)
CVulkanMeshLoader(CVulkanDevice* device, CVulkanQueue* queue, CVulkanCommandPool* commandPool, std::shared_ptr<CVulkanCommandBuffer> commandBuffer)
: device(device), queue(queue), commandPool(commandPool), commandBuffer(commandBuffer) {}

std::vector<CVulkanMesh> Load(std::string filename) {
Expand Down Expand Up @@ -86,28 +86,17 @@ public:
CVulkanMeshRenderer(CVulkanGraphicsPipeline* pipeline, std::vector<std::shared_ptr<CVulkanCommandBuffer>> commandBuffers)
: pipeline(pipeline), commandBuffers(commandBuffers) {}

void Render(CVulkanFrame frame, std::vector<std::shared_ptr<CVulkanMesh>> meshes) {
CVulkanRender render;
render.colorAttachments = { vk::RenderingAttachmentInfo(frame.imageView, vk::ImageLayout::eColorAttachmentOptimal,
vk::ResolveModeFlagBits::eNone, nullptr, vk::ImageLayout::eUndefined,
vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore,
vk::ClearColorValue(0.0f, 0.0f, 0.0f, 1.0f)) };
/*
render.setDepthAttachments = { vk::RenderingAttachmentInfo({}, vk::ImageLayout::eDepthStencilAttachmentOptimal,
vk::ResolveModeFlagBits::eNone, {}, vk::ImageLayout::eUndefined,
vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore,
vk::ClearDepthStencilValue(1.0f, 0)) };
*/
render.pipeline = pipeline->GetVkPipeline();

void Draw(CVulkanFrame frame, std::vector<std::shared_ptr<CVulkanMesh>> meshes) {
CVulkanDraw draw;
draw.pipeline = pipeline->GetVkPipeline();
for(auto& mesh : meshes) {
render.verticesCount = static_cast<uint32_t>(mesh->vertices.size());
render.vertexBuffers = { mesh->vertexBuffer->GetVkBuffer() };
render.vertexBufferOffsets = { 0 };
render.indicesCount = static_cast<uint32_t>(mesh->indices.size());
render.indexBuffer = mesh->indexBuffer->GetVkBuffer();
render.indexBufferOffset = 0;
commandBuffers[frame.currentFrame]->Render(frame, render);
draw.verticesCount = static_cast<uint32_t>(mesh->vertices.size());
draw.vertexBuffers = { mesh->vertexBuffer->GetVkBuffer() };
draw.vertexBufferOffsets = { 0 };
draw.indicesCount = static_cast<uint32_t>(mesh->indices.size());
draw.indexBuffer = mesh->indexBuffer->GetVkBuffer();
draw.indexBufferOffset = 0;
commandBuffers[frame.currentFrame]->Draw(draw);
}
}
};
8 changes: 1 addition & 7 deletions graphics/queue.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,16 @@ export class CVulkanQueue {
vk::Queue queue;
uint32_t familyIndex;
std::vector<vk::UniqueSemaphore> submitSemaphores;
friend class CVulkanQueueDeleter;
public:
CVulkanQueue(vk::Device device, uint32_t familyIndex) : device(device), familyIndex(familyIndex) {
queue = device.getQueue(familyIndex, 0);
}

CVulkanQueue(const CVulkanQueue&) = default;
CVulkanQueue(CVulkanQueue&&) = default;
CVulkanQueue& operator=(const CVulkanQueue&) = default;
CVulkanQueue& operator=(CVulkanQueue&&) = default;

~CVulkanQueue() {
queue.waitIdle();
}

void Submit(CVulkanCommandBuffer* commandBuffer, vk::Semaphore submitSemaphore = nullptr, vk::Semaphore waitSemaphore = nullptr, vk::PipelineStageFlags waitSemaphoreFlags = {}, vk::Fence signalFence = nullptr) {
void Submit(std::shared_ptr<CVulkanCommandBuffer> commandBuffer, vk::Semaphore submitSemaphore = nullptr, vk::Semaphore waitSemaphore = nullptr, vk::PipelineStageFlags waitSemaphoreFlags = {}, vk::Fence signalFence = nullptr) {
vk::SubmitInfo submitInfo;
std::vector<vk::PipelineStageFlags> waitSemaphoreDestinationFlags = {};
auto vkCommandBuffer = commandBuffer->GetVkCommandBuffer();
Expand Down
34 changes: 23 additions & 11 deletions graphics/renderer.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import cmd;
import pipeline;
import mesh;
import ui;
import window;
import types;

export struct CVulkanRendererProperties {
Expand Down Expand Up @@ -55,15 +56,16 @@ export class CVulkanRenderer {
std::unique_ptr<CVulkanQueue> computeQueue;
std::unique_ptr<CVulkanQueue> transferQueue;
public:
CVulkanRenderer(SDL_Window* window) {
instance = std::make_unique<CVulkanInstance>(window);
device = instance->CreateDevice();
CVulkanRenderer(CSDLWindow* window) {
window->AddEventCallback(static_cast<void*>(this), SDL_EventFilterCallback); // Add callback when certain events fire.

graphicsQueue = std::make_unique<CVulkanQueue>(device->GetGraphicsQueue());
computeQueue = std::make_unique<CVulkanQueue>(device->GetComputeQueue());
transferQueue = std::make_unique<CVulkanQueue>(device->GetTransferQueue());
instance = std::make_unique<CVulkanInstance>(window->GetSDL_Window());
device = instance->CreateDevice();
graphicsQueue = device->GetGraphicsQueue();
computeQueue = device->GetComputeQueue();
transferQueue = device->GetTransferQueue();

swapchain = std::make_unique<CVulkanSwapchain>(instance.get(), device.get(), graphicsQueue.get(), window, 2, true);
swapchain = std::make_unique<CVulkanSwapchain>(instance.get(), device.get(), graphicsQueue.get(), window->GetSDL_Window(), 2, true);

graphicsCommandPool = std::make_unique<CVulkanCommandPool>(graphicsQueue->CreateCommandPool());
computeCommandPool = std::make_unique<CVulkanCommandPool>(computeQueue->CreateCommandPool());
Expand All @@ -80,9 +82,9 @@ public:
pipeline = std::make_unique<CVulkanGraphicsPipeline>(device->CreateGraphicsPipeline("vertex.spv", "fragment.spv", surfaceFormat));

meshRenderer = std::make_unique<CVulkanMeshRenderer>(pipeline.get(), graphicsCommandBuffers);
meshLoader = std::make_unique<CVulkanMeshLoader>(device.get(), transferQueue.get(), transferCommandPool.get(), transferCommandBuffers[0].get());
meshLoader = std::make_unique<CVulkanMeshLoader>(device.get(), transferQueue.get(), transferCommandPool.get(), transferCommandBuffers[0]);
meshes.push_back(std::make_shared<CVulkanMesh>(meshLoader->Load(vertices, indices)));
ui = std::make_unique<CVulkanUi>(window, instance.get(), device.get(), graphicsQueue.get(), graphicsCommandBuffers[0].get(), 2, surfaceFormat);
ui = std::make_unique<CVulkanUi>(window->GetSDL_Window(), instance.get(), device.get(), graphicsQueue.get(), graphicsCommandPool.get(), graphicsCommandBuffers, 2, surfaceFormat);
}

void OnResize() {
Expand All @@ -92,8 +94,18 @@ public:
void DrawFrame() {
CVulkanFrame frame = swapchain->GetNextFrame();
graphicsCommandPool->Reset();
meshRenderer->Render(frame, meshes);
graphicsQueue->Submit(graphicsCommandBuffers[frame.currentFrame].get(), frame.submitSemaphore, frame.acquireSemaphore, vk::PipelineStageFlagBits::eColorAttachmentOutput, frame.acquireFence);
CVulkanRender render;
render.colorAttachments = { vk::RenderingAttachmentInfo(frame.imageView, vk::ImageLayout::eColorAttachmentOptimal,
vk::ResolveModeFlagBits::eNone, nullptr, vk::ImageLayout::eUndefined,
vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore,
vk::ClearColorValue(0.0f, 0.0f, 0.0f, 1.0f)) };

auto currentCommandBuffer = graphicsCommandBuffers[frame.currentFrame];
currentCommandBuffer->BeginRender(frame, render);
meshRenderer->Draw(frame, meshes);
ui->Draw(frame);
currentCommandBuffer->EndRender(frame);
graphicsQueue->Submit(currentCommandBuffer, frame.submitSemaphore, frame.acquireSemaphore, vk::PipelineStageFlagBits::eColorAttachmentOutput, frame.acquireFence);
swapchain->Present();
}

Expand Down
2 changes: 1 addition & 1 deletion graphics/swapchain.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ private:
capabilities = physicalDevice.getSurfaceCapabilitiesKHR(*surface);
auto extent = GetSwapchainExtent(window, capabilities);
presentMode = SelectPresentMode(physicalDevice.getSurfacePresentModesKHR(*surface), vsync ? vk::PresentModeKHR::eImmediate : vk::PresentModeKHR::eMailbox);
surfaceFormat = SelectSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface), vk::Format::eB8G8R8A8Srgb, vk::ColorSpaceKHR::eSrgbNonlinear);
surfaceFormat = SelectSurfaceFormat(physicalDevice.getSurfaceFormatsKHR(*surface), vk::Format::eB8G8R8A8Unorm, vk::ColorSpaceKHR::eExtendedSrgbLinearEXT);

vk::SwapchainCreateInfoKHR swapchainInfo;
swapchainInfo.setSurface(*surface);
Expand Down
9 changes: 7 additions & 2 deletions graphics/types.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,17 @@ export struct CVulkanFrame {
vk::Semaphore submitSemaphore;
};

// Data that can be passed into a draw call.
// Data that can be passed for rendering settings.
export struct CVulkanRender {
vk::Pipeline pipeline;
std::vector<vk::RenderingAttachmentInfo> colorAttachments;
std::vector<vk::RenderingAttachmentInfo> depthAttachments;
std::vector<vk::RenderingAttachmentInfo> stencilAttachments;

};

// Data passed in for draw settings.
export struct CVulkanDraw {
vk::Pipeline pipeline;
uint32_t verticesCount;
std::vector<vk::Buffer> vertexBuffers;
std::vector<vk::DeviceSize> vertexBufferOffsets;
Expand Down
37 changes: 24 additions & 13 deletions graphics/ui.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@ export module ui;
import instance;
import device;
import queue;
import pipeline;
import cmd;
import types;

export class CVulkanUi {
vk::UniqueDescriptorPool descriptorPool;
vk::UniquePipelineCache pipelineCache;
std::vector<std::shared_ptr<CVulkanCommandBuffer>> commandBuffers;
public:
CVulkanUi(SDL_Window* window, CVulkanInstance* instance, CVulkanDevice* device, CVulkanQueue* queue, CVulkanCommandBuffer* commandBuffer, uint32_t imageCount, vk::Format colorFormat) {
CVulkanUi(SDL_Window* window, CVulkanInstance* instance, CVulkanDevice* device, CVulkanQueue* queue,
CVulkanCommandPool* commandPool, std::vector<std::shared_ptr<CVulkanCommandBuffer>> commandBuffers,
uint32_t imageCount, vk::Format colorFormat)
: commandBuffers(commandBuffers) {
auto vkInstance = instance->GetVkInstance();
auto vkPhysicalDevice = device->GetVkPhysicalDevice();
auto vkDevice = device->GetVkDevice();
Expand Down Expand Up @@ -50,8 +56,8 @@ public:
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows


//io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoTaskBarIcons;
//io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoMerge;

ImGui_ImplVulkan_InitInfo imguiVulkanInitInfo;
imguiVulkanInitInfo.Instance = vkInstance;
Expand All @@ -68,35 +74,40 @@ public:
imguiVulkanInitInfo.CheckVkResultFn = nullptr;
imguiVulkanInitInfo.Allocator = nullptr;
imguiVulkanInitInfo.UseDynamicRendering = true;
imguiVulkanInitInfo.ColorAttachmentFormat = static_cast<VkFormat>(colorFormat);
imguiVulkanInitInfo.ColorAttachmentFormat = VK_FORMAT_B8G8R8A8_UNORM;

if(!ImGui_ImplSDL2_InitForVulkan(window) || !ImGui_ImplVulkan_Init(&imguiVulkanInitInfo, nullptr)) {
printf("CVulkanUi::CVulkanUi: Failed to initialize ImGui");
}

commandBuffer->UploadImguiFonts();
queue->Submit(commandBuffer);
commandBuffers[0]->UploadImguiFonts();
queue->Submit(commandBuffers[0]);
ImGui_ImplVulkan_DestroyFontUploadObjects();
commandPool->Reset();
}

~CVulkanUi() {
ImGui_ImplVulkan_Shutdown();
ImGui_ImplSDL2_Shutdown();
ImGui::DestroyContext();
}

ImDrawData* GetState() {
void Draw(CVulkanFrame frame) {
ImGui_ImplVulkan_NewFrame();
ImGui_ImplSDL2_NewFrame();
ImGui::NewFrame();

bool showDemoWindow = true;
ImGui::ShowDemoWindow(&showDemoWindow);

ImGui::Render();
return ImGui::GetDrawData();
}
};

export class CVulkanUiRenderer {
ImDrawData* drawData = ImGui::GetDrawData();
commandBuffers[frame.currentFrame]->Draw(drawData);

ImGuiIO& io = ImGui::GetIO();
// Update and Render additional Platform Windows
if(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
}
}
};
2 changes: 1 addition & 1 deletion graphics/window.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public:
void PollEvents() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
//ImGui_ImplSDL2_ProcessEvent(&event);
ImGui_ImplSDL2_ProcessEvent(&event); // ImGui event hooking.
if(event.type == SDL_QUIT) {
running = false;
break;
Expand Down
Loading

0 comments on commit 7f4df58

Please sign in to comment.