Get multi camera working

This commit is contained in:
2024-07-28 00:32:31 -04:00
parent 022cdc681e
commit 8fe9c94b6b
35 changed files with 426 additions and 248 deletions

View File

@@ -4,10 +4,17 @@ 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 (NOT DEFINED FGL_ENABLE_PROFILING)
set(FGL_ENABLE_PROFILING 0)
endif ()
#if (CMAKE_UPPER_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_UPPER_BUILD_TYPE STREQUAL "RELWITHDEBINFO" AND DEFINED FGL_ENABLE_PROFILING)
if (FGL_ENABLE_PROFILING)
set(TRACY_ENABLE ON)
set(TRACY_ON_DEMAND ON)
set(TRACY_NO_EXIT ON)
else ()
set(TRACY_ENABLE OFF)
endif ()
add_subdirectory(${CMAKE_SOURCE_DIR}/dependencies/tracy)

View File

@@ -1,43 +0,0 @@
#version 450
layout (location = 0) in vec2 frag_offset;
layout (location = 0) out vec4 out_color;
struct PointLight
{
vec4 position;
vec4 color;
};
layout (set = 0, binding = 0) uniform GlobalUbo {
mat4 projection;
mat4 view;
mat4 inverse_view;
vec4 ambient_light_color; // w is intensity
} ubo;
layout (set = 0, binding = 1) uniform LightingUBO
{
PointLight lights[10];
int num;
} point_lights;
layout (push_constant) uniform Push
{
vec4 position;
vec4 color;
float radius;
} push;
const float M_PI = 3.14151926538;
void main() {
float dis = sqrt(dot(frag_offset, frag_offset));
if (dis >= 1.0)
{
discard;
}
out_color = vec4(push.color.xyz, 0.5 * (cos(dis * M_PI) + 1.0));
}

View File

@@ -1,53 +0,0 @@
#version 450
const vec2 OFFSETS[6] = vec2[](
vec2(-1.0, -1.0),
vec2(-1.0, 1.0),
vec2(1.0, -1.0),
vec2(1.0, -1.0),
vec2(-1.0, 1.0),
vec2(1.0, 1.0)
);
layout (location = 0) out vec2 frag_offset;
struct PointLight
{
vec4 position;
vec4 color;
};
layout (set = 0, binding = 0) uniform GlobalUbo {
mat4 projection;
mat4 view;
mat4 inverse_view;
vec4 ambient_light_color; // w is intensity
} ubo;
layout (set = 0, binding = 1) uniform LightingUBO
{
PointLight lights[10];
int num;
} point_lights;
layout (push_constant) uniform Push
{
vec4 position;
vec4 color;
float radius;
} push;
void main() {
frag_offset = OFFSETS[gl_VertexIndex];
vec3 camera_right_world = { ubo.view[0][0], ubo.view[1][0], ubo.view[2][0] };
vec3 camera_up_world = { ubo.view[0][1], ubo.view[1][1], ubo.view[2][1] };
vec3 position_world = push.position.xyz + push.radius * frag_offset.x * camera_right_world + push.radius * frag_offset.y * camera_up_world;
gl_Position = ubo.projection * ubo.view * vec4(position_world, 1.0);
}

View File

@@ -11,13 +11,13 @@ layout (location = 0) out vec4 out_position;
layout (location = 1) out vec4 out_normal;
layout (location = 2) out vec4 out_albedo;
layout (set = 0, binding = 0) uniform CameraInfo {
layout (set = 1, binding = 0) uniform CameraInfo {
mat4 projection;
mat4 view;
mat4 inverse_view;
} ubo;
layout (set = 1, binding = 0) uniform sampler2D tex[];
layout (set = 2, binding = 0) uniform sampler2D tex[];
#define NEAR_PLANE 0.01f
#define FAR_PLANE 1000.0f

View File

@@ -14,7 +14,7 @@ layout (location = 1) out vec2 out_tex_coord;
layout (location = 2) out vec3 out_world_pos;
layout (location = 3) out flat uint out_texture_idx;
layout (set = 0, binding = 0) uniform CameraInfo {
layout (set = 1, binding = 0) uniform CameraInfo {
mat4 projection;
mat4 view;
mat4 inverse_view;

View File

@@ -11,7 +11,7 @@ layout (location = 0) out vec4 out_position;
layout (location = 1) out vec4 out_normal;
layout (location = 2) out vec4 out_albedo;
layout (set = 0, binding = 0) uniform CameraInfo {
layout (set = 1, binding = 0) uniform CameraInfo {
mat4 projection;
mat4 view;
mat4 inverse_view;

View File

@@ -13,14 +13,13 @@ layout (location = 1) out vec2 out_tex_coord;
layout (location = 2) out vec3 out_world_pos;
layout (location = 3) out vec3 out_color;
layout (set = 0, binding = 0) uniform CameraInfo {
layout (set = 1, binding = 0) uniform CameraInfo {
mat4 projection;
mat4 view;
mat4 inverse_view;
} ubo;
void main() {
vec4 position_world = instance_model_matrix * vec4(position, 1.0);
gl_Position = ubo.projection * ubo.view * position_world;

View File

@@ -40,18 +40,18 @@ target_compile_features(FGLEngine PRIVATE cxx_std_23)
string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_UPPER_BUILD_TYPE)
if (NOT DEFINED FORCE_DISABLE_IMGUI)
set(FORCE_DISABLE_IMGUI 0)
if (NOT DEFINED FGL_ENABLE_IMGUI AND CMAKE_UPPER_BUILD_TYPE STREQUAL "DEBUG")
set(FGL_ENABLE_IMGUI 1)
endif ()
if (FORCE_DISABLE_IMGUI EQUAL 0)
if (CMAKE_UPPER_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_UPPER_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
target_compile_definitions(FGLEngine PRIVATE ENABLE_IMGUI=1)
target_compile_definitions(FGLEngine PRIVATE ENABLE_IMGUI_DRAWERS=1)
else ()
target_compile_definitions(FGLEngine PRIVATE ENABLE_IMGUI=0)
target_compile_definitions(FGLEngine PRIVATE ENABLE_IMGUI_DRAWERS=0)
endif ()
message("-- FGL_ENABLE_IMGUI: ${FGL_ENABLE_IMGUI}")
if (FGL_ENABLE_IMGUI)
target_compile_definitions(FGLEngine PRIVATE ENABLE_IMGUI=1)
target_compile_definitions(FGLEngine PRIVATE ENABLE_IMGUI_DRAWERS=1)
else ()
target_compile_definitions(FGLEngine PRIVATE ENABLE_IMGUI=0)
target_compile_definitions(FGLEngine PRIVATE ENABLE_IMGUI_DRAWERS=0)
endif ()
#GLM settings

View File

@@ -15,13 +15,13 @@
#include "assets/stores.hpp"
#include "buffers/HostSingleT.hpp"
#include "camera/Camera.hpp"
#include "camera/CameraManager.hpp"
#include "engine/Average.hpp"
#include "engine/assets/TransferManager.hpp"
#include "engine/buffers/UniqueFrameSuballocation.hpp"
#include "engine/debug/drawers.hpp"
#include "engine/literals/size.hpp"
#include "engine/model/prebuilt/terrainModel.hpp"
#include "engine/pipeline/PipelineT.hpp"
#include "engine/systems/EntityRendererSystem.hpp"
#include "gui/core.hpp"
#include "model/builders/SceneBuilder.hpp"
@@ -49,16 +49,13 @@ namespace fgl::engine
{
TracyCZoneN( TRACY_PrepareEngine, "Inital Run", true );
std::cout << "Starting main loop run" << std::endl;
using namespace fgl::literals::size_literals;
memory::Buffer global_ubo_buffer { 512_KiB,
vk::BufferUsageFlagBits::eUniformBuffer,
vk::MemoryPropertyFlagBits::eHostVisible }; // 512 KB
//Camera prep
Camera::initCameraRenderer();
PerFrameSuballocation< HostSingleT< CameraInfo > > camera_info { global_ubo_buffer,
SwapChain::MAX_FRAMES_IN_FLIGHT };
CameraManager camera_manager {};
PerFrameSuballocation< HostSingleT< PointLight > > point_lights { global_ubo_buffer,
SwapChain::MAX_FRAMES_IN_FLIGHT };
@@ -74,7 +71,7 @@ namespace fgl::engine
std::vector< memory::Buffer > draw_parameter_buffers {};
std::vector< descriptors::DescriptorSet > global_descriptor_sets {};
// std::vector< descriptors::DescriptorSet > global_descriptor_sets {};
for ( int i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i )
{
@@ -88,19 +85,15 @@ namespace fgl::engine
vk::BufferUsageFlagBits::eIndirectBuffer,
vk::MemoryPropertyFlagBits::eDeviceLocal | vk::MemoryPropertyFlagBits::eHostVisible );
global_descriptor_sets.emplace_back( GlobalDescriptorSet::createLayout() );
// global_descriptor_sets.emplace_back( GlobalDescriptorSet::createLayout() );
}
for ( std::uint8_t i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i )
{
global_descriptor_sets[ i ].setMaxIDX( 2 );
global_descriptor_sets[ i ].bindUniformBuffer( 0, camera_info[ i ] );
global_descriptor_sets[ i ].bindUniformBuffer( 2, point_lights[ i ] );
global_descriptor_sets[ i ].update();
}
Camera camera { vk::Extent2D( 1920, 1080 ) };
debug::setDebugDrawingCamera( camera );
// for ( std::uint8_t i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i )
// {
// global_descriptor_sets[ i ].setMaxIDX( 2 );
// global_descriptor_sets[ i ].bindUniformBuffer( 2, point_lights[ i ] );
// global_descriptor_sets[ i ].update();
// }
auto viewer { GameObject::createGameObject() };
@@ -114,14 +107,22 @@ namespace fgl::engine
//camera.setOrthographicProjection( -aspect, aspect, -1, 1, -1, 1 );
const float aspect { m_renderer.getAspectRatio() };
camera.setPerspectiveProjection( glm::radians( 90.0f ), aspect, constants::NEAR_PLANE, constants::FAR_PLANE );
auto& primary_camera { camera_manager.getPrimary() };
auto secondary_camera { camera_manager.createCamera( { 1920, 1080 } ) };
primary_camera
.setPerspectiveProjection( glm::radians( 90.0f ), aspect, constants::NEAR_PLANE, constants::FAR_PLANE );
secondary_camera
->setPerspectiveProjection( glm::radians( 90.0f ), aspect, constants::NEAR_PLANE, constants::FAR_PLANE );
const auto old_aspect_ratio { m_renderer.getAspectRatio() };
TracyCZoneEnd( TRACY_PrepareEngine );
camera_controller.moveInPlaneXZ( m_window.window(), 0.0, viewer );
primary_camera.setView( viewer.getPosition(), viewer.getRotation() );
secondary_camera->setView( viewer.getPosition(), viewer.getRotation() );
//TODO: Make a camera management object
std::vector< Camera* > cameras { &camera };
TracyCZoneEnd( TRACY_PrepareEngine );
while ( !m_window.shouldClose() )
{
@@ -148,12 +149,12 @@ namespace fgl::engine
if ( old_aspect_ratio != m_renderer.getAspectRatio() )
{
camera.setPerspectiveProjection(
primary_camera.setPerspectiveProjection(
glm::radians( 90.0f ), m_renderer.getAspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE );
}
camera_controller.moveInPlaneXZ( m_window.window(), delta_time, viewer );
camera.setView( viewer.getPosition(), viewer.getRotation() );
primary_camera.setView( viewer.getPosition(), viewer.getRotation() );
if ( auto& command_buffer = m_renderer.beginFrame(); *command_buffer )
{
@@ -161,14 +162,13 @@ namespace fgl::engine
const FrameIndex frame_index { m_renderer.getFrameIndex() };
const PresentIndex present_idx { m_renderer.getPresentIndex() };
const auto view_frustum { camera.getFrustumBounds() };
FrameInfo frame_info { frame_index,
present_idx,
delta_time,
command_buffer,
{ camera, viewer.getTransform() },
global_descriptor_sets[ frame_index ],
{ nullptr, viewer.getTransform() },
camera_manager.getCameras(),
// global_descriptor_sets[ frame_index ],
m_game_objects_root,
m_renderer.getCurrentTracyCTX(),
matrix_info_buffers[ frame_index ],
@@ -176,33 +176,32 @@ namespace fgl::engine
*this->m_vertex_buffer,
*this->m_index_buffer,
m_renderer.getSwapChain().getInputDescriptor( present_idx ),
view_frustum,
this->m_renderer.getSwapChain() };
#if TRACY_ENABLE
//auto& tracy_ctx { frame_info.tracy_ctx };
#endif
CameraInfo current_camera_info { .projection = camera.getProjectionMatrix(),
.view = camera.getViewMatrix(),
.inverse_view = camera.getInverseViewMatrix() };
camera_info[ frame_index ] = current_camera_info;
TracyVkCollect( frame_info.tracy_ctx, *command_buffer );
//TODO: Setup semaphores to make this pass not always required.
memory::TransferManager::getInstance().recordOwnershipTransferDst( command_buffer );
for ( auto* current_camera : cameras )
for ( auto& current_camera_ptr : camera_manager.getCameras() )
{
current_camera->pass( frame_info );
if ( current_camera_ptr.expired() ) continue;
auto sh_camera { current_camera_ptr.lock() };
Camera& current_camera { *sh_camera };
current_camera.pass( frame_info );
}
auto* primary_camera { cameras[ 0 ] };
m_renderer.clearInputImage( command_buffer );
primary_camera
->copyOutput( command_buffer, frame_index, m_renderer.getSwapChain().getInputImage( present_idx ) );
//primary_camera
// .copyOutput( command_buffer, frame_index, m_renderer.getSwapChain().getInputImage( present_idx ) );
m_renderer.beginSwapchainRendererPass( command_buffer );

View File

@@ -12,7 +12,12 @@ namespace fgl::engine
descriptors::DescriptorSet& FrameInfo::getGBufferDescriptor()
{
return camera_data.camera.getSwapchain().getGBufferDescriptor( frame_idx );
return camera_data.camera->getSwapchain().getGBufferDescriptor( frame_idx );
}
descriptors::DescriptorSet& FrameInfo::getCameraDescriptor()
{
return camera_data.camera->getDescriptor( frame_idx );
}
} // namespace fgl::engine

View File

@@ -35,26 +35,13 @@ namespace fgl::engine
glm::vec4 color {};
};
struct CameraInfo
{
glm::mat4 projection { 1.0f };
glm::mat4 view { 1.0f };
glm::mat4 inverse_view { 1.0f };
};
struct PointLightUBO
{
alignas( 16 ) PointLight point_lights[ MAX_LIGHTS ] {};
alignas( 16 ) int num_lights { 0 };
};
using CameraDescriptor =
descriptors::Descriptor< 0, vk::DescriptorType::eUniformBuffer, vk::ShaderStageFlagBits::eAllGraphics >;
using LightDescriptor =
descriptors::Descriptor< 2, vk::DescriptorType::eUniformBuffer, vk::ShaderStageFlagBits::eAllGraphics >;
using GlobalDescriptorSet =
descriptors::DescriptorSetLayout< 0, CameraDescriptor, descriptors::EmptyDescriptor< 1 >, LightDescriptor >;
//using GlobalDescriptorSet = descriptors::DescriptorSetLayout< 0, descriptors::EmptyDescriptor< 0 > >;
using TextureDescriptor = descriptors::Descriptor<
0,
@@ -63,7 +50,7 @@ namespace fgl::engine
512,
vk::DescriptorBindingFlagBits::eUpdateAfterBind | vk::DescriptorBindingFlagBits::ePartiallyBound >;
using TextureDescriptorSet = descriptors::DescriptorSetLayout< 1, TextureDescriptor >;
using TextureDescriptorSet = descriptors::DescriptorSetLayout< 2, TextureDescriptor >;
using PositionDescriptor = descriptors::AttachmentDescriptor< 0, vk::ShaderStageFlagBits::eFragment >;
using NormalDescriptor = descriptors::AttachmentDescriptor< 1, vk::ShaderStageFlagBits::eFragment >;
@@ -90,11 +77,13 @@ namespace fgl::engine
struct
{
Camera& camera;
Camera* camera { nullptr };
TransformComponent& camera_transform;
} camera_data;
descriptors::DescriptorSet& global_descriptor_set;
std::vector< std::weak_ptr< Camera > >& m_camera_list;
// descriptors::DescriptorSet& global_descriptor_set;
OctTreeNode& game_objects;
TracyVkCtx tracy_ctx;
@@ -108,8 +97,8 @@ namespace fgl::engine
descriptors::DescriptorSet& gui_input_descriptor;
descriptors::DescriptorSet& getGBufferDescriptor();
descriptors::DescriptorSet& getCameraDescriptor();
const Frustum< CoordinateSpace::World >& camera_frustum;
SwapChain& swap_chain;
std::vector< std::vector< GameObject >* > in_view_leafs {};

View File

@@ -4,6 +4,9 @@
#pragma once
#include "Buffer.hpp"
#include "BufferSuballocation.hpp"
namespace fgl::engine
{

View File

@@ -8,6 +8,9 @@
#include <glm/gtx/string_cast.hpp>
#include <tracy/Tracy.hpp>
#include "CameraDescriptor.hpp"
#include "CameraInfo.hpp"
#include "CameraRenderer.hpp"
#include "CameraSwapchain.hpp"
namespace fgl::engine
@@ -40,9 +43,28 @@ namespace fgl::engine
return WorldCoordinate( inverse_view_matrix[ 3 ] );
}
void Camera::pass( FrameInfo& frame_info ) const
void Camera::updateInfo( const FrameIndex frame_index )
{
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 )
{
assert( index < m_camera_info_descriptors.size() );
return m_camera_info_descriptors[ index ];
}
void Camera::pass( FrameInfo& frame_info )
{
assert( frame_info.camera_data.camera == nullptr );
frame_info.camera_data.camera = this;
updateInfo( frame_info.frame_idx );
m_renderer->pass( frame_info, *m_swapchain );
frame_info.camera_data.camera = nullptr;
}
vk::raii::RenderPass& Camera::getRenderpass()
@@ -262,12 +284,23 @@ namespace fgl::engine
m_renderer = std::make_unique< CameraRenderer >();
}
Camera::Camera( const vk::Extent2D extent ) :
Camera::Camera( const vk::Extent2D extent, memory::Buffer& buffer ) :
m_extent( extent ),
m_camera_frame_info( buffer, SwapChain::MAX_FRAMES_IN_FLIGHT ),
m_swapchain( std::make_shared< CameraSwapchain >( m_renderer->getRenderpass(), m_extent ) )
{
this->setPerspectiveProjection( 90.0f, 16.0f / 9.0f, constants::NEAR_PLANE, constants::FAR_PLANE );
this->setView( WorldCoordinate( constants::CENTER ), Rotation( 0.0f, 0.0f, 0.0f ) );
for ( std::uint8_t i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i )
{
descriptors::DescriptorSet set { CameraDescriptorSet::createLayout() };
set.setMaxIDX( 0 );
set.bindUniformBuffer( 0, m_camera_frame_info[ i ] );
set.update();
m_camera_info_descriptors.emplace_back( std::move( set ) );
}
}
void Camera::setExtent( const vk::Extent2D extent )
@@ -340,4 +373,7 @@ namespace fgl::engine
return last_frustum_pos;
}
Camera::~Camera()
{}
} // namespace fgl::engine

View File

@@ -13,15 +13,26 @@
#pragma GCC diagnostic pop
#include "CameraRenderer.hpp"
#include "engine/constants.hpp"
#include "engine/buffers/HostSingleT.hpp"
#include "engine/buffers/UniqueFrameSuballocation.hpp"
#include "engine/descriptors/DescriptorSet.hpp"
#include "engine/primitives/Frustum.hpp"
#include "engine/primitives/TransformComponent.hpp"
#include "engine/primitives/matricies/Matrix.hpp"
#include "engine/primitives/points/Coordinate.hpp"
#include "engine/rendering/SwapChain.hpp"
#include "engine/primitives/Rotation.hpp"
#include "engine/rendering/types.hpp"
namespace vk::raii
{
class CommandBuffer;
class RenderPass;
} // namespace vk::raii
namespace fgl::engine
{
class Image;
struct FrameInfo;
class CameraRenderer;
struct CameraInfo;
class CameraSwapchain;
class Camera;
@@ -49,6 +60,11 @@ namespace fgl::engine
vk::Extent2D m_extent;
PerFrameSuballocation< HostSingleT< CameraInfo > > m_camera_frame_info;
// Camera info is expected at binding 0
std::vector< descriptors::DescriptorSet > m_camera_info_descriptors {};
inline static std::unique_ptr< CameraRenderer > m_renderer;
std::shared_ptr< CameraSwapchain > m_swapchain;
@@ -56,11 +72,19 @@ namespace fgl::engine
void updateFrustum();
Camera( vk::Extent2D extent, memory::Buffer& data_buffer );
friend class CameraManager;
public:
static void initCameraRenderer();
FGL_DELETE_ALL_Ro5( Camera );
Camera( vk::Extent2D extent );
~Camera();
CameraIDX getIDX() { return camera_idx; }
static void initCameraRenderer();
void setExtent( vk::Extent2D extent );
@@ -81,25 +105,45 @@ namespace fgl::engine
glm::mat4 getInverseViewMatrix() const { return glm::inverse( view_matrix ); }
enum ViewMode
{
Euler,
TaitBryan
};
void setView( WorldCoordinate pos, const Rotation& 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 );
Coordinate< CoordinateSpace::World > getPosition() const;
Vector getUp() const { return -getDown(); }
FGL_FORCE_INLINE Vector getUp() const { return -getDown(); }
Vector getRight() const { return Vector( glm::normalize( glm::vec3( inverse_view_matrix[ 0 ] ) ) ); }
FGL_FORCE_INLINE Vector getRight() const
{
return Vector( glm::normalize( glm::vec3( inverse_view_matrix[ 0 ] ) ) );
}
Vector getForward() const { return Vector( glm::normalize( glm::vec3( inverse_view_matrix[ 2 ] ) ) ); }
FGL_FORCE_INLINE Vector getForward() const
{
return Vector( glm::normalize( glm::vec3( inverse_view_matrix[ 2 ] ) ) );
}
Vector getLeft() const { return -getRight(); }
FGL_FORCE_INLINE Vector getLeft() const { return -getRight(); }
Vector getBackward() const { return -getForward(); }
FGL_FORCE_INLINE Vector getBackward() const { return -getForward(); }
Vector getDown() const { return Vector( glm::normalize( glm::vec3( inverse_view_matrix[ 1 ] ) ) ); }
FGL_FORCE_INLINE Vector getDown() const
{
return Vector( glm::normalize( glm::vec3( inverse_view_matrix[ 1 ] ) ) );
}
//! Updates the required info for rendering
void updateInfo( FrameIndex frame_index );
descriptors::DescriptorSet& getDescriptor( FrameIndex index );
//! Performs the render pass for this camera
void pass( FrameInfo& frame_info ) const;
void pass( FrameInfo& frame_info );
static vk::raii::RenderPass& getRenderpass();
CameraSwapchain& getSwapchain() const;
@@ -110,14 +154,6 @@ namespace fgl::engine
void endRenderpass( const vk::raii::CommandBuffer& command_buffer );
void copyOutput( const vk::raii::CommandBuffer& command_buffer, FrameIndex frame_index, Image& target );
enum ViewMode
{
Euler,
TaitBryan
};
void setView( WorldCoordinate pos, const Rotation& rotation, ViewMode mode = TaitBryan );
};
} // namespace fgl::engine

View File

@@ -0,0 +1,14 @@
//
// Created by kj16609 on 7/27/24.
//
#pragma once
#include "engine/descriptors/DescriptorSetLayout.hpp"
namespace fgl::engine
{
using CameraDescriptor =
descriptors::Descriptor< 0, vk::DescriptorType::eUniformBuffer, vk::ShaderStageFlagBits::eAllGraphics >;
using CameraDescriptorSet = descriptors::DescriptorSetLayout< 1, CameraDescriptor >;
} // namespace fgl::engine

View File

@@ -0,0 +1,17 @@
//
// Created by kj16609 on 7/23/24.
//
#pragma once
namespace fgl::engine
{
struct CameraInfo
{
glm::mat4 projection { 1.0f };
glm::mat4 view { 1.0f };
glm::mat4 inverse_view { 1.0f };
};
} // namespace fgl::engine

View File

@@ -0,0 +1,43 @@
//
// Created by kj16609 on 7/23/24.
//
#include "CameraManager.hpp"
#include "Camera.hpp"
#include "engine/debug/drawers.hpp"
#include "engine/literals/size.hpp"
namespace fgl::engine
{
using namespace fgl::literals::size_literals;
std::vector< std::weak_ptr< Camera > >& CameraManager::getCameras()
{
return cameras;
}
Camera& CameraManager::getPrimary()
{
return *m_primary_camera;
}
CameraManager::CameraManager() :
m_data_buffer( 4_KiB, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostVisible )
{
Camera::initCameraRenderer();
debug::setDebugDrawingCamera( getPrimary() );
m_primary_camera = createCamera( { 1920, 1080 } );
}
std::shared_ptr< Camera > CameraManager::createCamera( const vk::Extent2D extent )
{
std::shared_ptr< Camera > camera { new Camera( extent, m_data_buffer ) };
this->cameras.emplace_back( camera );
return camera;
}
} // namespace fgl::engine

View File

@@ -0,0 +1,37 @@
//
// Created by kj16609 on 7/23/24.
//
#pragma once
#include <vector>
#include "Camera.hpp"
#include "engine/buffers/UniqueFrameSuballocation.hpp"
namespace fgl::engine
{
namespace descriptors
{
class DescriptorSet;
}
class CameraManager
{
memory::Buffer m_data_buffer;
std::shared_ptr< Camera > m_primary_camera { nullptr };
std::vector< std::weak_ptr< Camera > > cameras {};
public:
std::vector< std::weak_ptr< Camera > >& getCameras();
Camera& getPrimary();
CameraManager();
std::shared_ptr< Camera > createCamera( vk::Extent2D extent );
};
} // namespace fgl::engine

View File

@@ -137,7 +137,7 @@ namespace fgl::engine
m_culling_system.wait();
m_terrain_system.pass( frame_info );
//m_terrain_system.pass( frame_info );
m_entity_renderer.pass( frame_info );

View File

@@ -9,7 +9,6 @@
#include "engine/systems/CompositionSystem.hpp"
#include "engine/systems/CullingSystem.hpp"
#include "engine/systems/EntityRendererSystem.hpp"
#include "engine/systems/TerrainSystem.hpp"
namespace fgl::engine
{
@@ -25,7 +24,7 @@ namespace fgl::engine
CullingSystem m_culling_system {};
// SubPass 0
TerrainSystem m_terrain_system { Device::getInstance(), m_renderpass };
//TerrainSystem m_terrain_system { Device::getInstance(), m_renderpass };
EntityRendererSystem m_entity_renderer { Device::getInstance(), m_renderpass };
// SubPass 1

42
src/engine/gui/camera.cpp Normal file
View File

@@ -0,0 +1,42 @@
//
// Created by kj16609 on 7/23/24.
//
#include "engine/camera/Camera.hpp"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wconversion"
#include <imgui.h>
#pragma GCC diagnostic pop
#include "engine/FrameInfo.hpp"
#include "preview.hpp"
namespace fgl::engine::gui
{
void drawCameraOutputs( FrameInfo& info )
{
auto& camera_list { info.m_camera_list };
for ( const auto& weak_camera_ptr : camera_list )
{
if ( weak_camera_ptr.expired() ) continue;
auto camera_ptr { weak_camera_ptr.lock() };
assert( camera_ptr );
Camera& camera { *camera_ptr };
const auto name { std::format( "Camera: {}", camera.getIDX() ) };
ImGui::Begin( name.c_str() );
drawRenderingOutputs( info, camera );
ImGui::End();
}
}
} // namespace fgl::engine::gui

View File

@@ -143,7 +143,7 @@ namespace fgl::engine::gui
//static std::once_flag flag;
//std::call_once( flag, prepareDock );
drawRenderingOutputs( info );
drawCameraOutputs( info );
drawEntityGUI( info );
drawEntityInfo( info );
drawFilesystemGUI( info );

View File

@@ -23,4 +23,6 @@ namespace fgl::engine::gui
void drawEntityInfo( FrameInfo& );
void drawFilesystemGUI( FrameInfo& info );
void drawCameraOutputs( FrameInfo& info );
} // namespace fgl::engine::gui

View File

@@ -98,13 +98,34 @@ namespace fgl::engine::gui
}
}
void drawRenderingOutputs( FrameInfo& info )
vk::Extent2D calculateTargetSize( const float ratio, const vk::Extent2D max_extent )
{
// r = w/h
// w = r*h
// h = w/r
float height_size { static_cast< float >( max_extent.height ) };
float width_size { ratio * static_cast< float >( max_extent.height ) };
// If height is larger then the size then we need to compute the width from the height max
if ( width_size > max_extent.width )
{
width_size = static_cast< float >( max_extent.width );
height_size = static_cast< float >( max_extent.width ) / ratio;
}
return { static_cast< std::uint32_t >( width_size ), static_cast< std::uint32_t >( height_size ) };
}
FGL_FORCE_INLINE_FLATTEN vk::Extent2D calculateTargetSize( const float ratio, const ImVec2 max_extent )
{
return calculateTargetSize( ratio, vk::Extent2D( max_extent.x, max_extent.y ) );
}
void drawRenderingOutputs( FrameInfo& info, const Camera& camera )
{
ZoneScoped;
const auto frame_index { info.frame_idx };
ImGui::Begin( "RenderOutputs" );
enum RenderingOutputSelection : std::uint_fast8_t
{
Composite = 0,
@@ -118,24 +139,10 @@ namespace fgl::engine::gui
if ( ImGui::BeginCombo( "Rendering Output", options[ current ] ) )
{
constexpr float desired_size { 64 };
constexpr vk::Extent2D desired_size { 64, 64 };
//Calculate size
const float ratio { info.swap_chain.extentAspectRatio() };
// h = w/h
float fh_size { desired_size };
float fv_size { desired_size * ratio };
// If height is larger then the size then we need to compute the width from the height max
if ( fv_size > desired_size )
{
fv_size = desired_size;
fh_size = fv_size / ratio;
}
std::uint32_t h_size { static_cast< std::uint32_t >( fh_size ) };
std::uint32_t v_size { static_cast< std::uint32_t >( fv_size ) };
const auto size { calculateTargetSize( ratio, desired_size ) };
//Composite
if ( ImGui::Selectable( options[ Composite ], current == Composite ) )
@@ -144,7 +151,7 @@ namespace fgl::engine::gui
current = Composite;
}
info.camera_data.camera.getSwapchain().g_buffer_albedo_img[ frame_index ]->drawImGui( { v_size, h_size } );
camera.getSwapchain().g_buffer_albedo_img[ frame_index ]->drawImGui( size );
ImGui::SameLine();
if ( ImGui::Selectable( options[ Albedo ], current == Albedo ) )
{
@@ -152,7 +159,7 @@ namespace fgl::engine::gui
current = Albedo;
}
info.camera_data.camera.getSwapchain().g_buffer_normal_img[ frame_index ]->drawImGui( { v_size, h_size } );
camera.getSwapchain().g_buffer_normal_img[ frame_index ]->drawImGui( size );
ImGui::SameLine();
if ( ImGui::Selectable( options[ Normal ], current == Normal ) )
{
@@ -160,8 +167,7 @@ namespace fgl::engine::gui
current = Normal;
}
info.camera_data.camera.getSwapchain().g_buffer_position_img[ frame_index ]->drawImGui( { v_size,
h_size } );
camera.getSwapchain().g_buffer_position_img[ frame_index ]->drawImGui( size );
ImGui::SameLine();
if ( ImGui::Selectable( options[ Position ], current == Position ) )
{
@@ -172,27 +178,31 @@ namespace fgl::engine::gui
ImGui::EndCombo();
}
const float ratio { info.swap_chain.extentAspectRatio() };
const auto imgui_size { ImGui::GetWindowSize() };
const auto target_size { calculateTargetSize( ratio, imgui_size ) };
//Compute optimal size using aspect ratio
switch ( current )
{
default:
[[fallthrough]];
case Composite:
info.camera_data.camera.getSwapchain().g_buffer_composite_img[ frame_index ]->drawImGui();
camera.getSwapchain().g_buffer_composite_img[ frame_index ]->drawImGui( target_size );
break;
case Albedo:
info.camera_data.camera.getSwapchain().g_buffer_albedo_img[ frame_index ]->drawImGui();
camera.getSwapchain().g_buffer_albedo_img[ frame_index ]->drawImGui( target_size );
break;
case Normal:
info.camera_data.camera.getSwapchain().g_buffer_normal_img[ frame_index ]->drawImGui();
camera.getSwapchain().g_buffer_normal_img[ frame_index ]->drawImGui( target_size );
break;
case Position:
info.camera_data.camera.getSwapchain().g_buffer_position_img[ frame_index ]->drawImGui();
camera.getSwapchain().g_buffer_position_img[ frame_index ]->drawImGui( target_size );
break;
}
handleDragDrop( info );
ImGui::End();
}
} // namespace fgl::engine::gui

View File

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

View File

@@ -8,9 +8,7 @@
#include "Shader.hpp"
#include "engine/concepts/is_descriptor_set_collection.hpp"
#include "engine/concepts/is_empty_descriptor_set.hpp"
#include "engine/concepts/is_valid_pipeline_input.hpp"
#include "engine/descriptors/DescriptorSet.hpp"
#include "engine/descriptors/createDescriptorSets.hpp"
namespace fgl::engine
{
@@ -25,7 +23,7 @@ namespace fgl::engine
//! Returns the binding type assocaited with the index
template < std::uint16_t binding_set_idx >
using BindingSet = DescriptorSetCollection::template BindingSet< binding_set_idx >;
using BindingSet = typename DescriptorSetCollection::template BindingSet< binding_set_idx >;
constexpr static std::uint16_t max_binding_set { DescriptorSetCollection::max_binding_set };

View File

@@ -26,6 +26,24 @@
namespace fgl::engine
{
void Renderer::clearInputImage( vk::raii::CommandBuffer& command_buffer )
{
auto& image { getSwapChain().getInputImage( current_present_index ) };
vk::ImageSubresourceRange range {};
range.aspectMask = vk::ImageAspectFlagBits::eColor;
range.layerCount = 1;
range.baseArrayLayer = 0;
range.levelCount = 1;
range.baseMipLevel = 0;
command_buffer.clearColorImage(
image.getVkImage(),
vk::ImageLayout::eShaderReadOnlyOptimal,
vk::ClearColorValue( 0.0f, 0.0f, 0.0f, 0.0f ),
{ range } );
}
Renderer::Renderer( Window& window, PhysicalDevice& phy_device ) :
m_window( window ),
m_phy_device( phy_device ),

View File

@@ -87,6 +87,8 @@ namespace fgl::engine
SwapChain& getSwapChain() { return *m_swapchain; }
void clearInputImage( vk::raii::CommandBuffer& command_buffer );
Renderer( Window& window, PhysicalDevice& phy_device );
~Renderer();
Renderer( Renderer&& other ) = delete;

View File

@@ -10,4 +10,6 @@ namespace fgl::engine
{
using PresentIndex = std::uint16_t;
using FrameIndex = std::uint16_t;
using CameraIndex = std::uint16_t;
}

View File

@@ -7,7 +7,7 @@
#include <tracy/TracyC.h>
#include "engine/FrameInfo.hpp"
#include "engine/debug/drawers.hpp"
#include "engine/camera/Camera.hpp"
#include "engine/model/Model.hpp"
#include "engine/tree/octtree/OctTreeNode.hpp"
@@ -24,7 +24,7 @@ namespace fgl::engine
{
ZoneScopedN( "Culling pass" );
const auto frustum { info.camera_frustum };
const auto frustum { info.camera_data.camera->getFrustumBounds() };
if ( !enable_culling )
{

View File

@@ -8,6 +8,7 @@
#include <vulkan/vulkan.hpp>
#include "DrawPair.hpp"
#include "engine/camera/Camera.hpp"
#include "engine/literals/size.hpp"
#include "engine/tree/octtree/OctTreeNode.hpp"
@@ -77,13 +78,12 @@ namespace fgl::engine
//Bind pipeline
m_standard_pipeline->bind( command_buffer );
//Bind only descriptor we need.
m_standard_pipeline
->bindDescriptor( command_buffer, GlobalDescriptorSet::m_set_idx, info.global_descriptor_set );
->bindDescriptor( command_buffer, CameraDescriptorSet::m_set_idx, info.getCameraDescriptor() );
//Get all commands for drawing anything without a texture
auto [ draw_commands, model_matricies ] =
getDrawCallsFromTree( info.game_objects, info.camera_frustum, IS_VISIBLE | IS_ENTITY, IS_TEXTURELESS );
auto [ draw_commands, model_matricies ] = getDrawCallsFromTree(
info.game_objects, info.camera_data.camera->getFrustumBounds(), IS_VISIBLE | IS_ENTITY, IS_TEXTURELESS );
//TODO: Filter Textureless models (#6)
@@ -120,14 +120,15 @@ namespace fgl::engine
m_textured_pipeline->bind( command_buffer );
m_textured_pipeline
->bindDescriptor( command_buffer, GlobalDescriptorSet::m_set_idx, info.global_descriptor_set );
// Since the camera was bound in the textureless pass we shouldn't need to bind it here too.
// m_textured_pipeline
// ->bindDescriptor( command_buffer, CameraDescriptorSet::m_set_idx, info.global_descriptor_set );
m_textured_pipeline
->bindDescriptor( command_buffer, TextureDescriptorSet::m_set_idx, Texture::getTextureDescriptorSet() );
auto [ draw_commands, model_matricies ] =
getDrawCallsFromTree( info.game_objects, info.camera_frustum, IS_VISIBLE | IS_ENTITY );
auto [ draw_commands, model_matricies ] = getDrawCallsFromTree(
info.game_objects, info.camera_data.camera->getFrustumBounds(), IS_VISIBLE | IS_ENTITY );
if ( draw_commands.empty() ) return;

View File

@@ -7,11 +7,13 @@
#include <tracy/Tracy.hpp>
#include "DrawPair.hpp"
#include "engine/camera/Camera.hpp"
#include "engine/literals/size.hpp"
namespace fgl::engine
{
/*
TerrainSystem::TerrainSystem( Device& device, vk::raii::RenderPass& render_pass )
{
ZoneScoped;
@@ -58,7 +60,7 @@ namespace fgl::engine
return;
auto [ draw_commands, model_matricies ] =
getDrawCallsFromTree( info.game_objects, info.camera_frustum, IS_VISIBLE );
getDrawCallsFromTree( info.game_objects, info.camera_data.camera.getFrustumBounds(), IS_VISIBLE );
if ( draw_commands.size() == 0 ) return;
@@ -84,5 +86,6 @@ namespace fgl::engine
draw_parameter_buffer->size(),
draw_parameter_buffer->stride() );
}
*/
} // namespace fgl::engine

View File

@@ -8,6 +8,7 @@
#include "concepts.hpp"
#include "engine/FrameInfo.hpp"
#include "engine/buffers/vector/HostVector.hpp"
#include "engine/camera/Camera.hpp"
#include "engine/descriptors/DescriptorSetCollection.hpp"
#include "engine/model/Model.hpp"
#include "engine/pipeline/PipelineT.hpp"
@@ -15,6 +16,8 @@
namespace fgl::engine
{
/*
class TerrainSystem
{
using VertexShader = VertexShaderT< "shaders/terrain/terrain.vert.spv" >;
@@ -23,7 +26,8 @@ namespace fgl::engine
using TessEShader = TesselationEvaluationShaderT< "shaders/terrain/terrain.tese.spv" >;
using Shaders = ShaderCollection< VertexShader, FragmentShader, TessCShader, TessEShader >;
using DescriptorSets = descriptors::DescriptorSetCollection< GlobalDescriptorSet, TextureDescriptorSet >;
using DescriptorSets =
descriptors::DescriptorSetCollection< GlobalDescriptorSet, CameraDescriptorSet, TextureDescriptorSet >;
using Pipeline = PipelineT< Shaders, DescriptorSets >;
@@ -73,6 +77,8 @@ namespace fgl::engine
};
static_assert( is_system< TerrainSystem > );
*/
} // namespace fgl::engine
#endif //GAME_TERRAINSYSTEM_HPP

View File

@@ -4,6 +4,7 @@
#pragma once
#include "engine/FrameInfo.hpp"
#include "engine/camera/CameraDescriptor.hpp"
#include "engine/descriptors/DescriptorSetCollection.hpp"
#include "engine/pipeline/PipelineT.hpp"
#include "engine/pipeline/Shader.hpp"
@@ -15,7 +16,9 @@ namespace fgl::engine
using StandardPipelineFragShader = FragmentShaderT< "shaders/textureless-gbuffer.frag.spv" >;
using StandardPipelineShaders = ShaderCollection< StandardPipelineVertexShader, StandardPipelineFragShader >;
using StandardPipelineDescriptorSets = descriptors::DescriptorSetCollection< GlobalDescriptorSet >;
// using StandardPipelineDescriptorSets = descriptors::DescriptorSetCollection< GlobalDescriptorSet >;
using StandardPipelineDescriptorSets =
descriptors::DescriptorSetCollection< descriptors::EmptyDescriptorSet< 0 >, CameraDescriptorSet >;
//! The standard pipeline is used for models without any form of texturing. They instead rely on Vertex coloring. A UV map is **NOT** expected
using StandardPipeline = PipelineT< StandardPipelineShaders, StandardPipelineDescriptorSets >;

View File

@@ -15,8 +15,10 @@ namespace fgl::engine
using TexturedPipelineFragShader = FragmentShaderT< "shaders/textured-gbuffer.frag.spv" >;
using TexturedPipelineShaders = ShaderCollection< TexturedPipelineVertexShader, TexturedPipelineFragShader >;
using TexturedPipelineDescriptorSets =
descriptors::DescriptorSetCollection< GlobalDescriptorSet, TextureDescriptorSet >;
//using TexturedPipelineDescriptorSets =
// descriptors::DescriptorSetCollection< GlobalDescriptorSet, TextureDescriptorSet >;
using TexturedPipelineDescriptorSets = descriptors::
DescriptorSetCollection< descriptors::EmptyDescriptorSet< 0 >, CameraDescriptorSet, TextureDescriptorSet >;
//! The standard pipeline is used for models without any form of texturing. They instead rely on Vertex coloring. A UV map is **NOT** expected
using TexturedPipeline = PipelineT< TexturedPipelineShaders, TexturedPipelineDescriptorSets >;