depth-prepass #1

Merged
KJ16609 merged 22 commits from depth-prepass into master 2025-12-15 19:59:49 -05:00
220 changed files with 2994 additions and 2416 deletions

5
.gitmodules vendored
View File

@@ -39,4 +39,7 @@
url = https://github.com/shader-slang/slang.git
[submodule "dependencies/libFGL"]
path = dependencies/libFGL
url = git@github.com:KJNeko/libFGL.git
url = git@github.com:KJNeko/libFGL.git
[submodule "dependencies/gtest"]
path = dependencies/gtest
url = https://github.com/google/googletest.git

View File

@@ -1,7 +1,6 @@
cmake_minimum_required(VERSION 3.25.0)
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(TitorGameEngine LANGUAGES CXX C)
@@ -9,20 +8,15 @@ add_subdirectory(dependencies/libFGL)
PreSetup()
#file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin/data)
#Enable cmake_modules
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules")
message("-- CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
string(TOUPPER ${CMAKE_BUILD_TYPE} UPPER_BUILD_TYPE)
add_subdirectory(dependencies/vma)
include(dependencies/glfw)
include(dependencies/glm)
include(cmake_modules/dependencies/tracy.cmake)
include(dependencies/vulkan)
include(dependencies/catch2)
include(dependencies/slang)
include(dependencies/json)

View File

@@ -1,2 +0,0 @@
add_subdirectory(${CMAKE_SOURCE_DIR}/dependencies/blurhash)
set_target_properties(BlurhashCXX PROPERTIES COMPILE_FLAGS ${FGL_FLAGS})

View File

@@ -1 +0,0 @@
add_subdirectory(${CMAKE_SOURCE_DIR}/dependencies/catch2)

View File

@@ -3,18 +3,14 @@
set(GLFW_BUILD_X11 ON)
set(GLFW_BUILD_WAYLAND OFF)
#if (WIN32)
if (DEFINED ENV{GLFW_PATH})
message("-- GLFW_PATH defined as: $ENV{GLFW_PATH}.")
list(APPEND CMAKE_PREFIX_PATH $ENV{GLFW_PATH})
find_package(glfw3 REQUIRED)
else ()
message("-- GLFW_PATH not defined. Using submodule instead")
add_subdirectory(${CMAKE_SOURCE_DIR}/dependencies/glfw3)
endif ()
#else ()
# find_package(glfw3 REQUIRED)
#endif ()
if (DEFINED ENV{GLFW_PATH})
message("-- GLFW_PATH defined as: $ENV{GLFW_PATH}.")
list(APPEND CMAKE_PREFIX_PATH $ENV{GLFW_PATH})
find_package(glfw3 REQUIRED)
else ()
message("-- GLFW_PATH not defined. Using submodule instead")
add_subdirectory(${CMAKE_SOURCE_DIR}/dependencies/glfw3)
endif ()
set(GLFW_BUILD_X11 ON)
set(GLFW_BUILD_WAYLAND OFF)

View File

@@ -1,11 +0,0 @@
include(FetchContent)
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

View File

@@ -1,11 +0,0 @@
set(LZ4_DIR ${CMAKE_SOURCE_DIR}/dependencies/lz4/lib)
file(GLOB_RECURSE LZ4_SOURCES ${LZ4_DIR}/*.c)
add_library(lz4 STATIC ${LZ4_SOURCES})
target_include_directories(lz4 PUBLIC ${LZ4_DIR})
if (WIN32)
#target_compile_definitions(${CMAKE_SOURCE_DIR}/dependencies/lz4 PRIVATE UNICODE=1)
target_compile_definitions(lz4 PRIVATE LZ4_DEBUG=0)
endif ()

View File

@@ -1,13 +0,0 @@
#Verify after setting QT_PATH
if (DEFINED QT_PATH)
message("-- QT_PATH defined as ${QT_PATH}.")
list(APPEND CMAKE_PREFIX_PATH ${QT_PATH})
else ()
message("-- QT_PATH not defined.")
endif ()
find_package(Qt6 COMPONENTS Widgets Core Concurrent Network Test Charts REQUIRED)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

View File

@@ -5,7 +5,7 @@ string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_UPPER_BUILD_TYPE)
message("-- Cmake upper: ${CMAKE_UPPER_BUILD_TYPE}")
#if (CMAKE_UPPER_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_UPPER_BUILD_TYPE STREQUAL "RELWITHDEBINFO" AND DEFINED FGL_ENABLE_PROFILING)
if (DEFINED FGL_ENABLE_PROFILING AND FGL_ENABLE_PROFILING)
if (DEFINED FGL_ENABLE_PROFILING AND FGL_ENABLE_PROFILING EQUAL 1)
set(TRACY_ENABLE ON)
set(TRACY_ON_DEMAND ON)
set(TRACY_NO_EXIT ON)

View File

@@ -3,4 +3,38 @@ if (NOT Vulkan_FOUND)
error("Vulkan not found")
endif ()
#add_library(VulkanCppModule)
#add_library(Vulkan::cppm ALIAS VulkanCppModule)
#
#target_compile_definitions(VulkanCppModule PUBLIC
# VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1
# VULKAN_HPP_NO_STRUCT_CONSTRUCTORS=1
# VULKAN_HPP_NO_STD_MODULE=1
#)
#
#target_include_directories(VulkanCppModule PRIVATE "${Vulkan_INCLUDE_DIR}")
#
#target_link_libraries(VulkanCppModule PUBLIC Vulkan::Vulkan)
#
#target_sources(VulkanCppModule
# PUBLIC
# FILE_SET cxx_modules TYPE CXX_MODULES
# BASE_DIRS "${Vulkan_INCLUDE_DIR}"
# FILES "${Vulkan_INCLUDE_DIR}/vulkan/vulkan.cppm"
#)
#
#if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.28" AND VULKAN_HEADERS_ENABLE_MODULE AND COMPILER_SUPPORTS_CXX_MODULES)
# add_library(Vulkan-Module)
# add_library(Vulkan::VulkanHppModule ALIAS Vulkan-Module)
# target_sources(Vulkan-Module
# PUBLIC
# FILE_SET module
# TYPE CXX_MODULES
# BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include"
# FILES "${CMAKE_CURRENT_SOURCE_DIR}/include/vulkan/vulkan.cppm"
# )
# target_compile_features(Vulkan-Module PUBLIC cxx_std_20)
# target_link_libraries(Vulkan-Module PUBLIC Vulkan-Headers)
#endif ()
message("Vulkan include: ${Vulkan_INCLUDE_DIR}")

1
dependencies/catch2 vendored

Submodule dependencies/catch2 deleted from 05e10dfccc

Submodule dependencies/shaderc deleted from ff84893dd5

View File

@@ -1,9 +1,8 @@
add_subdirectory(vma)
add_subdirectory(engine)
add_subdirectory(renderer)
add_subdirectory(objectloaders)
add_subdirectory(editor)
add_subdirectory(tests)
#add_subdirectory(editor)
#add_subdirectory(engine)
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)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -2,6 +2,8 @@
set(CMAKE_CXX_STANDARD 23)
include(dependencies/imgui)
target_compile_definitions(FGLEngine PUBLIC VULKAN_HPP_FLAGS_MASK_TYPE_AS_PUBLIC)
file(GLOB_RECURSE SOURCE_FILES
@@ -14,4 +16,4 @@ AddFGLExecutable(TitorEditor ${CMAKE_CURRENT_SOURCE_DIR}/src)
target_link_libraries(TitorEditor PRIVATE FGLEngine)
target_compile_definitions(TitorEditor PUBLIC TITOR_EDITOR)
target_compile_features(TitorEditor PRIVATE cxx_std_23)
target_link_libraries(TitorEditor PRIVATE glfw ImGui)
target_link_libraries(TitorEditor PRIVATE glfw ImGui X11)

View File

@@ -7,5 +7,4 @@
namespace fgl::engine
{
}

View File

@@ -28,7 +28,7 @@ namespace fgl::engine::components
}
}
TransformComponent::TransformComponent()
TransformComponent::TransformComponent() : m_transform()
{}
TransformComponent::TransformComponent( const WorldTransform& transform ) : m_transform( transform )

View File

@@ -7,6 +7,7 @@
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wuseless-cast"
#include <backends/imgui_impl_glfw.h>
#include <backends/imgui_impl_vulkan.h>
@@ -50,26 +51,28 @@ namespace fgl::editor
ImGui_ImplGlfw_InitForVulkan( window.window(), true );
ImGui_ImplVulkan_InitInfo init_info {
.ApiVersion = VK_API_VERSION_1_4,
.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,
.DescriptorPoolSize = 0,
.MinImageCount = 2,
.ImageCount = 2,
.MSAASamples = VK_SAMPLE_COUNT_1_BIT,
.PipelineCache = VK_NULL_HANDLE,
.RenderPass = VK_NULL_HANDLE,
.Subpass = 0,
.MSAASamples = VK_SAMPLE_COUNT_1_BIT,
.UseDynamicRendering = VK_TRUE,
.PipelineRenderingCreateInfo = pipeline_info,
.Allocator = VK_NULL_HANDLE,
.CheckVkResultFn = VK_NULL_HANDLE,
.MinAllocationSize = 1024 * 1024
.MinAllocationSize = 1024 * 1024,
};
ImGui_ImplVulkan_Init( &init_info );

View File

@@ -2,7 +2,7 @@
// Created by kj16609 on 7/23/24.
//
#include "engine/camera/Camera.hpp"
#include "engine/camera/RenderCamera.hpp"
#include <cassert>
@@ -13,7 +13,7 @@
namespace fgl::engine::gui
{
void handleCameraInput( const FrameInfo& info, Camera& camera )
void handleCameraInput( const FrameInfo& info, RenderCamera& camera )
{
const auto delta_time { info.delta_time };
@@ -104,7 +104,7 @@ namespace fgl::engine::gui
assert( camera_ptr );
Camera& camera { *camera_ptr };
RenderCamera& camera { *camera_ptr };
std::string name {};

View File

@@ -8,6 +8,7 @@
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wuseless-cast"
#include <imgui_internal.h> // Included for DockBuilder since it's not exposed yet
#pragma GCC diagnostic pop
@@ -15,7 +16,6 @@
#include "FileBrowser.hpp"
#include "engine/assets/model/Model.hpp"
#include "engine/debug/DEBUG_NAMES.hpp"
#include "engine/descriptors/DescriptorPool.hpp"
#include "engine/rendering/Renderer.hpp"
#include "gui_window_names.hpp"
#include "safe_include.hpp"
@@ -96,9 +96,9 @@ namespace fgl::engine::gui
// ImGui::PopStyleVar();
}
static std::weak_ptr< GameObject > selected_object {};
static std::weak_ptr< GameObject > SELECTED_OBJECT {};
void itterateGameObjectNode( FrameInfo& info, OctTreeNode& node )
void itterateGameObjectNode( [[maybe_unused]] FrameInfo& info, [[maybe_unused]] OctTreeNode& node )
{
/*
if ( node.isLeaf() )
@@ -161,7 +161,7 @@ namespace fgl::engine::gui
if ( ImGui::Selectable( object->getName().c_str() ) )
{
selected_object = object;
SELECTED_OBJECT = object;
}
ImGui::PopID();
@@ -194,13 +194,13 @@ namespace fgl::engine::gui
ZoneScoped;
ImGui::Begin( ENTITY_INFO_NAME );
if ( selected_object.expired() )
if ( SELECTED_OBJECT.expired() )
{
ImGui::End();
return;
}
const auto object { selected_object.lock() };
const auto object { SELECTED_OBJECT.lock() };
drawObject( *object );
drawComponentsList( *object );

View File

@@ -31,6 +31,8 @@ namespace fgl::engine::gui
void drawComponentsList( GameObject& game_object );
void drawSelectedComponent();
void drawShadowmaps( const FrameInfo& info );
void drawCameraOutputs( FrameInfo& info );
void drawStats( const FrameInfo& info );

View File

@@ -2,13 +2,14 @@
#include <vulkan/vulkan.hpp>
#include "assets/transfer/TransferManager.hpp"
#include "camera/CameraManager.hpp"
#include "camera/ShadowMap.hpp"
#include "core.hpp"
#include "engine/debug/profiling/counters.hpp"
#include "engine/debug/timing/FlameGraph.hpp"
#include "engine/flags.hpp"
#include "engine/math/literals/size.hpp"
#include "engine/memory/buffers/BufferHandle.hpp"
#include "memory/buffers/BufferHandle.hpp"
#include "engine/memory/buffers/VulkanBuffer.hpp"
#include "safe_include.hpp"
namespace fgl::engine::gui
@@ -123,6 +124,38 @@ namespace fgl::engine::gui
}
}
void drawShadowmaps( const FrameInfo& info )
{
ImGui::Begin( "Shadowmaps" );
static std::unordered_map< int*, std::vector< Texture > > textures {};
bool move_sun { false };
move_sun = ImGui::Button( "Move sun shadowmap to camera" );
for ( const auto& weak_shadowmap : getShadowmaps() )
{
if ( weak_shadowmap.expired() ) continue;
auto shadowmap_ptr { weak_shadowmap.lock() };
ShadowMap& shadowmap { *shadowmap_ptr };
// if ( move_sun )
{
shadowmap.m_camera->moveTo( CameraManager::instance().getPrimary()->getTransform() );
}
const FrameIndex frame_index { info.in_flight_idx };
// camera.getCompositeSwapchain().m_gbuffer_target[ frame_index ]->drawImGui( target_size );
shadowmap.m_swapchain->depthTexture( frame_index )->drawImGui();
}
ImGui::End();
}
void drawStats( const FrameInfo& info )
{
ImGui::Begin( "Stats" );
@@ -143,6 +176,11 @@ namespace fgl::engine::gui
debug::timing::render();
}
if ( ImGui::CollapsingHeader( "Shadowmaps" ) )
{
drawShadowmaps( info );
}
if ( ImGui::Button( "Reload shaders" ) )
{
flags::triggerShaderReload();

View File

@@ -7,7 +7,7 @@
#include "engine/FrameInfo.hpp"
#include "engine/assets/model/Model.hpp"
#include "engine/assets/model/builders/SceneBuilder.hpp"
#include "engine/camera/Camera.hpp"
#include "engine/camera/RenderCamera.hpp"
#include "engine/filesystem/scanner/FileScanner.hpp"
#include "engine/filesystem/types.hpp"
#include "engine/rendering/PresentSwapChain.hpp"
@@ -126,7 +126,7 @@ namespace fgl::engine::gui
inline void drawConfigBar(
[[maybe_unused]] const FrameInfo& info,
[[maybe_unused]] const Camera& camera,
[[maybe_unused]] const RenderCamera& camera,
[[maybe_unused]] const FrameIndex frame_index,
std::uint_fast8_t& current )
{
@@ -167,7 +167,7 @@ namespace fgl::engine::gui
}
}
void drawRenderingOutputs( FrameInfo& info, const Camera& camera )
void drawRenderingOutputs( FrameInfo& info, const RenderCamera& camera )
{
ZoneScoped;
const auto frame_index { info.in_flight_idx };

View File

@@ -7,12 +7,12 @@
namespace fgl::engine
{
struct FrameInfo;
class Camera;
class RenderCamera;
} // namespace fgl::engine
namespace fgl::engine::gui
{
void drawRenderingOutputs( FrameInfo& info, const Camera& camera );
void drawRenderingOutputs( FrameInfo& info, const RenderCamera& camera );
} // namespace fgl::engine::gui

View File

@@ -2,6 +2,7 @@
// Created by kj16609 on 6/5/24.
//
// ReSharper disable CppDFAInfiniteRecursion
// ReSharper disable CppInconsistentNaming
// ReSharper disable CppZeroConstantCanBeReplacedWithNullptr
@@ -12,8 +13,6 @@
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wconversion"
// clang-format off
#include <imgui.h>
#include <imgui/misc/cpp/imgui_stdlib.h>
// clang-format on
#pragma GCC diagnostic pop

View File

@@ -23,20 +23,22 @@ int main()
// major 7-bit, bits 28-22
// minor, 10 bit, 21-12
// patch, 12 bit, 10-0
// clang-format off
constexpr std::uint64_t PATCH_BITMASK { 0b00000000000000000000111111111111 };
constexpr std::uint64_t MINOR_BITMASK { 0b00000000001111111111000000000000 };
constexpr std::uint64_t MAJOR_BITMASK { 0b00011111110000000000000000000000 };
constexpr std::uint64_t VARIANT_BITMASK { 0b11100000000000000000000000000000 };
struct VersionBits
{
unsigned int patch:12;
unsigned int minor:10;
unsigned int major:7;
unsigned int variant:3;
};
const auto patch { ( version & PATCH_BITMASK ) >> 0};
const auto minor { ( version & MINOR_BITMASK ) >> 10};
const auto major { ( version & MAJOR_BITMASK ) >> (10 + 12)};
[[maybe_unused]] const auto variant { ( version & VARIANT_BITMASK ) >> (10 + 12 + 7) };
const auto* version_ptr { reinterpret_cast< const VersionBits* >( &version ) };
// clang-format on
log::debug( "Vulkan instance version: {}.{}.{}.{}", major, minor, patch, minor );
log::debug(
"Vulkan instance version: {}.{}.{}.{}",
version_ptr->major,
version_ptr->minor,
version_ptr->patch,
version_ptr->variant );
try
{

View File

@@ -1,6 +1,6 @@
file(GLOB_RECURSE CPP_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/**.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/**.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/**.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/**.hpp"
)
AddFGLLibrary(FGLEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
@@ -11,36 +11,27 @@ target_compile_definitions(FGLEngine PUBLIC VULKAN_HPP_FLAGS_MASK_TYPE_AS_PUBLIC
target_link_libraries(FGLEngine PUBLIC stdc++exp)
include(dependencies/spdlog)
include(dependencies/imgui)
target_link_libraries(FGLEngine PUBLIC Vulkan::Vulkan glm ImGui FGLLoader spdlog slang)
target_link_libraries(FGLEngine PUBLIC glfw Tracy::TracyClient VMA)
target_link_libraries(FGLEngine PUBLIC Vulkan::Vulkan ImGui FGLLoader spdlog slang glm)
target_include_directories(FGLEngine SYSTEM PUBLIC ${GLM_INCLUDE_DIRS})
target_link_libraries(FGLEngine PUBLIC glfw Tracy::TracyClient)
target_include_directories(FGLEngine PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
target_compile_features(FGLEngine PUBLIC cxx_std_23)
string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_UPPER_BUILD_TYPE)
if (NOT DEFINED FGL_ENABLE_IMGUI AND CMAKE_UPPER_BUILD_TYPE STREQUAL "DEBUG")
set(FGL_ENABLE_IMGUI 1)
set(FGL_ENABLE_IMGUI 1)
endif ()
message("-- FGL_ENABLE_IMGUI: ${FGL_ENABLE_IMGUI}")
if (FGL_ENABLE_IMGUI)
target_compile_definitions(FGLEngine PUBLIC ENABLE_IMGUI=1)
target_compile_definitions(FGLEngine PUBLIC ENABLE_IMGUI_DRAWERS=1)
else ()
target_compile_definitions(FGLEngine PUBLIC ENABLE_IMGUI=0)
target_compile_definitions(FGLEngine PUBLIC ENABLE_IMGUI_DRAWERS=0)
endif ()
if (DEFINED FGL_ENABLE_TESTS AND FGL_ENABLE_TESTS)
target_compile_definitions(FGLEngine PUBLIC FGL_TESTS=1)
target_compile_definitions(FGLEngine PUBLIC FGL_ENABLE_TEST_ASSERT=1)
target_link_libraries(FGLEngine PUBLIC Catch2::Catch2)
target_compile_definitions(FGLEngine PUBLIC FGL_TESTS=1)
target_compile_definitions(FGLEngine PUBLIC FGL_ENABLE_TEST_ASSERT=1)
else ()
target_compile_definitions(FGLEngine PUBLIC FGL_TESTS=0)
target_compile_definitions(FGLEngine PUBLIC FGL_ENABLE_TEST_ASSERT=0)
target_compile_definitions(FGLEngine PUBLIC FGL_TESTS=0)
target_compile_definitions(FGLEngine PUBLIC FGL_ENABLE_TEST_ASSERT=0)
endif ()
# Enable tracking for buffers, I need to find some way to disable this when trying to link
@@ -52,7 +43,7 @@ target_compile_definitions(FGLEngine PUBLIC TRACK_BUFFERS)
target_compile_definitions(FGLEngine PUBLIC GLM_FORCE_RADIANS GLM_FORCE_DEPTH_ZERO_TO_ONE)
if (DEFINED FGL_ENABLE_CALIBRATED_PROFILING AND FGL_ENABLE_CALIBRATED_PROFILING)
target_compile_definitions(FGLEngine PUBLIC ENABLE_CALIBRATED_PROFILING=1)
target_compile_definitions(FGLEngine PUBLIC ENABLE_CALIBRATED_PROFILING=1)
else ()
target_compile_definitions(FGLEngine PUBLIC ENABLE_CALIBRATED_PROFILING=0)
target_compile_definitions(FGLEngine PUBLIC ENABLE_CALIBRATED_PROFILING=0)
endif ()

View File

@@ -11,69 +11,41 @@
#include <iostream>
#include "KeyboardMovementController.hpp"
#include "camera/Camera.hpp"
#include "camera/CameraManager.hpp"
#include "camera/GBufferRenderer.hpp"
#include "camera/RenderCamera.hpp"
#include "camera/ShadowMap.hpp"
#include "debug/timing/FlameGraph.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 "memory/buffers/BufferHandle.hpp"
#include "memory/buffers/VulkanBuffer.hpp"
#include "systems/RenderGraph.hpp"
namespace fgl::engine
{
constexpr float MAX_DELTA_TIME { 0.5 };
inline static EngineContext* instance { nullptr };
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > createDrawCommandsDescriptors(
PerFrameArray< DeviceVector< vk::DrawIndexedIndirectCommand > >& gpu_draw_commands,
PerFrameArray< DeviceVector< InstanceRenderInfo > >& per_vertex_info )
{
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > descriptors {};
for ( std::uint16_t i = 0; i < gpu_draw_commands.size(); ++i )
{
auto& command_buffer { gpu_draw_commands[ i ] };
auto& per_vertex_buffer { per_vertex_info[ i ] };
auto descriptor { COMMANDS_SET.create() };
descriptor->bindStorageBuffer( 0, command_buffer );
descriptor->bindStorageBuffer( 1, per_vertex_buffer );
descriptor->update();
descriptor->setName( "Command Buffer + Vertex Buffer" );
descriptors[ i ] = std::move( descriptor );
}
return descriptors;
}
EngineContext::EngineContext() :
m_ubo_buffer_pool( 1_MiB, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostVisible ),
m_draw_parameter_pool(
4_MiB,
vk::BufferUsageFlagBits::eIndirectBuffer | vk::BufferUsageFlagBits::eStorageBuffer,
vk::MemoryPropertyFlagBits::eDeviceLocal | vk::MemoryPropertyFlagBits::eHostVisible ),
m_gpu_draw_commands(
constructPerFrame< DeviceVector< vk::DrawIndexedIndirectCommand > >( m_draw_parameter_pool ) ),
m_per_vertex_infos( m_model_buffers.m_generated_instance_info ),
m_gpu_draw_cmds_desc( createDrawCommandsDescriptors( m_gpu_draw_commands, m_per_vertex_infos ) ),
m_delta_time( 0.0 )
m_delta_time( 0.0 ),
m_camera_manager(),
m_sun( nullptr )
{
ZoneScoped;
using namespace fgl::literals::size_literals;
instance = this;
m_camera_manager.createPrimary();
m_sun = std::make_unique< Sun >();
// memory::TransferManager::createInstance( device, 128_MiB );
m_draw_parameter_pool->setDebugName( "Draw parameter pool" );
}
static Average< float, 60 * 15 > rolling_ms_average;
void EngineContext::processInput()
{
auto timer = debug::timing::push( "Process Inputs" );
@@ -116,15 +88,27 @@ namespace fgl::engine
auto sh_camera { current_camera_ptr.lock() };
Camera& current_camera { *sh_camera };
RenderCamera& current_camera { *sh_camera };
current_camera.pass( frame_info );
}
for ( auto& shadow_map : getShadowmaps() )
{
if ( shadow_map.expired() ) continue;
auto shadowmap { shadow_map.lock() };
shadowmap->pass( frame_info );
}
}
void EngineContext::renderFrame()
{
ZoneScoped;
RenderGraph graph {};
if ( auto command_buffers_o = m_renderer.beginFrame(); command_buffers_o.has_value() )
{
const auto timer = debug::timing::push( "Render Frame" );
@@ -136,20 +120,19 @@ namespace fgl::engine
// Begin by getting every single instance ready.
DeviceVector< PrimitiveInstanceInfo >& instances { m_model_buffers.m_primitive_instances.vec() };
m_gpu_draw_commands[ in_flight_idx ].resize( instances.size() );
m_model_buffers.m_generated_instance_info[ in_flight_idx ].resize( instances.size() );
FrameInfo frame_info { in_flight_idx,
present_idx,
m_delta_time,
graph,
command_buffers,
nullptr, // Camera
m_camera_manager.getCameras(),
m_renderer.getCurrentTracyCTX(),
*m_model_buffers.m_primitives_desc,
*m_model_buffers.m_instances_desc,
*m_gpu_draw_cmds_desc[ in_flight_idx ],
m_gpu_draw_commands[ in_flight_idx ],
instances,
// *m_gpu_draw_cmds_desc[ in_flight_idx ],
// m_gpu_draw_commands[ in_flight_idx ],
m_game_objects,
this->m_renderer.getSwapChain() };

View File

@@ -12,6 +12,7 @@
#include "engine/assets/transfer/TransferManager.hpp"
#include "engine/math/literals/size.hpp"
#include "engine/rendering/Renderer.hpp"
#include "lighting/lights/Sun.hpp"
#include "scene/World.hpp"
#include "systems/composition/GuiSystem.hpp"
@@ -67,9 +68,6 @@ namespace fgl::engine
// Memory pool for shader uniforms.
memory::Buffer m_ubo_buffer_pool;
// Memory pool for matrix info and draw parameters
memory::Buffer m_draw_parameter_pool;
public:
std::vector< std::shared_ptr< GameObject > > m_game_objects {};
@@ -78,22 +76,18 @@ namespace fgl::engine
private:
PerFrameArray< DeviceVector< vk::DrawIndexedIndirectCommand > > m_gpu_draw_commands;
//TODO: Outright remove this. Or the one in model buffers.
PerFrameArray< DeviceVector< InstanceRenderInfo > >& m_per_vertex_infos;
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > m_gpu_draw_cmds_desc;
MaterialManager m_material_manager {};
CameraManager m_camera_manager {};
memory::TransferManager m_transfer_manager { m_device, 512_MiB };
std::chrono::time_point< Clock > m_last_tick { Clock::now() };
DeltaTime m_delta_time;
CameraManager m_camera_manager {};
// World m_world;
std::unique_ptr< Sun > m_sun;
public:
// ModelManager& models() { return m_model_manager; }

View File

@@ -1,86 +0,0 @@
//
// Created by kj16609 on 3/1/24.
//
#pragma once
#define FGL_DELETE_DEFAULT_CTOR( ClassName ) ClassName() = delete;
#define FGL_DELETE_COPY_ASSIGN( ClassName ) ClassName& operator=( const ClassName& ) = delete;
#define FGL_DELETE_COPY_CTOR( ClassName ) ClassName( const ClassName& ) = delete;
#define FGL_DELETE_MOVE_ASSIGN( ClassName ) ClassName& operator=( ClassName&& ) = delete;
#define FGL_DELETE_MOVE_CTOR( ClassName ) ClassName( ClassName&& ) = delete;
#define FGL_DELETE_COPY( ClassName ) FGL_DELETE_COPY_CTOR( ClassName ) FGL_DELETE_COPY_ASSIGN( ClassName )
#define FGL_DELETE_MOVE( ClassName ) FGL_DELETE_MOVE_CTOR( ClassName ) FGL_DELETE_MOVE_ASSIGN( ClassName )
#define FGL_DELETE_ALL_RO5( ClassName ) \
FGL_DELETE_DEFAULT_CTOR( ClassName ) FGL_DELETE_COPY( ClassName ) FGL_DELETE_MOVE( ClassName )
#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 ) [[nodiscard]] ClassName( const ClassName& ) = default;
#define FGL_DEFAULT_MOVE_ASSIGN( ClassName ) ClassName& operator=( ClassName&& ) = default;
#define FGL_DEFAULT_MOVE_CTOR( ClassName ) [[nodiscard]] 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]]
#define FGL_COLD [[gnu::cold]]
#define FGL_FLATTEN_HOT FGL_FLATTEN FGL_HOT
#define FGL_FORCE_INLINE [[gnu::always_inline]]
#define FGL_FORCE_INLINE_FLATTEN FGL_FLATTEN FGL_FORCE_INLINE
#ifndef NDEBUG
#define FGL_ASSUME( ... ) \
FGL_ASSERT( ( __VA_ARGS__ ), "FGL_ASSUME: Check failed!" ); \
[[gnu::assume( __VA_ARGS__ )]];
#else
#define FGL_ASSUME( ... ) [[gnu::assume( __VA_ARGS__ )]]
#endif
#define FGL_ALIGN( bytesize ) [[gnu::alligned( bitsize )]]
#define FGL_FUNC_CLEANUP( func ) [[gnu::cleanup( func )]]
//! Warns if the variable is used as a string (strlen)
#define FGL_NONSTRING_DATA [[gnu::nonstring]]
//! Warns if the structure field is not alligned with a set number of bytes
#define FGL_STRICT_ALIGNMENT( bytesize ) [[gnu::warn_if_not_aligned( bytesize )]]
#ifndef NDEBUG
#include <format>
#include <stdexcept>
#pragma GCC diagnostic push
// Placed here to prevent strict warnings from preventing compilation, This is intentional.
#pragma GCC diagnostic ignored "-Wterminate"
#define FGL_ASSERT( test, msg ) \
if ( !( test ) ) \
throw std::runtime_error( std::format( "{}:{}:{}: {}", __FILE__, __LINE__, __PRETTY_FUNCTION__, msg ) );
#pragma GCC diagnostic pop
#else
#define FGL_ASSERT( test, msg )
#endif
#define FGL_UNIMPLEMENTED() FGL_ASSERT( false, "unimplemented" );
#ifndef NDEBUG
#include <utility>
#define FGL_UNREACHABLE() \
FGL_ASSERT( false, "Should have been unreachable!" ); \
std::unreachable()
#else
#define FGL_UNREACHABLE() std::unreachable()
#endif
#define FGL_NOTNAN( value ) FGL_ASSERT( !std::isnan( value ), "Value is NaN!" )
#define FGL_NOTNANVEC3( vec3 ) \
FGL_ASSERT( !std::isnan( ( vec3 ).x ), "X value was NaN!" ); \
FGL_ASSERT( !std::isnan( ( vec3 ).y ), "Y value was NaN!" ); \
FGL_ASSERT( !std::isnan( ( vec3 ).z ), "Z value was NaN!" )
#define FGL_TODO() throw std::runtime_error( std::format( "TODO: {}:{}:{}", __FILE__, __LINE__, __PRETTY_FUNCTION__ ) );

View File

@@ -4,20 +4,21 @@
#include "FrameInfo.hpp"
#include "camera/Camera.hpp"
#include "camera/GBufferSwapchain.hpp"
#include "camera/RenderCamera.hpp"
namespace fgl::engine
{
descriptors::DescriptorSet& FrameInfo::getGBufferDescriptor() const
{
return camera->getSwapchain().getGBufferDescriptor( in_flight_idx );
}
// descriptors::DescriptorSet& FrameInfo::getGBufferDescriptor() const
// {
// return camera->getSwapchain().getGBufferDescriptor( in_flight_idx );
// }
descriptors::DescriptorSet& FrameInfo::getCameraDescriptor() const
{
return camera->getDescriptor( in_flight_idx );
FGL_ASSERT( camera != nullptr, "Camera not set" );
return *camera->m_camera_info_descriptors[ in_flight_idx ];
}
void FrameInfo::bindCamera( [[maybe_unused]] Pipeline& pipeline )

View File

@@ -21,6 +21,9 @@
namespace fgl::engine
{
class RenderGraph;
class CameraViewpoint;
struct PrimitiveRenderInfo;
struct PrimitiveInstanceInfo;
class Pipeline;
@@ -31,7 +34,7 @@ namespace fgl::engine
}
class PresentSwapChain;
class Camera;
class RenderCamera;
struct PointLight
{
@@ -78,12 +81,13 @@ namespace fgl::engine
FrameIndex in_flight_idx;
PresentIndex present_idx;
DeltaTime delta_time;
RenderGraph& graph;
CommandBuffers& command_buffer;
Camera* camera { nullptr };
CameraViewpoint* camera { nullptr };
std::vector< std::weak_ptr< Camera > >& m_camera_list;
std::vector< std::weak_ptr< RenderCamera > >& m_camera_list;
// descriptors::DescriptorSet& global_descriptor_set;
// OctTreeNode& game_objects;
@@ -91,16 +95,17 @@ namespace fgl::engine
descriptors::DescriptorSet& m_primitives_desc;
descriptors::DescriptorSet& m_instances_desc;
descriptors::DescriptorSet& m_command_buffer_desc;
DeviceVector< PrimitiveInstanceInfo >& instances;
// descriptors::DescriptorSet& m_command_buffer_desc;
// out for rendering process
//! Populated commands buffer by the culling pass
DeviceVector< vk::DrawIndexedIndirectCommand >& m_commands;
// DeviceVector< vk::DrawIndexedIndirectCommand >& m_commands;
std::vector< std::shared_ptr< GameObject > >& m_game_objects;
// descriptors::DescriptorSet& gui_input_descriptor;
[[nodiscard]] descriptors::DescriptorSet& getGBufferDescriptor() const;
// [[nodiscard]] descriptors::DescriptorSet& getGBufferDescriptor() const;
[[nodiscard]] descriptors::DescriptorSet& getCameraDescriptor() const;
PresentSwapChain& swap_chain;

View File

@@ -7,6 +7,7 @@
#include <tracy/Tracy.hpp>
#include <memory>
#include <mutex>
#include <unordered_map>
namespace fgl::engine

View File

@@ -6,7 +6,7 @@
#include "engine/debug/logging/logging.hpp"
#include "engine/math/literals/size.hpp"
#include "material/Material.hpp"
#include "memory/buffers/BufferHandle.hpp"
#include "memory/buffers/VulkanBuffer.hpp"
namespace fgl::engine
{

View File

@@ -3,7 +3,7 @@
//
#pragma once
#include "engine/memory/buffers/BufferHandle.hpp"
#include "engine/memory/buffers/VulkanBuffer.hpp"
#include "material/Material.hpp"
#include "memory/buffers/vector/DeviceVector.hpp"

View File

@@ -19,6 +19,9 @@ namespace fgl::engine
return ptr;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum"
constexpr vk::AccessFlags getAccessFlags( const vk::ImageLayout layout )
{
switch ( layout )
@@ -27,13 +30,8 @@ namespace fgl::engine
FGL_UNREACHABLE();
case vk::ImageLayout::eUndefined:
return vk::AccessFlagBits::eNone;
case vk::ImageLayout::eGeneral:
break;
case vk::ImageLayout::eColorAttachmentOptimal:
return vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite;
break;
case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
break;
case vk::ImageLayout::eShaderReadOnlyOptimal:
return vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eInputAttachmentRead;
case vk::ImageLayout::eTransferSrcOptimal:
@@ -42,50 +40,18 @@ namespace fgl::engine
return vk::AccessFlagBits::eTransferWrite;
case vk::ImageLayout::ePreinitialized:
return vk::AccessFlagBits::eHostWrite;
case vk::ImageLayout::eDepthReadOnlyStencilAttachmentOptimal:
break;
case vk::ImageLayout::eDepthAttachmentStencilReadOnlyOptimal:
break;
case vk::ImageLayout::eStencilAttachmentOptimal:
break;
case vk::ImageLayout::eDepthStencilAttachmentOptimal:
[[fallthrough]];
case vk::ImageLayout::eDepthReadOnlyOptimal:
[[fallthrough]];
case vk::ImageLayout::eDepthAttachmentOptimal:
return vk::AccessFlagBits::eDepthStencilAttachmentWrite;
case vk::ImageLayout::eStencilReadOnlyOptimal:
break;
case vk::ImageLayout::eReadOnlyOptimal:
break;
case vk::ImageLayout::eAttachmentOptimal:
break;
case vk::ImageLayout::ePresentSrcKHR:
return vk::AccessFlags( 0 );
case vk::ImageLayout::eVideoDecodeDstKHR:
break;
case vk::ImageLayout::eVideoDecodeSrcKHR:
break;
case vk::ImageLayout::eVideoDecodeDpbKHR:
break;
case vk::ImageLayout::eSharedPresentKHR:
break;
case vk::ImageLayout::eFragmentDensityMapOptimalEXT:
break;
case vk::ImageLayout::eFragmentShadingRateAttachmentOptimalKHR:
return vk::AccessFlagBits::eFragmentShadingRateAttachmentReadKHR;
case vk::ImageLayout::eRenderingLocalReadKHR:
return vk::AccessFlagBits::eColorAttachmentWrite;
case vk::ImageLayout::eVideoEncodeDstKHR:
break;
case vk::ImageLayout::eVideoEncodeSrcKHR:
break;
case vk::ImageLayout::eVideoEncodeDpbKHR:
break;
case vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT:
break;
case vk::ImageLayout::eVideoEncodeQuantizationMapKHR:
break;
}
FGL_UNREACHABLE();
@@ -99,69 +65,23 @@ namespace fgl::engine
FGL_UNREACHABLE();
case vk::ImageLayout::eUndefined:
return vk::PipelineStageFlagBits::eTopOfPipe;
case vk::ImageLayout::eGeneral:
break;
case vk::ImageLayout::eColorAttachmentOptimal:
return vk::PipelineStageFlagBits::eColorAttachmentOutput;
case vk::ImageLayout::eDepthStencilAttachmentOptimal:
break;
case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
break;
case vk::ImageLayout::eShaderReadOnlyOptimal:
return vk::PipelineStageFlagBits::eVertexShader | vk::PipelineStageFlagBits::eFragmentShader;
case vk::ImageLayout::eTransferSrcOptimal:
[[fallthrough]];
case vk::ImageLayout::eTransferDstOptimal:
return vk::PipelineStageFlagBits::eTransfer;
case vk::ImageLayout::ePreinitialized:
break;
case vk::ImageLayout::eDepthReadOnlyStencilAttachmentOptimal:
break;
case vk::ImageLayout::eDepthAttachmentStencilReadOnlyOptimal:
break;
case vk::ImageLayout::eDepthAttachmentOptimal:
break;
case vk::ImageLayout::eDepthReadOnlyOptimal:
break;
case vk::ImageLayout::eStencilAttachmentOptimal:
break;
case vk::ImageLayout::eStencilReadOnlyOptimal:
break;
case vk::ImageLayout::eReadOnlyOptimal:
break;
case vk::ImageLayout::eAttachmentOptimal:
break;
case vk::ImageLayout::ePresentSrcKHR:
return vk::PipelineStageFlagBits::eBottomOfPipe;
case vk::ImageLayout::eVideoDecodeDstKHR:
break;
case vk::ImageLayout::eVideoDecodeSrcKHR:
break;
case vk::ImageLayout::eVideoDecodeDpbKHR:
break;
case vk::ImageLayout::eSharedPresentKHR:
break;
case vk::ImageLayout::eFragmentDensityMapOptimalEXT:
break;
case vk::ImageLayout::eFragmentShadingRateAttachmentOptimalKHR:
break;
case vk::ImageLayout::eRenderingLocalReadKHR:
break;
case vk::ImageLayout::eVideoEncodeDstKHR:
break;
case vk::ImageLayout::eVideoEncodeSrcKHR:
break;
case vk::ImageLayout::eVideoEncodeDpbKHR:
break;
case vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT:
break;
case vk::ImageLayout::eVideoEncodeQuantizationMapKHR:
break;
}
FGL_UNREACHABLE();
}
#pragma GCC diagnostic pop
vk::ImageMemoryBarrier Image::transitionTo(
const vk::ImageLayout old_layout,
const vk::ImageLayout new_layout,

View File

@@ -60,7 +60,7 @@ namespace fgl::engine
[[nodiscard]] const vk::Extent2D& getExtent() const { return m_extent; }
[[nodiscard]] std::shared_ptr< ImageView > getView( Sampler sampler = {});
[[nodiscard]] std::shared_ptr< ImageView > getView( Sampler sampler = {} );
[[nodiscard]] vk::ImageMemoryBarrier transitionTo(
vk::ImageLayout old_layout, vk::ImageLayout new_layout, const vk::ImageSubresourceRange& range ) const;

View File

@@ -10,7 +10,7 @@
#include "engine/debug/logging/logging.hpp"
#include "engine/rendering/devices/Device.hpp"
#include "vma/vma_impl.hpp"
#include "memory/vma_impl.hpp"
#include "vulkan/vulkan.hpp"
namespace fgl::engine

View File

@@ -56,6 +56,23 @@ namespace fgl::engine
m_sampler( createSampler( min_filter, mag_filter, mipmap_mode, sampler_wrap_u, sampler_wrap_v, sampler_wrap_w ) )
{}
Sampler::Sampler(
const vk::Filter min_filter,
const vk::Filter mag_filter,
const vk::SamplerMipmapMode mipmap_mode,
const vk::SamplerAddressMode sampler_wrap_u,
const vk::SamplerAddressMode sampler_wrap_v ) :
Sampler( min_filter, mag_filter, mipmap_mode, sampler_wrap_u, sampler_wrap_v, sampler_wrap_v )
{}
Sampler::Sampler(
const vk::Filter min_filter,
const vk::Filter mag_filter,
const vk::SamplerMipmapMode mipmap_mode,
const vk::SamplerAddressMode sampler_wrap_u ) :
Sampler( min_filter, mag_filter, mipmap_mode, sampler_wrap_u, sampler_wrap_u, sampler_wrap_u )
{}
namespace gl
{
vk::Filter filterToVk( const int value )

View File

@@ -18,7 +18,7 @@ namespace fgl::engine
public:
FGL_DELETE_COPY( Sampler )
FGL_DELETE_COPY( Sampler );
Sampler() :
Sampler(
@@ -36,22 +36,18 @@ namespace fgl::engine
vk::SamplerAddressMode sampler_wrap_v,
vk::SamplerAddressMode sampler_wrap_w );
FGL_FORCE_INLINE_FLATTEN Sampler(
const vk::Filter min_filter,
const vk::Filter mag_filter,
const vk::SamplerMipmapMode mipmap_mode,
const vk::SamplerAddressMode sampler_wrap_u,
const vk::SamplerAddressMode sampler_wrap_v ) :
Sampler( min_filter, mag_filter, mipmap_mode, sampler_wrap_u, sampler_wrap_v, sampler_wrap_v )
{}
Sampler(
vk::Filter min_filter,
vk::Filter mag_filter,
vk::SamplerMipmapMode mipmap_mode,
vk::SamplerAddressMode sampler_wrap_u,
vk::SamplerAddressMode sampler_wrap_v );
FGL_FORCE_INLINE_FLATTEN Sampler(
const vk::Filter min_filter,
const vk::Filter mag_filter,
const vk::SamplerMipmapMode mipmap_mode,
const vk::SamplerAddressMode sampler_wrap_u ) :
Sampler( min_filter, mag_filter, mipmap_mode, sampler_wrap_u, sampler_wrap_u, sampler_wrap_u )
{}
Sampler(
vk::Filter min_filter,
vk::Filter mag_filter,
vk::SamplerMipmapMode mipmap_mode,
vk::SamplerAddressMode sampler_wrap_u );
//TODO: This should be moved to favor a single sampler when possible, Making a duplicate sampler is not required.
//TODO: Singleton

View File

@@ -15,14 +15,14 @@ namespace fgl::engine
inline static IDPool< MaterialID > material_id_counter { 1 };
TextureID getTexID( const std::shared_ptr< Texture >& tex )
{
if ( tex ) return tex->getID();
return constants::INVALID_TEXTURE_ID;
}
void MaterialProperties::writeData( DeviceMaterialData& data ) const
{
auto getTexID = []( const std::shared_ptr< Texture >& tex )
{
if ( tex ) return tex->getID();
return constants::INVALID_TEXTURE_ID;
};
// PBR
data.color.color_texture_id = getTexID( m_pbr.m_color_tex );
data.color.color_factors = m_pbr.m_color_factors;
@@ -53,7 +53,7 @@ namespace fgl::engine
return data;
}
MaterialProperties::MaterialProperties()
MaterialProperties::MaterialProperties() : m_pbr(), m_normal(), m_occlusion(), m_emissive()
{
Sampler sampler {};

View File

@@ -4,20 +4,16 @@
#pragma once
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <memory>
#include "engine/types.hpp"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#include "glm/vec3.hpp"
#include "glm/vec4.hpp"
#pragma GCC diagnostic pop
#include "engine/constants.hpp"
#include "engine/descriptors/Descriptor.hpp"
#include "engine/descriptors/DescriptorSetLayout.hpp"
#include "engine/memory/buffers/vector/DeviceVector.hpp"
#include "engine/types.hpp"
namespace fgl::engine
{
@@ -44,31 +40,31 @@ namespace fgl::engine
{
struct
{
std::shared_ptr< Texture > m_color_tex {};
glm::vec4 m_color_factors { 0.0f };
std::shared_ptr< Texture > m_color_tex { nullptr };
glm::vec4 m_color_factors { 1.0f };
std::shared_ptr< Texture > m_metallic_roughness_tex;
std::shared_ptr< Texture > m_metallic_roughness_tex { nullptr };
float m_metallic_factor { 0.0f };
float m_roughness_factor { 0.0f };
} m_pbr;
} m_pbr {};
struct
{
float m_scale { 0.0f };
std::shared_ptr< Texture > m_texture;
} m_normal;
float m_scale { 1.0f };
std::shared_ptr< Texture > m_texture { nullptr };
} m_normal {};
struct
{
float m_strength { 0.0f };
std::shared_ptr< Texture > m_texture;
} m_occlusion;
float m_strength { 1.0f };
std::shared_ptr< Texture > m_texture { nullptr };
} m_occlusion {};
struct
{
glm::vec3 m_factors { 0.0f };
std::shared_ptr< Texture > m_texture;
} m_emissive;
glm::vec3 m_factors { 1.0f };
std::shared_ptr< Texture > m_texture { nullptr };
} m_emissive {};
void writeData( DeviceMaterialData& data ) const;
DeviceMaterialData data() const;
@@ -85,8 +81,8 @@ namespace fgl::engine
alignas( 16 ) struct Albedo
{
TextureID color_texture_id { constants::INVALID_TEXTURE_ID };
alignas( 4 * 4 ) glm::vec4 color_factors {};
} color;
alignas( 4 * 4 ) glm::vec4 color_factors { 1.0f, 1.0f, 1.0f, 1.0f };
} color {};
alignas( 16 ) struct Metallic
{
@@ -94,25 +90,25 @@ namespace fgl::engine
alignas( 16 ) TextureID metallic_texture_id { constants::INVALID_TEXTURE_ID };
float metallic_factor { 0.0f };
float roughness_factor { 0.0f };
} metallic;
} metallic {};
alignas( 16 ) struct Normal
{
TextureID normal_texture_id { constants::INVALID_TEXTURE_ID };
float normal_tex_scale { 0.0f };
} normal;
} normal {};
alignas( 16 ) struct Occlusion
{
TextureID occlusion_texture_id { constants::INVALID_TEXTURE_ID };
float occlusion_tex_strength { 0.0f };
} occlusion;
} occlusion {};
alignas( 16 ) struct Emissive
{
TextureID emissive_texture_id { constants::INVALID_TEXTURE_ID };
alignas( 4 * 4 ) glm::vec3 emissive_factors { 0.0f, 0.0f, 0.0f };
} emissive;
} emissive {};
DeviceMaterialData() = default;
};
@@ -138,16 +134,6 @@ namespace fgl::engine
static_assert( sizeof( DeviceMaterialData ) == 112 );
/*
static_assert( sizeof( DeviceMaterialData ) == 76 );
static_assert( offsetof( DeviceMaterialData, color_factors ) == 16 );
static_assert( offsetof( DeviceMaterialData, metallic_texture_id ) == 32 );
static_assert( offsetof( DeviceMaterialData, normal_texture_id ) == 44 );
static_assert( offsetof( DeviceMaterialData, occlusion_texture_id ) == 52 );
static_assert( offsetof( DeviceMaterialData, emissive_texture_id ) == 60 );
static_assert( offsetof( DeviceMaterialData, emissive_factors ) == 64 );
*/
class Material
{
MaterialID m_id;

View File

@@ -38,20 +38,19 @@ namespace fgl::engine
1_GiB,
vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst,
vk::MemoryPropertyFlagBits::eDeviceLocal ),
m_generated_instance_info( constructPerFrame< DeviceVector< InstanceRenderInfo > >( m_vertex_buffer ) ),
m_primitive_info( m_long_buffer ),
m_primitive_instances( m_short_buffer ),
m_model_instances( m_short_buffer )
m_model_instances( m_short_buffer ),
m_primitives_desc( PRIMITIVE_SET.create() ),
m_instances_desc( INSTANCES_SET.create() )
{
m_vertex_buffer->setDebugName( "Vertex buffer GPU" );
m_index_buffer->setDebugName( "Index buffer" );
m_primitives_desc = PRIMITIVE_SET.create();
m_primitives_desc->bindStorageBuffer( 0, m_primitive_info );
m_primitives_desc->update();
m_primitives_desc->setName( "Primitives" );
m_instances_desc = INSTANCES_SET.create();
m_instances_desc->bindStorageBuffer( 0, m_primitive_instances );
m_instances_desc->bindStorageBuffer( 1, m_model_instances );
m_instances_desc->update();
@@ -110,7 +109,7 @@ namespace fgl::engine
PrimitiveInstanceInfo instance_info {};
instance_info.m_primitive_info = render_info->idx();
instance_info.m_model_info = model_instance.idx();
instance_info.m_material = primitive.default_material->getID();
instance_info.m_material = primitive.m_default_material->getID();
primitive_instances.emplace_back( buffers.m_primitive_instances.acquire( instance_info ) );
}

View File

@@ -4,11 +4,7 @@
#pragma once
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wduplicated-branches"
#include <glm/glm.hpp>
#pragma GCC diagnostic pop
#include <filesystem>
#include <memory>
@@ -36,13 +32,15 @@ namespace fgl::engine
namespace memory
{
class BufferHandle;
class VulkanBuffer;
}
struct ModelBuilder;
ModelGPUBuffers& getModelBuffers();
// Primitive render info, Contains the vertex and index info
constexpr descriptors::Descriptor RENDER_INFO_DESCRIPTOR { 0,
vk::DescriptorType::eStorageBuffer,
@@ -104,9 +102,6 @@ namespace fgl::engine
memory::Buffer m_vertex_buffer;
memory::Buffer m_index_buffer;
//! Generated by the compute shader, This vector contains the instance info for each primitive.
PerFrameArray< DeviceVector< InstanceRenderInfo > > m_generated_instance_info;
//! contains the core primitive info, like vertex and index offsets and counts
IndexedVector< PrimitiveRenderInfo > m_primitive_info;
//! contains a list of all rendered primitives

View File

@@ -2,6 +2,7 @@
// Created by kj16609 on 4/5/25.
//
#pragma once
#include "constants.hpp"
#include "memory/buffers/vector/IndexedVector.hpp"
namespace fgl::engine

View File

@@ -4,14 +4,15 @@
#include "ModelVertex.hpp"
#define GLM_ENABLE_EXPERIMENTAL
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wduplicated-branches"
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/hash.hpp>
#include <glm/vec2.hpp>
#pragma GCC diagnostic pop
#include <meta>
#include "Model.hpp"
#include "ModelInstance.hpp"
#include "VertexAttribute.hpp"
@@ -40,24 +41,23 @@ namespace fgl::engine
{
AttributeBuilder builder { SimpleVertex::getAttributeDescriptions() };
#pragma GCC diagnostic push // TODO: Fix with reflection once we get it in 20 years
#pragma GCC diagnostic ignored "-Winvalid-offsetof"
// builder.add< decltype( ModelVertex::m_position ), offsetof( ModelVertex, m_position ) >( 0 );
// builder.add< decltype( ModelVertex::m_color ), offsetof( ModelVertex, m_color ) >( 0 );
builder.add< decltype( ModelVertex::m_normal ), offsetof( ModelVertex, m_normal ) >( 0 );
builder.add< decltype( ModelVertex::m_tangent ), offsetof( ModelVertex, m_tangent ) >( 0 );
builder.add< decltype( ModelVertex::m_uv ), offsetof( ModelVertex, m_uv ) >( 0 );
#pragma GCC diagnostic pop
builder.add< decltype( ModelVertex::m_normal ), std::meta::offset_of( ^^ModelVertex::m_normal ).bytes >( 0 );
builder.add< decltype( ModelVertex::m_tangent ), std::meta::offset_of( ^^ModelVertex::m_tangent ).bytes >( 0 );
builder.add< decltype( ModelVertex::m_uv ), std::meta::offset_of( ^^ModelVertex::m_uv ).bytes >( 0 );
builder
.add< decltype( InstanceRenderInfo::m_model_matrix ), offsetof( InstanceRenderInfo, m_model_matrix ) >( 1 );
builder.add<
decltype( InstanceRenderInfo::m_model_matrix ),
std::meta::offset_of( ^^InstanceRenderInfo::m_model_matrix ).bytes >( 1 );
// builder.add<
// decltype( InstanceRenderInfo::m_normal_matrix ),
// offsetof( InstanceRenderInfo, m_normal_matrix ) >( 1 );
builder
.add< decltype( InstanceRenderInfo::m_material_id ), offsetof( InstanceRenderInfo, m_material_id ) >( 1 );
builder.add<
decltype( InstanceRenderInfo::m_material_id ),
std::meta::offset_of( ^^InstanceRenderInfo::m_material_id ).bytes >( 1 );
return builder.get();
}

View File

@@ -4,13 +4,9 @@
#pragma once
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#pragma GCC diagnostic pop
#include <vulkan/vulkan.hpp>
#include "SimpleVertex.hpp"

View File

@@ -34,10 +34,10 @@ namespace fgl::engine
bool Primitive::ready() const
{
return default_material->ready() && m_vertex_buffer.ready() && m_index_buffer.ready();
return m_default_material->ready() && m_vertex_buffer.ready() && m_index_buffer.ready();
}
std::shared_ptr< PrimitiveRenderInfoIndex > Primitive::buildRenderInfo()
std::shared_ptr< PrimitiveRenderInfoIndex > Primitive::buildRenderInfo() const
{
auto& buffers { getModelBuffers() };
@@ -59,8 +59,8 @@ namespace fgl::engine
m_index_buffer( std::move( index_buffer ) ),
m_bounding_box( bounding_box ),
m_mode( mode ),
default_material(),
m_primitive_info( buildRenderInfo() )
m_primitive_info( buildRenderInfo() ),
m_default_material()
{
assert( m_bounding_box.getTransform().scale != glm::vec3( 0.0f ) );
}
@@ -75,8 +75,8 @@ namespace fgl::engine
m_index_buffer( std::move( index_buffer ) ),
m_bounding_box( bounding_box ),
m_mode( mode ),
default_material( material ),
m_primitive_info( buildRenderInfo() )
m_primitive_info( buildRenderInfo() ),
m_default_material( material )
{
assert( m_bounding_box.getTransform().scale != glm::vec3( 0.0f ) );
}

View File

@@ -4,14 +4,6 @@
#pragma once
#include <cstdint>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Weffc++"
#include "objectloaders/tiny_gltf.h"
#pragma GCC diagnostic pop
#include "ModelInstanceInfo.hpp"
#include "assets/material/Material.hpp"
#include "engine/memory/buffers/vector/DeviceVector.hpp"
@@ -27,6 +19,18 @@ namespace fgl::engine
using IndexBufferSuballocation = DeviceVector< std::uint32_t >;
enum class PrimitiveMode
{
POINTS,
LINE,
LINE_LOOP,
LINE_STRIP,
TRIANGLES,
TRIANGLE_STRIP,
TRIANGLE_FAN
};
/*
enum PrimitiveMode
{
POINTS = TINYGLTF_MODE_POINTS,
@@ -37,6 +41,7 @@ namespace fgl::engine
TRI_STRIP = TINYGLTF_MODE_TRIANGLE_STRIP,
TRI_FAN = TINYGLTF_MODE_TRIANGLE_FAN
};
*/
struct PrimitiveTextures
{
@@ -72,7 +77,7 @@ namespace fgl::engine
struct Primitive
{
bool draw { true };
bool m_draw { true };
VertexBufferSuballocation m_vertex_buffer;
IndexBufferSuballocation m_index_buffer;
OrientedBoundingBox< CoordinateSpace::Model > m_bounding_box;
@@ -80,14 +85,14 @@ namespace fgl::engine
std::shared_ptr< PrimitiveRenderInfoIndex > m_primitive_info;
std::shared_ptr< Material > default_material;
std::shared_ptr< Material > m_default_material;
std::string m_name { "Unnamed Primitive" };
//! Returns true if the primitive is ready to be rendered (must have all textures, vertex buffer, and index buffer ready)
bool ready() const;
std::shared_ptr< PrimitiveRenderInfoIndex > buildRenderInfo();
std::shared_ptr< PrimitiveRenderInfoIndex > buildRenderInfo() const;
Primitive(
VertexBufferSuballocation&& vertex_buffer,

View File

@@ -4,6 +4,7 @@
#include "SimpleVertex.hpp"
#include <meta>
#include <vector>
#include "ModelVertex.hpp"
@@ -12,6 +13,12 @@
namespace fgl::engine
{
SimpleVertex::SimpleVertex()
{}
SimpleVertex::SimpleVertex( const glm::vec3 pos, const glm::vec3 color ) : m_position( pos ), m_color( color )
{}
std::vector< vk::VertexInputBindingDescription > SimpleVertex::getBindingDescriptions()
{
// {buffer_idx, stride, rate}
@@ -22,8 +29,9 @@ namespace fgl::engine
{
AttributeBuilder builder {};
builder.add< decltype( SimpleVertex::m_position ), offsetof( SimpleVertex, m_position ) >( 0 );
builder.add< decltype( SimpleVertex::m_color ), offsetof( SimpleVertex, m_color ) >( 0 );
builder
.add< decltype( SimpleVertex::m_position ), std::meta::offset_of( ^^SimpleVertex::m_position ).bytes >( 0 );
builder.add< decltype( SimpleVertex::m_color ), std::meta::offset_of( ^^SimpleVertex::m_color ).bytes >( 0 );
return builder.get();
}

View File

@@ -4,11 +4,8 @@
#pragma once
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#pragma GCC diagnostic pop
#include <vector>
@@ -25,9 +22,9 @@ namespace fgl::engine
glm::vec3 m_position { 0.0f };
glm::vec3 m_color { 1.0f };
SimpleVertex() = default;
SimpleVertex();
SimpleVertex( const glm::vec3 pos, const glm::vec3 color ) : m_position( pos ), m_color( color ) {}
SimpleVertex( glm::vec3 pos, glm::vec3 color );
static std::vector< vk::VertexInputBindingDescription > getBindingDescriptions();
static std::vector< vk::VertexInputAttributeDescription > getAttributeDescriptions();

View File

@@ -2,12 +2,8 @@
// Created by kj16609 on 7/5/25.
//
#pragma once
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wduplicated-branches"
#include <glm/mat3x3.hpp>
#include <glm/mat4x4.hpp>
#pragma GCC diagnostic pop
#include "rendering/RenderingFormats.hpp"
@@ -25,7 +21,7 @@ namespace fgl::engine
{
return vk::Format::eR32G32B32Sfloat;
}
else if constexpr ( std::same_as< T, glm::vec4 > || std ::same_as< T, glm::mat4 > )
else if constexpr ( std::same_as< T, glm::vec4 > || std::same_as< T, glm::mat4 > )
{
return vk::Format::eR32G32B32A32Sfloat;
}

View File

@@ -6,8 +6,8 @@
#include <tracy/Tracy.hpp>
#include "engine/assets/model/Primitive.hpp"
#include "engine/assets/model/ModelVertex.hpp"
#include "engine/assets/model/Primitive.hpp"
namespace fgl::engine
{
@@ -23,7 +23,8 @@ namespace fgl::engine
throw std::runtime_error( "Unknown model file extension" );
}
void ModelBuilder::loadVerts( const std::vector< ModelVertex >& verts, const std::vector< std::uint32_t >& indicies )
void ModelBuilder::
loadVerts( const std::vector< ModelVertex >& verts, const std::vector< std::uint32_t >& indicies )
{
ZoneScoped;
VertexBufferSuballocation vertex_suballoc { this->m_vertex_buffer, verts };
@@ -33,7 +34,7 @@ namespace fgl::engine
std::move( vertex_suballoc ),
std::move( index_suballoc ),
generateBoundingFromVerts( verts ),
PrimitiveMode::TRIS );
PrimitiveMode::TRIANGLES );
}
} // namespace fgl::engine

View File

@@ -8,7 +8,7 @@
#include <vector>
#include "engine/primitives/Transform.hpp"
#include "memory/buffers/BufferHandle.hpp"
#include "memory/buffers/VulkanBuffer.hpp"
namespace fgl::engine
{
@@ -24,8 +24,7 @@ namespace fgl::engine
ModelBuilder() = delete;
ModelBuilder(
const memory::Buffer& parent_vertex_buffer, const memory::Buffer& parent_index_buffer ) :
ModelBuilder( const memory::Buffer& parent_vertex_buffer, const memory::Buffer& parent_index_buffer ) :
m_vertex_buffer( parent_vertex_buffer ),
m_index_buffer( parent_index_buffer )
{}

View File

@@ -4,17 +4,16 @@
#include "SceneBuilder.hpp"
#include "engine/assets/model/Model.hpp"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Weffc++"
#include "objectloaders/tiny_gltf.h"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#include <tiny_gltf.h>
#pragma GCC diagnostic pop
#include "assets/model/ModelVertex.hpp"
#include "engine/assets/model/Model.hpp"
#include "engine/assets/stores.hpp"
#include "engine/camera/Camera.hpp"
#include "engine/camera/RenderCamera.hpp"
#include "engine/debug/logging/logging.hpp"
#include "engine/descriptors/DescriptorSet.hpp"
#include "engine/gameobjects/GameObject.hpp"
@@ -373,11 +372,11 @@ namespace fgl::engine
context.m_pUserData = &interface;
context.m_pInterface = &interface;
auto getNumFaces = [ & ]( [[maybe_unused]] const SMikkTSpaceContext* ctx ) -> int
auto getNumFaces = [ & ]( [[maybe_unused]] const SMikkTSpaceContext* ctx ) noexcept -> int
{ return static_cast< int >( indicies.size() ) / 3; };
auto getNumVerticesOfFace =
[ & ]( [[maybe_unused]] const SMikkTSpaceContext* ctx, [[maybe_unused]] const int i_face ) -> int
[ & ]( [[maybe_unused]] const SMikkTSpaceContext* ctx, [[maybe_unused]] const int i_face ) noexcept -> int
{ return 3; };
auto getPosition = [ & ](
@@ -462,22 +461,25 @@ namespace fgl::engine
std::vector< ModelVertex > verts { extractVertexInfo( prim, root ) };
std::vector< std::uint32_t > indicies { extractIndicies( prim, root ) };
switch ( static_cast< PrimitiveMode >( prim.mode ) )
PrimitiveMode primitive_mode { PrimitiveMode::POINTS };
switch ( prim.mode )
{
case TRIS:
case TINYGLTF_MODE_TRIANGLES:
generateTrisTangents( verts, indicies );
primitive_mode = PrimitiveMode::TRIANGLES;
break;
case POINTS:
case TINYGLTF_MODE_POINTS:
[[fallthrough]];
case LINE:
case TINYGLTF_MODE_LINE:
[[fallthrough]];
case LINE_LOOP:
case TINYGLTF_MODE_LINE_LOOP:
[[fallthrough]];
case LINE_STRIP:
case TINYGLTF_MODE_LINE_STRIP:
[[fallthrough]];
case TRI_STRIP:
case TINYGLTF_MODE_TRIANGLE_STRIP:
[[fallthrough]];
case TRI_FAN:
case TINYGLTF_MODE_TRIANGLE_FAN:
[[fallthrough]];
default:
{
@@ -486,18 +488,16 @@ namespace fgl::engine
}
}
Primitive primitive_mesh { Primitive::fromVerts(
std::move( verts ),
static_cast< PrimitiveMode >( prim.mode ),
std::move( indicies ),
m_vertex_buffer,
m_index_buffer ) };
auto primitive_mesh {
Primitive::
fromVerts( std::move( verts ), primitive_mode, std::move( indicies ), m_vertex_buffer, m_index_buffer )
};
// If we have a texcoord then we have a UV map. Meaning we likely have textures to use
if ( !has_texcoord ) return primitive_mesh;
//primitive_mesh.m_textures = loadTextures( prim, root );
primitive_mesh.default_material = loadMaterial( prim, root );
primitive_mesh.m_default_material = loadMaterial( prim, root );
return primitive_mesh;
}
@@ -654,15 +654,15 @@ namespace fgl::engine
material->properties.m_pbr.m_metallic_roughness_tex =
loadTexture( metallic_roughness.metallicRoughnessTexture.index, root );
material->properties.m_pbr.m_metallic_factor = metallic_roughness.metallicFactor;
material->properties.m_pbr.m_roughness_factor = metallic_roughness.roughnessFactor;
material->properties.m_pbr.m_metallic_factor = static_cast< float >( metallic_roughness.metallicFactor );
material->properties.m_pbr.m_roughness_factor = static_cast< float >( metallic_roughness.roughnessFactor );
}
material->properties.m_normal.m_texture = loadTexture( gltf_material.normalTexture.index, root );
material->properties.m_normal.m_scale = gltf_material.normalTexture.scale;
material->properties.m_normal.m_scale = static_cast< float >( gltf_material.normalTexture.scale );
material->properties.m_occlusion.m_texture = loadTexture( gltf_material.occlusionTexture.index, root );
material->properties.m_occlusion.m_strength = gltf_material.occlusionTexture.strength;
material->properties.m_occlusion.m_strength = static_cast< float >( gltf_material.occlusionTexture.strength );
material->properties.m_emissive.m_texture = loadTexture( gltf_material.emissiveTexture.index, root );
material->properties.m_emissive.m_factors = convertToVec3( gltf_material.emissiveFactor );
@@ -678,7 +678,7 @@ namespace fgl::engine
const tinygltf::Node& node { root.nodes[ node_idx ] };
const int mesh_idx { node.mesh };
const int skin_idx { node.skin };
[[maybe_unused]] const int skin_idx { node.skin };
auto obj { GameObject::createGameObject() };

View File

@@ -4,15 +4,6 @@
#pragma once
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wduplicated-branches"
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/hash.hpp>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#pragma GCC diagnostic pop
#include <filesystem>
#include <vector>
@@ -30,7 +21,7 @@ namespace fgl::engine
namespace memory
{
class BufferHandle;
class VulkanBuffer;
}
} // namespace fgl::engine

View File

@@ -2,15 +2,14 @@
// Created by kj16609 on 5/18/24.
//
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Weffc++"
#include <objectloaders/tiny_obj_loader.h>
#pragma GCC diagnostic pop
#include <fstream>
#include <unordered_map>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#include <tiny_obj_loader.h>
#pragma GCC diagnostic pop
#include "ModelBuilder.hpp"
#include "engine/assets/model/ModelVertex.hpp"
#include "engine/assets/model/Primitive.hpp"
@@ -32,7 +31,7 @@ namespace fgl::engine
const std::vector< tinyobj::shape_t >& shapes { reader.GetShapes() };
[[maybe_unused]] const std::vector< tinyobj::material_t >& materials { reader.GetMaterials() };
if ( shapes.size() == 0 ) throw std::runtime_error( "Failed to get shapes from OBJ" );
if ( shapes.empty() ) throw std::runtime_error( "Failed to get shapes from OBJ" );
const std::string& warn { reader.Warning() };
const std::string& error { reader.Error() };
@@ -51,33 +50,37 @@ namespace fgl::engine
for ( const auto& index : shape.mesh.indices )
{
ModelVertex vert {};
if ( index.vertex_index >= 0 )
{
const auto vertex_index { 3ul * static_cast< std::uint64_t >( index.vertex_index ) };
vert.m_position = {
attrib.vertices[ static_cast< std::uint64_t >( 3 * index.vertex_index + 0 ) ],
attrib.vertices[ static_cast< std::uint64_t >( 3 * index.vertex_index + 1 ) ],
attrib.vertices[ static_cast< std::uint64_t >( 3 * index.vertex_index + 2 ) ],
attrib.vertices[ vertex_index + 0ul ],
attrib.vertices[ vertex_index + 1ul ],
attrib.vertices[ vertex_index + 2ul ],
};
vert.m_color = { attrib.colors[ static_cast< std::uint64_t >( 3 * index.vertex_index + 0 ) ],
attrib.colors[ static_cast< std::uint64_t >( 3 * index.vertex_index + 1 ) ],
attrib.colors[ static_cast< std::uint64_t >( 3 * index.vertex_index + 2 ) ] };
vert.m_color = { attrib.colors[ vertex_index + 0ul ],
attrib.colors[ vertex_index + 1ul ],
attrib.colors[ vertex_index + 2ul ] };
}
if ( index.normal_index >= 0 )
{
const auto normal_index { 3ul * static_cast< std::uint64_t >( index.normal_index ) };
vert.m_normal = {
attrib.normals[ static_cast< std::uint64_t >( 3 * index.normal_index + 0 ) ],
attrib.normals[ static_cast< std::uint64_t >( 3 * index.normal_index + 1 ) ],
attrib.normals[ static_cast< std::uint64_t >( 3 * index.normal_index + 2 ) ],
attrib.normals[ normal_index + 0ul ],
attrib.normals[ normal_index + 1ul ],
attrib.normals[ normal_index + 2ul ],
};
}
if ( index.texcoord_index >= 0 )
{
const auto texcoord_index { 3ul * static_cast< std::uint64_t >( index.texcoord_index ) };
vert.m_uv = {
attrib.texcoords[ static_cast< std::uint64_t >( 3 * index.texcoord_index + 0 ) ],
attrib.texcoords[ static_cast< std::uint64_t >( 3 * index.texcoord_index + 1 ) ],
attrib.texcoords[ texcoord_index + 0ul ],
attrib.texcoords[ texcoord_index + 1ul ],
};
}
@@ -106,9 +109,9 @@ namespace fgl::engine
const OrientedBoundingBox bounding_box { generateBoundingFromVerts( verts ) };
[[maybe_unused]] auto& itter = m_primitives.emplace_back(
VertexBufferSuballocation( m_vertex_buffer, std::move( verts ) ),
IndexBufferSuballocation( m_index_buffer, std::move( indicies ) ),
VertexBufferSuballocation( m_vertex_buffer, verts ),
IndexBufferSuballocation( m_index_buffer, indicies ),
bounding_box,
PrimitiveMode::TRIS );
PrimitiveMode::TRIANGLES );
}
} // namespace fgl::engine

View File

@@ -35,6 +35,11 @@
#include "glm/geometric.hpp"
#include "glm/vec3.hpp"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wshadow"
#define TFALSE false
#define TTRUE true
@@ -853,10 +858,10 @@ int GenerateInitialVerticesIndexList(
const SVec3 P1 = GetPosition( pContext, i1 );
const SVec3 P2 = GetPosition( pContext, i2 );
const SVec3 P3 = GetPosition( pContext, i3 );
const float distSQ_02 = LengthSquared( vsub( P2, P0 ) );
const float distSQ_13 = LengthSquared( vsub( P3, P1 ) );
const float distSQ_02_2 = LengthSquared( vsub( P2, P0 ) );
const float distSQ_13_2 = LengthSquared( vsub( P3, P1 ) );
bQuadDiagIs_02 = distSQ_13 >= distSQ_02;
bQuadDiagIs_02 = distSQ_13_2 >= distSQ_02_2;
}
if ( bQuadDiagIs_02 )
@@ -1984,3 +1989,5 @@ void DegenEpilogue(
}
}
}
#pragma GCC diagnostic pop

View File

@@ -10,7 +10,7 @@ namespace fgl::engine
{
class Texture;
using TextureStore = AssetStore< Texture>;
using TextureStore = AssetStore< Texture >;
TextureStore& getTextureStore();

View File

@@ -4,21 +4,25 @@
#include "Texture.hpp"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wconversion"
#include <imgui/backends/imgui_impl_vulkan.h>
#pragma GCC diagnostic pop
#pragma GCC diagnostic push
#include <stb_image.h>
#pragma GCC diagnostic pop
#include "engine/FrameInfo.hpp"
#include "engine/assets/image/Image.hpp"
#include "engine/assets/image/ImageView.hpp"
#include "engine/debug/logging/logging.hpp"
#include "engine/descriptors/DescriptorSet.hpp"
#include "engine/math/noise/perlin/generator.hpp"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wconversion"
#include "engine/utility/IDPool.hpp"
#include "imgui/backends/imgui_impl_vulkan.h"
#include "objectloaders/stb_image.h"
#pragma GCC diagnostic pop
namespace fgl::engine
{
@@ -46,8 +50,8 @@ namespace fgl::engine
std::vector< std::byte > data {};
data.resize( x * y * 4 );
std::memcpy( data.data(), data_c, x * y * 4 );
data.resize( static_cast< std::size_t >( x ) * static_cast< std::size_t >( y ) * 4 );
std::memcpy( data.data(), data_c, data.size() );
stbi_image_free( data_c );
@@ -72,7 +76,7 @@ namespace fgl::engine
const ImVec2 imgui_size { static_cast< float >( extent.width ), static_cast< float >( extent.height ) };
ImGui::Image( getImGuiDescriptorSet(), imgui_size );
ImGui::Image( getImGuiTexture(), imgui_size );
}
bool Texture::drawImGuiButton( vk::Extent2D extent )
@@ -94,7 +98,7 @@ namespace fgl::engine
const ImVec2 imgui_size { static_cast< float >( extent.width ), static_cast< float >( extent.height ) };
return ImGui::ImageButton( m_name.c_str(), getImGuiDescriptorSet(), imgui_size );
return ImGui::ImageButton( m_name.c_str(), getImGuiTexture(), imgui_size );
}
Texture::Texture( std::tuple< std::vector< std::byte >, int, int, vk::Format, Sampler > tuple ) :
@@ -132,9 +136,7 @@ namespace fgl::engine
memory::TransferManager::getInstance()
.copyToImage( std::forward< std::vector< std::byte > >( data ), *m_image );
#if ENABLE_IMGUI
createImGuiSet();
#endif
}
Texture::Texture( const std::filesystem::path& path, Sampler&& sampler, const vk::Format format ) :
@@ -172,6 +174,23 @@ namespace fgl::engine
return m_image_view->descriptorInfo( vk::ImageLayout::eGeneral );
}
ImTextureRef Texture::createImGuiTexture() const
{
const ImTextureRef ref { m_imgui_set };
return ref;
}
ImTextureRef Texture::getImGuiTexture() const
{
if ( !m_imgui_texture.has_value() )
{
m_imgui_texture = createImGuiTexture();
}
return m_imgui_texture.value();
}
vk::Extent2D Texture::getExtent() const
{
return m_image_view->getExtent();
@@ -204,13 +223,6 @@ namespace fgl::engine
m_imgui_set = ImGui_ImplVulkan_AddTexture( vk_sampler, vk_view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL );
}
vk::DescriptorSet& Texture::getImGuiDescriptorSet()
{
assert( ready() );
assert( m_imgui_set != VK_NULL_HANDLE );
return m_imgui_set;
}
Texture::Texture( const std::shared_ptr< Image >& image, Sampler&& sampler ) :
m_texture_id( texture_id_pool.getID() ),
m_image( image ),

View File

@@ -15,6 +15,8 @@
#include "engine/constants.hpp"
#include "engine/types.hpp"
struct ImTextureRef;
namespace fgl::engine
{
class Sampler;
@@ -61,7 +63,8 @@ namespace fgl::engine
vk::Extent2D m_extent;
//! Descriptor set used for displaying the texture in ImGui
vk::DescriptorSet m_imgui_set { VK_NULL_HANDLE };
mutable vk::DescriptorSet m_imgui_set { VK_NULL_HANDLE };
mutable std::optional< ImTextureRef > m_imgui_texture { std::nullopt };
std::string m_name;
@@ -111,7 +114,9 @@ namespace fgl::engine
const std::string& getName() const { return m_name; }
[[nodiscard]] vk::DescriptorImageInfo getDescriptor() const;
[[nodiscard]] vk::DescriptorSet& getImGuiDescriptorSet();
[[nodiscard]] ImTextureRef createImGuiTexture() const;
// [[nodiscard]] vk::DescriptorSet& getImGuiDescriptorSet();
[[nodiscard]] ImTextureRef getImGuiTexture() const;
[[nodiscard]] vk::Extent2D getExtent() const;

View File

@@ -6,7 +6,7 @@
#include "engine/assets/image/ImageHandle.hpp"
#include "engine/debug/logging/logging.hpp"
#include "engine/memory/buffers/BufferHandle.hpp"
#include "engine/memory/buffers/VulkanBuffer.hpp"
#include "engine/memory/buffers/exceptions.hpp"
#include "engine/memory/buffers/vector/HostVector.hpp"
#include "engine/utils.hpp"
@@ -29,6 +29,23 @@ namespace fgl::engine::memory
return seed;
}
bool TransferData::convertRawToBuffer( Buffer& staging_buffer )
{
// Prepare the staging buffer first.
assert( std::holds_alternative< RawData >( m_source ) );
assert( !std::get< RawData >( m_source ).empty() );
// Check if we are capable of allocating into the staging buffer
if ( !staging_buffer->canAllocate( std::get< RawData >( m_source ).size(), 1 ) ) return false;
HostVector< std::byte > vector { staging_buffer, std::get< RawData >( m_source ) };
m_source = vector.getHandle();
std::get< TransferBufferHandle >( m_source )->setReady( true );
return true;
}
bool TransferData::
performImageStage( vk::raii::CommandBuffer& cmd_buffer, std::uint32_t transfer_idx, std::uint32_t graphics_idx )
{
@@ -116,11 +133,11 @@ namespace fgl::engine::memory
bool TransferData::performBufferStage( CopyRegionMap& copy_regions )
{
ZoneScoped;
auto& source { std::get< TransferBufferHandle >( m_source ) };
auto& target { std::get< TransferBufferHandle >( m_target ) };
const auto& source { std::get< TransferBufferHandle >( m_source ) };
const auto& target { std::get< TransferBufferHandle >( m_target ) };
const CopyRegionKey key { std::make_pair( source->getBuffer(), target->getBuffer() ) };
const auto copy_info { source->copyRegion( *target, m_target_offset ) };
const auto copy_info { source->copyRegion( *target, m_target_offset, m_size ) };
if ( auto itter = copy_regions.find( key ); itter != copy_regions.end() )
{
@@ -142,23 +159,6 @@ namespace fgl::engine::memory
return performBufferStage( copy_regions );
}
bool TransferData::convertRawToBuffer( Buffer& staging_buffer )
{
// Prepare the staging buffer first.
assert( std::holds_alternative< RawData >( m_source ) );
assert( !std::get< RawData >( m_source ).empty() );
// Check if we are capable of allocating into the staging buffer
if ( !staging_buffer->canAllocate( std::get< RawData >( m_source ).size(), 1 ) ) return false;
HostVector< std::byte > vector { staging_buffer, std::get< RawData >( m_source ) };
m_source = vector.getHandle();
std::get< TransferBufferHandle >( m_source )->setReady( true );
return true;
}
bool TransferData::stage(
vk::raii::CommandBuffer& buffer,
Buffer& staging_buffer,

View File

@@ -9,7 +9,7 @@
#include <variant>
#include <vector>
#include "engine/memory/buffers/BufferHandle.hpp"
#include "engine/memory/buffers/VulkanBuffer.hpp"
namespace vk
{
@@ -28,8 +28,8 @@ namespace fgl::engine
namespace memory
{
struct BufferSuballocationHandle;
class BufferHandle;
class BufferSuballocationHandle;
class VulkanBuffer;
} // namespace memory
} // namespace fgl::engine

View File

@@ -8,14 +8,10 @@
#include "engine/assets/image/ImageHandle.hpp"
#include "engine/assets/texture/Texture.hpp"
#include "engine/math/literals/size.hpp"
#include "engine/memory/buffers/BufferHandle.hpp"
#include "engine/memory/buffers/BufferSuballocation.hpp"
#include "engine/memory/buffers/VulkanBuffer.hpp"
#include "engine/memory/buffers/vector/HostVector.hpp"
#ifdef ENABLE_IMGUI
#include "imgui.h"
#endif
namespace fgl::engine::memory
{
void TransferManager::recordCommands( vk::raii::CommandBuffer& command_buffer )
@@ -94,9 +90,9 @@ namespace fgl::engine::memory
command_buffer.endDebugUtilsLabelEXT();
}
void TransferManager::resizeBuffer( const std::uint64_t size )
void TransferManager::resizeBuffer( [[maybe_unused]] const std::uint64_t size )
{
m_staging_buffer.resize( size );
// m_staging_buffer.resize( size );
}
void TransferManager::copySuballocationRegion(
@@ -367,7 +363,7 @@ namespace fgl::engine::memory
"|- %s Unused",
literals::size_literals::toString( m_staging_buffer->size() - m_staging_buffer->used() ).c_str() );
ImGui::Text( "|- %i transfer remaining", m_queue.size() );
ImGui::Text( "|- %zu transfer remaining", m_queue.size() );
ImGui::Text( "|- %zu objects being processed", m_processing.size() );
ImGui::Text( "|- %zu total copy regions", m_copy_regions.size() );
#endif

View File

@@ -14,6 +14,7 @@
namespace fgl::engine
{
class CommandBuffer;
class Image;
class Device;
@@ -21,10 +22,11 @@ namespace fgl::engine
{
class BufferVector;
struct BufferSuballocationHandle;
class BufferSuballocationHandle;
class BufferSuballocation;
} // namespace memory
} // namespace fgl::engine
namespace fgl::engine::memory

View File

@@ -4,6 +4,8 @@
#pragma once
#include <glm/mat4x4.hpp>
namespace fgl::engine
{

View File

@@ -4,8 +4,8 @@
#include "CameraManager.hpp"
#include "Camera.hpp"
#include "GBufferRenderer.hpp"
#include "RenderCamera.hpp"
#include "engine/debug/DEBUG_NAMES.hpp"
#include "engine/math/literals/size.hpp"
@@ -14,35 +14,64 @@ namespace fgl::engine
using namespace fgl::literals::size_literals;
std::vector< std::weak_ptr< Camera > >& CameraManager::getCameras()
{
return cameras;
}
std::shared_ptr< Camera >& CameraManager::getPrimary()
{
return m_primary_camera;
}
inline static CameraManager* camera_manager_instance { nullptr };
CameraManager::CameraManager() :
m_renderer( std::make_shared< GBufferRenderer >() ),
m_data_buffer( 4_KiB, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostVisible )
{
m_primary_camera = createCamera( { 1920, 1080 } );
m_primary_camera->setName( CAMERA_EDITOR_NAME );
}
FGL_ASSERT( camera_manager_instance == nullptr, "CameraManager already initialized" );
camera_manager_instance = this;
std::shared_ptr< Camera > CameraManager::createCamera( const vk::Extent2D extent )
{
std::shared_ptr< Camera > camera { new Camera( extent, m_data_buffer, m_renderer ) };
this->cameras.emplace_back( camera );
return camera;
m_data_buffer->setDebugName( "Camera data buffer" );
}
CameraManager::~CameraManager()
{
m_primary_camera.reset();
camera_manager_instance = nullptr;
}
std::vector< std::weak_ptr< RenderCamera > >& CameraManager::getCameras()
{
return cameras;
}
std::shared_ptr< RenderCamera >& CameraManager::getPrimary()
{
return m_primary_camera;
}
void CameraManager::createPrimary()
{
m_primary_camera = createCamera( { 1920, 1080 } );
m_primary_camera->setName( CAMERA_EDITOR_NAME );
}
CameraManager& CameraManager::instance()
{
FGL_ASSERT( camera_manager_instance, "CameraManager not initialized" );
return *camera_manager_instance;
}
std::shared_ptr< RenderCamera > CameraManager::createCamera( const vk::Extent2D extent )
{
auto& instance = CameraManager::instance();
std::shared_ptr< RenderCamera > camera {
new RenderCamera( extent, instance.m_data_buffer, instance.m_renderer )
};
instance.cameras.emplace_back( camera );
return camera;
}
std::shared_ptr< CameraViewpoint > CameraManager::createViewpoint( const vk::Extent2D extent )
{
auto& instance = CameraManager::instance();
std::shared_ptr< CameraViewpoint > camera_viewpoint { new CameraViewpoint( instance.m_data_buffer, extent ) };
return camera_viewpoint;
}
} // namespace fgl::engine

View File

@@ -5,8 +5,8 @@
#pragma once
#include <vector>
#include "Camera.hpp"
#include "engine/memory/buffers/BufferHandle.hpp"
#include "RenderCamera.hpp"
#include "engine/memory/buffers/VulkanBuffer.hpp"
namespace fgl::engine
{
@@ -20,20 +20,23 @@ namespace fgl::engine
std::shared_ptr< GBufferRenderer > m_renderer;
memory::Buffer m_data_buffer;
std::shared_ptr< Camera > m_primary_camera { nullptr };
std::shared_ptr< RenderCamera > m_primary_camera { nullptr };
std::vector< std::weak_ptr< Camera > > cameras {};
std::vector< std::weak_ptr< RenderCamera > > cameras {};
public:
CameraManager();
~CameraManager();
std::vector< std::weak_ptr< Camera > >& getCameras();
std::vector< std::weak_ptr< RenderCamera > >& getCameras();
std::shared_ptr< Camera >& getPrimary();
std::shared_ptr< RenderCamera >& getPrimary();
void createPrimary();
std::shared_ptr< Camera > createCamera( vk::Extent2D extent );
static CameraManager& instance();
static std::shared_ptr< RenderCamera > createCamera( vk::Extent2D extent );
static std::shared_ptr< CameraViewpoint > createViewpoint( vk::Extent2D extent );
};
} // namespace fgl::engine

View File

@@ -0,0 +1,242 @@
//
// Created by kj16609 on 9/23/25.
//
#include "CameraViewpoint.hpp"
#include "CameraInfo.hpp"
#include "RenderCamera.hpp"
#include "assets/model/Model.hpp"
#include "math/literals/size.hpp"
namespace fgl::engine
{
void CameraViewpoint::updateMatrix()
{
const auto& [ pos, scale, rotation ] = m_transform;
const auto rotation_matrix { rotation.forcedQuat().mat() };
const glm::vec3 forward { rotation_matrix * glm::vec4( constants::WORLD_FORWARD, 0.0f ) };
const glm::vec3 camera_up { rotation_matrix * glm::vec4( -constants::WORLD_Z, 0.0f ) };
const WorldCoordinate center_pos { pos + forward };
m_view_matrix = Matrix< MatrixType::WorldToCamera >( glm::lookAt( pos.vec(), center_pos.vec(), camera_up ) );
m_inverse_view_matrix = glm::inverse( m_view_matrix );
updateFrustum();
}
void CameraViewpoint::updateFrustum()
{
m_last_frustum_pos = getPosition();
const Matrix< MatrixType::ModelToWorld > translation_matrix { frustumTranslationMatrix() };
m_frustum = translation_matrix * m_base_frustum;
}
constexpr descriptors::Descriptor camera_descriptor { 0,
vk::DescriptorType::eUniformBuffer,
vk::ShaderStageFlagBits::eAllGraphics };
inline static descriptors::DescriptorSetLayout camera_descriptor_set { 1, camera_descriptor };
memory::BufferSuballocation& CameraViewpoint::frameInfo( const FrameIndex i )
{
return m_camera_frame_info[ i ];
}
std::vector< std::unique_ptr< descriptors::DescriptorSet > > CameraViewpoint::createCameraDescriptors()
{
std::vector< std::unique_ptr< descriptors::DescriptorSet > > sets {};
sets.reserve( constants::MAX_FRAMES_IN_FLIGHT );
for ( std::uint8_t i = 0; i < constants::MAX_FRAMES_IN_FLIGHT; ++i )
{
auto set { camera_descriptor_set.create() };
set->bindUniformBuffer( 0, m_camera_frame_info[ i ] );
set->update();
set->setName( std::format( "Viewpoint {} descriptor set {}", m_viewpoint_idx, i ) );
sets.emplace_back( std::move( set ) );
}
return sets;
}
using namespace fgl::literals::size_literals;
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > createDrawCommandsDescriptors(
PerFrameArray< DeviceVector< vk::DrawIndexedIndirectCommand > >& gpu_draw_commands,
PerFrameArray< DeviceVector< InstanceRenderInfo > >& per_vertex_info )
{
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > descriptors {};
for ( std::uint16_t i = 0; i < gpu_draw_commands.size(); ++i )
{
auto& command_buffer { gpu_draw_commands[ i ] };
auto& per_vertex_buffer { per_vertex_info[ i ] };
auto descriptor { COMMANDS_SET.create() };
descriptor->bindStorageBuffer( 0, command_buffer );
descriptor->bindStorageBuffer( 1, per_vertex_buffer );
descriptor->update();
descriptor->setName( "Command Buffer + Vertex Buffer" );
descriptors[ i ] = std::move( descriptor );
}
return descriptors;
}
CameraViewpoint::CameraViewpoint( memory::Buffer& buffer, const vk::Extent2D extent ) :
m_extent( extent ),
m_camera_frame_info( buffer ),
m_draw_parameter_pool(
4_MiB,
vk::BufferUsageFlagBits::eIndirectBuffer | vk::BufferUsageFlagBits::eStorageBuffer,
vk::MemoryPropertyFlagBits::eDeviceLocal | vk::MemoryPropertyFlagBits::eHostVisible ),
m_gpu_draw_commands(
constructPerFrame< DeviceVector< vk::DrawIndexedIndirectCommand > >( m_draw_parameter_pool ) ),
m_generated_instance_info(
constructPerFrame< DeviceVector< InstanceRenderInfo > >( getModelBuffers().m_vertex_buffer ) ),
m_gpu_draw_cmds_desc( createDrawCommandsDescriptors( m_gpu_draw_commands, m_generated_instance_info ) ),
m_camera_info_descriptors( createCameraDescriptors() )
{
setFOV( m_fov_y );
}
Coordinate< CoordinateSpace::World > CameraViewpoint::getPosition() const
{
//Should maybe store the inverse view matrix
return WorldCoordinate( m_inverse_view_matrix[ 3 ] );
}
Matrix< MatrixType::WorldToScreen > CameraViewpoint::getProjectionViewMatrix() const
{
assert( m_projection_matrix != constants::MAT4_IDENTITY );
return m_projection_matrix * m_view_matrix;
}
glm::mat4 CameraViewpoint::getInverseViewMatrix() const
{
return glm::inverse( m_view_matrix );
}
FGL_FLATTEN_HOT void CameraViewpoint::
setView( const WorldCoordinate pos, const QuatRotation& rotation, const ViewMode mode )
{
switch ( mode )
{
case ViewMode::TaitBryan:
{
m_transform.translation = pos;
m_transform.rotation = rotation;
updateMatrix();
break;
}
case ViewMode::Euler:
[[fallthrough]];
{
//TODO: Implement
//view_matrix = glm::lookAt(position, position + );
}
default:
throw std::runtime_error( "Unimplemented view mode" );
}
updateFrustum();
}
void CameraViewpoint::setOrthographicProjection(
const float left, const float right, const float top, const float bottom, const float near, const float far )
{
m_projection_matrix = Matrix< MatrixType::CameraToScreen >( glm::ortho( left, right, bottom, top, near, far ) );
}
FGL_FLATTEN_HOT void CameraViewpoint::
setPerspectiveProjection( const float fovy, const float aspect, const float near, const float far )
{
m_projection_matrix = Matrix< MatrixType::CameraToScreen >( glm::perspective( fovy, aspect, near, far ) );
m_base_frustum = createFrustum( aspect, fovy, near, far );
}
void CameraViewpoint::setViewport( const vk::raii::CommandBuffer& command_buffer )
{
vk::Viewport viewport {};
viewport.x = 0.0f;
viewport.y = 0.0f;
const auto& [ width, height ] = m_extent;
viewport.width = static_cast< float >( width );
viewport.height = static_cast< float >( height );
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
const std::vector< vk::Viewport > viewports { viewport };
command_buffer.setViewport( 0, viewports );
}
void CameraViewpoint::setScissor( const vk::raii::CommandBuffer& command_buffer )
{
const vk::Rect2D scissor { { 0, 0 }, m_extent };
const std::vector< vk::Rect2D > scissors { scissor };
command_buffer.setScissor( 0, scissors );
}
void CameraViewpoint::setFOV( const float fov_y )
{
m_fov_y = fov_y;
setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE );
}
float CameraViewpoint::aspectRatio() const
{
return static_cast< float >( m_extent.width ) / static_cast< float >( m_extent.height );
}
void CameraViewpoint::moveTo( const WorldTransform pos )
{
this->m_transform = pos;
}
void CameraViewpoint::updateInfo( const FrameIndex frame_index )
{
ZoneScoped;
updateMatrix();
CameraInfo current_camera_info { .projection = getProjectionMatrix(),
.view = getViewMatrix(),
.inverse_view = getInverseViewMatrix() };
m_camera_frame_info[ frame_index ] = current_camera_info;
}
void CameraViewpoint::setExtent( const vk::Extent2D extent )
{
m_extent = extent;
}
vk::Rect2D CameraViewpoint::scissor() const
{
return { { 0, 0 }, m_extent };
}
vk::Viewport CameraViewpoint::viewport() const
{
return { 0, 0, static_cast< float >( this->m_extent.width ), static_cast< float >( this->m_extent.height ),
0.0f, 1.0f };
}
descriptors::DescriptorSetLayout& CameraViewpoint::getDescriptorLayout()
{
return camera_descriptor_set;
}
} // namespace fgl::engine

View File

@@ -1,82 +1,37 @@
//
// Created by kj16609 on 11/28/23.
// Created by kj16609 on 9/23/25.
//
#pragma once
#include <vulkan/vulkan.hpp>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wduplicated-branches"
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/glm.hpp>
#include <glm/gtx/string_cast.hpp>
#pragma GCC diagnostic pop
#include "../primitives/rotation/QuatRotation.hpp"
#include "CompositeSwapchain.hpp"
#include "GBufferSwapchain.hpp"
#include "debug/Track.hpp"
#include "engine/descriptors/DescriptorSet.hpp"
#include "engine/memory/buffers/HostSingleT.hpp"
#include "engine/memory/buffers/UniqueFrameSuballocation.hpp"
#include "engine/primitives/Frustum.hpp"
#include "engine/primitives/Transform.hpp"
#include "engine/rendering/types.hpp"
namespace vk::raii
{
class CommandBuffer;
class RenderPass;
} // namespace vk::raii
#include "CameraInfo.hpp"
#include "memory/buffers/HostSingleT.hpp"
#include "memory/buffers/UniqueFrameSuballocation.hpp"
#include "primitives/Frustum.hpp"
#include "primitives/Transform.hpp"
#include "primitives/matricies/Matrix.hpp"
#include "rendering/PresentSwapChain.hpp"
namespace fgl::engine
{
struct InstanceRenderInfo;
namespace descriptors
{
class DescriptorSetLayout;
}
class Image;
struct FrameInfo;
class GBufferRenderer;
class DescriptorSet;
} // namespace descriptors
struct CameraInfo;
class Camera;
FrustumBase createFrustum( float aspect, float fovy, float near, float far );
using CameraIDX = std::uint8_t;
class Camera
class CameraViewpoint
{
inline static CameraIDX m_camera_counter { 0 };
debug::Track< "CPU", "Camera" > m_camera {};
vk::Extent2D m_target_extent;
std::unique_ptr< CompositeSwapchain > m_composite_swapchain;
std::unique_ptr< GBufferSwapchain > m_gbuffer_swapchain;
//TODO: Move to deffered deleter
std::queue< std::unique_ptr< CompositeSwapchain > > m_old_composite_swapchain {};
std::queue< std::unique_ptr< GBufferSwapchain > > m_old_gbuffer_swapchain {};
std::shared_ptr< GBufferRenderer > m_camera_renderer;
//! True if the camera is active and to be rendered
bool m_active { true };
//! If true, The camera's swapchain is to be destroyed in order to preserve memory.
//! This is here to allow us to set a camera cold when it's not likely to be used soon
bool m_cold { false };
// Const is acceptable, Since this value should never change. EVER
const CameraIDX m_camera_idx { m_camera_counter++ };
protected:
vk::Extent2D m_extent;
Matrix< MatrixType::CameraToScreen > m_projection_matrix { 1.0f };
Matrix< MatrixType::WorldToCamera > m_view_matrix { 1.0f };
glm::mat4 m_inverse_view_matrix { 1.0f };
bool m_ortho { false };
//! Frustum of the camera in model space relative to the camera
//! @note Must be transformed by the inverse view matrix to get the frustum in world space
@@ -86,58 +41,62 @@ namespace fgl::engine
WorldTransform m_transform {};
float m_fov_y { glm::radians( 90.0f ) };
float& x { m_transform.translation.x };
float& y { m_transform.translation.y };
float& z { m_transform.translation.z };
PerFrameSuballocation< HostSingleT< CameraInfo > > m_camera_frame_info;
std::uint32_t m_viewpoint_idx { 0 };
memory::Buffer m_draw_parameter_pool;
public:
PerFrameArray< DeviceVector< vk::DrawIndexedIndirectCommand > > m_gpu_draw_commands;
PerFrameArray< DeviceVector< InstanceRenderInfo > > m_generated_instance_info;
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > m_gpu_draw_cmds_desc;
memory::BufferSuballocation& frameInfo( FrameIndex i );
// Camera info is expected at binding 0
std::vector< std::unique_ptr< descriptors::DescriptorSet > > createCameraDescriptors();
std::vector< std::unique_ptr< descriptors::DescriptorSet > > m_camera_info_descriptors;
std::string m_name { "Unnamed Camera" };
private:
[[nodiscard]] Matrix< MatrixType::ModelToWorld > frustumTranslationMatrix() const;
void updateFrustum();
#ifdef EXPOSE_CAMERA_TESTS
//Constructor for tests
Camera( vk::Extent2D test_extent ) : m_target_extent( test_extent ) {}
#endif
Camera( vk::Extent2D extent, memory::Buffer& buffer, const std::shared_ptr< GBufferRenderer >& renderer );
friend class CameraManager;
enum ViewMode
{
Euler,
TaitBryan
};
public:
float& x { m_transform.translation.x };
float& y { m_transform.translation.y };
float& z { m_transform.translation.z };
float m_fov_y { glm::radians( 90.0f ) };
FGL_DELETE_ALL_RO5( Camera );
FGL_DELETE_ALL_RO5( CameraViewpoint );
~Camera();
explicit CameraViewpoint( memory::Buffer& buffer, vk::Extent2D extent = { 1920, 1080 } );
[[nodiscard]] CameraIDX getIDX() const;
[[nodiscard]] Coordinate< CoordinateSpace::World > getPosition() const;
[[nodiscard]] const std::string& getName() const;
void setExtent( vk::Extent2D extent );
WorldTransform& getTransform() { return m_transform; }
[[nodiscard]] QuatRotation getRotation() const { return m_transform.rotation.forcedQuat(); }
[[nodiscard]] const WorldTransform& getTransform() const { return m_transform; }
WorldTransform& getTransform() { return m_transform; }
WorldCoordinate getFrustumPosition() const;
[[nodiscard]] const FrustumBase& getBaseFrustum() const { return m_base_frustum; }
//! Returns the frustum of the camera in world space
[[nodiscard]] const Frustum& getFrustumBounds() const { return m_frustum; }
[[nodiscard]] WorldCoordinate getFrustumPosition() const;
void updateMatrix();
void updateFrustum();
[[nodiscard]] const Matrix< MatrixType::CameraToScreen >& getProjectionMatrix() const
{
return m_projection_matrix;
@@ -148,20 +107,13 @@ namespace fgl::engine
[[nodiscard]] Matrix< MatrixType::WorldToScreen > getProjectionViewMatrix() const;
[[nodiscard]] glm::mat4 getInverseViewMatrix() const;
enum ViewMode
{
Euler,
TaitBryan
};
[[nodiscard]] Matrix< MatrixType::ModelToWorld > frustumTranslationMatrix() const;
void setView( WorldCoordinate pos, const QuatRotation& rotation, ViewMode mode = TaitBryan );
void setOrthographicProjection( float left, float right, float top, float bottom, float near, float far );
void setPerspectiveProjection( float fovy, float aspect, float near, float far );
[[nodiscard]] Coordinate< CoordinateSpace::World > getPosition() const;
FGL_FORCE_INLINE NormalVector getUp() const { return -getDown(); }
FGL_FORCE_INLINE NormalVector getLeft() const { return -getRight(); }
FGL_FORCE_INLINE NormalVector getRight() const
{
@@ -173,45 +125,30 @@ namespace fgl::engine
return -NormalVector( glm::vec3( m_inverse_view_matrix[ 2 ] ) );
}
FGL_FORCE_INLINE NormalVector getLeft() const { return -getRight(); }
FGL_FORCE_INLINE NormalVector getBackward() const { return -getForward(); }
FGL_FORCE_INLINE NormalVector getUp() const { return -getDown(); }
FGL_FORCE_INLINE NormalVector getDown() const
{
return NormalVector( glm::vec3( m_inverse_view_matrix[ 1 ] ) );
}
//! Updates the required info for rendering
void updateInfo( FrameIndex frame_index );
descriptors::DescriptorSet& getDescriptor( FrameIndex index );
void setFOV( float fov_y );
//! Performs the render pass for this camera
void pass( FrameInfo& frame_info );
[[nodiscard]] GBufferSwapchain& getSwapchain() const;
[[nodiscard]] CompositeSwapchain& getCompositeSwapchain() const;
void setViewport( const vk::raii::CommandBuffer& command_buffer );
void setScissor( const vk::raii::CommandBuffer& command_buffer );
void setFOV( float fov_y );
[[nodiscard]] float aspectRatio() const;
void remakeSwapchain( vk::Extent2D extent );
void moveTo( const WorldTransform pos );
void setName( std::string_view str );
//! Updates the required info for rendering
void updateInfo( FrameIndex frame_index );
float aspectRatio() const;
void setExtent( vk::Extent2D extent );
void copyOutput( const vk::raii::CommandBuffer& command_buffer, FrameIndex frame_index, Image& target );
void updateMatrix();
vk::Rect2D scissor() const;
vk::Viewport viewport() const;
static descriptors::DescriptorSetLayout& getDescriptorLayout();
#ifdef EXPOSE_CAMERA_TESTS
Camera CREATE_TESTING_CAMERA() { return { { 1920, 1080 } }; }
#endif
};
} // namespace fgl::engine
} // namespace fgl::engine

View File

@@ -3,9 +3,10 @@
//
#include "GBufferCompositor.hpp"
#include "Camera.hpp"
#include "CompositeSwapchain.hpp"
#include "GBufferSwapchain.hpp"
#include "RenderCamera.hpp"
#include "ShadowMap.hpp"
#include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp"
namespace fgl::engine
@@ -56,7 +57,8 @@ namespace fgl::engine
PipelineBuilder builder { 0 };
builder.addDescriptorSet( gbuffer_set );
builder.addDescriptorSet( Camera::getDescriptorLayout() );
builder.addDescriptorSet( RenderCamera::getDescriptorLayout() );
builder.addDescriptorSet( ShadowMap::getDescriptorLayout() );
builder.addColorAttachment().setFormat( pickColorFormat() ).finish();
@@ -73,7 +75,8 @@ namespace fgl::engine
m_pipeline->setDebugName( "Composition pipeline" );
}
void GBufferCompositor::composite( CommandBuffer& command_buffer, Camera& camera, const FrameIndex frame_index )
void GBufferCompositor::
composite( CommandBuffer& command_buffer, RenderCamera& camera, const FrameIndex frame_index )
{
auto& gbuffer_swapchain { camera.getSwapchain() };
auto& composite_swapchain { camera.getCompositeSwapchain() };

View File

@@ -5,7 +5,7 @@
#include <vulkan/vulkan_raii.hpp>
#include "Camera.hpp"
#include "RenderCamera.hpp"
#include "engine/rendering/pipelines/v2/Pipeline.hpp"
#include "engine/rendering/types.hpp"
#include "engine/systems/composition/Control.hpp"
@@ -48,7 +48,7 @@ namespace fgl::engine
GBufferCompositor( CompositeFlags flags = CompositeFlagBits_Standard );
void composite( CommandBuffer& command_buffer, Camera& camera, FrameIndex frame_index );
void composite( CommandBuffer& command_buffer, RenderCamera& camera, FrameIndex frame_index );
inline void switchMode( const CompositeFlags flags ) { m_flags = flags; }
};

View File

@@ -73,7 +73,8 @@ namespace fgl::engine
camera_swapchain.transitionImages( command_buffer, GBufferSwapchain::FINAL, frame_info.in_flight_idx );
m_compositor.composite( command_buffer, *frame_info.camera, frame_info.in_flight_idx );
m_compositor
.composite( command_buffer, *static_cast< RenderCamera* >( frame_info.camera ), frame_info.in_flight_idx );
}
} // namespace fgl::engine

View File

@@ -4,6 +4,8 @@
#include "GBufferSwapchain.hpp"
#include <meta>
#include "engine/descriptors/DescriptorSet.hpp"
namespace fgl::engine

View File

@@ -2,13 +2,12 @@
// Created by kj16609 on 11/28/23.
//
#include "Camera.hpp"
#include "RenderCamera.hpp"
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/string_cast.hpp>
#include <tracy/Tracy.hpp>
#include "CameraInfo.hpp"
#include "GBufferRenderer.hpp"
#include "GBufferSwapchain.hpp"
#include "engine/debug/timing/FlameGraph.hpp"
@@ -16,61 +15,67 @@
namespace fgl::engine
{
Matrix< MatrixType::WorldToScreen > Camera::getProjectionViewMatrix() const
FrustumBase createFrustum( const float aspect, const float fov_y, const float near, const float far )
{
assert( m_projection_matrix != constants::MAT4_IDENTITY );
return m_projection_matrix * m_view_matrix;
const Plane< CoordinateSpace::Model > near_plane { ModelCoordinate( constants::WORLD_FORWARD * near ),
NormalVector( constants::WORLD_FORWARD ) };
const Plane< CoordinateSpace::Model > far_plane { ModelCoordinate( constants::WORLD_FORWARD * far ),
NormalVector( -constants::WORLD_FORWARD ) };
const float half_height { far * glm::tan( fov_y / 2.0f ) };
const float half_width { half_height * aspect };
const ModelCoordinate far_forward { constants::WORLD_FORWARD * far };
const ModelCoordinate right_half { constants::WORLD_RIGHT * half_width };
const Vector right_forward { ( far_forward + right_half ).vec() };
const Vector left_forward { ( far_forward - right_half ).vec() };
const Plane< CoordinateSpace::Model > right_plane {
ModelCoordinate( constants::WORLD_CENTER ),
NormalVector( glm::cross( right_forward.vec(), constants::WORLD_Z_NEG ) )
};
const Plane< CoordinateSpace::Model > left_plane {
ModelCoordinate( constants::WORLD_CENTER ),
NormalVector( glm::cross( left_forward.vec(), constants::WORLD_Z ) )
};
const ModelCoordinate top_half { constants::WORLD_Z * half_height };
const Vector top_forward { ( far_forward + top_half ).vec() };
const Vector bottom_forward { ( far_forward - top_half ).vec() };
const Plane< CoordinateSpace::Model > top_plane {
ModelCoordinate( constants::WORLD_CENTER ),
NormalVector( glm::cross( top_forward.vec(), constants::WORLD_RIGHT ) )
};
const Plane< CoordinateSpace::Model > bottom_plane {
ModelCoordinate( constants::WORLD_CENTER ),
NormalVector( glm::cross( bottom_forward.vec(), -constants::WORLD_RIGHT ) )
};
return { near_plane,
far_plane,
top_plane,
bottom_plane,
right_plane,
left_plane,
Coordinate< CoordinateSpace::Model >( constants::WORLD_CENTER ) };
}
glm::mat4 Camera::getInverseViewMatrix() const
const std::string& RenderCamera::getName() const
{
return glm::inverse( m_view_matrix );
return m_name;
}
void Camera::setOrthographicProjection( float left, float right, float top, float bottom, float near, float far )
{
m_projection_matrix = Matrix< MatrixType::CameraToScreen >( glm::ortho( left, right, bottom, top, near, far ) );
//TODO: Figure out frustum culling for orthographic projection. (If we even wanna use it)
}
FGL_FLATTEN_HOT void Camera::
setPerspectiveProjection( const float fovy, const float aspect, const float near, const float far )
{
m_projection_matrix = Matrix< MatrixType::CameraToScreen >( glm::perspective( fovy, aspect, near, far ) );
m_base_frustum = createFrustum( aspect, fovy, near, far );
}
Coordinate< CoordinateSpace::World > Camera::getPosition() const
{
//Should maybe store the inverse view matrix
return WorldCoordinate( m_inverse_view_matrix[ 3 ] );
}
void Camera::updateInfo( const FrameIndex frame_index )
{
ZoneScoped;
CameraInfo current_camera_info { .projection = getProjectionMatrix(),
.view = getViewMatrix(),
.inverse_view = getInverseViewMatrix() };
m_camera_frame_info[ frame_index ] = current_camera_info;
}
descriptors::DescriptorSet& Camera::getDescriptor( const FrameIndex index )
descriptors::DescriptorSet& RenderCamera::getDescriptor( const FrameIndex index )
{
assert( index < m_camera_info_descriptors.size() );
return *m_camera_info_descriptors[ index ];
}
void Camera::setFOV( const float fov_y )
{
m_fov_y = fov_y;
setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE );
}
void Camera::pass( FrameInfo& frame_info )
void RenderCamera::pass( FrameInfo& frame_info )
{
ZoneScopedN( "Camera::pass" );
auto timer = debug::timing::push( "Camera" );
@@ -98,45 +103,20 @@ namespace fgl::engine
frame_info.camera = nullptr;
}
GBufferSwapchain& Camera::getSwapchain() const
GBufferSwapchain& RenderCamera::getSwapchain() const
{
return *m_gbuffer_swapchain;
}
CompositeSwapchain& Camera::getCompositeSwapchain() const
CompositeSwapchain& RenderCamera::getCompositeSwapchain() const
{
return *m_composite_swapchain;
}
void Camera::setViewport( const vk::raii::CommandBuffer& command_buffer )
void RenderCamera::remakeSwapchain( vk::Extent2D extent )
{
vk::Viewport viewport {};
viewport.x = 0.0f;
viewport.y = 0.0f;
const auto& [ width, height ] = m_gbuffer_swapchain->getExtent();
viewport.width = static_cast< float >( width );
viewport.height = static_cast< float >( height );
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
const std::vector< vk::Viewport > viewports { viewport };
command_buffer.setViewport( 0, viewports );
}
void Camera::setScissor( const vk::raii::CommandBuffer& command_buffer )
{
const vk::Rect2D scissor { { 0, 0 }, m_gbuffer_swapchain->getExtent() };
const std::vector< vk::Rect2D > scissors { scissor };
command_buffer.setScissor( 0, scissors );
}
void Camera::remakeSwapchain( vk::Extent2D extent )
{
this->setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE );
setExtent( extent );
this->setPerspectiveProjection( m_fov_y, this->aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE );
log::debug( "Camera swapchain recreated" );
@@ -148,20 +128,22 @@ namespace fgl::engine
m_composite_swapchain = std::make_unique< CompositeSwapchain >( extent );
m_gbuffer_swapchain = std::make_unique< GBufferSwapchain >( extent );
CameraViewpoint::setExtent( extent );
}
void Camera::setName( const std::string_view str )
void RenderCamera::setName( const std::string_view str )
{
m_name = str;
}
float Camera::aspectRatio() const
float RenderCamera::aspectRatio() const
{
return m_gbuffer_swapchain->getAspectRatio();
}
void Camera::
copyOutput( const vk::raii::CommandBuffer& command_buffer, const FrameIndex frame_index, Image& target )
void RenderCamera::
copyOutput( const vk::raii::CommandBuffer& command_buffer, const FrameIndex frame_index, Image& target ) const
{
assert( m_gbuffer_swapchain->getExtent() == target.getExtent() );
@@ -271,175 +253,39 @@ namespace fgl::engine
{ barrier_to_source } );
}
void Camera::updateMatrix()
WorldCoordinate CameraViewpoint::getFrustumPosition() const
{
const auto& [ pos, scale, rotation ] = m_transform;
const auto rotation_matrix { rotation.forcedQuat().mat() };
const glm::vec3 forward { rotation_matrix * glm::vec4( constants::WORLD_FORWARD, 0.0f ) };
const glm::vec3 camera_up { rotation_matrix * glm::vec4( -constants::WORLD_Z, 0.0f ) };
const WorldCoordinate center_pos { pos + forward };
m_view_matrix = Matrix< MatrixType::WorldToCamera >( glm::lookAt( pos.vec(), center_pos.vec(), camera_up ) );
m_inverse_view_matrix = glm::inverse( m_view_matrix );
updateFrustum();
return m_last_frustum_pos;
}
FGL_FLATTEN_HOT void Camera::setView( const WorldCoordinate pos, const QuatRotation& rotation, const ViewMode mode )
Matrix< MatrixType::ModelToWorld > CameraViewpoint::frustumTranslationMatrix() const
{
switch ( mode )
{
case ViewMode::TaitBryan:
{
m_transform.translation = pos;
m_transform.rotation = rotation;
updateMatrix();
break;
}
case ViewMode::Euler:
[[fallthrough]];
{
//TODO: Implement
//view_matrix = glm::lookAt(position, position + );
}
default:
throw std::runtime_error( "Unimplemented view mode" );
}
updateFrustum();
return m_transform.mat();
}
void Camera::updateFrustum()
{
m_last_frustum_pos = getPosition();
const Matrix< MatrixType::ModelToWorld > translation_matrix { frustumTranslationMatrix() };
m_frustum = translation_matrix * m_base_frustum;
}
const std::string& Camera::getName() const
{
return m_name;
}
constexpr descriptors::Descriptor camera_descriptor { 0,
vk::DescriptorType::eUniformBuffer,
vk::ShaderStageFlagBits::eAllGraphics };
inline static descriptors::DescriptorSetLayout camera_descriptor_set { 1, camera_descriptor };
descriptors::DescriptorSetLayout& Camera::getDescriptorLayout()
{
return camera_descriptor_set;
}
Camera::Camera(
RenderCamera::RenderCamera(
const vk::Extent2D extent, memory::Buffer& buffer, const std::shared_ptr< GBufferRenderer >& renderer ) :
CameraViewpoint( buffer, extent ),
m_target_extent( extent ),
m_composite_swapchain( std::make_unique< CompositeSwapchain >( m_target_extent ) ),
m_gbuffer_swapchain( std::make_unique< GBufferSwapchain >( m_target_extent ) ),
m_camera_renderer( renderer ),
m_camera_frame_info( buffer ),
m_camera_info_descriptors( createCameraDescriptors() )
m_camera_renderer( renderer )
{
FGL_ASSERT( renderer, "Camera renderer is null" );
this->setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE );
this->setView( WorldCoordinate( constants::CENTER ), QuatRotation( 0.0f, 0.0f, 0.0f ) );
}
std::vector< std::unique_ptr< descriptors::DescriptorSet > > Camera::createCameraDescriptors()
{
std::vector< std::unique_ptr< descriptors::DescriptorSet > > sets {};
sets.reserve( constants::MAX_FRAMES_IN_FLIGHT );
RenderCamera::~RenderCamera() = default;
for ( std::uint8_t i = 0; i < constants::MAX_FRAMES_IN_FLIGHT; ++i )
{
auto set { camera_descriptor_set.create() };
set->bindUniformBuffer( 0, m_camera_frame_info[ i ] );
set->update();
set->setName( std::format( "Camera {} descriptor set {}", m_camera_idx, i ) );
sets.emplace_back( std::move( set ) );
}
return sets;
}
void Camera::setExtent( const vk::Extent2D extent )
{
m_target_extent = extent;
}
FrustumBase createFrustum( const float aspect, const float fov_y, const float near, const float far )
{
const Plane< CoordinateSpace::Model > near_plane { ModelCoordinate( constants::WORLD_FORWARD * near ),
NormalVector( constants::WORLD_FORWARD ) };
const Plane< CoordinateSpace::Model > far_plane { ModelCoordinate( constants::WORLD_FORWARD * far ),
NormalVector( -constants::WORLD_FORWARD ) };
const float half_height { far * glm::tan( fov_y / 2.0f ) };
const float half_width { half_height * aspect };
const ModelCoordinate far_forward { constants::WORLD_FORWARD * far };
const ModelCoordinate right_half { constants::WORLD_RIGHT * half_width };
const Vector right_forward { ( far_forward + right_half ).vec() };
const Vector left_forward { ( far_forward - right_half ).vec() };
const Plane< CoordinateSpace::Model > right_plane {
ModelCoordinate( constants::WORLD_CENTER ),
NormalVector( glm::cross( right_forward.vec(), constants::WORLD_Z_NEG ) )
};
const Plane< CoordinateSpace::Model > left_plane {
ModelCoordinate( constants::WORLD_CENTER ),
NormalVector( glm::cross( left_forward.vec(), constants::WORLD_Z ) )
};
const ModelCoordinate top_half { constants::WORLD_Z * half_height };
const Vector top_forward { ( far_forward + top_half ).vec() };
const Vector bottom_forward { ( far_forward - top_half ).vec() };
const Plane< CoordinateSpace::Model > top_plane {
ModelCoordinate( constants::WORLD_CENTER ),
NormalVector( glm::cross( top_forward.vec(), constants::WORLD_RIGHT ) )
};
const Plane< CoordinateSpace::Model > bottom_plane {
ModelCoordinate( constants::WORLD_CENTER ),
NormalVector( glm::cross( bottom_forward.vec(), -constants::WORLD_RIGHT ) )
};
return { near_plane,
far_plane,
top_plane,
bottom_plane,
right_plane,
left_plane,
Coordinate< CoordinateSpace::Model >( constants::WORLD_CENTER ) };
}
Matrix< MatrixType::ModelToWorld > Camera::frustumTranslationMatrix() const
{
return m_transform.mat();
}
WorldCoordinate Camera::getFrustumPosition() const
{
return m_last_frustum_pos;
}
Camera::~Camera()
{}
CameraIDX Camera::getIDX() const
CameraIDX RenderCamera::getIDX() const
{
return m_camera_idx;
}
void RenderCamera::setExtent( const vk::Extent2D extent )
{
m_target_extent = extent;
}
} // namespace fgl::engine

View File

@@ -0,0 +1,100 @@
//
// Created by kj16609 on 11/28/23.
//
#pragma once
#include "CameraViewpoint.hpp"
#include "CompositeSwapchain.hpp"
#include "GBufferSwapchain.hpp"
#include "debug/Track.hpp"
#include "engine/descriptors/DescriptorSet.hpp"
#include "engine/primitives/Frustum.hpp"
#include "engine/rendering/types.hpp"
namespace vk::raii
{
class CommandBuffer;
class RenderPass;
} // namespace vk::raii
namespace fgl::engine
{
namespace descriptors
{
class DescriptorSetLayout;
}
class Image;
struct FrameInfo;
class GBufferRenderer;
struct CameraInfo;
class RenderCamera;
FrustumBase createFrustum( float aspect, float fovy, float near, float far );
using CameraIDX = std::uint8_t;
class RenderCamera final : public CameraViewpoint
{
inline static CameraIDX m_camera_counter { 0 };
debug::Track< "CPU", "Camera" > m_camera {};
vk::Extent2D m_target_extent;
std::unique_ptr< CompositeSwapchain > m_composite_swapchain;
std::unique_ptr< GBufferSwapchain > m_gbuffer_swapchain;
//TODO: Move to deffered deleter
std::queue< std::unique_ptr< CompositeSwapchain > > m_old_composite_swapchain {};
std::queue< std::unique_ptr< GBufferSwapchain > > m_old_gbuffer_swapchain {};
std::shared_ptr< GBufferRenderer > m_camera_renderer;
//! True if the camera is active and to be rendered
bool m_active { true };
//! If true, The camera's swapchain is to be destroyed to preserve memory.
//! This is here to allow us to set a camera cold when it's not likely to be used soon
bool m_cold { false };
// Const is acceptable, Since this value should never change. EVER
const CameraIDX m_camera_idx { m_camera_counter++ };
std::string m_name { "Unnamed Camera" };
RenderCamera( vk::Extent2D extent, memory::Buffer& buffer, const std::shared_ptr< GBufferRenderer >& renderer );
friend class CameraManager;
public:
FGL_DELETE_ALL_RO5( RenderCamera );
~RenderCamera();
[[nodiscard]] CameraIDX getIDX() const;
[[nodiscard]] const std::string& getName() const;
descriptors::DescriptorSet& getDescriptor( FrameIndex index );
void setExtent( vk::Extent2D extent );
//! Performs the render pass for this camera
void pass( FrameInfo& frame_info );
[[nodiscard]] GBufferSwapchain& getSwapchain() const;
[[nodiscard]] CompositeSwapchain& getCompositeSwapchain() const;
void remakeSwapchain( vk::Extent2D extent );
void setName( std::string_view str );
[[nodiscard]] float aspectRatio() const;
void copyOutput( const vk::raii::CommandBuffer& command_buffer, FrameIndex frame_index, Image& target ) const;
};
} // namespace fgl::engine

View File

@@ -0,0 +1,169 @@
//
// Created by kj16609 on 9/23/25.
//
#include "ShadowMap.hpp"
#include "CameraManager.hpp"
#include "assets/model/Model.hpp"
#include "assets/model/ModelVertex.hpp"
#include "debug/timing/FlameGraph.hpp"
#include "rendering/pipelines/v2/Pipeline.hpp"
#include "rendering/pipelines/v2/PipelineBuilder.hpp"
namespace fgl::engine
{
std::shared_ptr< Swapchain > createDepthSwapchain( const vk::Extent2D extent )
{
std::vector< SwapchainImageInfo > swapchain_images {
{ .m_format = { .m_canidates = { vk::Format::eD32Sfloat,
vk::Format::eD32SfloatS8Uint,
vk::Format::eD24UnormS8Uint },
.m_usage =
vk::ImageUsageFlagBits::eDepthStencilAttachment | vk::ImageUsageFlagBits::eSampled,
.m_features = vk::FormatFeatureFlagBits::eDepthStencilAttachment },
.m_inital_layout = vk::ImageLayout::eUndefined,
.m_final_layout = vk::ImageLayout::eDepthReadOnlyOptimal,
.m_extent = extent,
.m_name = "Shadowmap Depth" }
};
return std::make_shared< Swapchain >( std::move( swapchain_images ) );
}
constexpr descriptors::Descriptor camera_descriptor { 0,
vk::DescriptorType::eUniformBuffer,
vk::ShaderStageFlagBits::eAllGraphics };
// 2d sampler
constexpr descriptors::Descriptor shadowmap_descriptor { 1,
vk::DescriptorType::eSampledImage,
vk::ShaderStageFlagBits::eFragment };
inline static descriptors::DescriptorSetLayout shadowmap_descriptor_set { 2,
camera_descriptor,
shadowmap_descriptor };
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > ShadowMap::createShadowmapDescriptors() const
{
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > data {};
for ( FrameIndex i = 0; i < data.size(); ++i )
{
auto set { shadowmap_descriptor_set.create() };
set->bindImage(
shadowmap_descriptor.m_index,
*this->m_swapchain->depthView( i ),
vk::ImageLayout::eDepthReadOnlyOptimal );
set->bindUniformBuffer( camera_descriptor.m_index, this->m_camera->frameInfo( i ) );
set->update();
data[ i ] = std::move( set );
}
return data;
}
ShadowMap::ShadowMap( const UniversalRotation& direction, const vk::Extent2D extent ) :
m_swapchain( createDepthSwapchain( extent ) ),
m_direction( direction ),
m_camera( CameraManager::createViewpoint( extent ) ),
m_shadow_pipeline( nullptr ),
m_culling_system(),
m_extent( extent ),
m_shadowmap_descriptor( createShadowmapDescriptors() )
{
PipelineBuilder builder { 0 };
builder.addDepthAttachment();
builder.addDescriptorSet( CameraViewpoint::getDescriptorLayout() );
builder.setVertexShader( Shader::loadVertex( "shaders/shadowmap.slang" ) );
builder.setFragmentShader( Shader::loadFragment( "shaders/shadowmap.slang" ) );
builder.setAttributeDescriptions( ModelVertex::getAttributeDescriptions() );
builder.setBindingDescriptions( ModelVertex::getBindingDescriptions() );
m_shadow_pipeline = builder.create();
m_shadow_pipeline->setDebugName( "Shadow pipeline" );
}
void ShadowMap::pass( FrameInfo info )
{
ZoneScopedN( "ShadowMap::pass" );
auto timer = debug::timing::push( "ShadowMap" );
info.camera = m_camera.get();
info.camera->updateInfo( info.in_flight_idx );
m_culling_system.pass( info );
auto& command_buffer { info.command_buffer.render_cb };
vk::RenderingInfo rendering_info {};
vk::RenderingAttachmentInfo depth_info {};
depth_info.setClearValue( vk::ClearDepthStencilValue( 1.0f, 0 ) );
depth_info.setLoadOp( vk::AttachmentLoadOp::eClear );
depth_info.setStoreOp( vk::AttachmentStoreOp::eStore );
depth_info.imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
depth_info.imageView = m_swapchain->depthView( info.in_flight_idx )->getVkView();
rendering_info.colorAttachmentCount = 0;
rendering_info.pColorAttachments = nullptr;
rendering_info.setRenderArea( { { 0, 0 }, this->m_extent } );
rendering_info.layerCount = 1;
rendering_info.setPDepthAttachment( &depth_info );
command_buffer->beginRendering( rendering_info );
command_buffer->setViewport( 0, { info.camera->viewport() } );
command_buffer->setScissor( 0, { info.camera->scissor() } );
m_shadow_pipeline->bind( command_buffer );
m_shadow_pipeline->bindDescriptor( command_buffer, info.getCameraDescriptor() );
auto& model_buffers { getModelBuffers() };
const std::vector< vk::Buffer > vert_buffers {
model_buffers.m_vertex_buffer->getVkBuffer(),
info.camera->m_generated_instance_info[ info.in_flight_idx ].getVkBuffer(),
};
command_buffer->bindVertexBuffers(
0, vert_buffers, { 0, info.camera->m_generated_instance_info[ info.in_flight_idx ].getOffset() } );
command_buffer->bindIndexBuffer( model_buffers.m_index_buffer->getVkBuffer(), 0, vk::IndexType::eUint32 );
const auto& commands { info.camera->m_gpu_draw_commands[ info.in_flight_idx ] };
command_buffer
->drawIndexedIndirect( commands.getVkBuffer(), commands.getOffset(), commands.size(), commands.stride() );
command_buffer->endRendering();
}
static std::vector< std::weak_ptr< ShadowMap > > shadowmaps {};
descriptors::DescriptorSetLayout& ShadowMap::getDescriptorLayout()
{
return shadowmap_descriptor_set;
}
std::shared_ptr< ShadowMap > createShadowmap( UniversalRotation direction )
{
constexpr int size { 1024 };
auto ptr { std::make_shared< ShadowMap >( direction, vk::Extent2D { size, size } ) };
shadowmaps.emplace_back( ptr );
return ptr;
}
std::vector< std::weak_ptr< ShadowMap > > getShadowmaps()
{
return shadowmaps;
}
} // namespace fgl::engine

View File

@@ -0,0 +1,55 @@
//
// Created by kj16609 on 9/23/25.
//
#pragma once
#include <vulkan/vulkan.hpp>
#include <memory>
#include "RenderCamera.hpp"
#include "Swapchain.hpp"
#include "primitives/rotation/UniversalRotation.hpp"
#include "systems/prerender/CullingSystem.hpp"
namespace fgl::engine
{
namespace gui
{
extern void drawShadowmaps( const FrameInfo& info );
}
struct CameraInfo;
class ShadowMap
{
std::shared_ptr< Swapchain > m_swapchain;
UniversalRotation m_direction;
std::shared_ptr< CameraViewpoint > m_camera;
std::unique_ptr< Pipeline > m_shadow_pipeline;
CullingSystem m_culling_system;
vk::Extent2D m_extent;
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > createShadowmapDescriptors() const;
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > m_shadowmap_descriptor;
public:
ShadowMap() = delete;
ShadowMap( const UniversalRotation& direction, vk::Extent2D extent );
void pass( FrameInfo info );
friend void gui::drawShadowmaps( const FrameInfo& info );
static descriptors::DescriptorSetLayout& getDescriptorLayout();
};
std::shared_ptr< ShadowMap > createShadowmap( UniversalRotation direction );
std::vector< std::weak_ptr< ShadowMap > > getShadowmaps();
} // namespace fgl::engine

View File

@@ -0,0 +1,79 @@
//
// Created by kj16609 on 9/23/25.
//
#include "Swapchain.hpp"
#include "assets/image/Image.hpp"
#include "assets/image/ImageView.hpp"
#include "assets/texture/Texture.hpp"
#include "constants.hpp"
#include "rendering/devices/Device.hpp"
namespace fgl::engine
{
vk::Format SwapchainImageInfo::pickBestFormat() const
{
return Device::getInstance()
.findSupportedFormat( m_format.m_canidates, vk::ImageTiling::eOptimal, m_format.m_features );
}
SwapchainImageSet::SwapchainImageSet( const SwapchainImageInfo& info )
{
for ( int i = 0; i < constants::MAX_FRAMES_IN_FLIGHT; ++i )
{
auto image_itter { m_image.emplace_back(
std::make_shared< Image >(
info.m_extent,
info.pickBestFormat(),
info.m_format.m_usage,
info.m_inital_layout,
info.m_final_layout ) ) };
auto view_itter { m_view.emplace_back( image_itter->getView() ) };
image_itter->setName( std::format( "Swapchain image {}:{}", info.m_name, i ) );
}
}
std::shared_ptr< Texture > SwapchainImageSet::getTexture( const FrameIndex frame_index ) const
{
if ( m_texture.empty() ) m_texture.resize( constants::MAX_FRAMES_IN_FLIGHT );
if ( !m_texture[ frame_index ] )
{
Sampler default_sampler {};
m_texture[ frame_index ] =
std::make_shared< Texture >( m_image[ frame_index ], std::move( default_sampler ) );
}
return m_texture[ frame_index ];
}
std::shared_ptr< ImageView > Swapchain::depthView( const FrameIndex frame_index ) const
{
const SwapchainImageSet& set { m_depth.value() };
return set.m_view[ frame_index ];
}
std::shared_ptr< Image > Swapchain::depthImage( const FrameIndex frame_index ) const
{
return m_depth.value().m_image[ frame_index ];
}
std::shared_ptr< Texture > Swapchain::depthTexture( const FrameIndex frame_index ) const
{
return m_depth.value().getTexture( frame_index );
}
Swapchain::Swapchain( const std::vector< SwapchainImageInfo >& in )
{
for ( const SwapchainImageInfo& info : in )
{
if ( info.m_format.m_usage & vk::ImageUsageFlagBits::eDepthStencilAttachment )
m_depth.emplace( info );
else
m_swapchain_images.emplace_back( info );
}
}
} // namespace fgl::engine

View File

@@ -0,0 +1,69 @@
//
// Created by kj16609 on 9/23/25.
//
#pragma once
#include <vulkan/vulkan.hpp>
#include <memory>
#include <unordered_map>
#include <vector>
#include "FGL_DEFINES.hpp"
#include "assets/texture/Texture.hpp"
#include "rendering/types.hpp"
namespace fgl::engine
{
class Image;
class ImageView;
struct SwapchainImageInfo
{
struct
{
std::vector< vk::Format > m_canidates;
vk::ImageUsageFlags m_usage;
vk::FormatFeatureFlags m_features;
} m_format;
vk::ImageLayout m_inital_layout;
vk::ImageLayout m_final_layout;
vk::Extent2D m_extent;
std::string m_name;
[[nodiscard]] vk::Format pickBestFormat() const;
};
class SwapchainImageSet
{
std::vector< std::shared_ptr< Image > > m_image {};
std::vector< std::shared_ptr< ImageView > > m_view {};
mutable std::vector< std::shared_ptr< Texture > > m_texture {};
friend class Swapchain;
public:
SwapchainImageSet() = delete;
[[nodiscard]] SwapchainImageSet( const SwapchainImageInfo& info );
std::shared_ptr< Texture > getTexture( FrameIndex frame_index ) const;
};
class Swapchain
{
std::vector< SwapchainImageSet > m_swapchain_images {};
std::optional< SwapchainImageSet > m_depth {};
public:
[[nodiscard]] std::shared_ptr< ImageView > depthView( FrameIndex frame_index ) const;
[[nodiscard]] std::shared_ptr< Image > depthImage( FrameIndex frame_index ) const;
std::shared_ptr< Texture > depthTexture( FrameIndex frame_index ) const;
FGL_DELETE_ALL_RO5( Swapchain );
[[nodiscard]] explicit Swapchain( const std::vector< SwapchainImageInfo >& in );
};
} // namespace fgl::engine

View File

@@ -10,16 +10,12 @@ namespace fgl::engine
{
template < typename T >
concept is_bindable_buffer = requires( T t ) {
{
t.descriptorInfo()
} -> std::same_as< vk::DescriptorBufferInfo >;
{ t.descriptorInfo() } -> std::same_as< vk::DescriptorBufferInfo >;
};
template < typename T >
concept is_bindable_image = requires( T t ) {
{
t.descriptorInfo()
} -> std::same_as< vk::DescriptorImageInfo >;
{ t.descriptorInfo() } -> std::same_as< vk::DescriptorImageInfo >;
};
template < typename T > concept is_bindable = is_bindable_image< T > || is_bindable_buffer< T >;

View File

@@ -10,8 +10,6 @@ namespace fgl::engine
{
template < typename T >
concept is_constant_range = requires( T t ) {
{
t.m_range
} -> std::same_as< const vk::PushConstantRange& >;
{ t.m_range } -> std::same_as< const vk::PushConstantRange& >;
};
} // namespace fgl::engine

View File

@@ -9,15 +9,9 @@ namespace fgl::engine
template < typename T >
concept is_image = requires( T a ) {
{
a.getVkImage()
} -> std::same_as< vk::Image& >;
{
a.format()
} -> std::same_as< vk::Format >;
{
a.extent()
} -> std::same_as< vk::Extent2D >;
{ a.getVkImage() } -> std::same_as< vk::Image& >;
{ a.format() } -> std::same_as< vk::Format >;
{ a.extent() } -> std::same_as< vk::Extent2D >;
};
}
} // namespace fgl::engine

View File

@@ -4,11 +4,8 @@
#pragma once
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#include <glm/mat4x4.hpp>
#include <glm/vec3.hpp>
#pragma GCC diagnostic pop
#include "types.hpp"
@@ -55,4 +52,6 @@ namespace fgl::engine::constants
constexpr glm::vec3 DEFAULT_SCALE { 1.0f };
constexpr glm::vec3 SUN_DIR { 0.0f, 0.0f, 1.0f };
} // namespace fgl::engine::constants

View File

@@ -4,11 +4,7 @@
#include "matrix.hpp"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wduplicated-branches"
#include <glm/glm.hpp>
#pragma GCC diagnostic pop
std::format_context::iterator std::formatter< glm::vec4 >::format( const glm::vec4& vec, format_context& ctx ) const
{

View File

@@ -4,17 +4,11 @@
#pragma once
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#pragma GCC diagnostic ignored "-Wnoexcept"
#include <spdlog/spdlog.h>
#pragma GCC diagnostic pop
#include "formatters/filesystem.hpp"
#include "formatters/matrix.hpp"
#include "formatters/glm.hpp"
#include "formatters/matrix.hpp"
namespace fgl::engine::log
{

View File

@@ -6,12 +6,6 @@
#include <cassert>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Weffc++"
#include <imgui.h>
#pragma GCC diagnostic pop
#include "engine/FGL_DEFINES.hpp"
#include "engine/clock.hpp"
#include "engine/debug/logging/logging.hpp"
@@ -30,9 +24,9 @@ namespace fgl::engine::debug
using Duration = ProfilingClock::duration;
Duration getDuration() const { return m_end - m_start; }
[[nodiscard]] Duration getDuration() const { return m_end - m_start; }
Duration getTotalTime() const
[[nodiscard]] Duration getTotalTime() const
{
if ( m_parent != nullptr ) return m_parent->getTotalTime();

View File

@@ -9,7 +9,15 @@
namespace fgl::engine::descriptors
{
vk::raii::DescriptorPool createPool( std::uint32_t set_count )
static const std::unordered_map< vk::DescriptorType, float > DESCRIPTOR_ALLOCATION_RATIOS {
{ vk::DescriptorType::eUniformBuffer, 1.0f },
{ vk::DescriptorType::eCombinedImageSampler, 2.0f },
{ vk::DescriptorType::eStorageBuffer, 1.0f },
{ vk::DescriptorType::eInputAttachment, 0.5f },
{ vk::DescriptorType::eSampledImage, 2.0f }
};
vk::raii::DescriptorPool createPool( const std::uint32_t set_count )
{
std::vector< vk::DescriptorPoolSize > pool_sizes {};
for ( auto& [ type, ratio ] : DESCRIPTOR_ALLOCATION_RATIOS )

Some files were not shown because too many files have changed in this diff Show More