Compare commits
3 Commits
b9ee037216
...
4dd8effd7b
| Author | SHA1 | Date |
|---|---|---|
|
|
4dd8effd7b | |
|
|
b356991cad | |
|
|
980533dbb7 |
|
|
@ -9,19 +9,18 @@ A Vulkan based renderer created with Vulkan 1.3 in C++.
|
||||||
- [X] Load Material Data
|
- [X] Load Material Data
|
||||||
- [ ] Load Animation Data
|
- [ ] Load Animation Data
|
||||||
- [ ] Load Camera
|
- [ ] Load Camera
|
||||||
- [ ] Load Lights
|
|
||||||
- [ ] Support Specular Materials
|
- [ ] Support Specular Materials
|
||||||
- [X] Bindless Descriptors
|
- [X] Bindless Descriptors
|
||||||
- [X] Simplified Descriptor Creation Pipeline
|
- [X] Simplified Descriptor Creation Pipeline
|
||||||
- [ ] Debugging
|
- [ ] Debugging
|
||||||
- [ ] Tracy Integration
|
- [ ] Tracy Integration
|
||||||
- [ ] Dear ImGui Integration
|
- [X] Dear ImGui Integration
|
||||||
- [ ] Transparency
|
- [ ] Transparency
|
||||||
- [ ] Sorted
|
- [ ] Sorted
|
||||||
- [ ] Order Independent
|
- [ ] Order Independent
|
||||||
- [ ] Shadows v1
|
- [ ] Shadows v1
|
||||||
- [ ] Omnidirectional Cubemap Shadows
|
- [ ] Omnidirectional Cubemap Shadows
|
||||||
- [ ] Spot Lights
|
- [ ] SpotLight Shadows
|
||||||
- [ ] Directional Shadows
|
- [ ] Directional Shadows
|
||||||
- [ ] Cascaded Shadows
|
- [ ] Cascaded Shadows
|
||||||
- [ ] PCF
|
- [ ] PCF
|
||||||
|
|
|
||||||
|
|
@ -19,14 +19,14 @@ Image::Destroy(const Device *device)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Texture::Init(const Device *device, const vk::Extent2D extent, vk::Format imageFormat, const bool isMipmapped,
|
Texture::Init(const Device *device, const vk::Extent2D extent, vk::Format imageFormat, const bool isMipMapped,
|
||||||
const cstr name)
|
const cstr name)
|
||||||
{
|
{
|
||||||
const u32 mipLevels = isMipmapped ? 1 + Cast<u32>(floor(log2(eastl::max(extent.width, extent.height)))) : 1;
|
const u32 mipLevels = isMipMapped ? 1 + Cast<u32>(floor(log2(eastl::max(extent.width, extent.height)))) : 1;
|
||||||
assert(mipLevels <= MIP_MASK);
|
assert(mipLevels <= MIP_MASK);
|
||||||
|
|
||||||
auto usage = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst;
|
auto usage = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst;
|
||||||
if (isMipmapped)
|
if (isMipMapped)
|
||||||
{
|
{
|
||||||
usage |= vk::ImageUsageFlagBits::eTransferSrc;
|
usage |= vk::ImageUsageFlagBits::eTransferSrc;
|
||||||
}
|
}
|
||||||
|
|
@ -81,6 +81,59 @@ Texture::Init(const Device *device, const vk::Extent2D extent, vk::Format imageF
|
||||||
device->SetName(m_Image, name);
|
device->SetName(m_Image, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AttachmentImage::Init(const Device *device, vk::Extent2D extent, vk::Format imageFormat, cstr name)
|
||||||
|
{
|
||||||
|
vk::ImageCreateInfo imageCreateInfo = {
|
||||||
|
.imageType = vk::ImageType::e2D,
|
||||||
|
.format = imageFormat,
|
||||||
|
.extent = {.width = extent.width, .height = extent.height, .depth = 1},
|
||||||
|
.mipLevels = 1,
|
||||||
|
.arrayLayers = 1,
|
||||||
|
.samples = vk::SampleCountFlagBits::e1,
|
||||||
|
.tiling = vk::ImageTiling::eOptimal,
|
||||||
|
.usage = vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferSrc,
|
||||||
|
.sharingMode = vk::SharingMode::eExclusive,
|
||||||
|
.initialLayout = vk::ImageLayout::eUndefined,
|
||||||
|
};
|
||||||
|
constexpr VmaAllocationCreateInfo allocationCreateInfo = {
|
||||||
|
.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
|
||||||
|
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkImage image;
|
||||||
|
VmaAllocation allocation;
|
||||||
|
auto result = Cast<vk::Result>(vmaCreateImage(device->m_Allocator, Recast<VkImageCreateInfo *>(&imageCreateInfo),
|
||||||
|
&allocationCreateInfo, &image, &allocation, nullptr));
|
||||||
|
ERROR_IF(Failed(result), "Could not allocate depth buffer. Cause: {}", result) THEN_ABORT(result);
|
||||||
|
|
||||||
|
vk::ImageView view;
|
||||||
|
vk::ImageViewCreateInfo imageViewCreateInfo = {
|
||||||
|
.image = image,
|
||||||
|
.viewType = vk::ImageViewType::e2D,
|
||||||
|
.format = imageFormat,
|
||||||
|
.components = {},
|
||||||
|
.subresourceRange =
|
||||||
|
{
|
||||||
|
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.levelCount = 1,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
result = device->m_Device.createImageView(&imageViewCreateInfo, nullptr, &view);
|
||||||
|
ERROR_IF(Failed(result), "Could not create depth image view {}. Cause: {}", name, result) THEN_ABORT(result);
|
||||||
|
|
||||||
|
m_Image = image;
|
||||||
|
m_View = view;
|
||||||
|
m_Allocation = allocation;
|
||||||
|
m_Extent = {extent.width, extent.height, 1};
|
||||||
|
m_MipLevels_ = 1 | OWNED_BIT | VALID_BIT;
|
||||||
|
|
||||||
|
device->SetName(m_Image, name);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DepthImage::Init(const Device *device, vk::Extent2D extent, cstr name)
|
DepthImage::Init(const Device *device, vk::Extent2D extent, cstr name)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,24 @@
|
||||||
|
|
||||||
struct Device;
|
struct Device;
|
||||||
|
|
||||||
|
[[nodiscard]] inline vk::Extent2D
|
||||||
|
ToExtent2D(const vk::Extent3D &extent)
|
||||||
|
{
|
||||||
|
return {extent.width, extent.height};
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline vk::Offset2D
|
||||||
|
ToOffset2D(const vk::Extent3D &extent)
|
||||||
|
{
|
||||||
|
return {Cast<i32>(extent.width), Cast<i32>(extent.height)};
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline vk::Offset3D
|
||||||
|
ToOffset3D(const vk::Extent3D &extent)
|
||||||
|
{
|
||||||
|
return {Cast<i32>(extent.width), Cast<i32>(extent.height), Cast<i32>(extent.depth)};
|
||||||
|
}
|
||||||
|
|
||||||
struct Image
|
struct Image
|
||||||
{
|
{
|
||||||
vk::Image m_Image = nullptr;
|
vk::Image m_Image = nullptr;
|
||||||
|
|
@ -32,7 +50,12 @@ struct Image
|
||||||
|
|
||||||
struct Texture : Image
|
struct Texture : Image
|
||||||
{
|
{
|
||||||
void Init(const Device *device, vk::Extent2D extent, vk::Format imageFormat, bool isMipmapped, cstr name = nullptr);
|
void Init(const Device *device, vk::Extent2D extent, vk::Format imageFormat, bool isMipMapped, cstr name = nullptr);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AttachmentImage : Image
|
||||||
|
{
|
||||||
|
void Init(const Device *device, vk::Extent2D extent, vk::Format imageFormat, cstr name = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DepthImage : Image
|
struct DepthImage : Image
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ Swapchain::Create(const Window *window)
|
||||||
.imageColorSpace = swapchainColorSpace,
|
.imageColorSpace = swapchainColorSpace,
|
||||||
.imageExtent = m_Extent,
|
.imageExtent = m_Extent,
|
||||||
.imageArrayLayers = 1,
|
.imageArrayLayers = 1,
|
||||||
.imageUsage = vk::ImageUsageFlagBits::eColorAttachment,
|
.imageUsage = vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferDst,
|
||||||
.imageSharingMode = vk::SharingMode::eExclusive,
|
.imageSharingMode = vk::SharingMode::eExclusive,
|
||||||
.preTransform = surfaceCapabilities.currentTransform,
|
.preTransform = surfaceCapabilities.currentTransform,
|
||||||
.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque,
|
.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque,
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,12 @@
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
Window::RequestExit() const noexcept
|
||||||
|
{
|
||||||
|
glfwSetWindowShouldClose(m_Window, true);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Window::SetWindowSize(const vk::Extent2D &extent) const noexcept
|
Window::SetWindowSize(const vk::Extent2D &extent) const noexcept
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ struct Window final
|
||||||
return !glfwWindowShouldClose(m_Window);
|
return !glfwWindowShouldClose(m_Window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RequestExit() const noexcept;
|
||||||
void SetWindowSize(const vk::Extent2D &extent) const noexcept;
|
void SetWindowSize(const vk::Extent2D &extent) const noexcept;
|
||||||
void SetWindowSize(u32 width, u32 height) const noexcept;
|
void SetWindowSize(u32 width, u32 height) const noexcept;
|
||||||
/// Actual size of the framebuffer being used for the window render.
|
/// Actual size of the framebuffer being used for the window render.
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,18 @@
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
|
find_package(imgui CONFIG REQUIRED)
|
||||||
|
|
||||||
add_library(util_helper STATIC
|
add_library(util_helper STATIC
|
||||||
helpers.h
|
helpers.h
|
||||||
helpers.cpp
|
helpers.cpp
|
||||||
frame.cpp
|
frame.cpp
|
||||||
frame.h
|
frame.h
|
||||||
gpu_resource_manager.cpp
|
gpu_resource_manager.cpp
|
||||||
gpu_resource_manager.h)
|
gpu_resource_manager.h
|
||||||
|
gui.cpp
|
||||||
|
gui.h)
|
||||||
|
|
||||||
target_link_libraries(util_helper PRIVATE aster_core)
|
target_link_libraries(util_helper PRIVATE aster_core)
|
||||||
|
target_link_libraries(util_helper PRIVATE imgui::imgui)
|
||||||
target_include_directories(util_helper PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
target_include_directories(util_helper PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,213 @@
|
||||||
|
// =============================================
|
||||||
|
// Aster: gui.cpp
|
||||||
|
// Copyright (c) 2020-2024 Anish Bhobe
|
||||||
|
// =============================================
|
||||||
|
|
||||||
|
#include "gui.h"
|
||||||
|
|
||||||
|
#include "context.h"
|
||||||
|
#include "device.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
#include "image.h"
|
||||||
|
#include "window.h"
|
||||||
|
|
||||||
|
#include <imgui_impl_glfw.h>
|
||||||
|
#include <imgui_impl_vulkan.h>
|
||||||
|
#include <imgui_internal.h>
|
||||||
|
|
||||||
|
namespace ImGui
|
||||||
|
{
|
||||||
|
vk::Format g_AttachmentFormat;
|
||||||
|
vk::DescriptorPool g_DescriptorPool;
|
||||||
|
|
||||||
|
void
|
||||||
|
VulkanAssert(VkResult result)
|
||||||
|
{
|
||||||
|
AbortIfFailed(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Init(const Context *context, const Device *device, const Window *window, vk::Format attachmentFormat,
|
||||||
|
const u32 imageCount, const u32 queueFamily, const vk::Queue queue)
|
||||||
|
{
|
||||||
|
g_AttachmentFormat = attachmentFormat;
|
||||||
|
|
||||||
|
eastl::vector<vk::DescriptorPoolSize> poolSizes = {
|
||||||
|
{vk::DescriptorType::eSampler, 1000},
|
||||||
|
{vk::DescriptorType::eCombinedImageSampler, 1000},
|
||||||
|
{vk::DescriptorType::eSampledImage, 1000},
|
||||||
|
{vk::DescriptorType::eStorageImage, 1000},
|
||||||
|
{vk::DescriptorType::eUniformTexelBuffer, 1000},
|
||||||
|
{vk::DescriptorType::eStorageTexelBuffer, 1000},
|
||||||
|
{vk::DescriptorType::eUniformBuffer, 1000},
|
||||||
|
{vk::DescriptorType::eStorageBuffer, 1000},
|
||||||
|
{vk::DescriptorType::eUniformBufferDynamic, 1000},
|
||||||
|
{vk::DescriptorType::eStorageBufferDynamic, 1000},
|
||||||
|
{vk::DescriptorType::eInputAttachment, 1000},
|
||||||
|
};
|
||||||
|
|
||||||
|
const vk::DescriptorPoolCreateInfo descriptorPoolCreateInfo = {
|
||||||
|
.flags = vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet,
|
||||||
|
.maxSets = 1000,
|
||||||
|
.poolSizeCount = Cast<u32>(poolSizes.size()),
|
||||||
|
.pPoolSizes = poolSizes.data(),
|
||||||
|
};
|
||||||
|
|
||||||
|
AbortIfFailed(device->m_Device.createDescriptorPool(&descriptorPoolCreateInfo, nullptr, &g_DescriptorPool));
|
||||||
|
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
CreateContext();
|
||||||
|
ImGuiIO &io = GetIO();
|
||||||
|
(void)io;
|
||||||
|
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||||
|
// io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Viewports bad
|
||||||
|
|
||||||
|
StyleColorsDark();
|
||||||
|
|
||||||
|
ImGui_ImplGlfw_InitForVulkan(window->m_Window, true);
|
||||||
|
|
||||||
|
vk::PipelineRenderingCreateInfo renderingCreateInfo = {
|
||||||
|
.colorAttachmentCount = 1,
|
||||||
|
.pColorAttachmentFormats = &g_AttachmentFormat,
|
||||||
|
};
|
||||||
|
|
||||||
|
ImGui_ImplVulkan_InitInfo imguiVulkanInitInfo = {
|
||||||
|
.Instance = context->m_Instance,
|
||||||
|
.PhysicalDevice = device->m_PhysicalDevice,
|
||||||
|
.Device = device->m_Device,
|
||||||
|
.QueueFamily = queueFamily,
|
||||||
|
.Queue = queue,
|
||||||
|
.DescriptorPool = g_DescriptorPool,
|
||||||
|
.MinImageCount = imageCount,
|
||||||
|
.ImageCount = imageCount,
|
||||||
|
.PipelineCache = nullptr,
|
||||||
|
.UseDynamicRendering = true,
|
||||||
|
.PipelineRenderingCreateInfo = renderingCreateInfo,
|
||||||
|
.Allocator = nullptr,
|
||||||
|
.CheckVkResultFn = VulkanAssert,
|
||||||
|
};
|
||||||
|
ImGui_ImplVulkan_Init(&imguiVulkanInitInfo);
|
||||||
|
|
||||||
|
ImGui_ImplVulkan_CreateFontsTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Destroy(const Device *device)
|
||||||
|
{
|
||||||
|
|
||||||
|
ImGui_ImplVulkan_Shutdown();
|
||||||
|
ImGui_ImplGlfw_Shutdown();
|
||||||
|
DestroyContext();
|
||||||
|
|
||||||
|
device->m_Device.destroy(Take(g_DescriptorPool), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
StartBuild()
|
||||||
|
{
|
||||||
|
ImGui_ImplVulkan_NewFrame();
|
||||||
|
ImGui_ImplGlfw_NewFrame();
|
||||||
|
NewFrame();
|
||||||
|
|
||||||
|
static ImGuiDockNodeFlags dockspaceFlags = ImGuiDockNodeFlags_None | ImGuiDockNodeFlags_PassthruCentralNode;
|
||||||
|
|
||||||
|
// We are using the ImGuiWindowFlags_NoDocking flag to make the parent window not dockable into,
|
||||||
|
// because it would be confusing to have two docking targets within each others.
|
||||||
|
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoDocking;
|
||||||
|
|
||||||
|
const ImGuiViewport *viewport = GetMainViewport();
|
||||||
|
SetNextWindowPos(viewport->WorkPos);
|
||||||
|
SetNextWindowSize(viewport->WorkSize);
|
||||||
|
SetNextWindowViewport(viewport->ID);
|
||||||
|
PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||||
|
PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||||
|
windowFlags |=
|
||||||
|
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
||||||
|
windowFlags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
||||||
|
windowFlags |= ImGuiWindowFlags_NoBackground;
|
||||||
|
|
||||||
|
// Important: note that we proceed even if Begin() returns false (aka window is collapsed).
|
||||||
|
// This is because we want to keep our DockSpace() active. If a DockSpace() is inactive,
|
||||||
|
// all active windows docked into it will lose their parent and become undocked.
|
||||||
|
// We cannot preserve the docking relationship between an active window and an inactive docking, otherwise
|
||||||
|
// any change of dockspace/settings would lead to windows being stuck in limbo and never being visible.
|
||||||
|
PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||||
|
Begin("DockSpace Demo", nullptr, windowFlags);
|
||||||
|
PopStyleVar();
|
||||||
|
|
||||||
|
PopStyleVar(2);
|
||||||
|
|
||||||
|
// DockSpace
|
||||||
|
if (GetIO().ConfigFlags & ImGuiConfigFlags_DockingEnable)
|
||||||
|
{
|
||||||
|
const ImGuiID dockspaceId = GetID("MyDockSpace");
|
||||||
|
DockSpace(dockspaceId, ImVec2(0.0f, 0.0f), dockspaceFlags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
EndBuild()
|
||||||
|
{
|
||||||
|
End();
|
||||||
|
Render();
|
||||||
|
|
||||||
|
EndFrame();
|
||||||
|
if (GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||||
|
{
|
||||||
|
GLFWwindow *backupCurrentContext = glfwGetCurrentContext();
|
||||||
|
UpdatePlatformWindows();
|
||||||
|
RenderPlatformWindowsDefault();
|
||||||
|
glfwMakeContextCurrent(backupCurrentContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Draw(const vk::CommandBuffer commandBuffer, const AttachmentImage *attachmentImage)
|
||||||
|
{
|
||||||
|
// OPTICK_EVENT();
|
||||||
|
|
||||||
|
constexpr vk::DebugUtilsLabelEXT label = {
|
||||||
|
.pLabelName = "UI pass",
|
||||||
|
.color = std::array{0.0f, 0.0f, 1.0f, 1.0f},
|
||||||
|
};
|
||||||
|
commandBuffer.beginDebugUtilsLabelEXT(&label);
|
||||||
|
vk::RenderingAttachmentInfo attachmentInfo = {
|
||||||
|
.imageView = attachmentImage->m_View,
|
||||||
|
.imageLayout = vk::ImageLayout::eColorAttachmentOptimal,
|
||||||
|
.resolveMode = vk::ResolveModeFlagBits::eNone,
|
||||||
|
.loadOp = vk::AttachmentLoadOp::eLoad,
|
||||||
|
.storeOp = vk::AttachmentStoreOp::eStore,
|
||||||
|
.clearValue = vk::ClearColorValue{0.0f, 0.0f, 0.0f, 1.0f},
|
||||||
|
};
|
||||||
|
|
||||||
|
const vk::RenderingInfo renderingInfo = {
|
||||||
|
.renderArea = {.extent = ToExtent2D(attachmentImage->m_Extent)},
|
||||||
|
.layerCount = 1,
|
||||||
|
.colorAttachmentCount = 1,
|
||||||
|
.pColorAttachments = &attachmentInfo,
|
||||||
|
.pDepthAttachment = nullptr,
|
||||||
|
};
|
||||||
|
|
||||||
|
commandBuffer.beginRendering(&renderingInfo);
|
||||||
|
|
||||||
|
ImGui_ImplVulkan_RenderDrawData(GetDrawData(), commandBuffer);
|
||||||
|
|
||||||
|
commandBuffer.endRendering();
|
||||||
|
|
||||||
|
commandBuffer.endDebugUtilsLabelEXT();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PushDisable()
|
||||||
|
{
|
||||||
|
PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||||
|
PushStyleVar(ImGuiStyleVar_Alpha, GetStyle().Alpha * 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PopDisable()
|
||||||
|
{
|
||||||
|
PopStyleVar();
|
||||||
|
PopItemFlag();
|
||||||
|
}
|
||||||
|
} // namespace ImGui
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
// =============================================
|
||||||
|
// Aster: gui.h
|
||||||
|
// Copyright (c) 2020-2024 Anish Bhobe
|
||||||
|
// =============================================
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
struct AttachmentImage;
|
||||||
|
struct Device;
|
||||||
|
struct Context;
|
||||||
|
struct Window;
|
||||||
|
struct Swapchain;
|
||||||
|
|
||||||
|
// ReSharper disable once CppInconsistentNaming
|
||||||
|
namespace ImGui
|
||||||
|
{
|
||||||
|
void Init(const Context *context, const Device *device, const Window *window, vk::Format attachmentFormat,
|
||||||
|
u32 imageCount, u32 queueFamily, vk::Queue queue);
|
||||||
|
void Destroy(const Device *device);
|
||||||
|
|
||||||
|
void Recreate();
|
||||||
|
void StartBuild();
|
||||||
|
void EndBuild();
|
||||||
|
void Draw(vk::CommandBuffer commandBuffer, const AttachmentImage *attachmentImage);
|
||||||
|
|
||||||
|
void PushDisable();
|
||||||
|
void PopDisable();
|
||||||
|
} // namespace ImGui
|
||||||
|
|
||||||
|
namespace gui = ImGui;
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include "light_manager.h"
|
#include "light_manager.h"
|
||||||
|
|
||||||
#include "gpu_resource_manager.h"
|
#include "gpu_resource_manager.h"
|
||||||
|
#include "gui.h"
|
||||||
#include "model_loader.h"
|
#include "model_loader.h"
|
||||||
#include "pipeline_utils.h"
|
#include "pipeline_utils.h"
|
||||||
|
|
||||||
|
|
@ -79,7 +80,8 @@ main(int, char **)
|
||||||
|
|
||||||
Model model = modelLoader.LoadModel(MODEL_FILE);
|
Model model = modelLoader.LoadModel(MODEL_FILE);
|
||||||
|
|
||||||
Pipeline pipeline = CreatePipeline(&device, &swapchain, &resourceManager);
|
vk::Format attachmentFormat = vk::Format::eR8G8B8A8Srgb;
|
||||||
|
Pipeline pipeline = CreatePipeline(&device, attachmentFormat, &resourceManager);
|
||||||
|
|
||||||
Camera camera = {
|
Camera camera = {
|
||||||
.m_View = glm::lookAt(vec3(0.0f, 2.0f, 2.0f), vec3(0.0f), vec3(0.0f, 1.0f, 0.0f)),
|
.m_View = glm::lookAt(vec3(0.0f, 2.0f, 2.0f), vec3(0.0f), vec3(0.0f, 1.0f, 0.0f)),
|
||||||
|
|
@ -154,14 +156,6 @@ main(int, char **)
|
||||||
.extent = swapchain.m_Extent,
|
.extent = swapchain.m_Extent,
|
||||||
};
|
};
|
||||||
|
|
||||||
auto fnResizeViewportScissor = [&viewport, &scissor](vk::Extent2D extent) {
|
|
||||||
viewport.y = Cast<f32>(extent.height);
|
|
||||||
viewport.width = Cast<f32>(extent.width);
|
|
||||||
viewport.height = -Cast<f32>(extent.height);
|
|
||||||
scissor.extent = extent;
|
|
||||||
};
|
|
||||||
swapchain.RegisterResizeCallback(fnResizeViewportScissor);
|
|
||||||
|
|
||||||
vk::ImageSubresourceRange subresourceRange = {
|
vk::ImageSubresourceRange subresourceRange = {
|
||||||
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
||||||
.baseMipLevel = 0,
|
.baseMipLevel = 0,
|
||||||
|
|
@ -176,8 +170,26 @@ main(int, char **)
|
||||||
.dstQueueFamilyIndex = queueAllocation.m_Family,
|
.dstQueueFamilyIndex = queueAllocation.m_Family,
|
||||||
.subresourceRange = subresourceRange,
|
.subresourceRange = subresourceRange,
|
||||||
};
|
};
|
||||||
vk::ImageMemoryBarrier renderToPresentBarrier = {
|
vk::ImageMemoryBarrier renderToTransferSrcBarrier = {
|
||||||
.oldLayout = vk::ImageLayout::eColorAttachmentOptimal,
|
.oldLayout = vk::ImageLayout::eColorAttachmentOptimal,
|
||||||
|
.newLayout = vk::ImageLayout::eTransferSrcOptimal,
|
||||||
|
.srcQueueFamilyIndex = queueAllocation.m_Family,
|
||||||
|
.dstQueueFamilyIndex = queueAllocation.m_Family,
|
||||||
|
.subresourceRange = subresourceRange,
|
||||||
|
};
|
||||||
|
vk::ImageMemoryBarrier acquireToTransferDstBarrier = {
|
||||||
|
.oldLayout = vk::ImageLayout::eUndefined,
|
||||||
|
.newLayout = vk::ImageLayout::eTransferDstOptimal,
|
||||||
|
.srcQueueFamilyIndex = queueAllocation.m_Family,
|
||||||
|
.dstQueueFamilyIndex = queueAllocation.m_Family,
|
||||||
|
.subresourceRange = subresourceRange,
|
||||||
|
};
|
||||||
|
eastl::array postRenderBarriers = {
|
||||||
|
renderToTransferSrcBarrier,
|
||||||
|
acquireToTransferDstBarrier,
|
||||||
|
};
|
||||||
|
vk::ImageMemoryBarrier transferDstToPresentBarrier = {
|
||||||
|
.oldLayout = vk::ImageLayout::eTransferDstOptimal,
|
||||||
.newLayout = vk::ImageLayout::ePresentSrcKHR,
|
.newLayout = vk::ImageLayout::ePresentSrcKHR,
|
||||||
.srcQueueFamilyIndex = queueAllocation.m_Family,
|
.srcQueueFamilyIndex = queueAllocation.m_Family,
|
||||||
.dstQueueFamilyIndex = queueAllocation.m_Family,
|
.dstQueueFamilyIndex = queueAllocation.m_Family,
|
||||||
|
|
@ -186,25 +198,26 @@ main(int, char **)
|
||||||
|
|
||||||
FrameManager frameManager = {&device, queueAllocation.m_Family, MAX_FRAMES_IN_FLIGHT};
|
FrameManager frameManager = {&device, queueAllocation.m_Family, MAX_FRAMES_IN_FLIGHT};
|
||||||
eastl::fixed_vector<DepthImage, MAX_FRAMES_IN_FLIGHT> depthImages(frameManager.m_FramesInFlight);
|
eastl::fixed_vector<DepthImage, MAX_FRAMES_IN_FLIGHT> depthImages(frameManager.m_FramesInFlight);
|
||||||
|
eastl::fixed_vector<AttachmentImage, MAX_FRAMES_IN_FLIGHT> attachmentImages(frameManager.m_FramesInFlight);
|
||||||
{
|
{
|
||||||
u32 depthImageIdx = 0;
|
auto depthIter = depthImages.begin();
|
||||||
for (auto &depthImage : depthImages)
|
auto attachmentIter = attachmentImages.begin();
|
||||||
|
for (u32 index = 0; index < frameManager.m_FramesInFlight; ++index)
|
||||||
{
|
{
|
||||||
auto name = fmt::format("Depth {}", depthImageIdx++);
|
auto name = fmt::format("Depth Frame{}", index);
|
||||||
depthImage.Init(&device, swapchain.m_Extent, name.c_str());
|
depthIter->Init(&device, swapchain.m_Extent, name.c_str());
|
||||||
|
|
||||||
|
name = fmt::format("Attachment0 Frame{}", index);
|
||||||
|
attachmentIter->Init(&device, swapchain.m_Extent, attachmentFormat, name.c_str());
|
||||||
|
|
||||||
|
++depthIter;
|
||||||
|
++attachmentIter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fnRecreateDepthBuffers = [&device, &depthImages](vk::Extent2D extent) {
|
gui::Init(&context, &device, &window, attachmentFormat, frameManager.m_FramesInFlight, queueAllocation.m_Family,
|
||||||
u32 depthImageIdx = 0;
|
commandQueue);
|
||||||
for (auto &depthImage : depthImages)
|
bool rotating = false;
|
||||||
{
|
|
||||||
auto name = fmt::format("Depth {}", depthImageIdx++);
|
|
||||||
depthImage.Destroy(&device);
|
|
||||||
depthImage.Init(&device, extent, name.c_str());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
swapchain.RegisterResizeCallback(fnRecreateDepthBuffers);
|
|
||||||
|
|
||||||
Time::Init();
|
Time::Init();
|
||||||
|
|
||||||
|
|
@ -213,21 +226,43 @@ main(int, char **)
|
||||||
{
|
{
|
||||||
Time::Update();
|
Time::Update();
|
||||||
|
|
||||||
model.SetModelTransform(
|
gui::StartBuild();
|
||||||
rotate(model.GetModelTransform(), Cast<f32>(45.0_deg * Time::m_Delta), vec3(0.0f, 1.0f, 0.0f)));
|
|
||||||
|
gui::Begin("Settings");
|
||||||
|
gui::Text("Delta: %0.6f ms", 1000.0f * Time::m_Delta);
|
||||||
|
gui::Text("FPS: %0.6f", 1.0f / Time::m_Delta);
|
||||||
|
gui::Checkbox("Rotate", &rotating);
|
||||||
|
if (gui::Button("Exit"))
|
||||||
|
{
|
||||||
|
window.RequestExit();
|
||||||
|
}
|
||||||
|
gui::End();
|
||||||
|
|
||||||
|
gui::EndBuild();
|
||||||
|
|
||||||
|
if (rotating)
|
||||||
|
{
|
||||||
|
model.SetModelTransform(
|
||||||
|
rotate(model.GetModelTransform(), Cast<f32>(45.0_deg * Time::m_Delta), vec3(0.0f, 1.0f, 0.0f)));
|
||||||
|
}
|
||||||
model.Update();
|
model.Update();
|
||||||
ubo.Write(&device, 0, sizeof camera, &camera);
|
ubo.Write(&device, 0, sizeof camera, &camera);
|
||||||
|
|
||||||
Frame *currentFrame = frameManager.GetNextFrame(&swapchain, &window);
|
Frame *currentFrame = frameManager.GetNextFrame(&swapchain, &window);
|
||||||
|
|
||||||
u32 imageIndex = currentFrame->m_ImageIdx;
|
u32 imageIndex = currentFrame->m_ImageIdx;
|
||||||
vk::ImageView currentImageView = swapchain.m_ImageViews[imageIndex];
|
vk::Image currentSwapchainImage = swapchain.m_Images[imageIndex];
|
||||||
vk::Image currentImage = swapchain.m_Images[imageIndex];
|
|
||||||
vk::CommandBuffer cmd = currentFrame->m_CommandBuffer;
|
vk::CommandBuffer cmd = currentFrame->m_CommandBuffer;
|
||||||
vk::ImageView currentDepthImageView = depthImages[currentFrame->m_FrameIdx].m_View;
|
vk::ImageView currentDepthImageView = depthImages[currentFrame->m_FrameIdx].m_View;
|
||||||
|
|
||||||
|
AttachmentImage *currentAttachment = &attachmentImages[currentFrame->m_ImageIdx];
|
||||||
|
vk::Image currentImage = currentAttachment->m_Image;
|
||||||
|
vk::ImageView currentImageView = currentAttachment->m_View;
|
||||||
|
|
||||||
topOfThePipeBarrier.image = currentImage;
|
topOfThePipeBarrier.image = currentImage;
|
||||||
renderToPresentBarrier.image = currentImage;
|
postRenderBarriers[0].image = currentImage;
|
||||||
|
postRenderBarriers[1].image = currentSwapchainImage;
|
||||||
|
transferDstToPresentBarrier.image = currentSwapchainImage;
|
||||||
|
|
||||||
vk::CommandBufferBeginInfo beginInfo = {.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit};
|
vk::CommandBufferBeginInfo beginInfo = {.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit};
|
||||||
AbortIfFailed(cmd.begin(&beginInfo));
|
AbortIfFailed(cmd.begin(&beginInfo));
|
||||||
|
|
@ -257,7 +292,7 @@ main(int, char **)
|
||||||
};
|
};
|
||||||
|
|
||||||
vk::RenderingInfo renderingInfo = {
|
vk::RenderingInfo renderingInfo = {
|
||||||
.renderArea = {.extent = swapchain.m_Extent},
|
.renderArea = {.extent = ToExtent2D(currentAttachment->m_Extent)},
|
||||||
.layerCount = 1,
|
.layerCount = 1,
|
||||||
.colorAttachmentCount = Cast<u32>(attachmentInfos.size()),
|
.colorAttachmentCount = Cast<u32>(attachmentInfos.size()),
|
||||||
.pColorAttachments = attachmentInfos.data(),
|
.pColorAttachments = attachmentInfos.data(),
|
||||||
|
|
@ -285,19 +320,54 @@ main(int, char **)
|
||||||
|
|
||||||
for (auto &prim : model.m_MeshPrimitives)
|
for (auto &prim : model.m_MeshPrimitives)
|
||||||
{
|
{
|
||||||
cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, pcbOffset, sizeof prim.m_MaterialIdx,
|
u32 innerPcbOffset = pcbOffset;
|
||||||
&prim.m_MaterialIdx);
|
cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, innerPcbOffset,
|
||||||
pcbOffset += sizeof prim.m_MaterialIdx;
|
sizeof prim.m_MaterialIdx, &prim.m_MaterialIdx);
|
||||||
cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, pcbOffset, sizeof prim.m_TransformIdx,
|
innerPcbOffset += sizeof prim.m_MaterialIdx;
|
||||||
&prim.m_TransformIdx);
|
cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, innerPcbOffset,
|
||||||
pcbOffset += sizeof prim.m_TransformIdx;
|
sizeof prim.m_TransformIdx, &prim.m_TransformIdx);
|
||||||
|
innerPcbOffset += sizeof prim.m_TransformIdx;
|
||||||
cmd.drawIndexed(prim.m_IndexCount, 1, prim.m_FirstIndex, Cast<i32>(prim.m_VertexOffset), 0);
|
cmd.drawIndexed(prim.m_IndexCount, 1, prim.m_FirstIndex, Cast<i32>(prim.m_VertexOffset), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.endRendering();
|
cmd.endRendering();
|
||||||
|
|
||||||
cmd.pipelineBarrier(vk::PipelineStageFlagBits::eColorAttachmentOutput, vk::PipelineStageFlagBits::eBottomOfPipe,
|
gui::Draw(cmd, currentAttachment);
|
||||||
{}, 0, nullptr, 0, nullptr, 1, &renderToPresentBarrier);
|
|
||||||
|
cmd.pipelineBarrier(vk::PipelineStageFlagBits::eColorAttachmentOutput, vk::PipelineStageFlagBits::eAllCommands,
|
||||||
|
{}, 0, nullptr, 0, nullptr, postRenderBarriers.size(), postRenderBarriers.data());
|
||||||
|
|
||||||
|
vk::ImageBlit blitRegion = {
|
||||||
|
.srcSubresource =
|
||||||
|
{
|
||||||
|
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
||||||
|
.mipLevel = 0,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
},
|
||||||
|
.srcOffsets =
|
||||||
|
std::array{
|
||||||
|
vk::Offset3D{0, 0, 0},
|
||||||
|
ToOffset3D(currentAttachment->m_Extent),
|
||||||
|
},
|
||||||
|
.dstSubresource =
|
||||||
|
{
|
||||||
|
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
||||||
|
.mipLevel = 0,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
},
|
||||||
|
.dstOffsets =
|
||||||
|
std::array{
|
||||||
|
vk::Offset3D{0, 0, 0},
|
||||||
|
vk::Offset3D{Cast<i32>(swapchain.m_Extent.width), Cast<i32>(swapchain.m_Extent.height), 1},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
cmd.blitImage(currentImage, postRenderBarriers[0].newLayout, currentSwapchainImage,
|
||||||
|
postRenderBarriers[1].newLayout, 1, &blitRegion, vk::Filter::eLinear);
|
||||||
|
|
||||||
|
cmd.pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eAllCommands, {}, 0,
|
||||||
|
nullptr, 0, nullptr, 1, &transferDstToPresentBarrier);
|
||||||
|
|
||||||
AbortIfFailed(cmd.end());
|
AbortIfFailed(cmd.end());
|
||||||
|
|
||||||
|
|
@ -318,10 +388,16 @@ main(int, char **)
|
||||||
|
|
||||||
AbortIfFailed(device.m_Device.waitIdle());
|
AbortIfFailed(device.m_Device.waitIdle());
|
||||||
|
|
||||||
|
gui::Destroy(&device);
|
||||||
|
|
||||||
for (auto &depthImage : depthImages)
|
for (auto &depthImage : depthImages)
|
||||||
{
|
{
|
||||||
depthImage.Destroy(&device);
|
depthImage.Destroy(&device);
|
||||||
}
|
}
|
||||||
|
for (auto &attachmentImage : attachmentImages)
|
||||||
|
{
|
||||||
|
attachmentImage.Destroy(&device);
|
||||||
|
}
|
||||||
ubo.Destroy(&device);
|
ubo.Destroy(&device);
|
||||||
device.m_Device.destroy(descriptorPool, nullptr);
|
device.m_Device.destroy(descriptorPool, nullptr);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
#include <EASTL/array.h>
|
#include <EASTL/array.h>
|
||||||
|
|
||||||
Pipeline
|
Pipeline
|
||||||
CreatePipeline(const Device *device, const Swapchain *swapchain, const GpuResourceManager *resourceManager)
|
CreatePipeline(const Device *device, vk::Format attachmentFormat, const GpuResourceManager *resourceManager)
|
||||||
{
|
{
|
||||||
// Pipeline Setup
|
// Pipeline Setup
|
||||||
auto vertexShaderModule = CreateShader(device, VERTEX_SHADER_FILE);
|
auto vertexShaderModule = CreateShader(device, VERTEX_SHADER_FILE);
|
||||||
|
|
@ -132,7 +132,7 @@ CreatePipeline(const Device *device, const Swapchain *swapchain, const GpuResour
|
||||||
vk::PipelineRenderingCreateInfo renderingCreateInfo = {
|
vk::PipelineRenderingCreateInfo renderingCreateInfo = {
|
||||||
.viewMask = 0,
|
.viewMask = 0,
|
||||||
.colorAttachmentCount = 1,
|
.colorAttachmentCount = 1,
|
||||||
.pColorAttachmentFormats = &swapchain->m_Format,
|
.pColorAttachmentFormats = &attachmentFormat,
|
||||||
.depthAttachmentFormat = vk::Format::eD24UnormS8Uint,
|
.depthAttachmentFormat = vk::Format::eD24UnormS8Uint,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,4 +16,4 @@ constexpr auto VERTEX_SHADER_FILE = "shader/model.vs.hlsl.spv";
|
||||||
constexpr auto FRAGMENT_SHADER_FILE = "shader/model.ps.hlsl.spv";
|
constexpr auto FRAGMENT_SHADER_FILE = "shader/model.ps.hlsl.spv";
|
||||||
|
|
||||||
vk::ShaderModule CreateShader(const Device *device, cstr shaderFile);
|
vk::ShaderModule CreateShader(const Device *device, cstr shaderFile);
|
||||||
Pipeline CreatePipeline(const Device *device, const Swapchain *swapchain, const GpuResourceManager *resourceManager);
|
Pipeline CreatePipeline(const Device *device, vk::Format attachmentFormat, const GpuResourceManager *resourceManager);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,14 @@
|
||||||
"fmt",
|
"fmt",
|
||||||
"glfw3",
|
"glfw3",
|
||||||
"glm",
|
"glm",
|
||||||
|
{
|
||||||
|
"name": "imgui",
|
||||||
|
"features": [
|
||||||
|
"glfw-binding",
|
||||||
|
"vulkan-binding",
|
||||||
|
"docking-experimental"
|
||||||
|
]
|
||||||
|
},
|
||||||
"scottt-debugbreak",
|
"scottt-debugbreak",
|
||||||
"tinygltf",
|
"tinygltf",
|
||||||
"vulkan-memory-allocator"
|
"vulkan-memory-allocator"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue