Add in shader reloading and cleanup
This commit is contained in:
@@ -4,8 +4,9 @@ add_subdirectory(engine)
|
||||
add_subdirectory(objectloaders)
|
||||
add_subdirectory(editor)
|
||||
add_subdirectory(tests)
|
||||
add_subdirectory(shaders)
|
||||
add_subdirectory(assets)
|
||||
|
||||
add_dependencies(TitorEditor shaders)
|
||||
add_dependencies(TitorEditor assets)
|
||||
message("-- Creating SYMLINK ${CMAKE_BINARY_DIR}/shaders -> ${CMAKE_CURRENT_SOURCE_DIR}/shaders")
|
||||
file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/shaders ${CMAKE_BINARY_DIR}/bin/shaders SYMBOLIC)
|
||||
|
||||
message("-- Creating SYMLINK ${CMAKE_BINARY_DIR}/assets -> ${CMAKE_CURRENT_SOURCE_DIR}/assets")
|
||||
file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/assets ${CMAKE_BINARY_DIR}/bin/assets SYMBOLIC)
|
||||
@@ -1,39 +0,0 @@
|
||||
file(GLOB_RECURSE ASSETS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/**.obj
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/**.png
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/**.jpg
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/**.glb
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/**.bin
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/**.gltf
|
||||
)
|
||||
|
||||
foreach (ASSET IN LISTS ASSETS)
|
||||
get_filename_component(FILENAME ${ASSET} NAME)
|
||||
get_filename_component(FILE_DIRECTORY ${ASSET} DIRECTORY)
|
||||
file(RELATIVE_PATH REL_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${FILE_DIRECTORY})
|
||||
|
||||
if (NOT REL_PATH STREQUAL "")
|
||||
set(REL_PATH ${REL_PATH}/)
|
||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin/assets/${REL_PATH})
|
||||
endif ()
|
||||
|
||||
set(OUT_DIR ${CMAKE_BINARY_DIR}/bin/assets/${REL_PATH})
|
||||
set(OUT_PATH ${OUT_DIR}${FILENAME})
|
||||
|
||||
#add_custom_command(OUTPUT ${OUT_DIR}
|
||||
# COMMAND ${CMAKE_COMMAND} -E make_directory ${OUT_DIR} COMMENT "Creating directory ${OUT_DIR}")
|
||||
|
||||
if (EXISTS ${OUT_PATH})
|
||||
file(REMOVE ${OUT_PATH})
|
||||
endif ()
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/bin/assets/${FILENAME}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${ASSET} ${OUT_PATH} DEPENDS ${ASSET}
|
||||
COMMENT "Copying ${ASSET} to ${OUT_PATH}")
|
||||
|
||||
list(APPEND OUT_ASSETS ${CMAKE_BINARY_DIR}/bin/assets/${FILENAME})
|
||||
list(APPEND ADDITIONAL_CLEAN_FILES ${OUT_PATH})
|
||||
endforeach ()
|
||||
|
||||
add_custom_target(assets ALL DEPENDS ${OUT_ASSETS})
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#include "FileBrowser.hpp"
|
||||
#include "engine/debug/DEBUG_NAMES.hpp"
|
||||
#include "engine/descriptors/DescriptorPool.hpp"
|
||||
#include "engine/assets/model/Model.hpp"
|
||||
#include "engine/debug/DEBUG_NAMES.hpp"
|
||||
#include "engine/debug/profiling/counters.hpp"
|
||||
#include "engine/descriptors/DescriptorPool.hpp"
|
||||
#include "engine/rendering/Renderer.hpp"
|
||||
#include "engine/tree/octtree/OctTreeNode.hpp"
|
||||
#include "gui_window_names.hpp"
|
||||
@@ -88,6 +89,11 @@ namespace fgl::engine::gui
|
||||
//ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
void endDrawImGui( FrameInfo& info )
|
||||
{
|
||||
endImGui( info.command_buffer );
|
||||
}
|
||||
|
||||
inline void prepareDock( ImGuiID& primary_id )
|
||||
{
|
||||
ImGui::DockBuilderRemoveNode( primary_id );
|
||||
@@ -161,11 +167,15 @@ namespace fgl::engine::gui
|
||||
// ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
void drawMainGUI( FrameInfo& info )
|
||||
void startDrawImGui( [[maybe_unused]] FrameInfo& info )
|
||||
{
|
||||
beginImGui();
|
||||
profiling::resetCounters();
|
||||
}
|
||||
|
||||
void drawImGui( FrameInfo& info )
|
||||
{
|
||||
ZoneScoped;
|
||||
beginImGui();
|
||||
|
||||
// ImGui::ShowDemoWindow();
|
||||
|
||||
drawDock();
|
||||
@@ -176,8 +186,6 @@ namespace fgl::engine::gui
|
||||
drawFilesystemGUI( info );
|
||||
|
||||
drawStats( info );
|
||||
|
||||
endImGui( info.command_buffer );
|
||||
}
|
||||
|
||||
static GameObject* selected_object { nullptr };
|
||||
|
||||
@@ -15,10 +15,14 @@ namespace fgl::engine
|
||||
|
||||
namespace fgl::engine::gui
|
||||
{
|
||||
// Setup/Destruction
|
||||
void initGui( const Window& window, const Renderer& renderer );
|
||||
void cleanupImGui();
|
||||
|
||||
void drawMainGUI( FrameInfo& );
|
||||
// Draws
|
||||
void startDrawImGui( FrameInfo& info );
|
||||
|
||||
void drawImGui( FrameInfo& );
|
||||
void drawEntityGUI( FrameInfo& );
|
||||
|
||||
void drawEntityInfo( FrameInfo& );
|
||||
@@ -32,4 +36,6 @@ namespace fgl::engine::gui
|
||||
|
||||
void drawStats( const FrameInfo& info );
|
||||
|
||||
void endDrawImGui( FrameInfo& info );
|
||||
|
||||
} // namespace fgl::engine::gui
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "core.hpp"
|
||||
#include "engine/debug/profiling/counters.hpp"
|
||||
#include "engine/flags.hpp"
|
||||
#include "engine/math/literals/size.hpp"
|
||||
#include "engine/memory/buffers/Buffer.hpp"
|
||||
#include "engine/tree/octtree/OctTreeNode.hpp"
|
||||
@@ -102,9 +103,7 @@ namespace fgl::engine::gui
|
||||
const auto& counters { profiling::getCounters() };
|
||||
ImGui::Text( "Models drawn: %zu", counters.models_draw );
|
||||
ImGui::Text( "Verts drawn: %zu", counters.verts_drawn );
|
||||
|
||||
//TODO: This should likely be moved to the just before we start rendering again.
|
||||
profiling::resetCounters();
|
||||
ImGui::Text( "Draw instances: %zu", counters.instance_count );
|
||||
|
||||
if ( ImGui::CollapsingHeader( "Memory" ) )
|
||||
{
|
||||
@@ -113,6 +112,11 @@ namespace fgl::engine::gui
|
||||
|
||||
imGuiOctTreeSettings( info );
|
||||
|
||||
if ( ImGui::Button( "Reload shaders" ) )
|
||||
{
|
||||
flags::triggerShaderReload();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,10 @@ int main()
|
||||
|
||||
// We start by hooking into the imgui rendering.
|
||||
engine_ctx.hookInitImGui( gui::initGui );
|
||||
engine_ctx.hookCleanupImGui( gui::cleanupImGui );
|
||||
engine_ctx.TEMPhookGuiRender( gui::drawMainGUI );
|
||||
engine_ctx.hookPreFrame( gui::startDrawImGui );
|
||||
engine_ctx.hookEarlyFrame( gui::drawImGui );
|
||||
engine_ctx.hookLateFrame( gui::endDrawImGui );
|
||||
engine_ctx.hookDestruction( gui::cleanupImGui );
|
||||
|
||||
// Now we need to create the camera for the editor.
|
||||
CameraManager& camera_manager { engine_ctx.cameraManager() };
|
||||
@@ -47,9 +49,9 @@ int main()
|
||||
|
||||
// Render step
|
||||
engine_ctx.renderFrame();
|
||||
}
|
||||
|
||||
engine_ctx.run();
|
||||
engine_ctx.finishFrame();
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "camera/CameraRenderer.hpp"
|
||||
#include "engine/assets/model/builders/SceneBuilder.hpp"
|
||||
#include "engine/assets/transfer/TransferManager.hpp"
|
||||
#include "engine/flags.hpp"
|
||||
#include "engine/math/Average.hpp"
|
||||
#include "engine/math/literals/size.hpp"
|
||||
#include "engine/rendering/pipelines/v2/Pipeline.hpp"
|
||||
@@ -144,6 +145,7 @@ namespace fgl::engine
|
||||
void EngineContext::renderFrame()
|
||||
{
|
||||
ZoneScoped;
|
||||
|
||||
if ( auto& command_buffer = m_renderer.beginFrame(); *command_buffer )
|
||||
{
|
||||
const FrameIndex frame_index { m_renderer.getFrameIndex() };
|
||||
@@ -165,26 +167,26 @@ namespace fgl::engine
|
||||
// m_renderer.getSwapChain().getInputDescriptor( present_idx ),
|
||||
this->m_renderer.getSwapChain() };
|
||||
|
||||
{
|
||||
ZoneScopedN( "Pre frame hooks" );
|
||||
for ( const auto& hook : pre_frame_hooks ) hook( frame_info );
|
||||
}
|
||||
|
||||
TracyVkCollect( frame_info.tracy_ctx, *command_buffer );
|
||||
|
||||
//TODO: Setup semaphores to make this pass not always required.
|
||||
memory::TransferManager::getInstance().recordOwnershipTransferDst( command_buffer );
|
||||
|
||||
for ( const auto& hook : early_render_hooks ) hook( frame_info );
|
||||
//TODO: Add some way of 'activating' cameras. We don't need to render cameras that aren't active.
|
||||
renderCameras( frame_info );
|
||||
|
||||
// m_renderer.clearInputImage( command_buffer );
|
||||
|
||||
// camera_manager.getPrimary()
|
||||
// .copyOutput( command_buffer, frame_index, m_renderer.getSwapChain().getInputImage( present_idx ) );
|
||||
for ( const auto& hook : render_hooks ) hook( frame_info );
|
||||
|
||||
m_renderer.beginSwapchainRendererPass( command_buffer );
|
||||
|
||||
m_gui_system.pass( frame_info );
|
||||
|
||||
// TODO: Implement some way we can record extra things into the command buffer during this stage.
|
||||
// We'll probably just use multiple command buffers and allow the caller to pass some in with flags on where to put them
|
||||
renderGui( frame_info );
|
||||
for ( const auto& hook : late_render_hooks ) hook( frame_info );
|
||||
|
||||
m_renderer.endSwapchainRendererPass( command_buffer );
|
||||
|
||||
@@ -192,6 +194,13 @@ namespace fgl::engine
|
||||
|
||||
memory::TransferManager::getInstance().dump();
|
||||
|
||||
{
|
||||
ZoneScopedN( "Post frame hooks" );
|
||||
for ( const auto& hook : post_frame_hooks ) hook( frame_info );
|
||||
}
|
||||
|
||||
flags::resetFlags();
|
||||
|
||||
FrameMark;
|
||||
}
|
||||
|
||||
@@ -199,6 +208,9 @@ namespace fgl::engine
|
||||
descriptors::deleteQueuedDescriptors();
|
||||
}
|
||||
|
||||
void EngineContext::finishFrame()
|
||||
{}
|
||||
|
||||
Window& EngineContext::getWindow()
|
||||
{
|
||||
return m_window;
|
||||
@@ -214,68 +226,13 @@ namespace fgl::engine
|
||||
return m_camera_manager;
|
||||
}
|
||||
|
||||
void EngineContext::run()
|
||||
{
|
||||
TracyCZoneN( TRACY_PrepareEngine, "Inital Run", true );
|
||||
std::cout << "Starting main loop run" << std::endl;
|
||||
|
||||
auto viewer { GameObject::createGameObject() };
|
||||
|
||||
viewer.getTransform().translation = WorldCoordinate( constants::WORLD_CENTER + glm::vec3( 0.0f, 0.0f, 2.5f ) );
|
||||
|
||||
KeyboardMovementController camera_controller {};
|
||||
|
||||
auto current_time { fgl::clock::now() };
|
||||
|
||||
auto previous_frame_start { fgl::clock::now() };
|
||||
|
||||
camera_controller.moveInPlaneXZ( m_window.window(), 0.0, viewer );
|
||||
|
||||
TracyCZoneEnd( TRACY_PrepareEngine );
|
||||
|
||||
while ( good() )
|
||||
{
|
||||
memory::TransferManager::getInstance().submitNow();
|
||||
|
||||
{
|
||||
ZoneScopedN( "Poll" );
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
const auto new_time { fgl::clock::now() };
|
||||
|
||||
auto delta_time { std::chrono::duration< float >( new_time - current_time ).count() };
|
||||
|
||||
current_time = new_time;
|
||||
delta_time = glm::min( delta_time, MAX_DELTA_TIME );
|
||||
|
||||
camera_controller.moveInPlaneXZ( m_window.window(), delta_time, viewer );
|
||||
|
||||
renderFrame();
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
// std::this_thread::sleep_for( 13ms );
|
||||
}
|
||||
|
||||
Device::getInstance().device().waitIdle();
|
||||
}
|
||||
|
||||
void EngineContext::loadGameObjects()
|
||||
{
|
||||
ZoneScoped;
|
||||
std::cout << "Loading game objects" << std::endl;
|
||||
auto command_buffer { Device::getInstance().beginSingleTimeCommands() };
|
||||
|
||||
Device::getInstance().endSingleTimeCommands( command_buffer );
|
||||
log::info( "Finished loading game object" );
|
||||
}
|
||||
|
||||
EngineContext::~EngineContext()
|
||||
{
|
||||
// Destroy all objects
|
||||
m_game_objects_root.clear();
|
||||
destroyMaterialDataVec();
|
||||
cleanupImGui();
|
||||
|
||||
for ( const auto& hook : destruction_hooks ) hook();
|
||||
}
|
||||
|
||||
bool EngineContext::good()
|
||||
|
||||
@@ -19,6 +19,13 @@ namespace fgl::engine
|
||||
|
||||
using namespace fgl::literals::size_literals;
|
||||
|
||||
inline void dummyFrameInfoFunc( [[maybe_unused]] FrameInfo& frame_info )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using FrameHookFunc = std::function< void( FrameInfo& ) >;
|
||||
|
||||
class EngineContext
|
||||
{
|
||||
static constexpr int DEFAULT_WIDTH { 1920 };
|
||||
@@ -51,9 +58,19 @@ namespace fgl::engine
|
||||
// SubPass 0
|
||||
GuiSystem m_gui_system { m_renderer.getSwapChainRenderPass() };
|
||||
|
||||
// Temp function
|
||||
std::function< void( FrameInfo& ) > renderGui { []( [[maybe_unused]] FrameInfo& ) noexcept {} };
|
||||
std::function< void() > cleanupImGui { []() noexcept {} };
|
||||
// Functions BEFORE a frame is started
|
||||
std::vector< FrameHookFunc > pre_frame_hooks {};
|
||||
|
||||
//! TODO: Make this so we can tell at what stage we should be doing something
|
||||
std::vector< FrameHookFunc > early_render_hooks {};
|
||||
std::vector< FrameHookFunc > render_hooks {};
|
||||
std::vector< FrameHookFunc > late_render_hooks {};
|
||||
|
||||
// Functions to call upon the frame ending (This happens AFTER the GPU call is dispatched)
|
||||
std::vector< FrameHookFunc > post_frame_hooks {};
|
||||
|
||||
//! Called before the context is destroyed
|
||||
std::vector< std::function< void() > > destruction_hooks;
|
||||
|
||||
// Memory pool for shader uniforms.
|
||||
memory::Buffer m_ubo_buffer_pool;
|
||||
@@ -69,8 +86,6 @@ namespace fgl::engine
|
||||
std::chrono::time_point< fgl::clock > last_tick { fgl::clock::now() };
|
||||
double m_delta_time;
|
||||
|
||||
void loadGameObjects();
|
||||
|
||||
public:
|
||||
|
||||
FGL_FORCE_INLINE_FLATTEN void hookInitImGui( const std::function< void( Window&, Renderer& ) >& func )
|
||||
@@ -78,9 +93,17 @@ namespace fgl::engine
|
||||
func( m_window, m_renderer );
|
||||
}
|
||||
|
||||
FGL_FORCE_INLINE_FLATTEN void hookCleanupImGui( const std::function< void() >& func ) { cleanupImGui = func; }
|
||||
void hookPreFrame( const FrameHookFunc& func ) { pre_frame_hooks.emplace_back( func ); }
|
||||
|
||||
void TEMPhookGuiRender( const std::function< void( FrameInfo& ) >& func ) { renderGui = func; }
|
||||
void hookEarlyFrame( const FrameHookFunc& func ) { early_render_hooks.emplace_back( func ); }
|
||||
|
||||
void hookFrame( const FrameHookFunc& func ) { render_hooks.emplace_back( func ); }
|
||||
|
||||
void hookLateFrame( const FrameHookFunc& func ) { late_render_hooks.emplace_back( func ); }
|
||||
|
||||
void hookPostFrame( const FrameHookFunc& func ) { post_frame_hooks.emplace_back( func ); }
|
||||
|
||||
void hookDestruction( const std::function< void() >& func ) { destruction_hooks.emplace_back( func ); }
|
||||
|
||||
public:
|
||||
|
||||
@@ -104,12 +127,13 @@ namespace fgl::engine
|
||||
|
||||
void renderFrame();
|
||||
|
||||
//! Runs any post-frame processes
|
||||
void finishFrame();
|
||||
|
||||
Window& getWindow();
|
||||
float getWindowAspectRatio();
|
||||
|
||||
CameraManager& cameraManager();
|
||||
|
||||
void run();
|
||||
};
|
||||
|
||||
} // namespace fgl::engine
|
||||
|
||||
@@ -14,8 +14,18 @@
|
||||
#define FGL_DELETE_ALL_Ro5( ClassName ) \
|
||||
FGL_DELETE_DEFAULT_CTOR( ClassName ) FGL_DELETE_COPY( ClassName ) FGL_DELETE_MOVE( ClassName )
|
||||
|
||||
#define FGL_PACKED __attribute__(( packed ))
|
||||
#define FGL_PACKED_ALIGNED( al ) __attribute__(( packed, aligned( al ) ))
|
||||
#define FGL_DEFAULT_DEFAULT_CTOR( ClassName ) ClassName() = default;
|
||||
#define FGL_DEFAULT_COPY_ASSIGN( ClassName ) ClassName& operator=( const ClassName& ) = default;
|
||||
#define FGL_DEFAULT_COPY_CTOR( ClassName ) ClassName( const ClassName& ) = default;
|
||||
#define FGL_DEFAULT_MOVE_ASSIGN( ClassName ) ClassName& operator=( ClassName&& ) = default;
|
||||
#define FGL_DEFAULT_MOVE_CTOR( ClassName ) ClassName( ClassName&& ) = default;
|
||||
#define FGL_DEFAULT_COPY( ClassName ) FGL_DEFAULT_COPY_CTOR( ClassName ) FGL_DEFAULT_COPY_ASSIGN( ClassName )
|
||||
#define FGL_DEFAULT_MOVE( ClassName ) FGL_DEFAULT_MOVE_CTOR( ClassName ) FGL_DEFAULT_MOVE_ASSIGN( ClassName )
|
||||
#define FGL_DEFAULT_ALL_Ro5( ClassName ) \
|
||||
FGL_DEFAULT_DEFAULT_CTOR( ClassName ) FGL_DEFAULT_COPY( ClassName ) FGL_DEFAULT_MOVE( ClassName )
|
||||
|
||||
#define FGL_PACKED __attribute__( ( packed ) )
|
||||
#define FGL_PACKED_ALIGNED( al ) __attribute__( ( packed, aligned( al ) ) )
|
||||
#define FGL_FLATTEN [[gnu::flatten]]
|
||||
#define FGL_ARTIFICIAL [[gnu::artificial]]
|
||||
#define FGL_HOT [[gnu::hot]]
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "camera/Camera.hpp"
|
||||
#include "camera/CameraSwapchain.hpp"
|
||||
#include "rendering/pipelines/Pipeline.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
@@ -21,7 +20,7 @@ namespace fgl::engine
|
||||
return camera->getDescriptor( frame_idx );
|
||||
}
|
||||
|
||||
void FrameInfo::bindCamera( [[maybe_unused]] internal::Pipeline& pipeline )
|
||||
void FrameInfo::bindCamera( [[maybe_unused]] Pipeline& pipeline )
|
||||
{
|
||||
//TODO: This
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
//clang-format: off
|
||||
#include <tracy/TracyVulkan.hpp>
|
||||
//clang-format: on
|
||||
@@ -13,13 +11,13 @@
|
||||
#include "descriptors/Descriptor.hpp"
|
||||
#include "descriptors/DescriptorSetLayout.hpp"
|
||||
#include "primitives/Frustum.hpp"
|
||||
#include "rendering/pipelines/Pipeline.hpp"
|
||||
#include "rendering/types.hpp"
|
||||
|
||||
#define MAX_LIGHTS 10
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
class Pipeline;
|
||||
class GameObject;
|
||||
|
||||
namespace descriptors
|
||||
@@ -102,7 +100,7 @@ namespace fgl::engine
|
||||
std::vector< std::vector< GameObject >* > in_view_leafs {};
|
||||
|
||||
//! Binds the camera descriptor to the command buffer
|
||||
void bindCamera( internal::Pipeline& pipeline );
|
||||
void bindCamera( Pipeline& pipeline );
|
||||
};
|
||||
|
||||
} // namespace fgl::engine
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
//
|
||||
// Created by kj16609 on 12/7/23.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include <vulkan/vulkan_raii.hpp>
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
template < typename T, vk::ShaderStageFlags stages, std::uint16_t offset = 0 >
|
||||
struct PushConstant
|
||||
{
|
||||
using Type = T;
|
||||
|
||||
constexpr static vk::PushConstantRange m_range { stages, offset, sizeof( T ) };
|
||||
|
||||
PushConstant()
|
||||
{
|
||||
static_assert( sizeof( T ) <= 128, "Push constant range size must be less or equal to 128 bytes" );
|
||||
}
|
||||
|
||||
static void push( vk::raii::CommandBuffer& command_buffer, vk::PipelineLayout m_pipeline_layout, T& data )
|
||||
{
|
||||
command_buffer.pushConstants( m_pipeline_layout, stages, offset, sizeof( T ), &data );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace fgl::engine
|
||||
@@ -26,10 +26,16 @@ namespace fgl::engine::profiling
|
||||
counters.verts_drawn += n;
|
||||
}
|
||||
|
||||
void addInstances( std::size_t n )
|
||||
{
|
||||
counters.instance_count += n;
|
||||
}
|
||||
|
||||
void resetCounters()
|
||||
{
|
||||
counters.verts_drawn = 0;
|
||||
counters.models_draw = 0;
|
||||
counters.instance_count = 0;
|
||||
}
|
||||
|
||||
// In order for resetCounters to work we need to ensure we can just zero the struct.
|
||||
|
||||
@@ -12,12 +12,14 @@ namespace fgl::engine::profiling
|
||||
{
|
||||
std::size_t verts_drawn;
|
||||
std::size_t models_draw;
|
||||
std::size_t instance_count;
|
||||
};
|
||||
|
||||
Counters& getCounters();
|
||||
|
||||
void addModelDrawn( std::size_t n = 1 );
|
||||
void addVertexDrawn( std::size_t n );
|
||||
void addInstances( std::size_t n = 1 );
|
||||
|
||||
void resetCounters();
|
||||
|
||||
|
||||
@@ -31,7 +31,9 @@ namespace fgl::engine::filesystem
|
||||
nested_dirs_to_scan.push( *itter );
|
||||
}
|
||||
else
|
||||
throw std::runtime_error( "Unknown/Unspported file type" );
|
||||
{
|
||||
log::debug( "Weird file at {}", itter->path().string() );
|
||||
}
|
||||
}
|
||||
|
||||
nested_dirs.reserve( nested_dirs_to_scan.size() );
|
||||
|
||||
29
src/engine/flags.cpp
Normal file
29
src/engine/flags.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// Created by kj16609 on 10/18/24.
|
||||
//
|
||||
|
||||
#include "flags.hpp"
|
||||
|
||||
#include "engine/debug/logging/logging.hpp"
|
||||
|
||||
namespace fgl::engine::flags
|
||||
{
|
||||
static bool should_reload_shaders { false };
|
||||
|
||||
void triggerShaderReload()
|
||||
{
|
||||
log::debug( "Triggering shader reload" );
|
||||
should_reload_shaders = true;
|
||||
}
|
||||
|
||||
bool shouldReloadShaders()
|
||||
{
|
||||
return should_reload_shaders;
|
||||
}
|
||||
|
||||
void resetFlags()
|
||||
{
|
||||
should_reload_shaders = false;
|
||||
}
|
||||
|
||||
} // namespace fgl::engine::flags
|
||||
18
src/engine/flags.hpp
Normal file
18
src/engine/flags.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// Created by kj16609 on 10/18/24.
|
||||
//
|
||||
|
||||
// This file is supposed to contain various global flags used by the program
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace fgl::engine::flags
|
||||
{
|
||||
void triggerShaderReload();
|
||||
|
||||
bool shouldReloadShaders();
|
||||
|
||||
//! Resets any flags that can be reset after the frame is done
|
||||
void resetFlags();
|
||||
|
||||
} // namespace fgl::engine::flags
|
||||
@@ -108,7 +108,7 @@ namespace fgl::engine
|
||||
|
||||
for ( ComponentEngineInterface* comp : components )
|
||||
{
|
||||
if ( comp->id() == T::ID ) temp.emplace_back( dynamic_cast< T* >( comp ) );
|
||||
if ( comp->id() == T::ID ) temp.emplace_back( static_cast< T* >( comp ) );
|
||||
}
|
||||
|
||||
return temp;
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
//
|
||||
// Created by kj16609 on 11/27/23.
|
||||
//
|
||||
|
||||
#include "Pipeline.hpp"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "Shader.hpp"
|
||||
#include "engine/rendering/devices/Device.hpp"
|
||||
|
||||
namespace fgl::engine::internal
|
||||
{
|
||||
|
||||
vk::raii::Pipeline Pipeline::createGraphicsPipeline(
|
||||
std::vector< std::unique_ptr< Shader > >& shaders,
|
||||
const PipelineConfigInfo& info,
|
||||
const vk::raii::PipelineLayout& layout )
|
||||
{
|
||||
assert( info.render_pass != VK_NULL_HANDLE && "Cannot create graphics pipeline: no render pass provided" );
|
||||
|
||||
std::vector< vk::PipelineShaderStageCreateInfo > stages {};
|
||||
|
||||
for ( const auto& shader : shaders )
|
||||
{
|
||||
stages.emplace_back( shader->stage_info );
|
||||
}
|
||||
assert( stages.size() >= 2 );
|
||||
|
||||
auto& binding_descriptions { info.binding_descriptions };
|
||||
auto& attribute_descriptions { info.attribute_descriptions };
|
||||
|
||||
vk::PipelineVertexInputStateCreateInfo vertex_input_info {};
|
||||
vertex_input_info.pNext = VK_NULL_HANDLE;
|
||||
vertex_input_info.flags = {};
|
||||
vertex_input_info.vertexBindingDescriptionCount = static_cast< std::uint32_t >( binding_descriptions.size() );
|
||||
vertex_input_info.pVertexBindingDescriptions = binding_descriptions.data();
|
||||
vertex_input_info.vertexAttributeDescriptionCount =
|
||||
static_cast< std::uint32_t >( attribute_descriptions.size() );
|
||||
vertex_input_info.pVertexAttributeDescriptions = attribute_descriptions.data();
|
||||
|
||||
vk::GraphicsPipelineCreateInfo pipeline_info {};
|
||||
pipeline_info.pNext = VK_NULL_HANDLE;
|
||||
pipeline_info.flags = {};
|
||||
pipeline_info.stageCount = static_cast< std::uint32_t >( stages.size() );
|
||||
pipeline_info.pStages = stages.data();
|
||||
pipeline_info.pVertexInputState = &vertex_input_info;
|
||||
pipeline_info.pInputAssemblyState = &info.assembly_info;
|
||||
pipeline_info.pTessellationState = &info.tesselation_state_info;
|
||||
pipeline_info.pViewportState = &info.viewport_info;
|
||||
pipeline_info.pRasterizationState = &info.rasterization_info;
|
||||
pipeline_info.pMultisampleState = &info.multisample_info;
|
||||
pipeline_info.pDepthStencilState = &info.depth_stencil_info;
|
||||
pipeline_info.pColorBlendState = &info.color_blend_info;
|
||||
pipeline_info.pDynamicState = &info.dynamic_state_info;
|
||||
pipeline_info.layout = *layout;
|
||||
pipeline_info.renderPass = info.render_pass;
|
||||
pipeline_info.subpass = info.subpass;
|
||||
pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
|
||||
pipeline_info.basePipelineIndex = -1;
|
||||
|
||||
return m_device->createGraphicsPipeline( VK_NULL_HANDLE, pipeline_info );
|
||||
}
|
||||
|
||||
Pipeline::Pipeline(
|
||||
Device& device,
|
||||
vk::raii::PipelineLayout layout,
|
||||
PipelineConfigInfo info,
|
||||
std::vector< std::unique_ptr< Shader > > shaders ) :
|
||||
m_device( device ),
|
||||
m_layout( std::move( layout ) ),
|
||||
m_vk_pipeline( createGraphicsPipeline( shaders, info, m_layout ) )
|
||||
{}
|
||||
|
||||
void Pipeline::bind( vk::raii::CommandBuffer& command_buffer )
|
||||
{
|
||||
command_buffer.bindPipeline( vk::PipelineBindPoint::eGraphics, m_vk_pipeline );
|
||||
}
|
||||
|
||||
void Pipeline::setDebugName( const std::string str )
|
||||
{
|
||||
vk::DebugUtilsObjectNameInfoEXT info {};
|
||||
info.objectType = vk::ObjectType::ePipeline;
|
||||
info.pObjectName = str.c_str();
|
||||
info.objectHandle = reinterpret_cast< std::uint64_t >( static_cast< VkPipeline >( *this->m_vk_pipeline ) );
|
||||
Device::getInstance().setDebugUtilsObjectName( info );
|
||||
}
|
||||
|
||||
} // namespace fgl::engine::internal
|
||||
@@ -1,51 +0,0 @@
|
||||
//
|
||||
// Created by kj16609 on 11/27/23.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
|
||||
#include "PipelineConfigInfo.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
class Device;
|
||||
struct Shader;
|
||||
}
|
||||
|
||||
namespace fgl::engine::internal
|
||||
{
|
||||
|
||||
class Pipeline
|
||||
{
|
||||
protected:
|
||||
|
||||
Device& m_device;
|
||||
vk::raii::PipelineLayout m_layout;
|
||||
vk::raii::Pipeline m_vk_pipeline;
|
||||
vk::ShaderModule m_vert_shader { VK_NULL_HANDLE };
|
||||
vk::ShaderModule m_frag_shader { VK_NULL_HANDLE };
|
||||
|
||||
vk::raii::Pipeline createGraphicsPipeline(
|
||||
std::vector< std::unique_ptr< Shader > >& shaders,
|
||||
const PipelineConfigInfo& info,
|
||||
const vk::raii::PipelineLayout& layout );
|
||||
|
||||
public:
|
||||
|
||||
Pipeline(
|
||||
Device& device,
|
||||
vk::raii::PipelineLayout layout,
|
||||
PipelineConfigInfo info,
|
||||
std::vector< std::unique_ptr< Shader > > shaders );
|
||||
|
||||
Pipeline( const Pipeline& other ) = delete;
|
||||
Pipeline& operator=( const Pipeline& ) = delete;
|
||||
|
||||
void bind( vk::raii::CommandBuffer& command_buffer );
|
||||
|
||||
void setDebugName( const std::string str );
|
||||
};
|
||||
} // namespace fgl::engine::internal
|
||||
@@ -1,174 +0,0 @@
|
||||
//
|
||||
// Created by kj16609 on 12/14/23.
|
||||
//
|
||||
|
||||
#include "PipelineConfigInfo.hpp"
|
||||
|
||||
#include "engine/assets/model/Model.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
void PipelineConfigInfo::setTriangleListTopo( PipelineConfigInfo& info )
|
||||
{
|
||||
info.assembly_info.topology = vk::PrimitiveTopology::eTriangleList;
|
||||
}
|
||||
|
||||
void PipelineConfigInfo::setTriangleStripTopo( PipelineConfigInfo& info )
|
||||
{
|
||||
info.assembly_info.topology = vk::PrimitiveTopology::eTriangleStrip;
|
||||
}
|
||||
|
||||
void PipelineConfigInfo::setLineTopo( PipelineConfigInfo& info )
|
||||
{
|
||||
info.assembly_info.topology = vk::PrimitiveTopology::eLineList;
|
||||
}
|
||||
|
||||
void PipelineConfigInfo::setPointPatch( PipelineConfigInfo& info )
|
||||
{
|
||||
info.assembly_info.topology = vk::PrimitiveTopology::ePatchList;
|
||||
}
|
||||
|
||||
void PipelineConfigInfo::defaultConfig( PipelineConfigInfo& info )
|
||||
{
|
||||
info.viewport_info.viewportCount = 1;
|
||||
info.viewport_info.pViewports = nullptr;
|
||||
info.viewport_info.scissorCount = 1;
|
||||
info.viewport_info.pScissors = nullptr;
|
||||
|
||||
info.assembly_info.topology = vk::PrimitiveTopology::eTriangleList;
|
||||
info.assembly_info.primitiveRestartEnable = VK_FALSE;
|
||||
|
||||
info.rasterization_info.depthClampEnable = VK_FALSE;
|
||||
info.rasterization_info.rasterizerDiscardEnable = VK_FALSE;
|
||||
info.rasterization_info.polygonMode = vk::PolygonMode::eFill;
|
||||
info.rasterization_info.cullMode = vk::CullModeFlagBits::eBack;
|
||||
info.rasterization_info.frontFace = vk::FrontFace::eClockwise;
|
||||
info.rasterization_info.depthBiasEnable = VK_FALSE;
|
||||
info.rasterization_info.depthBiasConstantFactor = 0.0f;
|
||||
info.rasterization_info.depthBiasClamp = 0.0f;
|
||||
info.rasterization_info.depthBiasSlopeFactor = 0.0f;
|
||||
info.rasterization_info.lineWidth = 1.0f;
|
||||
|
||||
info.multisample_info.rasterizationSamples = vk::SampleCountFlagBits::e1;
|
||||
info.multisample_info.sampleShadingEnable = VK_FALSE;
|
||||
info.multisample_info.minSampleShading = 1.0f;
|
||||
info.multisample_info.pSampleMask = nullptr;
|
||||
info.multisample_info.alphaToCoverageEnable = VK_FALSE;
|
||||
info.multisample_info.alphaToOneEnable = VK_FALSE;
|
||||
|
||||
info.color_blend_info.logicOpEnable = VK_FALSE;
|
||||
info.color_blend_info.logicOp = vk::LogicOp::eCopy;
|
||||
info.color_blend_info.attachmentCount = 0;
|
||||
info.color_blend_info.pAttachments = nullptr;
|
||||
info.color_blend_info.blendConstants[ 0 ] = 0.0f;
|
||||
info.color_blend_info.blendConstants[ 1 ] = 0.0f;
|
||||
info.color_blend_info.blendConstants[ 2 ] = 0.0f;
|
||||
info.color_blend_info.blendConstants[ 3 ] = 0.0f;
|
||||
|
||||
info.depth_stencil_info.depthTestEnable = VK_TRUE;
|
||||
info.depth_stencil_info.depthWriteEnable = VK_TRUE;
|
||||
info.depth_stencil_info.depthCompareOp = vk::CompareOp::eLess;
|
||||
info.depth_stencil_info.depthBoundsTestEnable = VK_FALSE;
|
||||
info.depth_stencil_info.stencilTestEnable = VK_FALSE;
|
||||
//info.depth_stencil_info.front = {};
|
||||
//info.depth_stencil_info.back = {};
|
||||
info.depth_stencil_info.minDepthBounds = 0.0f;
|
||||
info.depth_stencil_info.maxDepthBounds = 1.0f;
|
||||
|
||||
info.dynamic_state_enables = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
|
||||
info.dynamic_state_info.pDynamicStates = info.dynamic_state_enables.data();
|
||||
info.dynamic_state_info.dynamicStateCount = static_cast< std::uint32_t >( info.dynamic_state_enables.size() );
|
||||
//info.dynamic_state_info.flags = 0;
|
||||
|
||||
info.binding_descriptions = ModelVertex::getBindingDescriptions();
|
||||
info.attribute_descriptions = ModelVertex::getAttributeDescriptions();
|
||||
}
|
||||
|
||||
void PipelineConfigInfo::setVertexInputType( PipelineConfigInfo& info, const VertexInputType type )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case None:
|
||||
disableVertexInput( info );
|
||||
break;
|
||||
case Simple:
|
||||
{
|
||||
info.binding_descriptions = SimpleVertex::getBindingDescriptions();
|
||||
info.attribute_descriptions = SimpleVertex::getAttributeDescriptions();
|
||||
}
|
||||
break;
|
||||
case Textured:
|
||||
{
|
||||
info.binding_descriptions = ModelVertex::getBindingDescriptions();
|
||||
info.attribute_descriptions = ModelVertex::getAttributeDescriptions();
|
||||
}
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
void PipelineConfigInfo::disableVertexInput( PipelineConfigInfo& info )
|
||||
{
|
||||
info.binding_descriptions = {};
|
||||
info.attribute_descriptions = {};
|
||||
}
|
||||
|
||||
void PipelineConfigInfo::enableAlphaBlending( PipelineConfigInfo& info )
|
||||
{
|
||||
for ( std::size_t i = 0; i < info.color_blend_attachment.size(); ++i )
|
||||
{
|
||||
info.color_blend_attachment[ i ].blendEnable = VK_TRUE;
|
||||
info.color_blend_attachment[ i ].srcColorBlendFactor = vk::BlendFactor::eSrcAlpha;
|
||||
info.color_blend_attachment[ i ].dstColorBlendFactor = vk::BlendFactor::eOne;
|
||||
info.color_blend_attachment[ i ].colorBlendOp = vk::BlendOp::eAdd;
|
||||
info.color_blend_attachment[ i ].srcAlphaBlendFactor = vk::BlendFactor::eOne;
|
||||
info.color_blend_attachment[ i ].dstAlphaBlendFactor = vk::BlendFactor::eZero;
|
||||
info.color_blend_attachment[ i ].alphaBlendOp = vk::BlendOp::eAdd;
|
||||
info.color_blend_attachment[ i ].colorWriteMask =
|
||||
vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB
|
||||
| vk::ColorComponentFlagBits::eA;
|
||||
}
|
||||
}
|
||||
|
||||
void PipelineConfigInfo::addColorAttachmentConfig( PipelineConfigInfo& info )
|
||||
{
|
||||
vk::PipelineColorBlendAttachmentState state;
|
||||
state.blendEnable = VK_FALSE;
|
||||
state.srcColorBlendFactor = vk::BlendFactor::eOne;
|
||||
state.dstColorBlendFactor = vk::BlendFactor::eZero;
|
||||
state.colorBlendOp = vk::BlendOp::eAdd;
|
||||
state.srcAlphaBlendFactor = vk::BlendFactor::eOne;
|
||||
state.dstAlphaBlendFactor = vk::BlendFactor::eZero;
|
||||
state.alphaBlendOp = vk::BlendOp::eAdd;
|
||||
state.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG
|
||||
| vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA;
|
||||
|
||||
info.color_blend_attachment.emplace_back( state );
|
||||
|
||||
info.color_blend_info.pAttachments = info.color_blend_attachment.data();
|
||||
info.color_blend_info.attachmentCount = static_cast< std::uint32_t >( info.color_blend_attachment.size() );
|
||||
}
|
||||
|
||||
void PipelineConfigInfo::addGBufferAttachmentsConfig( PipelineConfigInfo& config )
|
||||
{
|
||||
for ( int i = 0; i < 3; ++i ) addColorAttachmentConfig( config );
|
||||
}
|
||||
|
||||
void PipelineConfigInfo::disableCulling( PipelineConfigInfo& info )
|
||||
{
|
||||
info.rasterization_info.cullMode = vk::CullModeFlagBits::eNone;
|
||||
}
|
||||
|
||||
PipelineConfigInfo::PipelineConfigInfo( vk::raii::RenderPass& pass )
|
||||
{
|
||||
render_pass = pass;
|
||||
defaultConfig( *this );
|
||||
}
|
||||
|
||||
void PipelineConfigInfo::setQuadTesselation( PipelineConfigInfo& info )
|
||||
{
|
||||
info.tesselation_state_info.patchControlPoints = 4;
|
||||
}
|
||||
|
||||
} // namespace fgl::engine
|
||||
@@ -1,71 +0,0 @@
|
||||
//
|
||||
// Created by kj16609 on 12/14/23.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <vulkan/vulkan_raii.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "engine/FGL_DEFINES.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
enum VertexInputType
|
||||
{
|
||||
None,
|
||||
Simple,
|
||||
Textured
|
||||
};
|
||||
|
||||
struct PipelineConfigInfo
|
||||
{
|
||||
vk::PipelineViewportStateCreateInfo viewport_info {};
|
||||
vk::PipelineInputAssemblyStateCreateInfo assembly_info {};
|
||||
vk::PipelineTessellationStateCreateInfo tesselation_state_info {};
|
||||
vk::PipelineTessellationDomainOriginStateCreateInfo tesselation_domain_info {};
|
||||
vk::PipelineRasterizationStateCreateInfo rasterization_info {};
|
||||
vk::PipelineMultisampleStateCreateInfo multisample_info {};
|
||||
std::vector< vk::PipelineColorBlendAttachmentState > color_blend_attachment {};
|
||||
vk::PipelineColorBlendStateCreateInfo color_blend_info {};
|
||||
vk::PipelineDepthStencilStateCreateInfo depth_stencil_info {};
|
||||
|
||||
std::vector< vk::DynamicState > dynamic_state_enables {};
|
||||
vk::PipelineDynamicStateCreateInfo dynamic_state_info {};
|
||||
|
||||
vk::RenderPass render_pass { VK_NULL_HANDLE };
|
||||
std::uint32_t subpass { 0 };
|
||||
|
||||
std::vector< vk::VertexInputBindingDescription > binding_descriptions {};
|
||||
std::vector< vk::VertexInputAttributeDescription > attribute_descriptions {};
|
||||
|
||||
FGL_DELETE_COPY( PipelineConfigInfo )
|
||||
|
||||
PipelineConfigInfo( vk::raii::RenderPass& pass );
|
||||
|
||||
PipelineConfigInfo& operator=( PipelineConfigInfo&& other ) = default;
|
||||
PipelineConfigInfo( PipelineConfigInfo&& other ) = default;
|
||||
|
||||
static void setVertexInputType( PipelineConfigInfo& info, const VertexInputType type );
|
||||
|
||||
static void disableVertexInput( PipelineConfigInfo& info );
|
||||
|
||||
static void setTriangleListTopo( PipelineConfigInfo& info );
|
||||
static void setTriangleStripTopo( PipelineConfigInfo& info );
|
||||
static void setLineTopo( PipelineConfigInfo& info );
|
||||
|
||||
static void setQuadTesselation( PipelineConfigInfo& info );
|
||||
static void setPointPatch( PipelineConfigInfo& info );
|
||||
static void defaultConfig( PipelineConfigInfo& info );
|
||||
static void enableAlphaBlending( PipelineConfigInfo& config );
|
||||
static void disableCulling( PipelineConfigInfo& info );
|
||||
static void addColorAttachmentConfig( PipelineConfigInfo& info );
|
||||
|
||||
static void addGBufferAttachmentsConfig( PipelineConfigInfo& config );
|
||||
};
|
||||
|
||||
} // namespace fgl::engine
|
||||
@@ -45,7 +45,8 @@ namespace fgl::engine
|
||||
}
|
||||
|
||||
Shader::Shader( const std::filesystem::path& path, const vk::PipelineShaderStageCreateInfo& info ) :
|
||||
shader_data( loadData( path ) ),
|
||||
m_path( path ),
|
||||
shader_data( loadData( m_path ) ),
|
||||
module_create_info( createModuleInfo() ),
|
||||
stage_info( info ),
|
||||
shader_module( Device::getInstance()->createShaderModule( module_create_info ) )
|
||||
@@ -69,4 +70,13 @@ namespace fgl::engine
|
||||
return shader;
|
||||
}
|
||||
|
||||
void Shader::reload()
|
||||
{
|
||||
log::debug( "Reloading shader at {}", m_path.string() );
|
||||
shader_data = loadData( m_path );
|
||||
module_create_info = createModuleInfo();
|
||||
shader_module = Device::getInstance()->createShaderModule( module_create_info );
|
||||
stage_info.module = shader_module;
|
||||
}
|
||||
|
||||
} // namespace fgl::engine
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace fgl::engine
|
||||
|
||||
struct Shader
|
||||
{
|
||||
std::filesystem::path m_path;
|
||||
std::vector< std::byte > shader_data;
|
||||
vk::ShaderModuleCreateInfo module_create_info;
|
||||
vk::PipelineShaderStageCreateInfo stage_info;
|
||||
@@ -44,6 +45,9 @@ namespace fgl::engine
|
||||
{
|
||||
return loadShader( path, vk::ShaderStageFlagBits::eFragment );
|
||||
}
|
||||
|
||||
//! Reloads the shader from disk
|
||||
void reload();
|
||||
};
|
||||
|
||||
} // namespace fgl::engine
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace fgl::engine
|
||||
|
||||
void AttachmentBuilder::finish()
|
||||
{
|
||||
parent.config.color_blend_attachment.emplace_back( color_blend_config );
|
||||
parent.state->color_blend_attachment.emplace_back( color_blend_config );
|
||||
m_finished = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,17 +6,32 @@
|
||||
|
||||
#include "PipelineBuilder.hpp"
|
||||
#include "engine/descriptors/DescriptorSet.hpp"
|
||||
#include "engine/flags.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
Pipeline::Pipeline( vk::raii::Pipeline&& pipeline_in, vk::raii::PipelineLayout&& layout ) :
|
||||
vk::raii::Pipeline Pipeline::rebuildPipeline()
|
||||
{
|
||||
return PipelineBuilder::rebuildFromState( *m_builder_state, m_layout );
|
||||
}
|
||||
|
||||
Pipeline::Pipeline(
|
||||
vk::raii::Pipeline&& pipeline_in,
|
||||
vk::raii::PipelineLayout&& layout,
|
||||
std::unique_ptr< PipelineBuilder::BuilderState >&& builder_state ) :
|
||||
m_pipeline( std::move( pipeline_in ) ),
|
||||
m_layout( std::move( layout ) )
|
||||
m_layout( std::move( layout ) ),
|
||||
m_builder_state( std::forward< std::unique_ptr< PipelineBuilder::BuilderState > >( builder_state ) )
|
||||
{}
|
||||
|
||||
void Pipeline::bind( vk::raii::CommandBuffer& cmd_buffer )
|
||||
{
|
||||
if ( flags::shouldReloadShaders() )
|
||||
{
|
||||
m_pipeline = rebuildPipeline();
|
||||
}
|
||||
|
||||
cmd_buffer.bindPipeline( vk::PipelineBindPoint::eGraphics, m_pipeline );
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
// Created by kj16609 on 10/9/24.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PipelineBuilder.hpp"
|
||||
#include "engine/descriptors/DescriptorSet.hpp"
|
||||
#include "engine/rendering/pipelines/Pipeline.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
|
||||
@@ -17,18 +19,32 @@ namespace fgl::engine
|
||||
{
|
||||
vk::raii::Pipeline m_pipeline;
|
||||
vk::raii::PipelineLayout m_layout;
|
||||
std::unique_ptr< PipelineBuilder::BuilderState > m_builder_state;
|
||||
|
||||
vk::raii::Pipeline rebuildPipeline();
|
||||
|
||||
public:
|
||||
|
||||
Pipeline() = delete;
|
||||
Pipeline( vk::raii::Pipeline&& pipeline, vk::raii::PipelineLayout&& layout );
|
||||
Pipeline(
|
||||
vk::raii::Pipeline&& pipeline_in,
|
||||
vk::raii::PipelineLayout&& layout,
|
||||
std::unique_ptr< PipelineBuilder::BuilderState >&& builder_state );
|
||||
|
||||
void bind( vk::raii::CommandBuffer& );
|
||||
|
||||
void bindDescriptor( vk::raii::CommandBuffer&, descriptors::DescriptorIDX descriptor_idx, descriptors::DescriptorSet& set );
|
||||
void bindDescriptor(
|
||||
vk::raii::CommandBuffer&, descriptors::DescriptorIDX descriptor_idx, descriptors::DescriptorSet& set );
|
||||
void bindDescriptor( vk::raii::CommandBuffer& comd_buffer, descriptors::DescriptorSet& set );
|
||||
|
||||
void setDebugName( const char* str );
|
||||
|
||||
template < typename T >
|
||||
requires std::is_trivially_copyable_v< T >
|
||||
void pushConstant( vk::raii::CommandBuffer& command_buffer, vk::ShaderStageFlags stage, const T& t )
|
||||
{
|
||||
command_buffer.pushConstants< T >( m_layout, stage, 0, { t } );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace fgl::engine
|
||||
|
||||
@@ -12,26 +12,37 @@ namespace fgl::engine
|
||||
{
|
||||
|
||||
PipelineBuilder::PipelineBuilder( vk::raii::RenderPass& renderpass, const std::uint32_t subpass_stage ) :
|
||||
m_render_pass( renderpass ),
|
||||
subpass_idx( subpass_stage )
|
||||
state( std::make_unique< BuilderState >( renderpass, subpass_stage ) )
|
||||
{
|
||||
addDynamicState( vk::DynamicState::eViewport );
|
||||
addDynamicState( vk::DynamicState::eScissor );
|
||||
}
|
||||
|
||||
void PipelineBuilder::setVertexShader( std::shared_ptr< Shader >&& shader )
|
||||
{
|
||||
state->shaders.vertex = std::forward< std::shared_ptr< Shader > >( shader );
|
||||
}
|
||||
|
||||
void PipelineBuilder::setFragmentShader( std::shared_ptr< Shader >&& shader )
|
||||
{
|
||||
state->shaders.fragment = std::forward< std::shared_ptr< Shader > >( shader );
|
||||
}
|
||||
|
||||
descriptors::DescriptorSetLayout empty_set_layout { descriptors::DescriptorSetLayout::createEmptySet() };
|
||||
|
||||
vk::raii::PipelineLayout PipelineBuilder::createLayout()
|
||||
{
|
||||
vk::PipelineLayoutCreateInfo info {};
|
||||
|
||||
if ( state->push_constant.size > 0 ) info.setPushConstantRanges( state->push_constant );
|
||||
|
||||
std::vector< vk::DescriptorSetLayout > set_layouts {};
|
||||
|
||||
set_layouts.reserve( descriptor_set_layouts.size() );
|
||||
set_layouts.reserve( state->descriptor_set_layouts.size() );
|
||||
|
||||
SetID max_set_idx { 0 };
|
||||
|
||||
for ( const auto& [ set_idx, _ ] : descriptor_set_layouts )
|
||||
for ( const auto& [ set_idx, _ ] : state->descriptor_set_layouts )
|
||||
{
|
||||
max_set_idx = std::max( max_set_idx, set_idx );
|
||||
}
|
||||
@@ -41,8 +52,8 @@ namespace fgl::engine
|
||||
|
||||
for ( std::size_t i = 0; i < set_layouts.size(); ++i )
|
||||
{
|
||||
auto itter { descriptor_set_layouts.find( static_cast< SetID >( i ) ) };
|
||||
if ( itter == descriptor_set_layouts.end() )
|
||||
auto itter { state->descriptor_set_layouts.find( static_cast< SetID >( i ) ) };
|
||||
if ( itter == state->descriptor_set_layouts.end() )
|
||||
{
|
||||
// Could not find it. Empty
|
||||
set_layouts[ i ] = empty_set_layout.layout();
|
||||
@@ -55,7 +66,7 @@ namespace fgl::engine
|
||||
}
|
||||
}
|
||||
|
||||
for ( const auto& [ set_idx, layout ] : descriptor_set_layouts )
|
||||
for ( const auto& [ set_idx, layout ] : state->descriptor_set_layouts )
|
||||
{
|
||||
set_layouts[ set_idx ] = layout;
|
||||
}
|
||||
@@ -68,8 +79,8 @@ namespace fgl::engine
|
||||
void PipelineBuilder::
|
||||
addDescriptorSet( const SetID idx, const vk::raii::DescriptorSetLayout& descriptor_set_layout )
|
||||
{
|
||||
FGL_ASSERT( !descriptor_set_layouts.contains( idx ), "Descriptor already set!" );
|
||||
descriptor_set_layouts.insert( std::make_pair( idx, *descriptor_set_layout ) );
|
||||
FGL_ASSERT( !state->descriptor_set_layouts.contains( idx ), "Descriptor already set!" );
|
||||
state->descriptor_set_layouts.insert( std::make_pair( idx, *descriptor_set_layout ) );
|
||||
}
|
||||
|
||||
void PipelineBuilder::addDescriptorSet( descriptors::DescriptorSetLayout& descriptor )
|
||||
@@ -79,17 +90,24 @@ namespace fgl::engine
|
||||
|
||||
void PipelineBuilder::addDynamicState( vk::DynamicState dynamic_state )
|
||||
{
|
||||
m_dynamic_state.emplace_back( dynamic_state );
|
||||
state->m_dynamic_state.emplace_back( dynamic_state );
|
||||
}
|
||||
|
||||
[[nodiscard]] vk::PipelineColorBlendAttachmentState& PipelineBuilder::Config::addColorAttachment()
|
||||
void PipelineBuilder::setPushConstant( const vk::ShaderStageFlags flags, std::size_t size )
|
||||
{
|
||||
state->push_constant.offset = 0;
|
||||
state->push_constant.size = size;
|
||||
state->push_constant.stageFlags = flags;
|
||||
}
|
||||
|
||||
[[nodiscard]] vk::PipelineColorBlendAttachmentState& PipelineBuilder::BuilderState::addColorAttachment()
|
||||
{
|
||||
color_blend_attachment.emplace_back();
|
||||
color_blend_info.setAttachments( color_blend_attachment );
|
||||
return color_blend_attachment.back();
|
||||
}
|
||||
|
||||
PipelineBuilder::Config::Config()
|
||||
void PipelineBuilder::BuilderState::setDefault()
|
||||
{
|
||||
viewport_info.viewportCount = 1;
|
||||
viewport_info.pViewports = nullptr;
|
||||
@@ -143,18 +161,18 @@ namespace fgl::engine
|
||||
|
||||
void PipelineBuilder::setTopology( const vk::PrimitiveTopology primitive_topology )
|
||||
{
|
||||
config.assembly_info.topology = primitive_topology;
|
||||
state->assembly_info.topology = primitive_topology;
|
||||
}
|
||||
|
||||
void PipelineBuilder::disableVertexInput()
|
||||
{
|
||||
vertex_input_descriptions.bindings = {};
|
||||
vertex_input_descriptions.attributes = {};
|
||||
state->vertex_input_descriptions.bindings = {};
|
||||
state->vertex_input_descriptions.attributes = {};
|
||||
}
|
||||
|
||||
void PipelineBuilder::disableCulling()
|
||||
{
|
||||
config.rasterization_info.cullMode = vk::CullModeFlagBits::eNone;
|
||||
state->rasterization_info.cullMode = vk::CullModeFlagBits::eNone;
|
||||
}
|
||||
|
||||
AttachmentBuilder PipelineBuilder::addAttachment()
|
||||
@@ -170,74 +188,91 @@ namespace fgl::engine
|
||||
|
||||
void PipelineBuilder::setBindingDescriptions( const std::vector< vk::VertexInputBindingDescription >& descriptions )
|
||||
{
|
||||
vertex_input_descriptions.bindings = descriptions;
|
||||
state->vertex_input_descriptions.bindings = descriptions;
|
||||
}
|
||||
|
||||
void PipelineBuilder::setAttributeDescriptions( const std::vector< vk::VertexInputAttributeDescription >&
|
||||
descriptions )
|
||||
{
|
||||
vertex_input_descriptions.attributes = descriptions;
|
||||
state->vertex_input_descriptions.attributes = descriptions;
|
||||
}
|
||||
|
||||
std::unique_ptr< Pipeline > PipelineBuilder::create()
|
||||
vk::raii::Pipeline PipelineBuilder::createFromState( BuilderState& state, vk::raii::PipelineLayout& layout )
|
||||
{
|
||||
// Precheck
|
||||
{
|
||||
FGL_ASSERT( shaders.fragment, "Pipeline requires fragment shader" );
|
||||
FGL_ASSERT( shaders.vertex, "Pipeline requires vertex shader" );
|
||||
}
|
||||
|
||||
vk::raii::PipelineLayout layout { createLayout() };
|
||||
|
||||
vk::GraphicsPipelineCreateInfo info {};
|
||||
info.pNext = VK_NULL_HANDLE;
|
||||
info.flags = {};
|
||||
|
||||
m_stages.clear();
|
||||
state.m_stages.clear();
|
||||
|
||||
if ( shaders.vertex ) m_stages.emplace_back( shaders.vertex->stage_info );
|
||||
if ( shaders.fragment ) m_stages.emplace_back( shaders.fragment->stage_info );
|
||||
if ( state.shaders.vertex ) state.m_stages.emplace_back( state.shaders.vertex->stage_info );
|
||||
if ( state.shaders.fragment ) state.m_stages.emplace_back( state.shaders.fragment->stage_info );
|
||||
|
||||
info.setStages( m_stages );
|
||||
info.setStages( state.m_stages );
|
||||
|
||||
vk::PipelineVertexInputStateCreateInfo vertex_input_info {};
|
||||
vertex_input_info.pNext = VK_NULL_HANDLE;
|
||||
vertex_input_info.flags = {};
|
||||
vertex_input_info.setVertexBindingDescriptions( vertex_input_descriptions.bindings );
|
||||
vertex_input_info.setVertexAttributeDescriptions( vertex_input_descriptions.attributes );
|
||||
vertex_input_info.setVertexBindingDescriptions( state.vertex_input_descriptions.bindings );
|
||||
vertex_input_info.setVertexAttributeDescriptions( state.vertex_input_descriptions.attributes );
|
||||
info.setPVertexInputState( &vertex_input_info );
|
||||
|
||||
info.pInputAssemblyState = &config.assembly_info;
|
||||
info.pTessellationState = &config.tesselation_state_info;
|
||||
info.pViewportState = &config.viewport_info;
|
||||
info.pRasterizationState = &config.rasterization_info;
|
||||
info.pMultisampleState = &config.multisample_info;
|
||||
info.pDepthStencilState = &config.depth_stencil_info;
|
||||
info.pInputAssemblyState = &state.assembly_info;
|
||||
info.pTessellationState = &state.tesselation_state_info;
|
||||
info.pViewportState = &state.viewport_info;
|
||||
info.pRasterizationState = &state.rasterization_info;
|
||||
info.pMultisampleState = &state.multisample_info;
|
||||
info.pDepthStencilState = &state.depth_stencil_info;
|
||||
|
||||
config.color_blend_info.setAttachments( config.color_blend_attachment );
|
||||
state.color_blend_info.setAttachments( state.color_blend_attachment );
|
||||
|
||||
info.pColorBlendState = &config.color_blend_info;
|
||||
info.pDynamicState = &config.dynamic_state_info;
|
||||
info.pColorBlendState = &state.color_blend_info;
|
||||
info.pDynamicState = &state.dynamic_state_info;
|
||||
|
||||
info.layout = layout;
|
||||
info.renderPass = m_render_pass;
|
||||
info.subpass = subpass_idx;
|
||||
info.renderPass = state.m_render_pass;
|
||||
info.subpass = state.m_subpass_stage;
|
||||
|
||||
//TODO: Figure out what these do
|
||||
info.basePipelineHandle = VK_NULL_HANDLE;
|
||||
info.basePipelineIndex = -1;
|
||||
|
||||
vk::PipelineDynamicStateCreateInfo dynamic_state_create_info {};
|
||||
dynamic_state_create_info.setDynamicStates( m_dynamic_state );
|
||||
dynamic_state_create_info.setDynamicStates( state.m_dynamic_state );
|
||||
|
||||
if ( m_dynamic_state.size() > 0 ) info.setPDynamicState( &dynamic_state_create_info );
|
||||
if ( state.m_dynamic_state.size() > 0 ) info.setPDynamicState( &dynamic_state_create_info );
|
||||
|
||||
vk::raii::Pipeline pipeline { Device::getInstance()->createGraphicsPipeline( VK_NULL_HANDLE, info ) };
|
||||
|
||||
return std::make_unique< Pipeline >( std::move( pipeline ), std::move( layout ) );
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
void setGBufferOutputAttachments( PipelineBuilder::Config& config )
|
||||
vk::raii::Pipeline PipelineBuilder::rebuildFromState( BuilderState& state, vk::raii::PipelineLayout& layout )
|
||||
{
|
||||
auto& shaders { state.shaders };
|
||||
|
||||
if ( shaders.vertex ) shaders.vertex->reload();
|
||||
if ( shaders.fragment ) shaders.fragment->reload();
|
||||
|
||||
return createFromState( state, layout );
|
||||
}
|
||||
|
||||
std::unique_ptr< Pipeline > PipelineBuilder::create()
|
||||
{
|
||||
// Precheck
|
||||
{
|
||||
FGL_ASSERT( state->shaders.fragment, "Pipeline requires fragment shader" );
|
||||
FGL_ASSERT( state->shaders.vertex, "Pipeline requires vertex shader" );
|
||||
}
|
||||
|
||||
vk::raii::PipelineLayout layout { createLayout() };
|
||||
|
||||
vk::raii::Pipeline pipeline { createFromState( *state, layout ) };
|
||||
|
||||
return std::make_unique< Pipeline >( std::move( pipeline ), std::move( layout ), std::move( state ) );
|
||||
}
|
||||
|
||||
void setGBufferOutputAttachments( PipelineBuilder::BuilderState& config )
|
||||
{
|
||||
// In order for the pipeline to output, We need to ensure that we have enough attachments for the entire gbuffer (3)
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// Created by kj16609 on 10/10/24.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan_raii.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
@@ -22,26 +24,7 @@ namespace fgl::engine
|
||||
|
||||
class PipelineBuilder
|
||||
{
|
||||
vk::raii::RenderPass& m_render_pass;
|
||||
std::uint32_t subpass_idx;
|
||||
|
||||
struct
|
||||
{
|
||||
std::vector< vk::VertexInputBindingDescription > bindings {};
|
||||
std::vector< vk::VertexInputAttributeDescription > attributes {};
|
||||
} vertex_input_descriptions {};
|
||||
|
||||
struct
|
||||
{
|
||||
std::shared_ptr< Shader > vertex { nullptr };
|
||||
std::shared_ptr< Shader > fragment { nullptr };
|
||||
} shaders {};
|
||||
|
||||
std::vector< vk::PipelineShaderStageCreateInfo > m_stages {};
|
||||
std::vector< vk::DynamicState > m_dynamic_state {};
|
||||
|
||||
using SetID = std::uint32_t;
|
||||
std::unordered_map< SetID, vk::DescriptorSetLayout > descriptor_set_layouts {};
|
||||
|
||||
vk::raii::PipelineLayout createLayout();
|
||||
|
||||
@@ -50,11 +33,33 @@ namespace fgl::engine
|
||||
void addDescriptorSet( SetID idx, const vk::raii::DescriptorSetLayout& descriptor_set_layout );
|
||||
void addDescriptorSet( descriptors::DescriptorSetLayout& descriptor );
|
||||
void addDynamicState( vk::DynamicState dynamic_state );
|
||||
void setPushConstant( vk::ShaderStageFlags flags, std::size_t size );
|
||||
|
||||
PipelineBuilder() = delete;
|
||||
|
||||
struct Config
|
||||
struct BuilderState
|
||||
{
|
||||
vk::raii::RenderPass& m_render_pass;
|
||||
std::uint32_t m_subpass_stage;
|
||||
vk::PushConstantRange push_constant {};
|
||||
|
||||
std::vector< vk::PipelineShaderStageCreateInfo > m_stages {};
|
||||
std::vector< vk::DynamicState > m_dynamic_state {};
|
||||
|
||||
struct
|
||||
{
|
||||
std::vector< vk::VertexInputBindingDescription > bindings {};
|
||||
std::vector< vk::VertexInputAttributeDescription > attributes {};
|
||||
} vertex_input_descriptions {};
|
||||
|
||||
struct
|
||||
{
|
||||
std::shared_ptr< Shader > vertex { nullptr };
|
||||
std::shared_ptr< Shader > fragment { nullptr };
|
||||
} shaders {};
|
||||
|
||||
std::unordered_map< SetID, vk::DescriptorSetLayout > descriptor_set_layouts {};
|
||||
|
||||
vk::PipelineViewportStateCreateInfo viewport_info {};
|
||||
vk::PipelineInputAssemblyStateCreateInfo assembly_info {};
|
||||
vk::PipelineTessellationStateCreateInfo tesselation_state_info {};
|
||||
@@ -71,10 +76,20 @@ namespace fgl::engine
|
||||
std::vector< vk::DynamicState > dynamic_state_enables {};
|
||||
vk::PipelineDynamicStateCreateInfo dynamic_state_info {};
|
||||
|
||||
// Default config
|
||||
Config();
|
||||
vk::PipelineLayoutCreateInfo layout_info {};
|
||||
|
||||
} config {};
|
||||
// Default config
|
||||
void setDefault();
|
||||
|
||||
BuilderState( vk::raii::RenderPass& renderpass, const std::size_t subpass_stage ) :
|
||||
m_render_pass( renderpass ),
|
||||
m_subpass_stage( subpass_stage )
|
||||
{
|
||||
setDefault();
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr< BuilderState > state;
|
||||
|
||||
void setTopology( vk::PrimitiveTopology primitive_topology );
|
||||
void disableVertexInput();
|
||||
@@ -84,28 +99,23 @@ namespace fgl::engine
|
||||
[[nodiscard]] AttachmentBuilder addAttachment();
|
||||
[[nodiscard]] AttachmentBuilder addColorAttachment();
|
||||
|
||||
vk::PipelineLayoutCreateInfo layout_info {};
|
||||
|
||||
void setBindingDescriptions( const std::vector< vk::VertexInputBindingDescription >& descriptions );
|
||||
|
||||
void setAttributeDescriptions( const std::vector< vk::VertexInputAttributeDescription >& descriptions );
|
||||
|
||||
PipelineBuilder( vk::raii::RenderPass& renderpass, std::uint32_t subpass_stage );
|
||||
|
||||
void setVertexShader( std::shared_ptr< Shader >&& shader )
|
||||
{
|
||||
shaders.vertex = std::forward< std::shared_ptr< Shader > >( shader );
|
||||
}
|
||||
void setVertexShader( std::shared_ptr< Shader >&& shader );
|
||||
|
||||
void setFragmentShader( std::shared_ptr< Shader >&& shader )
|
||||
{
|
||||
shaders.fragment = std::forward< std::shared_ptr< Shader > >( shader );
|
||||
}
|
||||
void setFragmentShader( std::shared_ptr< Shader >&& shader );
|
||||
|
||||
static vk::raii::Pipeline createFromState( BuilderState& state, vk::raii::PipelineLayout& layout );
|
||||
static vk::raii::Pipeline rebuildFromState( BuilderState& state, vk::raii::PipelineLayout& layout );
|
||||
|
||||
std::unique_ptr< Pipeline > create();
|
||||
};
|
||||
|
||||
//! Adds the GBuffer output attachments to the config for the given pipeline
|
||||
void setGBufferOutputAttachments( PipelineBuilder::Config& config );
|
||||
void setGBufferOutputAttachments( PipelineBuilder::BuilderState& config );
|
||||
|
||||
} // namespace fgl::engine
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "CompositionSystem.hpp"
|
||||
|
||||
#include "Control.hpp"
|
||||
#include "editor/src/gui/safe_include.hpp"
|
||||
#include "engine/camera/Camera.hpp"
|
||||
#include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp"
|
||||
#include "engine/rendering/pipelines/v2/Pipeline.hpp"
|
||||
@@ -23,6 +25,8 @@ namespace fgl::engine
|
||||
|
||||
builder.addColorAttachment().finish();
|
||||
|
||||
builder.setPushConstant( vk::ShaderStageFlagBits::eFragment, sizeof( CompositionControl ) );
|
||||
|
||||
builder.setVertexShader( Shader::loadVertex( "shaders/fullscreen.vert" ) );
|
||||
builder.setFragmentShader( Shader::loadFragment( "shaders/composition.frag" ) );
|
||||
|
||||
@@ -48,6 +52,14 @@ namespace fgl::engine
|
||||
m_composite_pipeline->bindDescriptor( command_buffer, info.getGBufferDescriptor() );
|
||||
m_composite_pipeline->bindDescriptor( command_buffer, info.getCameraDescriptor() );
|
||||
|
||||
ImGui::Begin( "Composition" );
|
||||
|
||||
ImGui::InputInt( "Selection", &m_control.flags );
|
||||
|
||||
ImGui::End();
|
||||
|
||||
m_composite_pipeline->pushConstant( command_buffer, vk::ShaderStageFlagBits::eFragment, m_control );
|
||||
|
||||
return info.command_buffer;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Control.hpp"
|
||||
#include "engine/FrameInfo.hpp"
|
||||
#include "engine/systems/concepts.hpp"
|
||||
|
||||
@@ -17,6 +18,8 @@ namespace fgl::engine
|
||||
|
||||
vk::raii::CommandBuffer& setupSystem( FrameInfo& info );
|
||||
|
||||
CompositionControl m_control {};
|
||||
|
||||
public:
|
||||
|
||||
CompositionSystem( vk::raii::RenderPass& render_pass );
|
||||
|
||||
28
src/engine/systems/composition/Control.hpp
Normal file
28
src/engine/systems/composition/Control.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Created by kj16609 on 10/18/24.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
struct CompositionControl
|
||||
{
|
||||
enum Values
|
||||
{
|
||||
OutColor = 0,
|
||||
LoRender = 1,
|
||||
Normal = 2,
|
||||
CosLo = 3,
|
||||
F0 = 4,
|
||||
DirectLighting = 5,
|
||||
Ambient = 6,
|
||||
Lh = 7,
|
||||
MAX
|
||||
};
|
||||
|
||||
int flags { 0 };
|
||||
};
|
||||
} // namespace fgl::engine
|
||||
@@ -15,12 +15,6 @@ namespace fgl::engine
|
||||
|
||||
GuiSystem::GuiSystem( vk::raii::RenderPass& render_pass )
|
||||
{
|
||||
PipelineConfigInfo info { render_pass };
|
||||
PipelineConfigInfo::addColorAttachmentConfig( info );
|
||||
PipelineConfigInfo::disableVertexInput( info );
|
||||
PipelineConfigInfo::disableCulling( info );
|
||||
info.subpass = 0;
|
||||
|
||||
//descriptors::DescriptorSetCollection descriptors { gui_descriptor_set };
|
||||
|
||||
PipelineBuilder builder { render_pass, 0 };
|
||||
@@ -56,9 +50,6 @@ namespace fgl::engine
|
||||
auto& command_buffer { setupSystem( info ) };
|
||||
|
||||
command_buffer.draw( 3, 1, 0, 0 );
|
||||
|
||||
//Handle GUI
|
||||
// gui::drawMainGUI( info );
|
||||
}
|
||||
|
||||
} // namespace fgl::engine
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "engine/assets/model/Model.hpp"
|
||||
#include "engine/debug/drawers.hpp"
|
||||
#include "engine/debug/profiling/counters.hpp"
|
||||
#include "engine/gameobjects/components/ModelComponent.hpp"
|
||||
#include "engine/tree/octtree/OctTreeNode.hpp"
|
||||
|
||||
@@ -87,6 +88,8 @@ namespace fgl::engine
|
||||
|
||||
assert( primitive.m_index_buffer.size() > 0 );
|
||||
|
||||
profiling::addVertexDrawn( primitive.m_index_buffer.size() );
|
||||
|
||||
if ( auto itter = draw_pairs.find( key ); itter != draw_pairs.end() )
|
||||
{
|
||||
ZoneScopedN( "Accumulate for draw pair" );
|
||||
|
||||
@@ -164,6 +164,7 @@ namespace fgl::engine
|
||||
m_textured_pipeline->bindDescriptor( command_buffer, Material::getDescriptorSet() );
|
||||
|
||||
profiling::addModelDrawn( model_matricies.size() );
|
||||
profiling::addInstances( draw_commands.size() );
|
||||
|
||||
auto& model_matrix_info_buffer { m_textured_model_matrix_info_buffers[ info.frame_idx ] };
|
||||
model_matrix_info_buffer =
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
|
||||
|
||||
|
||||
file(GLOB_RECURSE SHADERS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/**.frag"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/**.vert"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/**.tesc"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/**.tese"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/**.glsl"
|
||||
)
|
||||
|
||||
foreach (SHADER IN LISTS SHADERS)
|
||||
get_filename_component(FILENAME ${SHADER} NAME)
|
||||
get_filename_component(FILE_DIRECTORY ${SHADER} DIRECTORY)
|
||||
file(RELATIVE_PATH REL_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${FILE_DIRECTORY})
|
||||
|
||||
if (NOT REL_PATH STREQUAL "")
|
||||
set(REL_PATH ${REL_PATH}/)
|
||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin/shaders/${REL_PATH})
|
||||
endif ()
|
||||
|
||||
set(OUT_DIR ${CMAKE_BINARY_DIR}/bin/shaders/${REL_PATH})
|
||||
set(OUT_PATH ${OUT_DIR}${FILENAME})
|
||||
|
||||
#add_custom_command(OUTPUT ${OUT_DIR}
|
||||
# COMMAND ${CMAKE_COMMAND} -E make_directory ${OUT_DIR} COMMENT "Creating directory ${OUT_DIR}")
|
||||
|
||||
#add_custom_command(OUTPUT ${OUT_PATH}
|
||||
# COMMAND ${Vulkan_GLSLC_EXECUTABLE} ${SHADER_DEBUG_FLAGS} ${SHADER} -o ${OUT_PATH} DEPENDS ${SHADER} ${OUT_DIR}
|
||||
# COMMENT "Compiling ${SHADER} ")
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/bin/shaders/${FILENAME}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${SHADER} ${OUT_PATH} DEPENDS ${SHADER}
|
||||
COMMENT "Copying ${ASSET} to ${OUT_PATH}")
|
||||
|
||||
list(APPEND SPV_SHADERS ${CMAKE_BINARY_DIR}/bin/shaders/${FILENAME})
|
||||
list(APPEND ADDITIONAL_CLEAN_FILES ${OUT_PATH})
|
||||
endforeach ()
|
||||
|
||||
add_custom_target(shaders ALL DEPENDS ${SPV_SHADERS})
|
||||
@@ -17,6 +17,10 @@ layout (set = 1, binding = 0) uniform CameraInfo {
|
||||
mat4 inverse_view;
|
||||
} camera_info;
|
||||
|
||||
layout(push_constant) uniform Constants {
|
||||
uint flags;
|
||||
} push;
|
||||
|
||||
//TODO: uniform binding with sun information
|
||||
|
||||
vec3 getCameraPosition()
|
||||
@@ -55,9 +59,10 @@ float gaSchlickGGX(float cosLi, float cosLo, float roughness)
|
||||
return gaSchlickG1(cosLi, k) * gaSchlickG1(cosLo, k);
|
||||
}
|
||||
|
||||
//TODO: Apparently this can be gotten from a texture instead?
|
||||
vec3 schlick(vec3 F0, float cosTheta)
|
||||
{
|
||||
return F0 + (vec3(1.0) - F0) * pow(1.0 - cosTheta, 5.0);
|
||||
return F0 + (vec3(1.0) - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
|
||||
}
|
||||
|
||||
void main()
|
||||
@@ -96,28 +101,77 @@ void main()
|
||||
vec3 direct_lighting = vec3(0.0);
|
||||
|
||||
// Do this for each light
|
||||
{
|
||||
vec3 Li = -sun_dir;
|
||||
vec3 Lradiance = vec3(1.0);// color?
|
||||
// {
|
||||
vec3 Li = -sun_dir;
|
||||
vec3 Lradiance = vec3(1.0);// color?
|
||||
|
||||
// half vector
|
||||
vec3 Lh = normalize(Li + Lo);
|
||||
// half vector
|
||||
vec3 Lh = normalize(Li + Lo);
|
||||
|
||||
float cosLi = max(dot(N, Li), 0.0);
|
||||
float cosLh = max(dot(N, Lh), 0.0);
|
||||
float cosLi = max(dot(N, Li), 0.0);
|
||||
float cosLh = max(dot(N, Lh), 0.0);
|
||||
|
||||
vec3 F = schlick(F0, max(dot(Lh, Lo), 0.0));
|
||||
float D = ndfGGX(cosLh, roughness_value);
|
||||
float G = gaSchlickGGX(cosLi, cosLo, roughness_value);
|
||||
vec3 F = schlick(F0, max(dot(Lh, Lo), 0.0));
|
||||
float D = ndfGGX(cosLh, roughness_value);
|
||||
float G = gaSchlickGGX(cosLi, cosLo, roughness_value);
|
||||
|
||||
vec3 kb = mix(vec3(1.0) - F, vec3(0.0), metallic_value);
|
||||
vec3 diffuse_BRDF = kb * albedo;
|
||||
vec3 specular_BRDF = (F * D * G) / max(0.04, 4.0 * cosLi * cosLo);
|
||||
vec3 kb = mix(vec3(1.0) - F, vec3(0.0), metallic_value);
|
||||
vec3 diffuse_BRDF = kb * albedo;
|
||||
vec3 specular_BRDF = (F * D * G) / max(0.04, 4.0 * cosLi * cosLo);
|
||||
|
||||
direct_lighting = (diffuse_BRDF + specular_BRDF) * Lradiance * cosLi;
|
||||
}
|
||||
direct_lighting = (diffuse_BRDF + specular_BRDF) * Lradiance * cosLi;
|
||||
// }
|
||||
|
||||
vec3 ambient_lighting = albedo * 0.1;
|
||||
|
||||
out_color = vec4(direct_lighting + ambient_lighting, 1.0);
|
||||
switch (push.flags)
|
||||
{
|
||||
case 0:
|
||||
out_color = vec4(direct_lighting + ambient_lighting, 1.0);
|
||||
return;
|
||||
case 1:
|
||||
out_color = vec4(Lo, 1.0);
|
||||
return;
|
||||
case 2:
|
||||
out_color = vec4(N, 1.0);
|
||||
return;
|
||||
case 3:
|
||||
out_color = vec4(cosLo, 0.0, 0.0, 1.0);
|
||||
return;
|
||||
case 4:
|
||||
out_color = vec4(F0, 1.0);
|
||||
return;
|
||||
case 5:
|
||||
out_color = vec4(direct_lighting, 1.0);
|
||||
return;
|
||||
case 6:
|
||||
out_color = vec4(ambient_lighting, 1.0);
|
||||
return;
|
||||
case 7:
|
||||
out_color = vec4(Lh, 1.0);
|
||||
return;
|
||||
case 8:
|
||||
out_color = vec4(cosLi, 0.0, 0.0, 1.0);
|
||||
return;
|
||||
case 9:
|
||||
out_color = vec4(cosLh, 0.0, 0.0, 1.0);
|
||||
return;
|
||||
case 10:
|
||||
out_color = vec4(F, 1.0);
|
||||
return;
|
||||
case 11:
|
||||
out_color = vec4(D, 0.0, 0.0, 1.0);
|
||||
return;
|
||||
case 12:
|
||||
out_color = vec4(G, 0.0, 0.0, 1.0);
|
||||
return;
|
||||
case 13:
|
||||
out_color = vec4(kb, 1.0);
|
||||
return;
|
||||
case 14:
|
||||
out_color = vec4(max(dot(Lh, Lo), 0.0));
|
||||
return;
|
||||
}
|
||||
|
||||
out_color = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user