Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ build.ninja
.ninja_*
compile_commands.json
*.cmake

imgui.ini
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@
[submodule "extern/cgltf"]
path = extern/cgltf
url = https://github.com/jkuhlmann/cgltf
[submodule "extern/imgui"]
path = extern/imgui
url = https://github.com/ocornut/imgui.git
21 changes: 20 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ add_executable(niagara

set_target_properties(niagara PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO)

target_compile_definitions(niagara PRIVATE GLFW_INCLUDE_NONE GLM_FORCE_XYZW_ONLY GLM_FORCE_QUAT_DATA_XYZW GLM_FORCE_QUAT_CTOR_XYZW)
target_compile_definitions(niagara PRIVATE
GLFW_INCLUDE_NONE
GLM_FORCE_XYZW_ONLY
GLM_FORCE_QUAT_DATA_XYZW
GLM_FORCE_QUAT_CTOR_XYZW
CMAKE_BINARY_DIR="${CMAKE_BINARY_DIR}"
)
target_include_directories(niagara PRIVATE extern/fast_obj extern/cgltf extern/glm)

if(WIN32)
Expand All @@ -40,10 +46,23 @@ endif()
add_subdirectory(extern/volk)
add_subdirectory(extern/meshoptimizer)

file(GLOB IMGUI_SOURCES "extern/imgui/*.cpp" "extern/imgui/*.c")

list(APPEND IMGUI_SOURCES "extern/imgui/misc/cpp/imgui_stdlib.cpp")
list(APPEND IMGUI_SOURCES "extern/imgui/backends/imgui_impl_glfw.cpp")
list(APPEND IMGUI_SOURCES "extern/imgui/backends/imgui_impl_vulkan.cpp")

add_library(imgui STATIC ${IMGUI_SOURCES})

target_link_libraries(imgui PUBLIC glfw volk)
target_include_directories(imgui PUBLIC "extern/imgui")
target_compile_definitions(imgui PUBLIC IMGUI_IMPL_VULKAN_USE_VOLK)

target_link_libraries(niagara
PRIVATE
glfw
volk
imgui
meshoptimizer)

if(UNIX)
Expand Down
1 change: 1 addition & 0 deletions extern/imgui
Submodule imgui added at 913a3c
102 changes: 102 additions & 0 deletions src/imgui_utils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include "imgui_utils.h"
#include <GLFW/glfw3.h>
#include <imgui.h>
#include <backends/imgui_impl_glfw.h>
#include <backends/imgui_impl_vulkan.h>

void imInit(GLFWwindow* window, VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, uint32_t queue_family, VkQueue queue, uint32_t sc_images, VkFormat sc_format)
{
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
(void)io;

io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;

// May trigger validation assertion due to the incorrect sync. implementation on ImGui side
// See https://github.com/ocornut/imgui/issues/8795
// io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;

// Makes all elements transparent, so the background is seen even when window is open
ImGui::GetStyle().Alpha = 0.75F;

ImGui_ImplGlfw_InitForVulkan(window, true);
ImGui_ImplVulkan_InitInfo init_info = {};

init_info.ApiVersion = VK_API_VERSION_1_4;
init_info.Instance = instance;
init_info.PhysicalDevice = physical_device;
init_info.Device = device;
init_info.QueueFamily = queue_family;
init_info.Queue = queue;
init_info.PipelineCache = VK_NULL_HANDLE;
init_info.UseDynamicRendering = true;
init_info.MinAllocationSize = 1024 * 1024;
init_info.DescriptorPool = VK_NULL_HANDLE;
init_info.MinImageCount = 2;
init_info.ImageCount = sc_images;
init_info.DescriptorPoolSize = IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE;
init_info.Allocator = nullptr;
init_info.PipelineInfoMain.PipelineRenderingCreateInfo = {
VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
nullptr,
0,
1,
&sc_format,
};

ImGui_ImplVulkan_Init(&init_info);
}

void imShutdown()
{
ImGui_ImplVulkan_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}

void imBeginFrame()
{
ImGui_ImplVulkan_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
}

void imEndAndRender(VkCommandBuffer command_buffer, VkImageView sc_img_view, VkRect2D viewport)
{
ImGui::Render();

VkRenderingAttachmentInfo color_attachment_info{ VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO };
color_attachment_info.imageView = sc_img_view;
color_attachment_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
color_attachment_info.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
color_attachment_info.storeOp = VK_ATTACHMENT_STORE_OP_STORE;

VkRenderingInfo rendering_info{ VK_STRUCTURE_TYPE_RENDERING_INFO };
rendering_info.renderArea = viewport;
rendering_info.layerCount = 1;
rendering_info.colorAttachmentCount = 1;
rendering_info.pColorAttachments = &color_attachment_info;

vkCmdBeginRendering(command_buffer, &rendering_info);
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), command_buffer);
vkCmdEndRendering(command_buffer);

if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
}
}

bool imWantCaptureMouse()
{
return ImGui::GetIO().WantCaptureMouse;
}

bool imWantCaptureKeyboard()
{
return ImGui::GetIO().WantCaptureKeyboard;
}
14 changes: 14 additions & 0 deletions src/imgui_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include <volk.h>

struct GLFWwindow;

void imInit(GLFWwindow* window, VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, uint32_t queue_family, VkQueue queue, uint32_t sc_images, VkFormat sc_format);
void imShutdown();

void imBeginFrame();
void imEndAndRender(VkCommandBuffer command_buffer, VkImageView sc_img_view, VkRect2D viewport);

bool imWantCaptureMouse();
bool imWantCaptureKeyboard();
73 changes: 71 additions & 2 deletions src/niagara.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
#include <unistd.h>
#endif

#define NIAGARA_ENABLE_IMGUI 1

#if NIAGARA_ENABLE_IMGUI
#include "imgui_utils.h"
#include <imgui.h>
#endif

bool meshShadingEnabled = true;
bool cullingEnabled = true;
bool lodEnabled = true;
Expand Down Expand Up @@ -955,6 +962,10 @@ int main(int argc, const char** argv)
uint64_t timestampResults[23] = {};
uint64_t pipelineResults[3] = {};

#if NIAGARA_ENABLE_IMGUI
imInit(window, instance, physicalDevice, device, familyIndex, queue, swapchain.imageCount, swapchainFormat);
#endif

while (!glfwWindowShouldClose(window))
{
double frameDelta = glfwGetTime() - frameTimestamp;
Expand Down Expand Up @@ -987,8 +998,14 @@ int main(int argc, const char** argv)
if (reloadShaders && glfwGetTime() >= reloadShadersTimer)
{
bool changed = false;
int rc = system("ninja --quiet compile_shaders");
if (rc == 0)

#if defined(CMAKE_BINARY_DIR)
int rr = system("cmake --build " CMAKE_BINARY_DIR " --target compile_shaders");
#else
int rr = system("ninja --quiet compile_shaders");
#endif

if (rr == 0)
{
for (Shader& shader : shaders.shaders)
{
Expand Down Expand Up @@ -1639,6 +1656,54 @@ int main(int argc, const char** argv)
}
}

#if NIAGARA_ENABLE_IMGUI
imBeginFrame();
ImGui::SetNextWindowCollapsed(true, ImGuiCond_Appearing);
if (ImGui::Begin("niagara", nullptr))
{
ImGui::BeginDisabled(!meshShadingSupported);
ImGui::Checkbox("Enable mesh shading (M)", &meshShadingEnabled);
ImGui::Checkbox("Enable task shader (T)", &taskShadingEnabled);
ImGui::EndDisabled();

ImGui::Checkbox("Enable frustum culling (C)", &cullingEnabled);
ImGui::Checkbox("Enable mesh occlusion culling (O)", &occlusionEnabled);
ImGui::Checkbox("Enable cluster occlusion culling (K)", &clusterOcclusionEnabled);
ImGui::Checkbox("Enable LODs (L)", &lodEnabled);
ImGui::Checkbox("Enable animation (Space)", &animationEnabled);
ImGui::Checkbox("Debug sleep (Z)", &debugSleep);

ImGui::Checkbox("Enable RT shadows (F)", &shadowsEnabled);
ImGui::Checkbox("Enable RT shadows blur (B)", &shadowblurEnabled);
ImGui::Checkbox("Enable RT shadows checkerboard (X)", &shadowCheckerboard);

ImGui::SliderInt("Set RT shadows quality (Q)", &shadowQuality, 0, 1);
ImGui::SliderInt("Set LOD step (0-9)", &debugLodStep, 0, COUNTOF(Mesh::lods));

debugGuiMode = debugGuiMode % 3;
ImGui::SliderInt("GUI debug level (G)", &debugGuiMode, 0, 2);

#if !defined(CMAKE_BINARY_DIR)
ImGui::Text("CMAKE_BINARY_DIR not defined: shaders reload may not work as expected");
#endif

if (!reloadShaders && ImGui::Button("Enable shaders live reload"))
{
reloadShaders = !reloadShaders;
reloadShadersTimer = 0;
}
else if (reloadShaders)
{
ImGui::Text("Shaders live reload active...");
if (ImGui::Button("Stop"))
reloadShaders = !reloadShaders;
}
}
ImGui::End();

imEndAndRender(commandBuffer, swapchainImageViews[imageIndex], { { 0, 0 }, { uint32_t(swapchain.width), uint32_t(swapchain.height) } });
#endif

VkImageMemoryBarrier2 presentBarrier = imageBarrier(swapchain.images[imageIndex],
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL,
0, 0, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
Expand Down Expand Up @@ -1706,6 +1771,10 @@ int main(int argc, const char** argv)

VK_CHECK(vkDeviceWaitIdle(device));

#if NIAGARA_ENABLE_IMGUI
imShutdown();
#endif

vkDestroyDescriptorPool(device, textureSet.first, 0);

for (Image& image : images)
Expand Down