Cleanup gui handling and destruction

This commit is contained in:
2025-01-21 23:59:00 -05:00
parent 89a0238c24
commit 9e3f9c2366
20 changed files with 366 additions and 274 deletions

View File

@@ -0,0 +1,131 @@
//
// Created by kj16609 on 1/21/25.
//
#include "EditorGuiContext.hpp"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wconversion"
#include <backends/imgui_impl_glfw.h>
#include <backends/imgui_impl_vulkan.h>
#include <imgui_internal.h> // Included for DockBuilder since it's not exposed yet
#pragma GCC diagnostic pop
#include "FrameInfo.hpp"
#include "core.hpp"
#include "debug/timing/FlameGraph.hpp"
#include "descriptors/DescriptorPool.hpp"
#include "gui_window_names.hpp"
#include "rendering/RenderingFormats.hpp"
namespace fgl::editor
{
using namespace fgl::engine;
EditorGuiContext::EditorGuiContext( const Window& window )
{
ZoneScoped;
IMGUI_CHECKVERSION();
ImGui::CreateContext();
[[maybe_unused]] ImGuiIO& io { ImGui::GetIO() };
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
// io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
io.ConfigWindowsResizeFromEdges = true;
ImGui::StyleColorsDark();
Device& device { Device::getInstance() };
vk::PipelineRenderingCreateInfo pipeline_info {};
//TODO: Remove the ability for pickPresentFormat to be used here. Instead this should be hidden from the end user in roder to prevent shittery. This should be applied to everything else here too within reason.
const std::vector< vk::Format > color_formats { pickPresentFormat() };
pipeline_info.setColorAttachmentFormats( color_formats );
pipeline_info.setDepthAttachmentFormat( pickDepthFormat() );
ImGui_ImplGlfw_InitForVulkan( window.window(), true );
ImGui_ImplVulkan_InitInfo init_info {
.Instance = device.instance(),
.PhysicalDevice = *device.phyDevice().handle(),
.Device = *device,
.QueueFamily = device.phyDevice().queueInfo().getIndex( vk::QueueFlagBits::eGraphics ),
.Queue = *device.graphicsQueue(),
.DescriptorPool = *DescriptorPool::getInstance().getPool(),
.RenderPass = VK_NULL_HANDLE,
.MinImageCount = 2,
.ImageCount = 2,
.MSAASamples = VK_SAMPLE_COUNT_1_BIT,
.PipelineCache = VK_NULL_HANDLE,
.Subpass = 0,
.UseDynamicRendering = VK_TRUE,
.PipelineRenderingCreateInfo = pipeline_info,
.Allocator = VK_NULL_HANDLE,
.CheckVkResultFn = VK_NULL_HANDLE,
.MinAllocationSize = 1024 * 1024
};
ImGui_ImplVulkan_Init( &init_info );
}
EditorGuiContext::~EditorGuiContext()
{
ZoneScoped;
ImGui_ImplVulkan_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
void EditorGuiContext::beginDraw()
{
ZoneScoped;
ImGui_ImplVulkan_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
}
void EditorGuiContext::draw( FrameInfo& info )
{
ZoneScoped;
auto timer = debug::timing::push( "Draw ImGui" );
ImGui::ShowDemoWindow();
gui::drawDock();
gui::drawCameraOutputs( info );
gui::drawEntityGUI( info );
gui::drawEntityInfo( info );
ImGui::Begin( FILE_PICKER_NAME.data(), nullptr, ImGuiWindowFlags_MenuBar );
m_file_browser.drawGui( info );
ImGui::End();
gui::drawStats( info );
}
void EditorGuiContext::endDraw( vk::raii::CommandBuffer& command_buffer )
{
ZoneScoped;
ImGui::Render();
ImDrawData* data { ImGui::GetDrawData() };
ImGui_ImplVulkan_RenderDrawData( data, *command_buffer );
//ImGui::UpdatePlatformWindows();
//ImGui::RenderPlatformWindowsDefault();
}
void EditorGuiContext::endDraw( FrameInfo& info )
{
return endDraw( info.command_buffer );
}
} // namespace fgl::editor

View File

@@ -0,0 +1,23 @@
//
// Created by kj16609 on 1/21/25.
//
#pragma once
#include "FileBrowser.hpp"
namespace fgl::editor
{
class EditorGuiContext
{
engine::filesystem::FileBrowser m_file_browser {};
public:
EditorGuiContext( const engine::Window& window );
~EditorGuiContext();
void beginDraw();
void draw( engine::FrameInfo& info );
void endDraw( vk::raii::CommandBuffer& command_buffer );
void endDraw( engine::FrameInfo& info );
};
} // namespace fgl::editor

View File

@@ -18,41 +18,15 @@ namespace fgl::engine::filesystem
{
//! Textures for files (pre-rendered image, images, ect)
inline static std::unordered_map< std::filesystem::path, std::shared_ptr< Texture > > file_textures {};
inline static std::unique_ptr< DirInfo > current { nullptr };
constexpr std::uint32_t DESIRED_SIZE { 128 };
constexpr std::uint32_t PADDING { 2 };
inline static std::once_flag flag {};
inline static std::shared_ptr< Texture > folder_texture { nullptr };
inline static std::shared_ptr< Texture > file_texture { nullptr };
inline static std::shared_ptr< Texture > up_texture { nullptr };
constexpr std::uint32_t desired_size { 128 };
constexpr std::uint32_t padding { 2 };
const std::filesystem::path test_path { std::filesystem::current_path() / "assets" };
void prepareFileGUI()
{
//Prepare textures needed.
folder_texture = getTextureStore().load( "./assets/folder.png", vk::Format::eR8G8B8A8Unorm );
file_texture = getTextureStore().load( "./assets/file.png", vk::Format::eR8G8B8A8Unorm );
up_texture = getTextureStore().load( "./assets/up.png", vk::Format::eR8G8B8A8Unorm );
current = std::make_unique< DirInfo >( test_path );
}
void destroyFileGui()
{
folder_texture.reset();
file_texture.reset();
up_texture.reset();
file_textures.clear();
}
const std::filesystem::path TEST_PATH { std::filesystem::current_path() / "assets" };
void FileBrowser::drawGui( [[maybe_unused]] FrameInfo& info )
{
ZoneScoped;
std::call_once( flag, prepareFileGUI );
/*
if ( ImGui::BeginMenuBar() )
@@ -72,19 +46,20 @@ namespace fgl::engine::filesystem
}
*/
if ( !current )
if ( !m_current_dir )
{
log::critical( "Current has no value!" );
std::abort();
m_current_dir = std::make_unique< DirInfo >( std::filesystem::current_path() );
log::warn(
"Current directory was not set, Defaulting to current directory: {}", std::filesystem::current_path() );
}
auto size { ImGui::GetWindowSize() };
//TODO: Probably a cleaner way to do this.
size.x -= 12; // Remove scrollbar pixels
const float extra { std::fmod( size.x, static_cast< float >( desired_size + ( padding * 2 ) ) ) };
const float extra { std::fmod( size.x, static_cast< float >( DESIRED_SIZE + ( PADDING * 2 ) ) ) };
const auto cols {
static_cast< int >( ( size.x - extra ) / static_cast< float >( desired_size + ( padding * 2 ) ) )
static_cast< int >( ( size.x - extra ) / static_cast< float >( DESIRED_SIZE + ( PADDING * 2 ) ) )
};
if ( cols == 0 )
@@ -93,33 +68,33 @@ namespace fgl::engine::filesystem
return;
}
ImGui::PushStyleVar( ImGuiStyleVar_CellPadding, { padding, padding } );
ImGui::PushStyleVar( ImGuiStyleVar_CellPadding, { PADDING, PADDING } );
if ( current && ImGui::BeginTable( "Files", cols ) )
if ( m_current_dir && ImGui::BeginTable( "Files", cols ) )
{
for ( int i = 0; i < cols; ++i )
ImGui::TableSetupColumn( "", ImGuiTableColumnFlags_WidthFixed, desired_size );
ImGui::TableSetupColumn( "", ImGuiTableColumnFlags_WidthFixed, DESIRED_SIZE );
//List up if we can go up
if ( current->hasParent() )
if ( m_current_dir->hasParent() )
{
ImGui::TableNextColumn();
drawUp( current );
drawUp( m_current_dir );
}
assert( current );
assert( m_current_dir );
//List folders first
for ( std::size_t i = 0; i < current->folderCount(); ++i )
for ( std::size_t i = 0; i < m_current_dir->folderCount(); ++i )
{
ImGui::TableNextColumn();
drawFolder( current->dir( i ) );
drawFolder( m_current_dir->dir( i ) );
}
for ( std::size_t i = 0; i < current->fileCount(); ++i )
for ( std::size_t i = 0; i < m_current_dir->fileCount(); ++i )
{
ImGui::TableNextColumn();
drawFile( current->file( i ) );
drawFile( m_current_dir->file( i ) );
}
ImGui::EndTable();
@@ -148,22 +123,22 @@ namespace fgl::engine::filesystem
return format_ns::format( "{:0.2f} GB", static_cast< float >( size ) / 1000.0f / 1000.0f / 1000.0f );
}
void drawTexture( const FileInfo& info )
void FileBrowser::drawTexture( const FileInfo& info )
{
if ( auto itter = file_textures.find( info.path ); itter != file_textures.end() )
if ( auto itter = m_file_textures.find( info.path ); itter != m_file_textures.end() )
{
auto& [ path, texture ] = *itter;
texture->drawImGuiButton( { desired_size, desired_size } );
texture->drawImGuiButton( { DESIRED_SIZE, DESIRED_SIZE } );
}
else
{
file_texture->drawImGuiButton( { desired_size, desired_size } );
m_file_texture->drawImGuiButton( { DESIRED_SIZE, DESIRED_SIZE } );
auto tex { getTextureStore().load( info.path ) };
// Add the texture
file_textures.insert( std::make_pair( info.path, std::move( tex ) ) );
m_file_textures.insert( std::make_pair( info.path, std::move( tex ) ) );
}
if ( ImGui::BeginDragDropSource() )
@@ -176,15 +151,15 @@ namespace fgl::engine::filesystem
}
}
void drawBinary( [[maybe_unused]] const FileInfo& info )
void FileBrowser::drawBinary( [[maybe_unused]] const FileInfo& info )
{
// file_texture->drawImGui( { 128, 128 } );
file_texture->drawImGuiButton( { desired_size, desired_size } );
m_file_texture->drawImGuiButton( { DESIRED_SIZE, DESIRED_SIZE } );
//Unable to drag/drop because we have no idea what this is supposed to be for.
}
void drawModel( const FileInfo& info )
void FileBrowser::drawModel( const FileInfo& info )
{
//TODO: Pre-render preview image for models
drawBinary( info );
@@ -234,7 +209,7 @@ namespace fgl::engine::filesystem
{
ImGui::PushID( data.m_path.c_str() );
if ( folder_texture->drawImGuiButton( { desired_size, desired_size } ) )
if ( m_folder_texture->drawImGuiButton( { DESIRED_SIZE, DESIRED_SIZE } ) )
{
openFolder( data );
ImGui::PopID();
@@ -247,15 +222,22 @@ namespace fgl::engine::filesystem
ImGui::PopID();
}
FileBrowser::FileBrowser()
{
m_folder_texture = getTextureStore().load( "./assets/folder.png", vk::Format::eR8G8B8A8Unorm );
m_file_texture = getTextureStore().load( "./assets/file.png", vk::Format::eR8G8B8A8Unorm );
m_up_texture = getTextureStore().load( "./assets/up.png", vk::Format::eR8G8B8A8Unorm );
}
void FileBrowser::goUp()
{
current = current->up();
m_current_dir = m_current_dir->up();
}
void FileBrowser::openFolder( const DirInfo& dir )
{
file_textures.clear();
current = std::make_unique< DirInfo >( dir.m_path );
m_file_textures.clear();
m_current_dir = std::make_unique< DirInfo >( dir.m_path );
}
void FileBrowser::drawUp( const std::unique_ptr< DirInfo >& current_dir )
@@ -264,7 +246,7 @@ namespace fgl::engine::filesystem
ImGui::PushID( up->m_path.c_str() );
if ( up_texture->drawImGuiButton( { desired_size, desired_size } ) )
if ( m_up_texture->drawImGuiButton( { DESIRED_SIZE, DESIRED_SIZE } ) )
{
openFolder( *up );
}

View File

@@ -3,7 +3,11 @@
//
#pragma once
#include <mutex>
#include <unordered_map>
#include "../../../engine/filesystem/scanner/FileScanner.hpp"
#include "assets/texture/Texture.hpp"
namespace fgl::engine
{
@@ -16,14 +20,29 @@ namespace fgl::engine::filesystem
struct FileBrowser
{
static void goUp();
std::unordered_map< std::filesystem::path, std::shared_ptr< Texture > > m_file_textures {};
static void openFolder( const DirInfo& dir );
std::unique_ptr< DirInfo > m_current_dir { nullptr };
static void drawUp( const std::unique_ptr< DirInfo >& current_dir );
static void drawGui( FrameInfo& info );
static void drawFile( const FileInfo& data );
static void drawFolder( const DirInfo& data );
std::shared_ptr< Texture > m_folder_texture { nullptr };
std::shared_ptr< Texture > m_file_texture { nullptr };
std::shared_ptr< Texture > m_up_texture { nullptr };
FileBrowser();
void goUp();
void openFolder( const DirInfo& dir );
void drawUp( const std::unique_ptr< DirInfo >& current_dir );
void drawGui( FrameInfo& info );
void drawFile( const FileInfo& data );
void drawFolder( const DirInfo& data );
// drawers
void drawBinary( const FileInfo& info );
void drawModel( const FileInfo& info );
void drawTexture( const FileInfo& info );
};
void destroyFileGui();

View File

@@ -8,102 +8,21 @@
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wconversion"
#include <backends/imgui_impl_glfw.h>
#include <backends/imgui_impl_vulkan.h>
#include <imgui_internal.h> // Included for DockBuilder since it's not exposed yet
#pragma GCC diagnostic pop
#include "FileBrowser.hpp"
#include "engine/assets/model/Model.hpp"
#include "engine/debug/DEBUG_NAMES.hpp"
#include "engine/debug/drawers.hpp"
#include "engine/debug/profiling/counters.hpp"
#include "engine/debug/timing/FlameGraph.hpp"
#include "engine/descriptors/DescriptorPool.hpp"
#include "engine/rendering/Renderer.hpp"
#include "engine/tree/octtree/OctTreeNode.hpp"
#include "gui_window_names.hpp"
#include "rendering/RenderingFormats.hpp"
#include "safe_include.hpp"
namespace fgl::engine::gui
{
void initGui( const Window& window, const Renderer& renderer )
{
ZoneScoped;
IMGUI_CHECKVERSION();
ImGui::CreateContext();
[[maybe_unused]] ImGuiIO& io { ImGui::GetIO() };
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
// io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
io.ConfigWindowsResizeFromEdges = true;
ImGui::StyleColorsDark();
Device& device { Device::getInstance() };
vk::PipelineRenderingCreateInfo pipeline_info {};
const std::vector< vk::Format > color_formats { pickPresentFormat() };
pipeline_info.setColorAttachmentFormats( color_formats );
pipeline_info.setDepthAttachmentFormat( pickDepthFormat() );
ImGui_ImplGlfw_InitForVulkan( window.window(), true );
ImGui_ImplVulkan_InitInfo init_info {
.Instance = device.instance(),
.PhysicalDevice = *device.phyDevice().handle(),
.Device = *device,
.QueueFamily = device.phyDevice().queueInfo().getIndex( vk::QueueFlagBits::eGraphics ),
.Queue = *device.graphicsQueue(),
.DescriptorPool = *DescriptorPool::getInstance().getPool(),
.RenderPass = VK_NULL_HANDLE,
.MinImageCount = 2,
.ImageCount = 2,
.MSAASamples = VK_SAMPLE_COUNT_1_BIT,
.PipelineCache = VK_NULL_HANDLE,
.Subpass = 0,
.UseDynamicRendering = VK_TRUE,
.PipelineRenderingCreateInfo = pipeline_info,
.Allocator = VK_NULL_HANDLE,
.CheckVkResultFn = VK_NULL_HANDLE,
.MinAllocationSize = 1024 * 1024
};
ImGui_ImplVulkan_Init( &init_info );
}
void beginImGui()
{
ZoneScoped;
ImGui_ImplVulkan_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
}
void endImGui( vk::raii::CommandBuffer& command_buffer )
{
ZoneScoped;
ImGui::Render();
ImDrawData* data { ImGui::GetDrawData() };
ImGui_ImplVulkan_RenderDrawData( data, *command_buffer );
//ImGui::UpdatePlatformWindows();
//ImGui::RenderPlatformWindowsDefault();
}
void endDrawImGui( FrameInfo& info )
{
endImGui( info.command_buffer );
}
inline void prepareDock( ImGuiID& primary_id )
{
ImGui::DockBuilderRemoveNode( primary_id );
@@ -177,29 +96,6 @@ namespace fgl::engine::gui
// ImGui::PopStyleVar();
}
void startDrawImGui( [[maybe_unused]] FrameInfo& info )
{
beginImGui();
profiling::resetCounters();
}
void drawImGui( FrameInfo& info )
{
ZoneScoped;
auto timer = debug::timing::push( "Draw ImGui" );
ImGui::ShowDemoWindow();
drawDock();
drawCameraOutputs( info );
drawEntityGUI( info );
drawEntityInfo( info );
drawFilesystemGUI( info );
drawStats( info );
}
static GameObject* selected_object { nullptr };
void itterateGameObjectNode( FrameInfo& info, OctTreeNode& node )
@@ -294,23 +190,4 @@ namespace fgl::engine::gui
ImGui::End();
}
void drawFilesystemGUI( FrameInfo& info )
{
ZoneScoped;
ImGui::Begin( FILE_PICKER_NAME, nullptr, ImGuiWindowFlags_MenuBar );
filesystem::FileBrowser::drawGui( info );
ImGui::End();
}
void cleanupImGui()
{
ZoneScoped;
filesystem::destroyFileGui();
ImGui_ImplVulkan_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
} // namespace fgl::engine::gui

View File

@@ -16,17 +16,14 @@ namespace fgl::engine
namespace fgl::engine::gui
{
// Setup/Destruction
void initGui( const Window& window, const Renderer& renderer );
void cleanupImGui();
// Draws
void startDrawImGui( FrameInfo& info );
void drawDock();
void drawImGui( FrameInfo& );
void drawEntityGUI( FrameInfo& );
void drawEntityInfo( FrameInfo& );
void drawFilesystemGUI( FrameInfo& info );
void drawObject( GameObject& game_object );
void drawComponentsList( GameObject& game_object );
@@ -36,6 +33,4 @@ namespace fgl::engine::gui
void drawStats( const FrameInfo& info );
void endDrawImGui( FrameInfo& info );
} // namespace fgl::engine::gui

View File

@@ -3,15 +3,18 @@
//
#include <cstdlib>
#include "debug/profiling/counters.hpp"
#include "engine/EngineContext.hpp"
#include "engine/camera/CameraManager.hpp"
#include "engine/debug/timing/FlameGraph.hpp"
#include "engine/gameobjects/components/CameraComponent.hpp"
#include "gui/EditorGuiContext.hpp"
#include "gui/core.hpp"
int main()
{
using namespace fgl::engine;
using namespace fgl::editor;
log::set_level( spdlog::level::debug );
@@ -38,13 +41,18 @@ int main()
try
{
EngineContext engine_ctx {};
EditorGuiContext editor_ctx { engine_ctx.getWindow() };
// We start by hooking into the imgui rendering.
engine_ctx.hookInitImGui( gui::initGui );
engine_ctx.hookPreFrame( gui::startDrawImGui );
engine_ctx.hookEarlyFrame( gui::drawImGui );
engine_ctx.hookLateFrame( gui::endDrawImGui );
engine_ctx.hookDestruction( gui::cleanupImGui );
engine_ctx.hookPreFrame(
[ & ]( [[maybe_unused]] FrameInfo& info )
{
editor_ctx.beginDraw();
profiling::resetCounters();
} );
engine_ctx.hookEarlyFrame( [ & ]( [[maybe_unused]] FrameInfo& info ) { editor_ctx.draw( info ); } );
engine_ctx.hookLateFrame( [ & ]( FrameInfo& info ) { editor_ctx.endDraw( info ); } );
// Now we need to create the camera for the editor.
CameraManager& camera_manager { engine_ctx.cameraManager() };
@@ -78,6 +86,8 @@ int main()
// This will 'end' the root node, Which is created on 'reset'
debug::timing::internal::pop();
}
engine_ctx.waitIdle();
}
catch ( const vk::LayerNotPresentError& e )
{