diff --git a/Engine/CMakeLists.txt b/Engine/CMakeLists.txt index e028d51a..0411e3c1 100644 --- a/Engine/CMakeLists.txt +++ b/Engine/CMakeLists.txt @@ -123,6 +123,7 @@ target_include_directories( $ $ $ + $ $ $ $ @@ -141,6 +142,7 @@ target_include_directories( INTERFACE $ $ $ + $ $ $ $ diff --git a/Engine/include/Popcorn.h b/Engine/include/Popcorn.h index 1458b61c..64235ec7 100644 --- a/Engine/include/Popcorn.h +++ b/Engine/include/Popcorn.h @@ -11,6 +11,7 @@ #include "Scene.h" #include "SplineFactory.h" #include +#include ENGINE_NAMESPACE_BEGIN CTX_NAMESPACE_BEGIN @@ -42,19 +43,70 @@ static void UnregisterScene(Scene &scene) { s_renderer->RemoveScene(&scene); }; static void StartGame() { // TODO: Move the ownership of commandbuffers to Renderflow base class - s_renderer->CreateRenderFlows(); + // + // NEW: --- Make your own renderflows --- + // + // const std::vector paintPasses{}; + // s_renderer->ProcessPaintPasses(paintPasses); + + s_renderer->CreateRenderFlows(); // 1. Each renderflow takes in + // a. Attachments (and Info) + // b. RenderInfo + // c. PipelineInfo + // s_renderer->PrepareRenderFlows(); // Creates attachments, renderflows, // framebuffers, and command buffers + // s_renderer->AssignSceneObjectsToRenderFlows(); // Sorts submeshes material // wise & adds to renderflows + // 1. Calculates offsets + + // alignment and stuff s_renderer->CreateRenderFlowResources(); // Renderflow submeshes converted and // copied to vulkan memory objects + // 1. Alloc Memory + // 2. Create Samplers + // 3. Alloc Shaders + // 4. Alloc DSets Global + // 5. Update DSets Global + // 6. Loops renderflows - + // a. Alloc DSets Local + // b. Update DSets Local + // c. Create Pipelines + // 7. Free Shaders #ifdef PC_DEBUG // s_renderer->PrintScenes(); // s_renderer->DebugPreGameLoop(); #endif - s_application->StartGameLoop(); // Starts game loop + s_application + ->StartGameLoop(); // Starts game loop + // 1. Update Layers - Update transforms etc. for render + // 2. Render Layers - + // a. Copy Dynamic UBOs to memory + // b. Begin command buffer + // c. Begin Renderpass/rendering + // d. Set viewport & scissor + // e. Bind VBO + // f. Bind IBO + // g. Bind basicMat pipeline + // h. Bind D-Sets (global - camera stuff) + // i. Loop over material (basicMat) buckets - + // i1. Bind D-Sets (local - basic mat) + // i2. Loop over submeshes - + // i1a. Bind D-Sets (local - submesh) + // i2a. DRAW indexed + // j. Bind pbrMat pipeline + // k. Bind D-Sets (global - camera stuff) + // l. Loop over material (pbrMat) buckets - + // l1. Bind D-Sets (local - pbr mat) + // l2. Loop over submeshes - + // l1a. Bind D-Sets (local - submesh) + // l2a. DRAW indexed + // m. End Renderpass/rendering + // n. Barrier transition stuff + // o. End command buffer + // + // }; static SplineFactory *GetSplineFactory() { return ContextGfx::AppSplines(); } @@ -86,18 +138,6 @@ static void EndContext() { // return *s_application; // }; -static void FillNamedLookUpMap(Scene &scene, GameObject *node) { - if (node == nullptr) { - PC_WARN("node is nullptr") - return; - } - scene.AddGameObjectToNamedLookUp(node->GetName(), node); - - for (GameObject *child : node->GetChildren()) { - FillNamedLookUpMap(scene, child); - } -} - static void ConvertGltfToScene(const std::string &filename, Scene &scene) { tinygltf::Model model; GltfLoader::LoadFromFile(filename, model); @@ -110,10 +150,6 @@ static void ConvertGltfToScene(const std::string &filename, Scene &scene) { scene.SetAnimationTracks(animationTracks); PC_WARN("ANIMATION TRACK SIZE AFTER: " << animationTracks.size()) - - for (GameObject *gameObj : scene.GetGameObjects()) { - FillNamedLookUpMap(scene, gameObj); - } }; CTX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Core/Buffer.h b/Engine/include/Popcorn/Core/Buffer.h index fdf18122..ebd3713f 100644 --- a/Engine/include/Popcorn/Core/Buffer.h +++ b/Engine/include/Popcorn/Core/Buffer.h @@ -32,8 +32,8 @@ struct HasPrint< class Buffer { public: - Buffer() { - // PC_PRINT("CREATED(DEFAULT)", TagType::Constr, "BUFFER") + Buffer() { + // PC_PRINT("CREATED(DEFAULT)", TagType::Constr, "BUFFER") }; ~Buffer() { FreeBytes(); @@ -64,13 +64,13 @@ class Buffer { m_size = size; }; - [[nodiscard]] inline byte_t *GetData() const { - return static_cast(m_data); + [[nodiscard]] inline PC_Byte_t *GetData() const { + return static_cast(m_data); }; void WriteBytes(const void *data, uint64_t size, uint64_t offset = 0) { PC_ASSERT(offset + size <= m_size, "WriteBytes out of bounds!"); - memcpy(static_cast(m_data) + offset, data, size); + memcpy(static_cast(m_data) + offset, data, size); } // @@ -183,13 +183,13 @@ class Buffer { void AllocBytes(uint64_t size) { FreeBytes(); - m_data = new byte_t[size]; + m_data = new PC_Byte_t[size]; m_size = size; }; void FreeBytes() { if (m_data) - delete[] static_cast(m_data); + delete[] static_cast(m_data); m_data = nullptr; m_size = 0; }; diff --git a/Engine/include/Popcorn/Core/Helpers.h b/Engine/include/Popcorn/Core/Helpers.h index 942efd51..087036b4 100644 --- a/Engine/include/Popcorn/Core/Helpers.h +++ b/Engine/include/Popcorn/Core/Helpers.h @@ -4,6 +4,7 @@ #include #include #include +#include #ifdef PC_DEBUG #include @@ -12,37 +13,62 @@ #endif ENGINE_NAMESPACE_BEGIN -constexpr std::size_t shift_l(std::size_t n) { return 1 << n; } + +// --- TYPES & VALUES ------------------------------------------------------ +// --- TYPES & VALUES ------------------------------------------------------ +// --- TYPES & VALUES ------------------------------------------------------ +using PC_Byte_t = uint8_t; + +extern int PC_PRINT_LEVEL; enum TagType { Constr, Destr, Print }; -using byte_t = uint8_t; +// --- BITWISE HELPERS ----------------------------------------------------- +// --- BITWISE HELPERS ----------------------------------------------------- +// --- BITWISE HELPERS ----------------------------------------------------- +constexpr std::size_t PC_ShiftLeft(std::size_t n) { return 1 << n; } + +// --- STRING HELPERS ------------------------------------------------------ +// --- STRING HELPERS ------------------------------------------------------ +// --- STRING HELPERS ------------------------------------------------------ +[[nodiscard]] static bool PC_StrEndsWith(const char *s, const char *suffix) { + if (!s || !suffix) + return false; -extern int PC_print_lvl; + size_t sLen = strlen(s); + size_t suffixLen = strlen(suffix); + if (sLen < suffixLen) + return false; + + return strcmp(s + sLen - suffixLen, suffix) == 0; +} + +// --- LOGGING HELPERS ----------------------------------------------------- +// --- LOGGING HELPERS ----------------------------------------------------- +// --- LOGGING HELPERS ----------------------------------------------------- static void PC_Print(const std::string &msg, const TagType tag, const std::string &className) { - - if (PC_print_lvl < 0) { + if (PC_PRINT_LEVEL < 0) { std::cout << "MISSING CONSTRUCTOR MESSAGE" << '\n'; return; }; if (tag == TagType::Constr) { - PC_print_lvl++; + PC_PRINT_LEVEL++; } else if (tag == TagType::Destr) - PC_print_lvl--; + PC_PRINT_LEVEL--; std::stringstream ss; - auto lvl = PC_print_lvl < 10 ? " " + std::to_string(PC_print_lvl) - : std::to_string(PC_print_lvl); + auto lvl = PC_PRINT_LEVEL < 10 ? " " + std::to_string(PC_PRINT_LEVEL) + : std::to_string(PC_PRINT_LEVEL); if (tag == TagType::Print) { lvl = " "; }; ss << lvl << " "; - for (int i = 0; i < std::min(PC_print_lvl, 10); ++i) { + for (int i = 0; i < std::min(PC_PRINT_LEVEL, 10); ++i) { ss << "| "; } diff --git a/Engine/include/Popcorn/Core/Layer.h b/Engine/include/Popcorn/Core/Layer.h index dce6ba10..66a2cc8b 100644 --- a/Engine/include/Popcorn/Core/Layer.h +++ b/Engine/include/Popcorn/Core/Layer.h @@ -9,6 +9,9 @@ class Layer { public: virtual ~Layer() = default; + Layer(const Layer &) = delete; + Layer &operator=(const Layer &) = delete; + virtual void OnAttach(); virtual void OnDetach(); diff --git a/Engine/include/Popcorn/Core/LayerStack.h b/Engine/include/Popcorn/Core/LayerStack.h index 3ee0e9e2..185d3197 100644 --- a/Engine/include/Popcorn/Core/LayerStack.h +++ b/Engine/include/Popcorn/Core/LayerStack.h @@ -26,27 +26,27 @@ class LayerStack { // cb(it); // } - for (auto it = m_layer_stack.rbegin(); it != m_layer_stack.rend(); ++it) { + for (auto it = m_layerStack.rbegin(); it != m_layerStack.rend(); ++it) { cb(it); } }; // TODO: Refactor when dealing with time void UpdateLayers(TimeEvent &e) { - for (Layer *l : m_layer_stack) { + for (Layer *l : m_layerStack) { l->OnUpdate(e); } }; void RenderLayers() { - for (Layer *l : m_layer_stack) { + for (Layer *l : m_layerStack) { l->OnRender(); } }; private: - std::vector m_layer_stack; - uint32_t m_separator_index = 0; + std::vector m_layerStack; + uint32_t m_separatorIndex = 0; }; ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Events/Event.h b/Engine/include/Popcorn/Events/Event.h index 7f3d3efb..e957d732 100644 --- a/Engine/include/Popcorn/Events/Event.h +++ b/Engine/include/Popcorn/Events/Event.h @@ -38,12 +38,12 @@ enum class EventType { enum class EventCategory { None = 0, - ApplicationEvent = shift_l(1), - WindowEvent = shift_l(2), - KeyboardEvent = shift_l(3), - MouseEvent = shift_l(4), - TimeEvent = shift_l(5), - VulkanEvent = shift_l(6) + ApplicationEvent = PC_ShiftLeft(1), + WindowEvent = PC_ShiftLeft(2), + KeyboardEvent = PC_ShiftLeft(3), + MouseEvent = PC_ShiftLeft(4), + TimeEvent = PC_ShiftLeft(5), + VulkanEvent = PC_ShiftLeft(6) }; // HASH DEFINE START ---------------------------------------------------------- diff --git a/Engine/include/Popcorn/Graphics/BufferObjects.h b/Engine/include/Popcorn/Graphics/BufferObjects.h index c3dc0630..0367f85b 100644 --- a/Engine/include/Popcorn/Graphics/BufferObjects.h +++ b/Engine/include/Popcorn/Graphics/BufferObjects.h @@ -131,7 +131,7 @@ class VertexBuffer { return m_layout; } - [[nodiscard]] inline byte_t *GetBufferData() const { + [[nodiscard]] inline PC_Byte_t *GetBufferData() const { return m_buffer.GetData(); } @@ -230,7 +230,7 @@ template class IndexBuffer { m_buffer.WriteBytes(data, size, offset); } - [[nodiscard]] inline byte_t *GetBufferData() const { + [[nodiscard]] inline PC_Byte_t *GetBufferData() const { return m_buffer.GetData(); } diff --git a/Engine/include/Popcorn/Graphics/Materials/Material.h b/Engine/include/Popcorn/Graphics/Materials/Material.h index 3f3f5841..7b88f2f3 100644 --- a/Engine/include/Popcorn/Graphics/Materials/Material.h +++ b/Engine/include/Popcorn/Graphics/Materials/Material.h @@ -15,12 +15,8 @@ class Mesh; template class Material { public: - Material() { - // PC_PRINT("CREATED", TagType::Constr, "Material.h"); - } - virtual ~Material() { - // PC_PRINT("DESTROYED", TagType::Destr, "Material.h"); - } + Material() = default; + virtual ~Material() {} static constexpr MaterialTypes type_value = T; diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/BloomBlurPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/BloomBlurPass.h new file mode 100644 index 00000000..e69de29b diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/BloomExtractPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/BloomExtractPass.h new file mode 100644 index 00000000..4f0325f7 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/BloomExtractPass.h @@ -0,0 +1,10 @@ + +#pragma once + +#include "GlobalMacros.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/CompositePass.h b/Engine/include/Popcorn/Graphics/PaintPasses/CompositePass.h new file mode 100644 index 00000000..e69de29b diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/CustomPaintPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/CustomPaintPass.h new file mode 100644 index 00000000..4f0325f7 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/CustomPaintPass.h @@ -0,0 +1,10 @@ + +#pragma once + +#include "GlobalMacros.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h b/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h new file mode 100644 index 00000000..7d3450d7 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/DataStructures.h @@ -0,0 +1,50 @@ +#pragma once + +#include "GlobalMacros.h" +#include + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +// +// --- USEFUL DATA STRUCTURES -------------------------------------------------- +typedef struct { + uint32_t x; + uint32_t y; +} CoordsXY_U32; + +typedef struct { + int32_t x; + int32_t y; +} CoordsXY_I32; + +typedef struct { + float x; + float y; +} CoordsXY_Float; + +// +// --- PAINT PASS SPECIFIC ----------------------------------------------------- +typedef enum { + MEM_ACCESS_READ, + MEM_ACCESS_WRITE, + MEM_ACCESS_READ_WRITE +} MemAccess; + +// A window into the buffer memory that shaders have access to. This memory +// lives in the CPU, and will be copied to the GPU later as required +typedef struct { + uint64_t stride; // buffer stride (in bytes) + uint64_t offset; // buffer view offset (in bytes) + uint64_t range; // buffer view range (in bytes) + MemAccess access; +} BufferView; + +typedef struct { + uint64_t offset; // buffer view offset (in bytes) + uint64_t range; // buffer view range (in bytes) + MemAccess access; +} MemView_Image; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/Example.h b/Engine/include/Popcorn/Graphics/PaintPasses/Example.h new file mode 100644 index 00000000..e416828f --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/Example.h @@ -0,0 +1,14 @@ +#pragma once + +#include "GlobalMacros.h" +#include "PaintPasses/GBufferPass.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +class Pass { + GBufferPass *gbuffer; +}; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h new file mode 100644 index 00000000..fb63f0b5 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/GBufferPass.h @@ -0,0 +1,41 @@ +#pragma once + +#include "GlobalMacros.h" +#include "PaintPasses/PaintPass.h" +#include "PaintPasses/PaintPassDefs.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +class GBufferPass : public PaintPass { +public: + GBufferPass() = default; + virtual ~GBufferPass() override {}; + + void Init() { + // + // --- Create attachments (images) ----------------------------------------- + DrawAttachmentInfo colorImage{ + .colorFormats = + { + ColorFormat::Low_UNorm8_SRGB, // albedo + ColorFormat::Low_UNorm8_Linear, // high precision normals + ColorFormat::Low_UNorm8_Linear, // roughness metallic + }, + .clearColorValues = + { + {0.0f, 0.0f, 0.0f, 1.0f}, // albedo + {0.5f, 0.5f, 1.0f, 0.0f}, // normals + {1.0f, 0.0f, 0.0f, 0.0f}, // roughness metallic + }, + }; + DrawAttachmentInfo depthImage{ + .depthFormat = DepthFormat::Medium_D24, + .clearDepthStencilValue = {.depth = 1.0f, .stencil = 0.0f}}; + + SetAttachmentInfos(colorImage, depthImage); + } +}; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/LightingPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/LightingPass.h new file mode 100644 index 00000000..b6937895 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/LightingPass.h @@ -0,0 +1,9 @@ +#pragma once + +#include "GlobalMacros.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h new file mode 100644 index 00000000..8838e86c --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPass.h @@ -0,0 +1,68 @@ +#pragma once + +#include "GlobalMacros.h" +#include "PaintPasses/PaintPassDefs.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +class PaintPassVk; + +// Every paint pipeline in a paint pass will have it's own shaders +class PaintPipeline { +public: + PaintPipeline(const PaintPipelineInfo &info, + const SubmeshBuffersBucket &submeshBuffersBucket) + : m_info(info), m_submeshBuffersBucket(submeshBuffersBucket) {} + + PaintPipeline(const PaintPipeline &) = delete; + PaintPipeline(PaintPipeline &&) = default; + +private: + const PaintPipelineInfo &m_info; + + // + // --- MEMORY VIEWS STUFF --------------------------------------------------- + // + // view into UBO memory + const SubmeshBuffersBucket &m_submeshBuffersBucket; // Uses this data + BufferView uboBufferView; // copy your material data here (from helper + // methods, automatically done from GltfLoader) +}; + +class PaintPass { +public: + PaintPass( + // PaintPass creation info + const PaintPassInfo &info) + : m_info(info) { + // TODO: Error out when paintkind is material geometry and the + // submeshes aren't provided + }; + virtual ~PaintPass() {}; + + PaintPass(const PaintPass &) = delete; + PaintPass(PaintPass &&) = default; + + friend class PaintPassVk; + +private: + // + // --- CREATION INFO STUFF -------------------------------------------------- + const PaintPassInfo &m_info; + + // + // --- PAINT PIPELINES ------------------------------------------------------ + std::vector m_paintPipelines; + + // + // Extract data from GLTFs - + // + // Submesh buckets + // VBO + IBO data here, beginning of every paintpass - these will be bound + // what about UBOs? + // Submesh UBOs can be drilled to PaintPipeline +}; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h new file mode 100644 index 00000000..7b77f3a5 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassDefs.h @@ -0,0 +1,201 @@ +#pragma once + +#include "DataStructures.h" +#include "GlobalMacros.h" +#include "Uniforms.h" +#include +#include +#include + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +// +// Attachments stuff ------------------------------------------------------ +// Attachments stuff ------------------------------------------------------ +// Attachments stuff ------------------------------------------------------ +enum class PaintPipelineKind { + None = 0, + Material, // Shades all the geometry made of one kind of a material -- ONLY + // one specific kinda material. All the geometry (submeshes) are + // arranged in a contiguous memory "bucket" known as submesh + // buckets. PaintPipeline of this kind needs a ref to the submesh + // bucket + BigTriangle // Shades ONE fullscreen triangle -- +}; + +enum class PaintImageKind { None = 0, ColorImage, DepthImage }; + +enum class ColorFormat : uint8_t { + Low_UNorm8_Linear, // 8-bit UNORM, linear color space (LDR, non-gamma) + Low_UNorm8_SRGB, // 8-bit UNORM, sRGB color space (LDR, gamma-correct) + Medium_Float16_Linear, // 16-bit float per channel (MDR, good perf/quality + // balance) +}; + +enum class DepthFormat : uint8_t { + Low_D16, // 16-bit depth (fast, low precision) + Medium_D24, // 24-bit depth (balanced precision) + High_D32, // 32-bit float depth (high precision, large scenes) +}; + +struct alignas(16) ClearColorValue { + float r = .0f; + float g = .0f; + float b = .0f; + float a = .0f; +}; + +typedef struct { +} GlobalUniformSet; + +struct alignas(16) ClearDepthStencilValue { + float depth = 1.0f; + float stencil = .0f; +}; + +enum class AttachmentFlags : uint32_t { + None = 0, + // Usage bits + SampledBit, + ColorBit, + DepthBit, + StorageBit, + DepthStencilBit, +}; + +template struct PaintAttachmentInfo; + +template <> struct PaintAttachmentInfo { + std::vector colorFormats{}; + std::vector clearColorValues{}; + std::vector sizes{}; + AttachmentFlags attachmentFlags = AttachmentFlags::ColorBit; +}; + +template <> struct PaintAttachmentInfo { + DepthFormat depthFormat; + ClearDepthStencilValue clearDepthStencilValue; + CoordsXY_U32 size; + AttachmentFlags attachmentFlags = AttachmentFlags::DepthBit; +}; + +struct PaintArea { + CoordsXY_U32 offset{0, 0}; + CoordsXY_U32 extent{100, 100}; +}; + +typedef struct { + const char *vertShaderLoc; + const char *fragShaderLoc; +} ShadersLoc; + +typedef struct { + // From Vulkan defs +} SamplerInfo; + +typedef struct { + // TODO: Write a vertex version + std::vector vertexLayout; + BufferView vboBucketView; + // TODO: Write a index version + std::vector indexLayout; + BufferView iboBucketView; + + // copy your uniforms here (from gltf loader) + std::vector uniformLayout; + BufferView + uboBucketView; // View into UBO memory - contains all the submesh data + // that needs to be sent as UBOs - for example things like + // transform matrices, world positions etc +} SubmeshBuffersBucket; + +// User copies material info here (Gltf loader does this for the user) +struct MaterialInfo { + uint64_t batchId; + // Shader info + ShadersLoc shaderFiles; + std::vector uniformLayout; +}; + +typedef struct { + // store uniform data here + std::vector uniformLayout; + // copy your uniforms here (from gltf loader) + BufferView bufferView; // view into UBO memory (Vulkan staging buffer?) +} ScreenspaceInfo; + +struct PaintPipelineInfo { + // Draw kind + PaintPipelineKind paintPipelineKind; + + // Make one for SSBOs too + SamplerInfo samplerInfo; + + // Material info - For Material DrawKind + MaterialInfo materialInfo; // Material UBO (Layout + BufferView) + + // Screenspace info - For FullscreenTri DrawKind + ScreenspaceInfo screenspaceInfo; // Screenspace UBO (Layout + BufferView) +}; + +/** + * Basic Vert - SET 0 (0 - Camera UBO) + * - SET 2 (0 - Submesh UBO) + * Basic Frag - SET 1 (0 - Basic UBO) + * + * Pbr Vert - SET 0 (0 - Camera UBO) + * - SET 2 (0 - Submesh UBO) + * Pbr Frag - SET 1 (0 - Pbr UBO) + * + * Lighting Frag - SET 0 (0 - Camera UBO) + * - SET 1 (0 - Light SSBO) + * (1 - Sampler Tex) + * (2 - Sampler Tex) + * (3 - Sampler Tex) + * (4 - Sampler Tex) + * + */ + +// Only for raster pipelines +struct PaintPassInfo { + // Attachments info + PaintAttachmentInfo colorImagesInfo; + PaintAttachmentInfo depthImageInfo; + + // Render info + PaintArea paintArea; + + // Paint pipelines + const std::vector paintPipelineInfos; +}; + +// +// Shading stuff ---------------------------------------------------------- +// Shading stuff ---------------------------------------------------------- +// Shading stuff ---------------------------------------------------------- +enum class ShadingModel : uint8_t { + None = 0, + Pbr, // Cook–Torrance BRDF (GGX, Fresnel, NDF) + Basic, // Lambert + Blinn-Phong + + // --- future ----------------------------------------------------------- + ClearCoat, // PBR + second specular lobes + Subsurface, // Light scattering inside + Hair, // Anisotropic strand lighting ? + Unlit // No lighting applied +}; + +enum class MaterialRole : uint8_t { + Opaque, // Deferred, depth write ON, no blending + Masked, // Deferred, alpha test, depth write ON + Translucent, // Forward, blending ON, depth write OFF + Unlit, // Forward, no lighting, optional blending + + // --- future ----------------------------------------------------------- + Decal, // Projects onto existing surfaces + Volumetric // Participating media(fog, smoke etc.) +}; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassMemory.h b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassMemory.h new file mode 100644 index 00000000..d8a1eefd --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/PaintPassMemory.h @@ -0,0 +1,37 @@ +#pragma once + +#include "GlobalMacros.h" +#include +#include + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +class PaintPassMemory { + // Raw data + + // Deps - Submesh draw order + // VBO + // IBO + // UBO (submesh specific) + + // Global Uniform Sets + // UBO (Camera, Lights etc) + // SSBO + // TODO: Template this + void GetVboView(uint32_t index) {}; + void GetIboView(uint32_t index) {}; + void GetUboView(uint32_t index) {}; + +private: + // + // TODO: Organise memory from gameobjects/materials or whatever to store here + std::byte *vbos = nullptr; + std::byte *ibos = nullptr; + std::byte *ubos = nullptr; + + // Images? do i need images? do i? do i???? +}; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/PostFxPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/PostFxPass.h new file mode 100644 index 00000000..e69de29b diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/ShadowPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/ShadowPass.h new file mode 100644 index 00000000..b6937895 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/ShadowPass.h @@ -0,0 +1,9 @@ +#pragma once + +#include "GlobalMacros.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/PaintPasses/TransclucencyPass.h b/Engine/include/Popcorn/Graphics/PaintPasses/TransclucencyPass.h new file mode 100644 index 00000000..b6937895 --- /dev/null +++ b/Engine/include/Popcorn/Graphics/PaintPasses/TransclucencyPass.h @@ -0,0 +1,9 @@ +#pragma once + +#include "GlobalMacros.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/Renderer.h b/Engine/include/Popcorn/Graphics/Renderer.h index 259757f3..34861b80 100644 --- a/Engine/include/Popcorn/Graphics/Renderer.h +++ b/Engine/include/Popcorn/Graphics/Renderer.h @@ -1,17 +1,19 @@ #pragma once #include "GlobalMacros.h" +#include "PaintPasses/PaintPass.h" #include "Popcorn/Core/Window.h" #include "Popcorn/Events/WindowEvent.h" #include "SceneLibrary.h" +#include ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN enum class RendererType { None = 0, - OpenGL = shift_l(1), - Vulkan = shift_l(2), + OpenGL, + Vulkan // DirectX = shift_l(3), // Metal = shift_l(4) }; @@ -39,10 +41,15 @@ class Renderer { void AddScene(Scene *scene) { m_sceneLibrary.Add(scene); }; void RemoveScene(Scene *scene) { m_sceneLibrary.Remove(scene); }; + // TODO: Delete virtual void CreateRenderFlows() = 0; virtual void DestroyRenderFlows() = 0; virtual void PrepareRenderFlows() = 0; + // PaintPasses + virtual void + ProcessPaintPasses(const std::vector &paintPasses) = 0; + virtual void AssignSceneObjectsToRenderFlows() = 0; virtual void CreateRenderFlowResources() = 0; virtual void ProcessGameObjectNode(GameObject *node) = 0; @@ -55,7 +62,7 @@ class Renderer { Renderer(const Renderer &) = delete; Renderer &operator=(const Renderer &) = delete; Renderer(Renderer &&) = delete; - Renderer &operator=(const Renderer &&) = delete; + Renderer &operator=(Renderer &&) = delete; #ifdef PC_DEBUG void PrintScenes() const { m_sceneLibrary.PrintScenes(); }; diff --git a/Engine/include/Popcorn/Graphics/Shader.h b/Engine/include/Popcorn/Graphics/Shader.h index 019467cf..02062342 100644 --- a/Engine/include/Popcorn/Graphics/Shader.h +++ b/Engine/include/Popcorn/Graphics/Shader.h @@ -17,12 +17,12 @@ enum ShaderStages { // // Graphics types VertexBit = 1, - TesselationBit = shift_l(1), - GeometryBit = shift_l(2), - FragmentBit = shift_l(3), + TesselationBit = PC_ShiftLeft(1), + GeometryBit = PC_ShiftLeft(2), + FragmentBit = PC_ShiftLeft(3), // // Compute types - ComputeBit = shift_l(4) + ComputeBit = PC_ShiftLeft(4) // // Ray tracing types // TODO: Fill it out when time arrives @@ -83,10 +83,11 @@ class ShaderLibrary { template void LoadShaders(); template void UnloadShaders(); - template Buffer &GetShader() { + template Buffer &GetShader() { switch (R) { case RendererType::Vulkan: { auto it = s_shaders.find(T); + if (it != s_shaders.end()) { return it->second; } else { @@ -116,7 +117,7 @@ class ShaderLibrary { private: bool m_shadersLoaded = false; static ShaderLibrary *s_instance; - static std::map s_shaders; + static std::map s_shaders; }; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Graphics/Uniforms.h b/Engine/include/Popcorn/Graphics/Uniforms.h index c86a0f9a..246b503d 100644 --- a/Engine/include/Popcorn/Graphics/Uniforms.h +++ b/Engine/include/Popcorn/Graphics/Uniforms.h @@ -1,9 +1,13 @@ #pragma once #include "GlobalMacros.h" +#include "Popcorn/Core/Assert.h" +#include +#include #include #include #include +#include ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN @@ -19,6 +23,128 @@ enum class Uniforms { // add more.. }; +// clang-format off +enum class UniformAttrs { + None = 0, + Float, + Vec2, Vec3, Vec4, + Mat3, Mat4, + Bool +}; + +static constexpr size_t GetUniformAttrSize(UniformAttrs attr) { + switch (attr) + { + case UniformAttrs::Float: return 4; + case UniformAttrs::Vec2: return sizeof(glm::vec2); + case UniformAttrs::Vec3: return sizeof(glm::vec3); + case UniformAttrs::Vec4: return sizeof(glm::vec4); + case UniformAttrs::Mat3: return sizeof(glm::mat3); + case UniformAttrs::Mat4: return sizeof(glm::mat4); + default: + PC_ASSERT(false, "Unknown AttrType"); + return 0; + } +}; + +template struct UniformAttrType; +template <> +struct UniformAttrType { using type = float; }; +template <> +struct UniformAttrType { using type = glm::vec2; }; +template <> +struct UniformAttrType { using type = glm::vec3; }; +template <> +struct UniformAttrType { using type = glm::vec4; }; +template <> +struct UniformAttrType { using type = glm::mat3; }; +template <> +struct UniformAttrType { using type = glm::mat4; }; +// clang-format on + +struct UniformSet { + std::vector layout; + std::vector offsets; + std::vector data; +}; + +template class UniformData { +public: + std::byte *RawData() { return data; }; + const std::byte *RawData() const { return data; }; + + // --- Helpers --- + static constexpr uint32_t Count = sizeof...(Attrs); + + inline static constexpr std::array Layout = [] { + std::array s; + uint32_t i = 0; + ((s[i++] = Attrs), ...); + return s; + }(); + + UniformSet MakeSet() const { + return {.layout = std::vector(Layout.begin(), Layout.end()), + .offsets = std::vector(Offsets.begin(), Offsets.end()), + // TODO: Change data to a "BufferView" that views into a large UBOs + // byte array + .data = std::vector(data, data + TotalSize)}; + } + + // TODO: ALIGNMENT FOR VULKAN!!! + // TODO: ALIGNMENT FOR VULKAN!!! + // TODO: ALIGNMENT FOR VULKAN!!! + // TODO: ALIGNMENT FOR VULKAN!!! + // TODO: ALIGNMENT FOR VULKAN!!! + inline static constexpr std::array Offsets = [] { + std::array offsets; + uint32_t i = 0; + size_t offset = 0; + ((offsets[i++] = offset, offset += GetUniformAttrSize(Attrs)), ...); + return offsets; + }(); + + inline static constexpr size_t TotalSize = (GetUniformAttrSize(Attrs) + ...); + + // + // --- Methods --- + template + typename UniformAttrType::type &GetAttr() { + static_assert(Index < Count, "Uniform attribute index out of bounds"); + using ExtractedGlmType = UniformAttrType::type; + return reinterpret_cast(data + Offsets[Index]); + }; + + template + const typename UniformAttrType::type &GetAttr() const { + static_assert(Index < Count, "Uniform attribute index out of bounds"); + using ExtractedGlmType = UniformAttrType::type; + return reinterpret_cast(data + Offsets[Index]); + }; + +private: + alignas(16) std::byte data[TotalSize]; +}; + +struct UniformSetView { + const void *data; // pointer to raw bytes + uint32_t size; // total size + const uint32_t *offsets; // optional (debug / validation) + uint32_t count; // number of attributes + uint32_t setIndex; // Vulkan descriptor set index +}; + +// TODO: Convert this to set +template +inline static constexpr UniformSetView +PcMakeUniformSetView(UniformData &u, uint32_t setIndex) { + return {.data = u.RawData(), + .size = UniformData::TotalSize, + .offsets = UniformData::Offsets.data(), + .count = UniformData::Count, + .setIndex = setIndex}; +} + template struct Uniform { static constexpr Uniforms layout = L; // Internally aligned size diff --git a/Engine/include/Popcorn/Platform/OpenGL/RendererOpenGL.h b/Engine/include/Popcorn/Platform/OpenGL/RendererOpenGL.h index bd5430f0..5a760118 100644 --- a/Engine/include/Popcorn/Platform/OpenGL/RendererOpenGL.h +++ b/Engine/include/Popcorn/Platform/OpenGL/RendererOpenGL.h @@ -14,6 +14,10 @@ class RendererOpenGL : public Renderer { virtual void CreateRenderFlows() override {}; virtual void DestroyRenderFlows() override {}; virtual void PrepareRenderFlows() override {}; + + virtual void + ProcessPaintPasses(const std::vector &paintPasses) override {}; + virtual void AssignSceneObjectsToRenderFlows() override {}; virtual void CreateRenderFlowResources() override {}; diff --git a/Engine/include/Popcorn/Platform/Vulkan/Descriptors/DescriptorLayoutsVk.h b/Engine/include/Popcorn/Platform/Vulkan/Descriptors/DescriptorLayoutsVk.h index 9d28edc2..246eb008 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Descriptors/DescriptorLayoutsVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Descriptors/DescriptorLayoutsVk.h @@ -39,21 +39,26 @@ class DescriptorLayoutsVk { [[nodiscard]] static VkDeviceSize GetDescriptorBufferRange(const VkPhysicalDeviceLimits &limits) { if constexpr (T == DescriptorSets::CameraSet) { - return PC_AlignCeil(UniformDefs::CameraUniform::size, - limits.minUniformBufferOffsetAlignment); + return UniformDefs::CameraUniform::size; + // return PC_AlignCeil(UniformDefs::CameraUniform::size, + // limits.minUniformBufferOffsetAlignment); } else if constexpr (T == DescriptorSets::BasicMatSet) { - return PC_AlignCeil(UniformDefs::BasicMaterialUniform::size, - limits.minUniformBufferOffsetAlignment); + return UniformDefs::BasicMaterialUniform::size; + // return PC_AlignCeil(UniformDefs::BasicMaterialUniform::size, + // limits.minUniformBufferOffsetAlignment); } else if constexpr (T == DescriptorSets::PbrMatSet) { - return PC_AlignCeil(UniformDefs::PbrMaterialUniform::size, - limits.minUniformBufferOffsetAlignment); + return UniformDefs::PbrMaterialUniform::size; + // return PC_AlignCeil(UniformDefs::PbrMaterialUniform::size, + // limits.minUniformBufferOffsetAlignment); } else if constexpr (T == DescriptorSets::SubmeshSet) { - return PC_AlignCeil(UniformDefs::SubmeshUniform::size, - limits.minUniformBufferOffsetAlignment); + return UniformDefs::SubmeshUniform::size; + // return PC_AlignCeil(UniformDefs::SubmeshUniform::size, + // limits.minUniformBufferOffsetAlignment); } else if constexpr (T == DescriptorSets::PresentSet) { } else if constexpr (T == DescriptorSets::LightingSet) { - return PC_AlignCeil(UniformDefs::LightUniform::size, - limits.minStorageBufferOffsetAlignment); + return UniformDefs::LightUniform::size; + // return PC_AlignCeil(UniformDefs::LightUniform::size, + // limits.minStorageBufferOffsetAlignment); }; }; diff --git a/Engine/include/Popcorn/Platform/Vulkan/ImageVk.h b/Engine/include/Popcorn/Platform/Vulkan/ImageVk.h index 613e6427..5a0a2879 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/ImageVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/ImageVk.h @@ -25,6 +25,7 @@ class ImageVk { [[nodiscard]] const VkImageView &GetVkImageView() const { return m_imageView; }; + [[nodiscard]] const VkFormat &GetVkImageFormat() const { return m_format; }; static void GetDefaultImageCreateInfo(VkImageCreateInfo &imageInfo, uint32_t width, uint32_t height, @@ -42,9 +43,9 @@ class ImageVk { public: // --- UTILS ------------------------------------------------------------- - static VkFormat FindSupportedFormat(const std::vector &candidates, - VkImageTiling tiling, - VkFormatFeatureFlags features); + [[nodiscard]] static VkFormat + FindSupportedFormat(const std::vector &candidates, + VkImageTiling tiling, VkFormatFeatureFlags features); const bool FormatHasStencilComponent() const { PC_ASSERT(m_format != VK_FORMAT_UNDEFINED, "m_format is null"); diff --git a/Engine/include/Popcorn/Platform/Vulkan/Memory/HelpersVk.h b/Engine/include/Popcorn/Platform/Vulkan/Memory/HelpersVk.h index bd57a417..0442575b 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Memory/HelpersVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Memory/HelpersVk.h @@ -29,8 +29,8 @@ template <> struct PcCopyUniformToMemory { ~PcCopyUniformToMemory() = default; void operator()(void *uboMapping, MaterialHashType matId) { - byte_t *basicMatUboMapping = - (byte_t *)uboMapping + bufferViews.basicMatUbo.offset + + PC_Byte_t *basicMatUboMapping = + (PC_Byte_t *)uboMapping + bufferViews.basicMatUbo.offset + bufferOffsets.materialOffsets[matId]; // all offsets are aligned uint64_t uniformSize = UniformDefs::BasicMaterialUniform::size; memcpy(basicMatUboMapping, &uniform, uniformSize); @@ -62,8 +62,8 @@ template <> struct PcCopyUniformToMemory { } void operator()(void *uboMapping, MaterialHashType matId) { - byte_t *dst = (byte_t *)uboMapping + bufferViews.pbrMatUbo.offset + - bufferOffsets.materialOffsets[matId]; + PC_Byte_t *dst = (PC_Byte_t *)uboMapping + bufferViews.pbrMatUbo.offset + + bufferOffsets.materialOffsets[matId]; memcpy(dst, &uniform, UniformDefs::PbrMaterialUniform::size); } @@ -87,8 +87,8 @@ template <> struct PcCopyUniformToMemory { size_t submeshIndex) { const auto &offsetTriple = bufferOffsets.submeshesOffsets[matId][submeshIndex]; - byte_t *dst = (byte_t *)uboMapping + bufferViews.submeshUbo.offset + - offsetTriple.uboOffset; + PC_Byte_t *dst = (PC_Byte_t *)uboMapping + bufferViews.submeshUbo.offset + + offsetTriple.uboOffset; memcpy(dst, &uniform, UniformDefs::SubmeshUniform::size); } @@ -105,8 +105,7 @@ template <> struct PcCopyUniformToMemory { : bufferViews(bfrViews), bufferOffsets(bfrOffsets) { const LightData &lightData = light->GetLightData(); - // TODO: Fix this -- this is not actually world position - const glm::vec3 &worldPos = light->GetPosition(); + const glm::vec3 &worldPos = light->GetWorldPosition(); // PC_WARN("LIGHT POSITION BEFORE COPY " << worldPos.x << ", " << worldPos.y // << ", " << worldPos.z) @@ -125,8 +124,8 @@ template <> struct PcCopyUniformToMemory { } void operator()(void *ssboMapping, size_t index) { - byte_t *lightSsboMapping = - (byte_t *)ssboMapping + bufferViews.lightsSsbo.offset + + PC_Byte_t *lightSsboMapping = + (PC_Byte_t *)ssboMapping + bufferViews.lightsSsbo.offset + bufferOffsets.lightsOffsets[index]; // aligned offset constexpr uint64_t uniformSize = UniformDefs::LightUniform::size; @@ -156,8 +155,8 @@ template <> struct PcCopyUniformToMemory { } void operator()(void *uboMapping, size_t index) { - byte_t *dst = (byte_t *)uboMapping + bufferViews.camerasUbo.offset + - bufferOffsets.camerasOffsets[index]; + PC_Byte_t *dst = (PC_Byte_t *)uboMapping + bufferViews.camerasUbo.offset + + bufferOffsets.camerasOffsets[index]; memcpy(dst, &uniform, UniformDefs::CameraUniform::size); } @@ -177,8 +176,8 @@ template <> struct PcCopyUniformToMemory { } void operator()(void *uboMapping, size_t index) { - byte_t *dst = (byte_t *)uboMapping + bufferViews.emptysUbo.offset + - bufferOffsets.emptysOffsets[index]; + PC_Byte_t *dst = (PC_Byte_t *)uboMapping + bufferViews.emptysUbo.offset + + bufferOffsets.emptysOffsets[index]; memcpy(dst, &uniform, UniformDefs::EmptyUniform::size); } diff --git a/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryDefsVk.h b/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryDefsVk.h index f8a1d641..bcc1a45d 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryDefsVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryDefsVk.h @@ -21,6 +21,9 @@ template using PcMaterialSubmeshesMap = std::unordered_map *>>; +template +using PcMaterialSubmeshIndexMap = std::vector; + struct PcSubmeshOffsets { VkDeviceSize vboOffset = 0; VkDeviceSize iboOffset = 0; diff --git a/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryVk.h b/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryVk.h index 271263f6..53454c9d 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Memory/MemoryVk.h @@ -63,8 +63,10 @@ class MemoryVk { // Dynamic buffer data, they all change per frame template - void FillUbosSubmesh(PcMaterialSubmeshesMap &materialSubmeshesMap, + void FillUbosSubmesh(PcMaterialSubmeshIndexMap &materialSubmeshIndexMap, + PcMaterialSubmeshesMap &materialSubmeshesMap, const uint32_t currentFrame); + void FillUbosSsbosLightCameraEmpty(std::vector &lights, std::vector &cameras, std::vector &emptys, @@ -156,6 +158,9 @@ class MemoryVk { // // Buffer views ----------------------------------------------------------- PcBufferViews m_bufferViews{}; + + // --- NEW ---------------------------------------------------------------- + // --- Pass specific views --- }; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h b/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h new file mode 100644 index 00000000..ad0e0b77 --- /dev/null +++ b/Engine/include/Popcorn/Platform/Vulkan/PaintPasses/PaintPassVk.h @@ -0,0 +1,133 @@ +#pragma once + +#include "GlobalMacros.h" +#include "ImageVk.h" +#include "PaintPasses/PaintPass.h" +#include + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +// enum PaintPassColorFormats { +// Low_UNorm8_Linear, +// Color_RGBA_HiRes, +// Depth_Auto, +// }; + +class PaintPassVk { +public: + PaintPassVk(const PaintPass &pp) : m_paintPass(pp) {} + + PaintPassVk(const PaintPassVk &) = delete; + PaintPassVk(PaintPassVk &&) = default; + + void MakeAttachmentInfos() { + // m_paintPass.m_colorAttachmentInfo; + // m_paintPass.m_depthAttachmentInfo; + + // Create Vk Images + } + + void CreateImageAndView(ImageVk &imageVk, uint32_t attachmentIndex) { + uint32_t width = + m_paintPass.m_info.colorImagesInfo.sizes[attachmentIndex].x; + uint32_t height = + m_paintPass.m_info.colorImagesInfo.sizes[attachmentIndex].y; + + std::vector formatCandidates{}; + VkFormat selectedFormat; + VkImageCreateInfo imageCreateInfo{}; + VmaAllocationCreateInfo imageAlloc{.usage = VMA_MEMORY_USAGE_AUTO}; + + VkImageViewCreateInfo imageViewCreateInfo{}; + // TODO: Write for paintpass typedefs + + // if constexpr (T == ColorFormat::Low_UNorm8_Linear) { + // // --- Color --- + // // Low Res color + // formatCandidates = {VK_FORMAT_R8G8B8A8_UNORM, + // VK_FORMAT_B8G8R8A8_UNORM}; selectedFormat = + // ImageVk::FindSupportedFormat( + // formatCandidates, VK_IMAGE_TILING_OPTIMAL, + // VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); + // + // ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, + // selectedFormat); + // imageCreateInfo.format = selectedFormat; + // + // imageCreateInfo.usage = + // VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + // + // imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + // + // // --- Image View --- + // ImageVk::GetDefaultImageViewCreateInfo( + // imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); + // imageViewCreateInfo.format = selectedFormat; + // imageViewCreateInfo.subresourceRange.aspectMask = + // VK_IMAGE_ASPECT_COLOR_BIT; + // } else if constexpr (T == ColorFormat::Medium_Float16_Linear) { + // // --- Color --- + // // High Res color, fallback to low res + // formatCandidates = {VK_FORMAT_R16G16B16A16_SFLOAT, + // VK_FORMAT_R8G8B8A8_UNORM}; + // selectedFormat = ImageVk::FindSupportedFormat( + // formatCandidates, VK_IMAGE_TILING_OPTIMAL, + // VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); + // + // ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, + // selectedFormat); + // imageCreateInfo.format = selectedFormat; + // imageCreateInfo.usage = + // VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + // + // imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + // + // // --- Image View --- + // ImageVk::GetDefaultImageViewCreateInfo( + // imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); + // imageViewCreateInfo.format = selectedFormat; + // imageViewCreateInfo.subresourceRange.aspectMask = + // VK_IMAGE_ASPECT_COLOR_BIT; + // } + // + // // else { + // // // --- Depth --- + // // // High Res depth, fallback to low res + // // formatCandidates = {VK_FORMAT_D32_SFLOAT, + // VK_FORMAT_D32_SFLOAT_S8_UINT, + // // VK_FORMAT_D24_UNORM_S8_UINT}; + // // selectedFormat = ImageVk::FindSupportedFormat( + // // formatCandidates, VK_IMAGE_TILING_OPTIMAL, + // // VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); + // // + // // ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, + // // selectedFormat); + // // imageCreateInfo.format = selectedFormat; + // // imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT + // | + // // VK_IMAGE_USAGE_SAMPLED_BIT; + // // + // // imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + // // + // // // --- Image View --- + // // ImageVk::GetDefaultImageViewCreateInfo( + // // imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); + // // imageViewCreateInfo.format = selectedFormat; + // // imageViewCreateInfo.subresourceRange.aspectMask = + // // VK_IMAGE_ASPECT_DEPTH_BIT; + // // if (imageVk.FormatHasStencilComponent()) { + // // imageViewCreateInfo.subresourceRange.aspectMask |= + // // VK_IMAGE_ASPECT_STENCIL_BIT; + // // } + // // } + + imageVk.CreateImageView(imageViewCreateInfo); + }; + +private: + const PaintPass &m_paintPass; +}; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.h b/Engine/include/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.h index 17f07f3f..dc83c710 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.h @@ -21,6 +21,8 @@ class BasicMatPipelineVk : public PipelineVk { virtual void Create(const BufferDefs::Layout &vertexBufferLayout, const VkRenderPass &renderPass) override; + virtual void Create(const BufferDefs::Layout &vertexBufferLayout, + const PcAttachmentsInfo &attachmentLayouts) override; }; // @@ -36,6 +38,8 @@ class PbrMatPipelineVk : public PipelineVk { virtual void Create(const BufferDefs::Layout &vertexBufferLayout, const VkRenderPass &renderPass) override; + virtual void Create(const BufferDefs::Layout &vertexBufferLayout, + const PcAttachmentsInfo &attachmentLayouts) override; }; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineDefsVk.h b/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineDefsVk.h index db8588d3..c0e4d301 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineDefsVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineDefsVk.h @@ -23,6 +23,7 @@ struct GfxPipelineState { VkPipelineMultisampleStateCreateInfo multisampleState{}; VkPipelineColorBlendStateCreateInfo colorBlendState{}; VkPipelineLayoutCreateInfo pipelineLayout{}; + VkPipelineRenderingCreateInfo renderingInfoState{}; }; struct ComputePipelineState { diff --git a/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.h b/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.h index c6015eeb..de684e60 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.h @@ -15,6 +15,12 @@ ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN +typedef struct PcAttachmentsInfo { + std::vector colorFormats; + std::vector depthFormats; + std::vector stencilFormats; +} PcAttachmentsInfo; + template class PipelineVk { public: [[nodiscard]] inline const VkPipeline &GetVkPipeline() const { @@ -28,6 +34,8 @@ template class PipelineVk { virtual void Create(const BufferDefs::Layout &vertexBufferLayout, const VkRenderPass &renderPass) = 0; + virtual void Create(const BufferDefs::Layout &vertexBufferLayout, + const PcAttachmentsInfo &attachmentLayouts) = 0; void Destroy(); @@ -55,6 +63,10 @@ template class PipelineVk { const PipelineStateType &pipelineCreateInfo, const VkRenderPass &renderPass); + // void CreateVkPipeline(const VkDevice &device, + // const PipelineStateType &pipelineCreateInfo, + // const VkRenderPass &renderPass); + void CreateShaderStageCreateInfos( std::forward_list &shaderModules); diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h index cb82c5f5..b6e5ede7 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.h @@ -14,13 +14,8 @@ GFX_NAMESPACE_BEGIN class GBufferRenderFlowVk : public RenderFlowVk { public: - GBufferRenderFlowVk() { - PC_PRINT("CREATED", TagType::Constr, "GBufferRenderFlowVk") - } - - virtual ~GBufferRenderFlowVk() override { - PC_PRINT("DESTROYED", TagType::Destr, "GBufferRenderflowVk") - } + GBufferRenderFlowVk() {}; + virtual ~GBufferRenderFlowVk() override = default; #ifdef PC_DEBUG virtual void PrintVboIbo() override; @@ -32,6 +27,8 @@ class GBufferRenderFlowVk : public RenderFlowVk { virtual void CreateFramebuffers() override; virtual void CreateRenderPass() override; + virtual void CreateRenderInfoState() override; + virtual void DestroyRenderPass() override; virtual void DestroyFramebuffers() override; virtual void DestroyAttachments() override; @@ -78,6 +75,21 @@ class GBufferRenderFlowVk : public RenderFlowVk { AttachmentsVk m_attachmentsVk{}; DescriptorSetsVk m_descriptorSetsVk{}; + struct RenderInfoStateVk { + PcRenderAttachmentInfoState<3> + // 0: Albedo + // 1: Normal + // 2: RoughnessMetallic + colorAttachmentInfos{}; + PcRenderAttachmentInfoState<1> + // 0: Depth + depthAttachmentInfos{}; + + std::array renderingInfo{}; + }; + + RenderInfoStateVk m_renderInfoState{}; + RenderPassVk m_renderPass; PcFramesFramebuffers_Bundle m_framebuffers; diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h new file mode 100644 index 00000000..7b4d1c52 --- /dev/null +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.h @@ -0,0 +1,146 @@ +#pragma once + +#include "GlobalMacros.h" +#include "ImageVk.h" +#include + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +enum PaintPassColorFormats { + Color_RGBA_HiRes, + Low_UNorm8_Linear, + Depth_Auto, +}; + +enum RFlowResources { + Image = 1, + Buffer, + Uniform, + Shader, +}; + +class RFlowResourcesVk { + // Images + // Barriers + // + // Descriptor Sets + // Attachments + +public: + RFlowResourcesVk() = default; + + static void + GetDefaultRenderingAttachmentInfo(const VkImageView &imageView, + VkRenderingAttachmentInfo &renderAttInfo) { + renderAttInfo.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + renderAttInfo.clearValue = { + {0.0f, 0.0f, 0.0f, 1.0f}}; // VkClearValue for Albedo + renderAttInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + renderAttInfo.imageView = imageView; + renderAttInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + renderAttInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + // + // For the future: MSAA + renderAttInfo.resolveMode = VK_RESOLVE_MODE_NONE; + renderAttInfo.resolveImageView = VK_NULL_HANDLE; + renderAttInfo.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + } + + static void GetDefaultRenderingInfo() {} + + // Creates [one image + one view] combo + // TODO: future, [one image + multiple views] + template + static void CreateImageAndView(uint32_t width, uint32_t height, + ImageVk &imageVk) { + std::vector formatCandidates{}; + VkFormat selectedFormat; + VkImageCreateInfo imageCreateInfo{}; + VmaAllocationCreateInfo imageAlloc{.usage = VMA_MEMORY_USAGE_AUTO}; + + VkImageViewCreateInfo imageViewCreateInfo{}; + + if constexpr (T == PaintPassColorFormats::Low_UNorm8_Linear) { + // --- Color --- + // Low Res color + formatCandidates = {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM}; + selectedFormat = ImageVk::FindSupportedFormat( + formatCandidates, VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); + + ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, + selectedFormat); + imageCreateInfo.format = selectedFormat; + imageCreateInfo.usage = + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + + imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + + // --- Image View --- + ImageVk::GetDefaultImageViewCreateInfo( + imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); + imageViewCreateInfo.format = selectedFormat; + imageViewCreateInfo.subresourceRange.aspectMask = + VK_IMAGE_ASPECT_COLOR_BIT; + } else if constexpr (T == PaintPassColorFormats::Color_RGBA_HiRes) { + // --- Color --- + // High Res color, fallback to low res + formatCandidates = {VK_FORMAT_R16G16B16A16_SFLOAT, + VK_FORMAT_R8G8B8A8_UNORM}; + selectedFormat = ImageVk::FindSupportedFormat( + formatCandidates, VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); + + ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, + selectedFormat); + imageCreateInfo.format = selectedFormat; + imageCreateInfo.usage = + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + + imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + + // --- Image View --- + ImageVk::GetDefaultImageViewCreateInfo( + imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); + imageViewCreateInfo.format = selectedFormat; + imageViewCreateInfo.subresourceRange.aspectMask = + VK_IMAGE_ASPECT_COLOR_BIT; + } else { + // --- Depth --- + // High Res depth, fallback to low res + formatCandidates = {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT}; + selectedFormat = ImageVk::FindSupportedFormat( + formatCandidates, VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); + + ImageVk::GetDefaultImageCreateInfo(imageCreateInfo, width, height, + selectedFormat); + imageCreateInfo.format = selectedFormat; + imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT; + + imageVk.CreateVmaImage(imageCreateInfo, imageAlloc); + + // --- Image View --- + ImageVk::GetDefaultImageViewCreateInfo( + imageViewCreateInfo, imageVk.GetVkImage(), selectedFormat); + imageViewCreateInfo.format = selectedFormat; + imageViewCreateInfo.subresourceRange.aspectMask = + VK_IMAGE_ASPECT_DEPTH_BIT; + if (imageVk.FormatHasStencilComponent()) { + imageViewCreateInfo.subresourceRange.aspectMask |= + VK_IMAGE_ASPECT_STENCIL_BIT; + } + } + + imageVk.CreateImageView(imageViewCreateInfo); + }; + +private: + // void +}; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowDefs.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowDefs.h index a225eb7b..5ed67544 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowDefs.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowDefs.h @@ -49,7 +49,6 @@ template struct PcRenderFlowImages { template struct PcRenderFlowImages { PcRenderFlowImages() {} - PC_STATIC_ASSERT(Count == MAX_FRAMES_IN_FLIGHT, "Count must be equal to MAX_FRAMES_IN_FLIGHT for Gbuffer"); PcFramesImages_Bundle albedoImages{}; @@ -85,5 +84,10 @@ using PcFramesDepthImageBarriers = using PcPresentationImageBarriers = std::vector>; +template +using PcRenderAttachmentInfoState = + std::array, + MAX_FRAMES_IN_FLIGHT>; + GFX_NAMESPACE_END ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h index 014d9fec..f52d9cfc 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.h @@ -7,6 +7,7 @@ #include "GlobalMacros.h" #include "Light.h" #include "MaterialTypes.h" +#include "MemoryDefsVk.h" #include "Mesh.h" #include "RenderFlowDefs.h" #include "SamplerVk.h" @@ -19,14 +20,13 @@ ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN -// TODO: Refactor -// - Vulkan specific for now. -// - Make it platform agnostic class RenderFlowVk { public: RenderFlowVk(); virtual ~RenderFlowVk(); + // + // --- Create/Init stuff ---------------------------------------------------- static void AllocMemory(); static void FreeMemory(); @@ -36,11 +36,13 @@ class RenderFlowVk { static void CopyDynamicUniformsToMemory(const uint32_t currentFrame); static void AllocShaders(); - static void FreeShaders(); static void AllocDescriptorsGlobal(); static void UpdateDescriptorSetsGlobal(); + // --- Cleanup stuff -------------------------------------------------------- + static void FreeShaders(); + public: #ifdef PC_DEBUG virtual void PrintVboIbo() {}; @@ -63,8 +65,10 @@ class RenderFlowVk { private: virtual void CreateAttachments() = 0; virtual void CreateImageBarriers() = 0; - virtual void CreateRenderPass() = 0; virtual void CreateFramebuffers() = 0; + virtual void CreateRenderPass() = 0; + + virtual void CreateRenderInfoState() = 0; virtual void CreateCommandBuffers() = 0; @@ -73,7 +77,7 @@ class RenderFlowVk { virtual void DestroyAttachments() = 0; public: - void Prepare() { + void CreateGfxResources() { PC_WARN("Preparing Renderflow............................") CreateAttachments(); @@ -118,6 +122,18 @@ class RenderFlowVk { template static void UnregisterMaterialAndSubmesh(Submesh *submesh); + static void CreateDrawOrderList() { + s_basicMatBucketDrawOrder.reserve(s_basicMatSubmeshBuckets.size()); + s_pbrMatBucketDrawOrder.reserve(s_pbrMatSubmeshBuckets.size()); + + for (auto &[materialHash, submeshBucket] : s_basicMatSubmeshBuckets) { + s_basicMatBucketDrawOrder.push_back(materialHash); + } + for (auto &[materialHash, submeshBucket] : s_pbrMatSubmeshBuckets) { + s_pbrMatBucketDrawOrder.push_back(materialHash); + } + }; + public: struct SamplersVk { SamplerVk colorSampler; @@ -131,8 +147,12 @@ class RenderFlowVk { protected: // // Game object refs ------------------------------------------------------- - static PcMaterialSubmeshesMap s_basicMatSubmeshesMap; - static PcMaterialSubmeshesMap s_pbrMatSubmeshesMap; + static PcMaterialSubmeshesMap + s_basicMatSubmeshBuckets; + static PcMaterialSubmeshesMap s_pbrMatSubmeshBuckets; + + static PcMaterialSubmeshIndexMap s_basicMatDrawOrder; + static PcMaterialSubmeshIndexMap s_pbrMatDrawOrder; static std::vector s_lights; static std::vector s_cameras; diff --git a/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/ShadowsRFlowVk.h b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/ShadowsRFlowVk.h new file mode 100644 index 00000000..94c3d656 --- /dev/null +++ b/Engine/include/Popcorn/Platform/Vulkan/RenderFlows/ShadowsRFlowVk.h @@ -0,0 +1,17 @@ +#pragma once + +#include "GlobalMacros.h" +#include "RenderFlowVk.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +class ShadowsRFlowsVk : public RenderFlowVk { + ShadowsRFlowsVk(); + virtual ~ShadowsRFlowsVk() override = default; + + virtual void CreateAttachments() override; +}; + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/include/Popcorn/Platform/Vulkan/RendererVk.h b/Engine/include/Popcorn/Platform/Vulkan/RendererVk.h index d12a38a5..ce81ba08 100644 --- a/Engine/include/Popcorn/Platform/Vulkan/RendererVk.h +++ b/Engine/include/Popcorn/Platform/Vulkan/RendererVk.h @@ -3,6 +3,7 @@ #include "ContextVk.h" #include "GameObject.h" #include "GlobalMacros.h" +#include "PaintPasses/PaintPassVk.h" #include "Popcorn/Core/Window.h" #include "Popcorn/Events/WindowEvent.h" #include "RenderFlowVk.h" @@ -24,6 +25,10 @@ class RendererVk : public Renderer { virtual void CreateRenderFlows() override; virtual void DestroyRenderFlows() override; virtual void PrepareRenderFlows() override; + + virtual void + ProcessPaintPasses(const std::vector &paintPasses) override; + virtual void AssignSceneObjectsToRenderFlows() override; virtual void CreateRenderFlowResources() override; @@ -44,6 +49,9 @@ class RendererVk : public Renderer { static ContextVk *s_vulkanContext; static std::vector s_renderFlows; static PcRenderFlowCmdBuffersMap s_renderFlowCmdBuffers; + + // New + std::vector m_paintPassVks; }; GFX_NAMESPACE_END diff --git a/Engine/include/Popcorn/Scene/GameObject.h b/Engine/include/Popcorn/Scene/GameObject.h index 75fc0657..4e6922b9 100644 --- a/Engine/include/Popcorn/Scene/GameObject.h +++ b/Engine/include/Popcorn/Scene/GameObject.h @@ -7,7 +7,6 @@ #include "Transforms.h" #include #include -#include #include #include #include @@ -17,12 +16,6 @@ ENGINE_NAMESPACE_BEGIN GFX_NAMESPACE_BEGIN -struct SceneData { - uint32_t sceneId; - // TODO: make this definition - // like ambient lights data, env map etc. -}; - enum class GameObjectTypes { None = 0, Mesh, diff --git a/Engine/include/Popcorn/Scene/Scene.h b/Engine/include/Popcorn/Scene/Scene.h index b306bc0f..874e47a7 100644 --- a/Engine/include/Popcorn/Scene/Scene.h +++ b/Engine/include/Popcorn/Scene/Scene.h @@ -5,7 +5,6 @@ #include "GlobalMacros.h" #include "Popcorn/Core/Base.h" #include "Popcorn/Core/Time.h" -#include #include #include #include @@ -75,7 +74,7 @@ class Scene { private: static uint32_t s_sceneId; - SceneData m_sceneData{}; // like ambient lights data, env map etc. + // SceneData m_sceneData{}; // like ambient lights data, env map etc. std::vector m_nodes; std::unordered_map m_gameObjectsByName; diff --git a/Engine/include/Popcorn/Scene/SceneLibrary.h b/Engine/include/Popcorn/Scene/SceneLibrary.h index a78ecb8d..d93c658f 100644 --- a/Engine/include/Popcorn/Scene/SceneLibrary.h +++ b/Engine/include/Popcorn/Scene/SceneLibrary.h @@ -23,10 +23,28 @@ class SceneLibrary { return m_scenes; } + static void FillNamedLookUpMap(Scene *scene, GameObject *node) { + if (node == nullptr) { + PC_WARN("node is nullptr") + return; + } + scene->AddGameObjectToNamedLookUp(node->GetName(), node); + + for (GameObject *child : node->GetChildren()) { + FillNamedLookUpMap(scene, child); + } + } + void Add(Scene *scene) { auto it = std::find(m_scenes.begin(), m_scenes.end(), scene); if (it == m_scenes.end()) { m_scenes.emplace_back(scene); + + // Populates a named lookUp map for fast game object access in the scene + for (GameObject *gameObj : scene->GetGameObjects()) { + FillNamedLookUpMap(scene, gameObj); + } + PC_PRINT("Scene added to library", TagType::Print, "SceneLibrary") } else { PC_WARN("Scene not added, it already exists in sceneLibrary") diff --git a/Engine/include/Popcorn2.h b/Engine/include/Popcorn2.h new file mode 100644 index 00000000..427200f2 --- /dev/null +++ b/Engine/include/Popcorn2.h @@ -0,0 +1,91 @@ + +#pragma once + +#include "Animation.h" +#include "Application.h" +#include "Assert.h" +#include "ContextGfx.h" +#include "GameObject.h" +#include "GlobalMacros.h" +#include "GltfLoader.h" +#include "Layer.h" +#include "Scene.h" +#include "SplineFactory.h" +#include +#include + +ENGINE_NAMESPACE_BEGIN +CTX_NAMESPACE_BEGIN + +static Application *s_application = nullptr; +static Renderer *s_renderer = nullptr; + +using Model = tinygltf::Model; + +// +// --- CORE METHODS (INIT PHASE) ----------------------------------------------- +static void BeginContext(); +static void EndContext(); +static void AddLayer(Layer *); + +// --- GAME SCENE UTILS -------------------------------------------------------- +static void RegisterScene(Scene &scene); +static void UnregisterScene(Scene &scene); + +// --- GLTF TO SCENE UTILS ----------------------------------------------------- +static void ExtractScenesFromGltfFile(const std::string &gltfFile); +// -- Extract scene data -- +// +// -- GameObject data -- +// - cameras, +// - lights, +// - static meshes, +// - skinned meshes, +// - static meshes (animatable), +// - terrain chunked meshes +// +// Make CPU structured buffers for related Uniform/SSBO data for each game +// object type, and rules around it (for dynamic data) +// Let users define the Layouts for these buffers +// +// -- Material Data -- +// - Opaque +// - Masked +// - Transclucent +// - Unlit +// - Emissive +// - ClearCoat +// - Subsurface (skin/wax) SONY HEHEHEHE +// - Additive (aura fx) +// - Volumetric (God rays, fog shapes) +// +// Make CPU structured buffers for related Uniform/SSBO data for each material +// type, and rules around it (for dynamic data) Let users define the Layouts +// for these buffers +// +// -- ScreenSpace Data -- (NON GLTF!) JUST FYI +// - Unlit +// - SSAO +// - SSR +// - SSGI +// - Screen-space shadows +// - Motion vectors +// - TAA history +// - Depth-based fog +// - Bloom thresholds +// - Exposure / tonemapping +// - Vignette +// - Film grain +// - Color grading LUTs + +// --- FOR CUSTOM ANIMATIONS --------------------------------------------------- +static SplineFactory *GetSplineFactory(); +static CurveFactory *GetCurveFactory(); + +// +// --- GAME METHODS ------------------------------------------------------------ +static void StartGame(); +static void PaintFrame(); + +CTX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/shaders/vulkan/composite.frag b/Engine/shaders/vulkan/composite.frag index fee1bfbe..ad91373f 100644 --- a/Engine/shaders/vulkan/composite.frag +++ b/Engine/shaders/vulkan/composite.frag @@ -38,8 +38,11 @@ void main() { // vec3 fogColor = vec3(0.020, 0.067, 0.102); // cyan // vec3 fogColor = vec3(0.122, 0.122, 0.027); // cyan // vec3 fogColor = vec3(0.090, 0.020, 0.039); // cyan - vec3 darkCyan = vec3(0.063, 0.200, 0.196); + // vec3 darkCyan = vec3(0.063, 0.200, 0.196); // present + // vec3 darkCyan = vec3(0.0, 0.0, 0.0); // present + // vec3 darkCyan = vec3(0.024, 0.122, 0.149); + vec3 darkCyan = vec3(0.259, 0.000, 0.125); // vec3 darkViolet = vec3(0.047, 0.004, 0.071); // vec3 darkViolet = vec3(0.043, 0.000, 0.078); // vec3 darkViolet = vec3(0.031, 0.000, 0.071); diff --git a/Engine/shaders/vulkan/lighting.frag b/Engine/shaders/vulkan/lighting.frag index c70c005e..c05f4da6 100644 --- a/Engine/shaders/vulkan/lighting.frag +++ b/Engine/shaders/vulkan/lighting.frag @@ -13,6 +13,7 @@ struct LightUniform { float outerConeAngle; }; +// SET 0 layout(set = 0, binding = 0) uniform CameraUBO { mat4 view; mat4 proj; @@ -21,6 +22,7 @@ layout(set = 0, binding = 0) uniform CameraUBO { vec3 camPos; } camera; +// SET 1 layout(set = 1, binding = 0) readonly buffer LightBuffer { LightUniform lights[]; }; @@ -117,7 +119,7 @@ void main() { // float ambient = 0.0025; // float ambient = 0.1; - float ambient = 0.08; + float ambient = 0.02; finalColor += albedo * ambient; // Ambient outColor = vec4(finalColor, 1.0); diff --git a/Engine/src/CMakeLists.txt b/Engine/src/CMakeLists.txt index fc1357c8..e5200136 100644 --- a/Engine/src/CMakeLists.txt +++ b/Engine/src/CMakeLists.txt @@ -10,6 +10,8 @@ set(SCENE_IMPL_DIR Popcorn/Scene) add_library( Popcorn # + Popcorn.cpp + # # CORE ${CORE_IMPL_DIR}/Application.cpp ${CORE_IMPL_DIR}/Externs.cpp diff --git a/Engine/src/Popcorn.cpp b/Engine/src/Popcorn.cpp new file mode 100644 index 00000000..1db92e3f --- /dev/null +++ b/Engine/src/Popcorn.cpp @@ -0,0 +1,9 @@ +#include "Popcorn2.h" + +ENGINE_NAMESPACE_BEGIN +CTX_NAMESPACE_BEGIN + +static void BeginContext() {}; + +CTX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/src/Popcorn/Core/Application.cpp b/Engine/src/Popcorn/Core/Application.cpp index eb9ebac6..1a4fe938 100644 --- a/Engine/src/Popcorn/Core/Application.cpp +++ b/Engine/src/Popcorn/Core/Application.cpp @@ -109,6 +109,7 @@ bool Application::OnWindowClose(WindowCloseEvent &e) const { } bool Application::OnClockTick(TimeEvent &e) { + // Polls for window events (keyboard, mouse etc) Window::OnUpdate(e); // diff --git a/Engine/src/Popcorn/Core/Externs.cpp b/Engine/src/Popcorn/Core/Externs.cpp index ebc166c7..05412661 100644 --- a/Engine/src/Popcorn/Core/Externs.cpp +++ b/Engine/src/Popcorn/Core/Externs.cpp @@ -2,5 +2,5 @@ #include "Popcorn/Core/Base.h" ENGINE_NAMESPACE_BEGIN -int PC_print_lvl = 0; +int PC_PRINT_LEVEL = 0; ENGINE_NAMESPACE_END diff --git a/Engine/src/Popcorn/Core/LayerStack.cpp b/Engine/src/Popcorn/Core/LayerStack.cpp index 51d0cce7..8ccc0773 100644 --- a/Engine/src/Popcorn/Core/LayerStack.cpp +++ b/Engine/src/Popcorn/Core/LayerStack.cpp @@ -5,39 +5,39 @@ ENGINE_NAMESPACE_BEGIN LayerStack::~LayerStack() { // CLEAN UP AND FREE RESOURCES - for (Layer *l : m_layer_stack) { + for (Layer *l : m_layerStack) { l->OnDetach(); delete l; l = nullptr; } - m_layer_stack.clear(); + m_layerStack.clear(); }; void LayerStack::PushLayer(Layer *l) { - m_layer_stack.emplace(m_layer_stack.begin() + m_separator_index++, l); + m_layerStack.emplace(m_layerStack.begin() + m_separatorIndex++, l); }; void LayerStack::PopLayer(Layer *l) { - auto it = std::find(m_layer_stack.begin(), - m_layer_stack.begin() + m_separator_index, l); + auto it = std::find(m_layerStack.begin(), + m_layerStack.begin() + m_separatorIndex, l); - if (it != m_layer_stack.begin() + m_separator_index) { + if (it != m_layerStack.begin() + m_separatorIndex) { l->OnDetach(); - m_layer_stack.erase(it); - --m_separator_index; + m_layerStack.erase(it); + --m_separatorIndex; } } -void LayerStack::PushOverlay(Layer *ol) { m_layer_stack.emplace_back(ol); } +void LayerStack::PushOverlay(Layer *ol) { m_layerStack.emplace_back(ol); } void LayerStack::PopOverlay(Layer *ol) { - auto it = std::find(m_layer_stack.begin() + m_separator_index, - m_layer_stack.end(), ol); + auto it = std::find(m_layerStack.begin() + m_separatorIndex, + m_layerStack.end(), ol); - if (it != m_layer_stack.end()) { + if (it != m_layerStack.end()) { ol->OnDetach(); - m_layer_stack.erase(it); + m_layerStack.erase(it); } } diff --git a/Engine/src/Popcorn/Loaders/GltfLoader.cpp b/Engine/src/Popcorn/Loaders/GltfLoader.cpp index a088d5e5..47e3f7ea 100644 --- a/Engine/src/Popcorn/Loaders/GltfLoader.cpp +++ b/Engine/src/Popcorn/Loaders/GltfLoader.cpp @@ -13,6 +13,7 @@ #include "LoaderUtils.h" #include "LoadersDefs.h" #include "Material.h" +#include "MaterialTypes.h" #include "Mesh.h" #include "Shader.h" #include "SplineFactory.h" @@ -393,6 +394,18 @@ void GltfLoader::ExtractMeshData(const tinygltf::Model &model, } }; +static float PC_SrgbToLinear(float c) { + if (c <= 0.04045f) + return c / 12.92f; + else + return pow((c + 0.055f) / 1.055f, 2.4f); +} + +static glm::vec3 PC_SrgbToLinear(glm::vec3 c) { + return glm::vec3(PC_SrgbToLinear(c.r), PC_SrgbToLinear(c.g), + PC_SrgbToLinear(c.b)); +} + // // // @@ -416,9 +429,12 @@ GltfLoader::ExtractMaterialData(const tinygltf::Model &model, if constexpr (T == MaterialTypes::PbrMat) { // Add shader byte code - materialData.baseColorFactor = glm::vec4( - gltfMatData.baseColorFactor[0], gltfMatData.baseColorFactor[1], - gltfMatData.baseColorFactor[2], gltfMatData.baseColorFactor[3]); + // Blender exports baseColorFactor in Srgb space + materialData.baseColorFactor = + glm::vec4(PC_SrgbToLinear(gltfMatData.baseColorFactor[0]), + PC_SrgbToLinear(gltfMatData.baseColorFactor[1]), + PC_SrgbToLinear(gltfMatData.baseColorFactor[2]), + gltfMatData.baseColorFactor[3]); materialData.metallicFactor = gltfMatData.metallicFactor; materialData.roughnessFactor = gltfMatData.roughnessFactor; materialData.hasNormalTexture = material.normalTexture.index != -1; @@ -427,9 +443,11 @@ GltfLoader::ExtractMaterialData(const tinygltf::Model &model, } else { // DEFAULTS TO BASIC MATERIAL // Add shader byte code - materialData.baseColorFactor = glm::vec4( - gltfMatData.baseColorFactor[0], gltfMatData.baseColorFactor[1], - gltfMatData.baseColorFactor[2], gltfMatData.baseColorFactor[3]); + materialData.baseColorFactor = + glm::vec4(PC_SrgbToLinear(gltfMatData.baseColorFactor[0]), + PC_SrgbToLinear(gltfMatData.baseColorFactor[1]), + PC_SrgbToLinear(gltfMatData.baseColorFactor[2]), + gltfMatData.baseColorFactor[3]); } // // Add shader files based on material type @@ -442,20 +460,14 @@ GltfLoader::ExtractMaterialData(const tinygltf::Model &model, MaterialTypes GltfLoader::GetGltfMaterialType(const tinygltf::Material &material) { - const auto &pbr = material.pbrMetallicRoughness; - - // Determine material type - bool isPBR = pbr.metallicFactor > 0.0f || pbr.roughnessFactor > 0.0f || - material.normalTexture.index != -1 || - material.occlusionTexture.index != -1; + const char *matName = material.name.c_str(); - if (isPBR) { - PC_PRINT("PBR Mat", TagType::Print, "GltfLoader.cpp") - return MaterialTypes::PbrMat; - } else { - PC_PRINT("Basic Mat", TagType::Print, "GltfLoader.cpp") + const char *suffix = "_unlit"; + if (PC_StrEndsWith(matName, suffix)) { return MaterialTypes::BasicMat; - } + } else { + return MaterialTypes::PbrMat; + }; } // @@ -470,9 +482,9 @@ GltfLoader::GetGltfMaterialType(const tinygltf::Material &material) { VertexBuffer * GltfLoader::ExtractVertexBuffer(const tinygltf::Model &model, const tinygltf::Primitive &primitive) { - const byte_t *posData = nullptr; - const byte_t *normData = nullptr; - const byte_t *uvData = nullptr; + const PC_Byte_t *posData = nullptr; + const PC_Byte_t *normData = nullptr; + const PC_Byte_t *uvData = nullptr; size_t posStride = 0; size_t normStride = 0; @@ -494,7 +506,7 @@ GltfLoader::ExtractVertexBuffer(const tinygltf::Model &model, const auto &posView = model.bufferViews[posAccessor.bufferView]; const auto &posBuffer = model.buffers[posView.buffer]; - posData = reinterpret_cast( + posData = reinterpret_cast( posBuffer.data.data() + posAccessor.byteOffset + posView.byteOffset); posStride = posView.byteStride ? posView.byteStride : 3 * sizeof(float); posByteSize = tinygltf::GetComponentSizeInBytes(posAccessor.componentType) * @@ -512,7 +524,7 @@ GltfLoader::ExtractVertexBuffer(const tinygltf::Model &model, model.bufferViews[normAccessor.bufferView]; // normView is HERE const auto &normBuffer = model.buffers[normView.buffer]; - normData = reinterpret_cast( + normData = reinterpret_cast( normBuffer.data.data() + normAccessor.byteOffset + normView.byteOffset); normStride = normView.byteStride ? normView.byteStride : 3 * sizeof(float); normByteSize = @@ -534,7 +546,7 @@ GltfLoader::ExtractVertexBuffer(const tinygltf::Model &model, model.bufferViews[uvAccessor.bufferView]; // uvView is HERE const auto &uvBuffer = model.buffers[uvView.buffer]; - uvData = reinterpret_cast( + uvData = reinterpret_cast( uvBuffer.data.data() + uvAccessor.byteOffset + uvView.byteOffset); uvStride = uvView.byteStride ? uvView.byteStride : 2 * sizeof(float); uvByteSize = @@ -564,14 +576,14 @@ GltfLoader::ExtractVertexBuffer(const tinygltf::Model &model, size_t baseOffset = i * totalAttrByteSize; size_t cpyOffset = 0; - const byte_t *pos = - reinterpret_cast(posData + i * posStride); + const PC_Byte_t *pos = + reinterpret_cast(posData + i * posStride); vertices->Fill(pos, posByteSize, baseOffset + cpyOffset); cpyOffset += posByteSize; if (normData) { - const byte_t *norm = - reinterpret_cast(normData + i * normStride); + const PC_Byte_t *norm = + reinterpret_cast(normData + i * normStride); vertices->Fill(norm, normByteSize, baseOffset + cpyOffset); cpyOffset += normByteSize; } else { @@ -581,8 +593,8 @@ GltfLoader::ExtractVertexBuffer(const tinygltf::Model &model, } if (uvData) { - const byte_t *uv = - reinterpret_cast(uvData + i * uvStride); + const PC_Byte_t *uv = + reinterpret_cast(uvData + i * uvStride); vertices->Fill(uv, uvByteSize, baseOffset + cpyOffset); cpyOffset += uvByteSize; } else { @@ -606,8 +618,8 @@ GltfLoader::ExtractIndexBuffer(const tinygltf::Model &model, const auto &indexView = model.bufferViews[indexAccessor.bufferView]; const auto &gltfIndexBuffer = model.buffers[indexView.buffer]; - const byte_t *srcData = gltfIndexBuffer.data.data() + indexView.byteOffset + - indexAccessor.byteOffset; + const PC_Byte_t *srcData = gltfIndexBuffer.data.data() + + indexView.byteOffset + indexAccessor.byteOffset; // Handle stride (distance between indices in bytes) // size_t stride = indexView.byteStride; @@ -639,7 +651,7 @@ GltfLoader::ExtractIndexBuffer(const tinygltf::Model &model, // Convert indices to 32-bit for (size_t i = 0; i < indexCount; ++i) { const size_t offset = i * stride; - const byte_t *src = srcData + offset; + const PC_Byte_t *src = srcData + offset; uint32_t indexValue = 0; switch (indexAccessor.componentType) { diff --git a/Engine/src/Popcorn/Platform/Vulkan/Memory/MemoryVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/Memory/MemoryVk.cpp index b402d42c..808d4768 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/Memory/MemoryVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/Memory/MemoryVk.cpp @@ -252,7 +252,7 @@ void MemoryVk::FillVbosIbosUbosSubmeshMaterial( const VkDeviceSize vboSize = submesh->GetVertexBuffer()->GetCount() * vboLayout.strideValue; - memcpy((byte_t *)m_vboStagingMapping + + memcpy((PC_Byte_t *)m_vboStagingMapping + m_bufferOffsets.submeshesOffsets[matId][i].vboOffset, submesh->GetVertexBuffer()->GetBufferData(), (size_t)vboSize); @@ -260,7 +260,7 @@ void MemoryVk::FillVbosIbosUbosSubmeshMaterial( // IBOs --------------------------------------------------------------- IndexBuffer *indexBuffer = submesh->GetIndexBuffer(); const VkDeviceSize iboSize = indexBuffer->GetCount() * sizeof(uint32_t); - memcpy((byte_t *)m_iboStagingMapping + + memcpy((PC_Byte_t *)m_iboStagingMapping + m_bufferOffsets.submeshesOffsets[matId][i].iboOffset, indexBuffer->GetBufferData(), (size_t)iboSize); } @@ -268,9 +268,13 @@ void MemoryVk::FillVbosIbosUbosSubmeshMaterial( }; template -void MemoryVk::FillUbosSubmesh(PcMaterialSubmeshesMap &materialSubmeshesMap, - const uint32_t currentFrame) { - for (auto &[matId, submeshes] : materialSubmeshesMap) { +void MemoryVk::FillUbosSubmesh( + PcMaterialSubmeshIndexMap &materialSubmeshIndexMap, + PcMaterialSubmeshesMap &materialSubmeshesMap, + const uint32_t currentFrame) { + for (MaterialHashType matId : materialSubmeshIndexMap) { + auto &submeshes = materialSubmeshesMap[matId]; + for (size_t i = 0; i < submeshes.size(); ++i) { Submesh *submesh = submeshes[i]; const glm::mat4 &worldMatrix = submesh->GetParentMesh()->GetWorldMatrix(); diff --git a/Engine/src/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.cpp index b91d381e..0fe6a5ff 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/Pipelines/MaterialPipelinesVk.cpp @@ -28,6 +28,9 @@ void BasicMatPipelineVk::Create(const BufferDefs::Layout &vertexBufferLayout, const VkRenderPass &renderPass) { const VkDevice &device = ContextVk::Device()->GetDevice(); + // + // --- SET SHADER STUFF ------------------------------------------------------ + // --- SET SHADER STUFF ------------------------------------------------------ const Buffer &vertShaderBuffer = Material::GetShader(ShaderStages::VertexBit); const Buffer &fragShaderBuffer = @@ -42,6 +45,9 @@ void BasicMatPipelineVk::Create(const BufferDefs::Layout &vertexBufferLayout, SetShaderStagesMask(ShaderStages::VertexBit | ShaderStages::FragmentBit); CreateShaderStageCreateInfos(shaderModules); + // + // --- VBO/IBO STUFF --------------------------------------------------------- + // --- VBO/IBO STUFF --------------------------------------------------------- VkVertexInputBindingDescription bindingDescription{}; VertexBufferVk::GetDefaultVertexInputBindingDescription(vertexBufferLayout, bindingDescription); @@ -76,6 +82,12 @@ void BasicMatPipelineVk::Create(const BufferDefs::Layout &vertexBufferLayout, pipelineState.depthStencilState.front = {}; pipelineState.depthStencilState.back = {}; + pipelineState.renderingInfoState.sType = + VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO; + pipelineState.renderingInfoState.pNext = VK_NULL_HANDLE; + pipelineState.renderingInfoState.colorAttachmentCount = 3; + // pipelineState.renderingInfoState.pColorAttachmentFormats = + auto *layouts = ContextVk::DescriptorLayouts(); VkDescriptorSetLayout &cameraLayout = layouts->GetLayout(); @@ -183,5 +195,86 @@ void PbrMatPipelineVk::Create(const BufferDefs::Layout &vertexBufferLayout, PC_DestroyShaderModule(device, fragShaderModule); }; +void PbrMatPipelineVk::Create(const BufferDefs::Layout &vertexBufferLayout, + const PcAttachmentsInfo &attachmentLayouts) { + const VkDevice &device = ContextVk::Device()->GetDevice(); + + const Buffer &vertShaderBuffer = + Material::GetShader(ShaderStages::VertexBit); + const Buffer &fragShaderBuffer = + Material::GetShader(ShaderStages::FragmentBit); + + auto vertShaderModule = PC_CreateShaderModule(device, vertShaderBuffer); + auto fragShaderModule = PC_CreateShaderModule(device, fragShaderBuffer); + + std::forward_list shaderModules = {vertShaderModule, + fragShaderModule}; + + SetShaderStagesMask(ShaderStages::VertexBit | ShaderStages::FragmentBit); + CreateShaderStageCreateInfos(shaderModules); + + VkVertexInputBindingDescription bindingDescription{}; + VertexBufferVk::GetDefaultVertexInputBindingDescription(vertexBufferLayout, + bindingDescription); + bindingDescription.binding = 0; + + std::vector attributeDescriptions{}; + VertexBufferVk::GetDefaultVertexInputAttributeDescriptions( + vertexBufferLayout, attributeDescriptions); + + std::vector colorBlendAttachments{}; + colorBlendAttachments.resize(3); + + GfxPipelineState pipelineState{}; + PipelineUtilsVk::GetDefaultGfxPipelineState(vertexBufferLayout, pipelineState, + colorBlendAttachments); + + pipelineState.vertexInputState.vertexBindingDescriptionCount = 1; + pipelineState.vertexInputState.vertexAttributeDescriptionCount = + static_cast(attributeDescriptions.size()); + pipelineState.vertexInputState.pVertexBindingDescriptions = + &bindingDescription; + pipelineState.vertexInputState.pVertexAttributeDescriptions = + attributeDescriptions.data(); + + pipelineState.depthStencilState.depthTestEnable = VK_TRUE; + pipelineState.depthStencilState.depthWriteEnable = VK_TRUE; + pipelineState.depthStencilState.depthCompareOp = VK_COMPARE_OP_LESS; + pipelineState.depthStencilState.depthBoundsTestEnable = VK_FALSE; + pipelineState.depthStencilState.minDepthBounds = 0.0f; + pipelineState.depthStencilState.maxDepthBounds = 1.0f; + pipelineState.depthStencilState.stencilTestEnable = VK_FALSE; + pipelineState.depthStencilState.front = {}; + pipelineState.depthStencilState.back = {}; + + pipelineState.renderingInfoState.sType = + VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO; + pipelineState.renderingInfoState.pNext = VK_NULL_HANDLE; + pipelineState.renderingInfoState.colorAttachmentCount = 3; + // pipelineState.renderingInfoState.pColorAttachmentFormats = + + auto *layouts = ContextVk::DescriptorLayouts(); + VkDescriptorSetLayout &cameraLayout = + layouts->GetLayout(); + VkDescriptorSetLayout &pbrMatLayout = + layouts->GetLayout(); + VkDescriptorSetLayout &submeshLayout = + layouts->GetLayout(); + + std::array dSetLayouts = { + cameraLayout, pbrMatLayout, submeshLayout}; + + // Pipeline Layout (descriptor set layout data) + pipelineState.pipelineLayout.setLayoutCount = dSetLayouts.size(); + pipelineState.pipelineLayout.pSetLayouts = dSetLayouts.data(); + + CreatePipelineLayout(device, pipelineState.pipelineLayout); + CreateVkPipeline(device, pipelineState, renderPass); + + // Destroy shader modules + PC_DestroyShaderModule(device, vertShaderModule); + PC_DestroyShaderModule(device, fragShaderModule); +}; + GFX_NAMESPACE_END ENGINE_NAMESPACE_END diff --git a/Engine/src/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.cpp index cc9688b7..3322041a 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/Pipelines/PipelineVk.cpp @@ -8,7 +8,7 @@ GFX_NAMESPACE_BEGIN template <> void PipelineVk::CreateVkPipeline( - const VkDevice &device, const PipelineStateType &pipelineCreateInfo, + const VkDevice &device, const PipelineStateType &pipelineState, const VkRenderPass &renderPass) { if (m_pipeline != VK_NULL_HANDLE) { @@ -16,7 +16,7 @@ void PipelineVk::CreateVkPipeline( return; }; - GfxPipelineState createInfo = pipelineCreateInfo; + const GfxPipelineState &gfxPipelineState = pipelineState; if (m_shaderStageCreateInfos.size() == 0) { PC_WARN("No shader stages set") }; @@ -29,15 +29,15 @@ void PipelineVk::CreateVkPipeline( pipelineInfo.stageCount = m_shaderStageCreateInfos.size(); pipelineInfo.pStages = m_shaderStageCreateInfos.data(); - pipelineInfo.pVertexInputState = &createInfo.vertexInputState; - pipelineInfo.pInputAssemblyState = &createInfo.inputAssemblyState; - pipelineInfo.pViewportState = &createInfo.viewportState; - pipelineInfo.pRasterizationState = &createInfo.rasterizationState; - pipelineInfo.pDepthStencilState = &createInfo.depthStencilState; + pipelineInfo.pVertexInputState = &gfxPipelineState.vertexInputState; + pipelineInfo.pInputAssemblyState = &gfxPipelineState.inputAssemblyState; + pipelineInfo.pViewportState = &gfxPipelineState.viewportState; + pipelineInfo.pRasterizationState = &gfxPipelineState.rasterizationState; + pipelineInfo.pDepthStencilState = &gfxPipelineState.depthStencilState; // pipelineInfo.pDepthStencilState = nullptr; - pipelineInfo.pMultisampleState = &createInfo.multisampleState; - pipelineInfo.pColorBlendState = &createInfo.colorBlendState; - pipelineInfo.pDynamicState = &createInfo.dynamicState; + pipelineInfo.pMultisampleState = &gfxPipelineState.multisampleState; + pipelineInfo.pColorBlendState = &gfxPipelineState.colorBlendState; + pipelineInfo.pDynamicState = &gfxPipelineState.dynamicState; pipelineInfo.layout = m_pipelineLayout; diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp index 9127ec75..c1f6a29b 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/GBufferRenderFlowVk.cpp @@ -8,7 +8,6 @@ #include "DescriptorLayoutsVk.h" #include "DescriptorPoolsVk.h" #include "FramebufferVk.h" -#include "ImageVk.h" #include "MaterialTypes.h" #include "Memory/MemoryVk.h" #include "Mesh.h" @@ -16,7 +15,9 @@ #include "Popcorn/Core/Base.h" #include "Popcorn/Core/Helpers.h" #include "Popcorn/Loaders/LoadersDefs.h" +#include "RFlowResourcesVk.h" #include "RenderPassVk.h" +#include "Uniforms.h" #include #include #include @@ -214,6 +215,78 @@ void GBufferRenderFlowVk::CreateAttachments() { } } +void GBufferRenderFlowVk::CreateRenderInfoState() { + + // + // --- RENDER ATTACHMENTS INFO ----------------------------------------------- + // --- RENDER ATTACHMENTS INFO ----------------------------------------------- + // + for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) { + // albedo + VkRenderingAttachmentInfo &albedoInfo = + m_renderInfoState.colorAttachmentInfos[i][0]; + RFlowResourcesVk::GetDefaultRenderingAttachmentInfo( + s_gBufferImages.albedoImages[i].GetVkImageView(), albedoInfo); + VkClearValue clearAlbedo = {{0.0f, 0.0f, 0.0f, 1.0f}}; + albedoInfo.clearValue = clearAlbedo; + + // normal + VkRenderingAttachmentInfo &normalInfo = + m_renderInfoState.colorAttachmentInfos[i][1]; + RFlowResourcesVk::GetDefaultRenderingAttachmentInfo( + s_gBufferImages.normalImages[i].GetVkImageView(), normalInfo); + VkClearValue clearNormal = {{0.0f, 0.0f, 0.0f, 0.0f}}; + normalInfo.clearValue = clearNormal; + + // roughnessMetallic + VkRenderingAttachmentInfo &roughnessMetallicInfo = + m_renderInfoState.colorAttachmentInfos[i][2]; + RFlowResourcesVk::GetDefaultRenderingAttachmentInfo( + s_gBufferImages.roughnessMetallicImages[i].GetVkImageView(), + roughnessMetallicInfo); + + VkClearValue clearRoughnessMetallic = {{0.0f, 0.0f, 0.0f, 0.0f}}; + roughnessMetallicInfo.clearValue = clearRoughnessMetallic; + + // depth + VkRenderingAttachmentInfo &depthInfo = + m_renderInfoState.depthAttachmentInfos[i][0]; + RFlowResourcesVk::GetDefaultRenderingAttachmentInfo( + s_gBufferImages.depthImages[i].GetVkImageView(), depthInfo); + bool depthHasStencilComponent = + s_gBufferImages.depthImages[i].FormatHasStencilComponent(); + depthInfo.imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; + depthInfo.imageLayout = + depthHasStencilComponent + ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL + : VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; + VkClearValue clearDepth{}; + clearDepth.depthStencil.depth = 1.0f; + clearDepth.depthStencil.stencil = 0; + depthInfo.clearValue = clearDepth; + + // + // --- RENDER INFO --------------------------------------------------------- + // --- RENDER INFO --------------------------------------------------------- + // + auto &swapchainExtent = ContextVk::Swapchain()->GetSwapchainExtent(); + VkRenderingInfo &renderingInfo = m_renderInfoState.renderingInfo[i]; + + renderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO; + renderingInfo.renderArea = {{0, 0}, swapchainExtent}; + renderingInfo.layerCount = 1; + renderingInfo.colorAttachmentCount = 3; + renderingInfo.pColorAttachments = + m_renderInfoState.colorAttachmentInfos[i].data(); + renderingInfo.pDepthAttachment = + m_renderInfoState.depthAttachmentInfos[i].data(); + + renderingInfo.pStencilAttachment = nullptr; + renderingInfo.pNext = nullptr; + renderingInfo.flags = 0; + } +}; + // // // @@ -461,18 +534,17 @@ void GBufferRenderFlowVk::UpdateDescriptorSetsLocal() { VkDescriptorBufferInfo submeshBufferInfo{}; submeshBufferInfo.buffer = memory->GetUboSet(i); submeshBufferInfo.offset = memory->GetBufferViews().submeshUbo.offset; - submeshBufferInfo.range = - // memory->GetBufferViews().submeshUbo.alignedSize; - DescriptorLayoutsVk::GetDescriptorBufferRange< - DescriptorSets::SubmeshSet>(properties.limits); + submeshBufferInfo.range = UniformDefs::SubmeshUniform::size; + // memory->GetBufferViews().submeshUbo.alignedSize; + // DescriptorLayoutsVk::GetDescriptorBufferRange< + // DescriptorSets::SubmeshSet>(properties.limits); VkDescriptorBufferInfo basicMatBufferInfo{}; basicMatBufferInfo.buffer = memory->GetUboSet(i); basicMatBufferInfo.offset = memory->GetBufferViews().basicMatUbo.offset; - basicMatBufferInfo.range = - // memory->GetBufferViews().basicMatUbo.alignedSize; - DescriptorLayoutsVk::GetDescriptorBufferRange< - DescriptorSets::BasicMatSet>(properties.limits); + basicMatBufferInfo.range = DescriptorLayoutsVk::GetDescriptorBufferRange< + DescriptorSets::BasicMatSet>(properties.limits); + // memory->GetBufferViews().basicMatUbo.alignedSize; VkDescriptorBufferInfo pbrMatBufferInfo{}; pbrMatBufferInfo.buffer = memory->GetUboSet(i); @@ -534,7 +606,13 @@ void GBufferRenderFlowVk::UpdateDescriptorSetsLocal() { // --- CREATE PIPELINES -------------------------------------------------------- // void GBufferRenderFlowVk::CreatePipelines() { - // Draws Gltf models + // + // PASS + // ---- + // 1. Dynamic renderflow info + // 2. Create one material pipeline instead of multiple (maybe one inbuilt, and + // one custom) + m_basicMatPipelineVk.Create(GltfVertexBufferLayout, m_renderPass.GetVkRenderPass()); m_pbrMatPipelineVk.Create(GltfVertexBufferLayout, @@ -659,8 +737,8 @@ void GBufferRenderFlowVk::RecordCommandBuffer(const uint32_t frameIndex, cameraSets.size(), cameraSets.data(), 1, &cameraOffset); - // TODO: Optimize - currently iterates over a map, make it vector - for (auto &[materialHash, submeshes] : s_basicMatSubmeshesMap) { + for (const MaterialHashType materialHash : s_basicMatDrawOrder) { + auto &submeshes = s_basicMatSubmeshBuckets[materialHash]; uint32_t basicMatOffset = bufferOffsets.materialOffsets[materialHash]; // Descriptor set 1 - Basic material @@ -702,8 +780,9 @@ void GBufferRenderFlowVk::RecordCommandBuffer(const uint32_t frameIndex, cameraSets.size(), cameraSets.data(), 1, &cameraOffset); - // TODO: Optimize - currently iterates over a map, make it vector - for (auto &[materialHash, submeshes] : s_pbrMatSubmeshesMap) { + for (const MaterialHashType materialHash : s_pbrMatDrawOrder) { + auto &submeshes = s_pbrMatSubmeshBuckets[materialHash]; + uint32_t pbrMatOffset = bufferOffsets.materialOffsets[materialHash]; // Descriptor set 1 - Pbr material diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/LightingRenderFlowVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/LightingRenderFlowVk.cpp index 003c79c8..b49326c8 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/LightingRenderFlowVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/LightingRenderFlowVk.cpp @@ -236,7 +236,9 @@ void LightingRenderFlowVk::UpdateDescriptorSetsLocal() { VkDescriptorBufferInfo lightBufferInfo{}; lightBufferInfo.buffer = memory->GetSsboSet(i); lightBufferInfo.offset = memory->GetBufferViews().lightsSsbo.offset; - lightBufferInfo.range = memory->GetBufferViews().lightsSsbo.alignedSize; + lightBufferInfo.range = + // let shader access full buffer + memory->GetBufferViews().lightsSsbo.alignedSize; // DescriptorLayoutsVk::GetDescriptorBufferRange< // DescriptorSets::LightingSet>(properties.limits); diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.cpp new file mode 100644 index 00000000..69d47b3a --- /dev/null +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RFlowResourcesVk.cpp @@ -0,0 +1,8 @@ +#include "RFlowResourcesVk.h" +#include "GlobalMacros.h" + +ENGINE_NAMESPACE_BEGIN +GFX_NAMESPACE_BEGIN + +GFX_NAMESPACE_END +ENGINE_NAMESPACE_END diff --git a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.cpp index d6ef6b85..405f6f05 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RenderFlows/RenderFlowVk.cpp @@ -17,9 +17,14 @@ GFX_NAMESPACE_BEGIN // // Game Object refs ------------------------------------------------------- PcMaterialSubmeshesMap - RenderFlowVk::s_basicMatSubmeshesMap{}; + RenderFlowVk::s_basicMatSubmeshBuckets{}; PcMaterialSubmeshesMap - RenderFlowVk::s_pbrMatSubmeshesMap{}; + RenderFlowVk::s_pbrMatSubmeshBuckets{}; + +PcMaterialSubmeshIndexMap + RenderFlowVk::s_basicMatDrawOrder{}; +PcMaterialSubmeshIndexMap + RenderFlowVk::s_pbrMatDrawOrder{}; std::vector RenderFlowVk::s_lights{}; std::vector RenderFlowVk::s_cameras{}; @@ -162,8 +167,8 @@ void RenderFlowVk::AllocMemory() { // Extract - // 1. All vbos, ibos, ubos individual offsets (BufferOffsets) // 2. Ubo & ssbo bufferView sizes (not aligned) - memory->ExtractOffsetsMaterialsSubmeshes(s_basicMatSubmeshesMap); - memory->ExtractOffsetsMaterialsSubmeshes(s_pbrMatSubmeshesMap); + memory->ExtractOffsetsMaterialsSubmeshes(s_basicMatSubmeshBuckets); + memory->ExtractOffsetsMaterialsSubmeshes(s_pbrMatSubmeshBuckets); memory->ExtractOffsetsLightsCamerasEmptys(s_lights, s_cameras, s_emptys); // Aligns vbo & ibo (BufferViews) for optimal copy (staging -> local) @@ -180,9 +185,10 @@ void RenderFlowVk::AllocMemory() { memory->AllocUboSsboLocalBuffers(); // clean up in RenderFlowVk::FreeMemory() // Fill submesh vbos, ibos and ubos, material ubos - memory->FillVbosIbosUbosSubmeshMaterial(s_basicMatSubmeshesMap, + memory->FillVbosIbosUbosSubmeshMaterial(s_basicMatSubmeshBuckets, s_basicMaterials); - memory->FillVbosIbosUbosSubmeshMaterial(s_pbrMatSubmeshesMap, s_pbrMaterials); + memory->FillVbosIbosUbosSubmeshMaterial(s_pbrMatSubmeshBuckets, + s_pbrMaterials); PC_ASSERT(s_submeshCount, "Submesh count is zero."); @@ -196,8 +202,10 @@ void RenderFlowVk::AllocMemory() { void RenderFlowVk::CopyDynamicUniformsToMemory(const uint32_t currentFrame) { auto *memory = ContextVk::Memory(); - memory->FillUbosSubmesh(s_basicMatSubmeshesMap, currentFrame); - memory->FillUbosSubmesh(s_pbrMatSubmeshesMap, currentFrame); + memory->FillUbosSubmesh(s_basicMatDrawOrder, s_basicMatSubmeshBuckets, + currentFrame); + memory->FillUbosSubmesh(s_pbrMatDrawOrder, s_pbrMatSubmeshBuckets, + currentFrame); memory->FillUbosSsbosLightCameraEmpty(s_lights, s_cameras, s_emptys, currentFrame); @@ -244,13 +252,14 @@ template void RenderFlowVk::RegisterMaterialAndSubmesh(Submesh *submesh) { if constexpr (T == MaterialTypes::BasicMat) { uint32_t materialId = PC_HashMaterialGroups(submesh->GetMaterial()); - if (PC_ValidateAndAddSubmesh(submesh, s_basicMatSubmeshesMap[materialId])) { + if (PC_ValidateAndAddSubmesh(submesh, + s_basicMatSubmeshBuckets[materialId])) { s_basicMaterials[materialId] = submesh->GetMaterial(); ++s_submeshCount; }; } else if constexpr (T == MaterialTypes::PbrMat) { uint32_t materialId = PC_HashMaterialGroups(submesh->GetMaterial()); - if (PC_ValidateAndAddSubmesh(submesh, s_pbrMatSubmeshesMap[materialId])) { + if (PC_ValidateAndAddSubmesh(submesh, s_pbrMatSubmeshBuckets[materialId])) { s_pbrMaterials[materialId] = submesh->GetMaterial(); ++s_submeshCount; }; @@ -266,13 +275,13 @@ void RenderFlowVk::UnregisterMaterialAndSubmesh(Submesh *submesh) { if constexpr (T == MaterialTypes::BasicMat) { uint32_t materialId = PC_HashMaterialGroups(submesh->GetMaterial()); if (PC_ValidateAndRemoveSubmesh(submesh, - s_basicMatSubmeshesMap[materialId])) { + s_basicMatSubmeshBuckets[materialId])) { --s_submeshCount; }; } else if constexpr (T == MaterialTypes::PbrMat) { uint32_t materialId = PC_HashMaterialGroups(submesh->GetMaterial()); if (PC_ValidateAndRemoveSubmesh(submesh, - s_pbrMatSubmeshesMap[materialId])) { + s_pbrMatSubmeshBuckets[materialId])) { --s_submeshCount; }; } diff --git a/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp b/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp index 19f9599a..744b1bad 100644 --- a/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp +++ b/Engine/src/Popcorn/Platform/Vulkan/RendererVk.cpp @@ -5,11 +5,14 @@ #include "GameObject.h" #include "LightingRenderFlowVk.h" #include "Material.h" +#include "PaintPasses/PaintPass.h" +#include "PaintPasses/PaintPassVk.h" #include "Popcorn/Core/Base.h" #include "Popcorn/Core/Helpers.h" #include "RenderFlowDefs.h" #include "RenderFlowVk.h" #include "Shader.h" +#include #include #include #include @@ -85,11 +88,28 @@ void RendererVk::DestroyVulkanContext() { // --------------------------------------------------------------------------- // --- RENDER WORKFLOWS ------------------------------------------------------ void RendererVk::CreateRenderFlows() { + // + // TODO: Take PaintPasses (paintpasses are only Info objects. they will be + // converted to RenderflowVks with Vulkan memory and vulkan passes) + // s_renderFlows.emplace_back(new GBufferRenderFlowVk()); - s_renderFlows.emplace_back(new LightingRenderFlowVk()); - s_renderFlows.emplace_back(new CompositeRenderFlowVk()); + // s_renderFlows.emplace_back(new LightingRenderFlowVk()); + // s_renderFlows.emplace_back(new CompositeRenderFlowVk()); } +void RendererVk::ProcessPaintPasses(const std::vector &paintPasses) { + // Converts PaintPasses to Vulkan CreateInfo objects + // Create Vulkan PaintPasses + // paintPassVk modifies the members of PaintPass to store the created render + // object infos like bufferViews, mem locations etc + for (const PaintPass &paintPass : paintPasses) { + PaintPassVk paintPassVk{paintPass}; + paintPassVk.MakeAttachmentInfos(); + + m_paintPassVks.emplace_back(std::move(paintPassVk)); + } +}; + void RendererVk::DestroyRenderFlows() { vkDeviceWaitIdle(ContextVk::Device()->GetDevice()); @@ -116,12 +136,12 @@ void RendererVk::PrepareRenderFlows() { for (auto &renderFlow : s_renderFlows) { PC_WARN("Preparing renderflow...") - renderFlow->Prepare(); // Creates Vulkan: - // - Attachments - // - ImageBarriers - // - RenderPass - // - Framebuffer - // - Commandbuffers + renderFlow->CreateGfxResources(); // Creates Vulkan: + // - Attachments + // - ImageBarriers + // - RenderPass + // - Framebuffer + // - Commandbuffers } s_renderFlowCmdBuffers[RenderFlows::GBuffer] = @@ -134,12 +154,53 @@ void RendererVk::PrepareRenderFlows() { &s_renderFlows[2]->GetCommandBuffers(); } +void MakePaintPasses(const std::vector &paintPasses) { + // Create Draw order list? + // PaintPassInfos, (contains PaintPipelineInfos) + // make sequence from ^ + + // + // 0. Extract data and create Vulkan memory from SubmeshBucketData + // (VBOs, IBOs, UBOs, SSBOs, Samplers, Compute) + // + // --- Global --- + // 1. Create Vulkan AttachmentInfos from DrawAttachmentInfos + // + // --- Per pass --- + // --- Per pipeline --- + // 2. Create Vulkan RenderingInfos from + // PaintPassInfo.PaintPipelineInfos[index] + // 3. Make DSets from SubmeshBucketData, MaterialData, .etc + // types - global(L0), per material(L1), per submesh(L2) + // linked to step 0 + // 4. Make shader modules and samplers (material/fullscreen) + // 5. Make Vulkan pipeline based on the renderinfos ^^ + // 6. Free shaders? + // + // --- Global/Outside --- + // 7. Accessor class to all of the above resources + // 8. Ready for game loop !! + // + + // + // STEP 0. + // + // STEP 1. + // --- Create Vulkan AttachmentInfos from DrawAttachmentInfos -------------- + // + for (const PaintPass &paintPass : paintPasses) { + } +}; + void RendererVk::CreateRenderFlowResources() { // // CREATE WORKFLOW RESOURCES ----------------------------------------------- PC_WARN("Expensive initialization operation: Creating workflow Vulkan " "resources! Should only be done once") + // Copies material hashed submesh buckets to an std::vector for faster + // iteration in hot loops + RenderFlowVk::CreateDrawOrderList(); // // Allocate memory, samplers & load shaders in the shader library RenderFlowVk::AllocMemory(); @@ -183,12 +244,14 @@ void RendererVk::ProcessGameObjectNode(GameObject *node) { // Recursive case Popcorn::Gfx::GameObjectTypes::Mesh: // { auto *mesh = static_cast(node); + for (auto &basicSubmesh : mesh->GetSubmeshes()) { RenderFlowVk::RegisterMaterialAndSubmesh(&basicSubmesh); } for (auto &pbrSubmesh : mesh->GetSubmeshes()) { RenderFlowVk::RegisterMaterialAndSubmesh(&pbrSubmesh); } + } break; case Popcorn::Gfx::GameObjectTypes::Camera: // diff --git a/Sandbox/02-Street-Scene/main-paintpasses.cpp b/Sandbox/02-Street-Scene/main-paintpasses.cpp new file mode 100644 index 00000000..eefaf417 --- /dev/null +++ b/Sandbox/02-Street-Scene/main-paintpasses.cpp @@ -0,0 +1,78 @@ +// TODO: Add to Popcorn.h instead of a whole bunch of these: +#include "paintpasses/paintPassBuilder.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Popcorn; + +class BlenderScene : public Scene {}; // Game Objects are owned by Scene + +class GameLayer : public Layer { +public: + GameLayer() = default; + + virtual void OnAttach() override { + Popcorn::Context::ConvertGltfToScene("../assets/models/gold.gltf", scene); + // Popcorn::Context::ConvertGltfToScene("../assets/models/gold.gltf", + // scene); + Popcorn::Context::RegisterScene(scene); + + // Init paintpass builder + paintPassBuilder.InitPasses(); + } + + virtual void OnDetach() override { + // Popcorn::Context::DisposeScene(scene); + } + virtual void OnUpdate(TimeEvent &e) override {} + virtual void OnRender() override { + // Draws all scenes + Popcorn::Context::RenderScenes(scene); + } + virtual bool OnEvent(Event &e) override { return false; } + +private: + BlenderScene scene; + Camera *camera; + + GameObject *rotorA; + + Paint::PaintPassBuilder paintPassBuilder; +}; + +int main(int argc, char **argv) { + Popcorn::Context::BeginContext(); + + auto gameLayer = new GameLayer(); + + Popcorn::Context::AddLayer(gameLayer); + Popcorn::Context::StartGame(); + + Popcorn::Context::EndContext(); + + return 0; +} diff --git a/Sandbox/02-Street-Scene/paintpasses/myPaintPass_01.h b/Sandbox/02-Street-Scene/paintpasses/myPaintPass_01.h new file mode 100644 index 00000000..e69de29b diff --git a/Sandbox/02-Street-Scene/paintpasses/myPaintPass_02.h b/Sandbox/02-Street-Scene/paintpasses/myPaintPass_02.h new file mode 100644 index 00000000..e69de29b diff --git a/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h b/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h new file mode 100644 index 00000000..7cf615be --- /dev/null +++ b/Sandbox/02-Street-Scene/paintpasses/paintPassBuilder.h @@ -0,0 +1,37 @@ +#pragma once + +namespace Paint { +class PaintPassBuilder { +public: + PaintPassBuilder() = default; + + void InitPasses() { + // + // TODO: Create actual memory for paintpasses (PaintPassVks) + // + // m_shadow->Init(); + // m_gbuffer->Init(); + // m_bloomExtract->Init(); + // m_lighting->Init(); + // m_transclucency->Init(); + // m_bloomBlur->Init(); + // m_postFx->Init(); + // m_composite->Init(); + // m_myPaintPass_01->Init(); + // m_myPaintPass_02->Init(); + } + + void Build() {} + + // ShadowPass m_shadow; + // GBufferPass m_gbuffer; + // LightingPass m_lighting; + // TransclucencyPass m_transclucency; + // BloomExtractPass m_bloomExtract; + // BloomBlurPass m_bloomBlur; + // PostFxPass m_postFx; + // CompositePass m_composite; + // CustomPass m_myPaintPass_01; + // CustomPass m_myPaintPass_02; +}; +} // namespace Paint diff --git a/tasks/daily.txt b/tasks/daily.txt index 7e327b11..fb299323 100644 --- a/tasks/daily.txt +++ b/tasks/daily.txt @@ -8,3 +8,4 @@ --- WEEK ------ TASK ---------------------------------------------- TIME --------- :: Sep 01 +