From aa1f037cb5b2e4ec2e922621fec816b08d405b13 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Fri, 4 Apr 2025 14:44:53 +0200 Subject: [PATCH] Initial environment loading (not working) --- res/shaders/EnvironmentMapping.slang | 95 +++++++++++ res/shaders/Skybox.slang | 112 ++++++------- src/Editor/Asset/AssetImporter.cpp | 11 +- src/Editor/Asset/AssetImporter.h | 5 +- src/Editor/Asset/CMakeLists.txt | 2 + src/Editor/Asset/EnvironmentLoader.cpp | 147 ++++++++++++++++++ src/Editor/Asset/EnvironmentLoader.h | 32 ++++ src/Editor/main.cpp | 4 + src/Engine/Asset/AssetRegistry.cpp | 58 ++++--- src/Engine/Asset/AssetRegistry.h | 5 + src/Engine/Asset/CMakeLists.txt | 2 + src/Engine/Asset/EnvironmentMapAsset.cpp | 13 ++ src/Engine/Asset/EnvironmentMapAsset.h | 19 +++ src/Engine/Asset/LevelAsset.h | 2 +- src/Engine/Asset/MaterialAsset.cpp | 2 +- src/Engine/Graphics/Descriptor.h | 4 +- src/Engine/Graphics/Graphics.h | 4 +- src/Engine/Graphics/RayTracing.cpp | 1 - src/Engine/Graphics/RayTracing.h | 1 + src/Engine/Graphics/RenderPass/BasePass.cpp | 4 +- .../Graphics/RenderPass/CachedDepthPass.cpp | 3 +- .../Graphics/RenderPass/DepthCullingPass.cpp | 2 +- .../Graphics/RenderPass/LightCullingPass.cpp | 5 +- .../Graphics/RenderPass/RayTracingPass.cpp | 4 +- .../Graphics/RenderPass/ToneMappingPass.cpp | 2 +- src/Engine/Graphics/RenderPass/UIPass.cpp | 2 +- src/Engine/Graphics/RenderTarget.cpp | 6 + src/Engine/Graphics/RenderTarget.h | 14 +- src/Engine/Graphics/Vulkan/Descriptor.cpp | 58 +------ src/Engine/Graphics/Vulkan/Descriptor.h | 4 +- src/Engine/Graphics/Vulkan/Framebuffer.cpp | 10 +- src/Engine/Graphics/Vulkan/Graphics.cpp | 7 +- src/Engine/Graphics/Vulkan/Graphics.h | 3 +- src/Engine/Graphics/Vulkan/RenderPass.cpp | 46 +++--- src/Engine/Graphics/Vulkan/RenderPass.h | 3 +- src/Engine/Graphics/Vulkan/Texture.cpp | 28 ++-- src/Engine/Graphics/Vulkan/Texture.h | 18 ++- src/Engine/Graphics/Window.cpp | 3 +- src/Engine/Graphics/Window.h | 6 + src/Engine/ThreadPool.cpp | 3 + tests/Engine/MinimalEngine.cpp | 11 ++ 41 files changed, 553 insertions(+), 208 deletions(-) create mode 100644 res/shaders/EnvironmentMapping.slang create mode 100644 src/Editor/Asset/EnvironmentLoader.cpp create mode 100644 src/Editor/Asset/EnvironmentLoader.h create mode 100644 src/Engine/Asset/EnvironmentMapAsset.cpp create mode 100644 src/Engine/Asset/EnvironmentMapAsset.h create mode 100644 tests/Engine/MinimalEngine.cpp diff --git a/res/shaders/EnvironmentMapping.slang b/res/shaders/EnvironmentMapping.slang new file mode 100644 index 0000000..ba950b8 --- /dev/null +++ b/res/shaders/EnvironmentMapping.slang @@ -0,0 +1,95 @@ +struct VertexOutput +{ + float4 svPos : SV_Position; + float3 localPos : LOCALPOS; +}; +const static float3 vertices[] = { + // Back + float3(-1, -1, 1), + float3(-1, 1, 1), + float3( 1, -1, 1), + + float3( 1, -1, 1), + float3(-1, 1, 1), + float3( 1, 1, 1), + + // Front + float3( 1, -1, -1), + float3( 1, 1, -1), + float3(-1, -1, -1), + + float3(-1, -1, -1), + float3( 1, 1, -1), + float3(-1, 1, -1), + + // Top + float3(-1, -1, -1), + float3(-1, -1, 1), + float3( 1, -1, -1), + + float3( 1, -1, -1), + float3(-1, -1, 1), + float3( 1, -1, 1), + + // Bottom + float3(-1, 1, 1), + float3(-1, 1, -1), + float3( 1, 1, 1), + + float3( 1, 1, 1), + float3(-1, 1, -1), + float3( 1, 1, -1), + + // Left + float3(-1, -1, -1), + float3(-1, 1, -1), + float3(-1, -1, 1), + + float3(-1, -1, 1), + float3(-1, 1, -1), + float3(-1, 1, 1), + + // Right + float3( 1, -1, 1), + float3( 1, 1, 1), + float3( 1, -1, -1), + + float3( 1, -1, -1), + float3( 1, 1, 1), + float3( 1, 1, -1), +}; + +struct ViewParams +{ + float4x4 view[6]; + float4x4 projection; + Texture2D equirectangularMap; + SamplerState sampler; +}; +ParameterBlock pViewParams; + +[shader("vertex")] +VertexOutput vertMain(uint vertexIndex : SV_VertexID, uint viewIndex : SV_ViewID) +{ + VertexOutput output; + output.localPos = vertices[vertexIndex + 6 * viewIndex]; + output.svPos = mul(pViewParams.projection, mul(pViewParams.view[viewIndex], float4(vertices[vertexIndex], 1))); + return output; +} + +const static float2 invAtan = float2(0.1591, 0.3183); +float2 sampleSphericalMap(float3 v) +{ + float2 uv = float2(atan(v.z / v.x), asin(v.y)); + uv *= invAtan; + uv += 0.5; + return uv; +} + +[shader("fragment")] +float4 fragMain(float3 localPos : LOCALPOS) : SV_Target +{ + float2 uv = sampleSphericalMap(normalize(localPos)); + float3 color = pViewParams.equirectangularMap.Sample(pViewParams.sampler, uv).rgb; + return float4(color, 1); +} \ No newline at end of file diff --git a/res/shaders/Skybox.slang b/res/shaders/Skybox.slang index f0e2aea..ff07380 100644 --- a/res/shaders/Skybox.slang +++ b/res/shaders/Skybox.slang @@ -12,66 +12,66 @@ struct SkyboxData }; ParameterBlock pSkyboxData; +const static float3 vertices[] = { + // Back + float3(-512, -512, 512), + float3(-512, 512, 512), + float3( 512, -512, 512), + + float3( 512, -512, 512), + float3(-512, 512, 512), + float3( 512, 512, 512), + + // Front + float3( 512, -512, -512), + float3( 512, 512, -512), + float3(-512, -512, -512), + + float3(-512, -512, -512), + float3( 512, 512, -512), + float3(-512, 512, -512), + + // Top + float3(-512, -512, -512), + float3(-512, -512, 512), + float3( 512, -512, -512), + + float3( 512, -512, -512), + float3(-512, -512, 512), + float3( 512, -512, 512), + + // Bottom + float3(-512, 512, 512), + float3(-512, 512, -512), + float3( 512, 512, 512), + + float3( 512, 512, 512), + float3(-512, 512, -512), + float3( 512, 512, -512), + + // Left + float3(-512, -512, -512), + float3(-512, 512, -512), + float3(-512, -512, 512), + + float3(-512, -512, 512), + float3(-512, 512, -512), + float3(-512, 512, 512), + + // Right + float3( 512, -512, 512), + float3( 512, 512, 512), + float3( 512, -512, -512), + + float3( 512, -512, -512), + float3( 512, 512, 512), + float3( 512, 512, -512), +}; + [shader("vertex")] VertexShaderOutput vertexMain( uint vertexIndex : SV_VertexId) { - const float3 vertices[] = { - // Back - float3(-512, -512, 512), - float3(-512, 512, 512), - float3( 512, -512, 512), - - float3( 512, -512, 512), - float3(-512, 512, 512), - float3( 512, 512, 512), - - // Front - float3( 512, -512, -512), - float3( 512, 512, -512), - float3(-512, -512, -512), - - float3(-512, -512, -512), - float3( 512, 512, -512), - float3(-512, 512, -512), - - // Top - float3(-512, -512, -512), - float3(-512, -512, 512), - float3( 512, -512, -512), - - float3( 512, -512, -512), - float3(-512, -512, 512), - float3( 512, -512, 512), - - // Bottom - float3(-512, 512, 512), - float3(-512, 512, -512), - float3( 512, 512, 512), - - float3( 512, 512, 512), - float3(-512, 512, -512), - float3( 512, 512, -512), - - // Left - float3(-512, -512, -512), - float3(-512, 512, -512), - float3(-512, -512, 512), - - float3(-512, -512, 512), - float3(-512, 512, -512), - float3(-512, 512, 512), - - // Right - float3( 512, -512, 512), - float3( 512, 512, 512), - float3( 512, -512, -512), - - float3( 512, -512, -512), - float3( 512, 512, 512), - float3( 512, 512, -512), - }; - VertexShaderOutput output; float3x3 cameraRotation = float3x3(pViewParams.viewMatrix); float4 worldPos = float4(mul(cameraRotation, vertices[vertexIndex]), 1.0f); diff --git a/src/Editor/Asset/AssetImporter.cpp b/src/Editor/Asset/AssetImporter.cpp index d7de0e9..8400d2a 100644 --- a/src/Editor/Asset/AssetImporter.cpp +++ b/src/Editor/Asset/AssetImporter.cpp @@ -4,7 +4,7 @@ #include "MaterialLoader.h" #include "MeshLoader.h" #include "TextureLoader.h" - +#include "EnvironmentLoader.h" using namespace Seele; @@ -40,12 +40,21 @@ void AssetImporter::importMaterial(MaterialImportArgs args) { get().materialLoader->importAsset(args); } +void Seele::AssetImporter::importEnvironmentMap(EnvironmentImportArgs args) { + if (get().registry->getOrCreateFolder(args.importPath)->materials.contains(args.filePath.stem().string())) { + // skip importing duplicates + return; + } + get().environmentLoader->importAsset(args); +} + void AssetImporter::init(Gfx::PGraphics graphics) { get().registry = AssetRegistry::getInstance(); get().meshLoader = new MeshLoader(graphics); get().textureLoader = new TextureLoader(graphics); get().materialLoader = new MaterialLoader(graphics); get().fontLoader = new FontLoader(graphics); + get().environmentLoader = new EnvironmentLoader(graphics); } AssetImporter& AssetImporter::get() { diff --git a/src/Editor/Asset/AssetImporter.h b/src/Editor/Asset/AssetImporter.h index 6f3fb22..2202386 100644 --- a/src/Editor/Asset/AssetImporter.h +++ b/src/Editor/Asset/AssetImporter.h @@ -1,6 +1,6 @@ #pragma once -#include "Asset/AssetRegistry.h" #include "MinimalEngine.h" +#include "Asset/AssetRegistry.h" namespace Seele { @@ -8,12 +8,14 @@ DECLARE_REF(TextureLoader) DECLARE_REF(FontLoader) DECLARE_REF(MeshLoader) DECLARE_REF(MaterialLoader) +DECLARE_REF(EnvironmentLoader) class AssetImporter { public: static void importMesh(struct MeshImportArgs args); static void importTexture(struct TextureImportArgs args); static void importFont(struct FontImportArgs args); static void importMaterial(struct MaterialImportArgs args); + static void importEnvironmentMap(struct EnvironmentImportArgs args); static void init(Gfx::PGraphics graphics); private: @@ -22,6 +24,7 @@ class AssetImporter { UPFontLoader fontLoader; UPMeshLoader meshLoader; UPMaterialLoader materialLoader; + UPEnvironmentLoader environmentLoader; AssetRegistry* registry; }; } // namespace Seele \ No newline at end of file diff --git a/src/Editor/Asset/CMakeLists.txt b/src/Editor/Asset/CMakeLists.txt index 240cb8f..58d56c5 100644 --- a/src/Editor/Asset/CMakeLists.txt +++ b/src/Editor/Asset/CMakeLists.txt @@ -2,6 +2,8 @@ target_sources(Editor PRIVATE AssetImporter.h AssetImporter.cpp + EnvironmentLoader.h + EnvironmentLoader.cpp FontLoader.h FontLoader.cpp MaterialLoader.h diff --git a/src/Editor/Asset/EnvironmentLoader.cpp b/src/Editor/Asset/EnvironmentLoader.cpp new file mode 100644 index 0000000..1b90cfe --- /dev/null +++ b/src/Editor/Asset/EnvironmentLoader.cpp @@ -0,0 +1,147 @@ +#include "EnvironmentLoader.h" +#include "Asset/AssetRegistry.h" +#include "Asset/EnvironmentMapAsset.h" +#include "Graphics/Descriptor.h" +#include "stb_image.h" + +using namespace Seele; + +EnvironmentLoader::EnvironmentLoader(Gfx::PGraphics graphics) : graphics(graphics) { + cubeRenderViewport = graphics->createViewport(nullptr, ViewportCreateInfo{ + .dimensions = + { + .size = {1024, 1024}, + .offset = {0, 0}, + }, + }); + + cubeRenderLayout = graphics->createDescriptorLayout("pViewParams"); + cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .name = "view", + .uniformLength = sizeof(Matrix4) * 6, + }); + cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .name = "projection", + .uniformLength = sizeof(Matrix4), + }); + cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .name = "equirectangularMap", + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + }); + cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .name = "sampler", + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER, + }); + cubeRenderLayout->create(); + + cubePipelineLayout = graphics->createPipelineLayout("CubeRenderLayout"); + cubePipelineLayout->addDescriptorLayout(cubeRenderLayout); + + graphics->beginShaderCompilation(ShaderCompilationInfo{ + .name = "CubeRenderPipeline", + .modules = {"EnvironmentMapping"}, + .entryPoints = + { + {"vertMain", "EnvironmentMapping"}, + {"fragMain", "EnvironmentMapping"}, + }, + .rootSignature = cubePipelineLayout, + }); + cubePipelineLayout->create(); + + cubeRenderVertex = graphics->createVertexShader({0}); + cubeRenderFrag = graphics->createFragmentShader({1}); + + cubeSampler = graphics->createSampler({ + .magFilter = Gfx::SE_FILTER_LINEAR, + .minFilter = Gfx::SE_FILTER_LINEAR, + .addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + }); +} + +EnvironmentLoader::~EnvironmentLoader() {} + +void EnvironmentLoader::importAsset(EnvironmentImportArgs args) { + std::filesystem::path assetPath = args.filePath.filename(); + assetPath.replace_extension("asset"); + OEnvironmentMapAsset asset = new EnvironmentMapAsset(args.importPath, assetPath.stem().string()); + asset->setStatus(Asset::Status::Loading); + // the registry takes ownership, but we need to edit the reference + PEnvironmentMapAsset ref = asset; + AssetRegistry::get().registerEnvironmentMap(std::move(asset)); + import(args, ref); +} + +void EnvironmentLoader::import(EnvironmentImportArgs args, PEnvironmentMapAsset asset) { + stbi_set_flip_vertically_on_load(true); + int width, height, nrComponents; + float* data = stbi_loadf(args.filePath.string().c_str(), &width, &height, &nrComponents, 4); + stbi_set_flip_vertically_on_load(false); + assert(data); + Gfx::OTexture2D hdrTexture = graphics->createTexture2D(TextureCreateInfo{ + .sourceData = + { + .size = width * height * 4 * sizeof(float), + .data = (uint8*)data, + }, + .format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT, + .width = (uint32)width, + .height = (uint32)height, + .name = "HDRRaw", + }); + Matrix4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f); + Matrix4 captureViews[] = { + glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 0.0f, 1.0f), Vector(0.0f, 1.0f, 0.0f)), + glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 0.0f, -1.0f), Vector(0.0f, 1.0f, 0.0f)), + glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, -1.0f, 0.0f), Vector(1.0f, 0.0f, 0.0f)), + glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f), Vector(1.0f, 0.0f, 0.0f)), + glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(-1.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f)), + glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(1.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f)), + }; + Gfx::PDescriptorSet set = cubeRenderLayout->allocateDescriptorSet(); + set->updateConstants("view", 0, captureViews); + set->updateConstants("projection", 0, &captureProjection); + set->updateTexture("equirectangularMap", 0, Gfx::PTexture2D(hdrTexture)); + set->updateSampler("sampler", 0, cubeSampler); + set->writeChanges(); + Gfx::OTextureCube cubeMap = graphics->createTextureCube(TextureCreateInfo{ + .format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT, + .width = 1024, + .height = 1024, + .usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + }); + cubeRenderPass = graphics->createRenderPass( + Gfx::RenderTargetLayout{ + .colorAttachments = {Gfx::RenderTargetAttachment(cubeMap, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, + Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE)}, + }, + {}, + URect{ + .size = {1024, 1024}, + .offset = {0, 0}, + }, + "EnvironmentRenderPass", {0b111111}, {0b111111}); + cubeRenderPipeline = graphics->createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo{ + .vertexShader = cubeRenderVertex, + .fragmentShader = cubeRenderFrag, + .renderPass = cubeRenderPass, + .pipelineLayout = cubePipelineLayout, + .colorBlend = + { + .attachmentCount = 1, + }, + }); + graphics->beginRenderPass(cubeRenderPass); + Gfx::ORenderCommand renderCommand = graphics->createRenderCommand("CubeMapRender"); + renderCommand->bindPipeline(cubeRenderPipeline); + renderCommand->bindDescriptor({set}); + renderCommand->setViewport(cubeRenderViewport); + renderCommand->draw(6, 1, 0, 0); + graphics->executeCommands(std::move(renderCommand)); + graphics->endRenderPass(); + graphics->waitDeviceIdle(); + asset->diffuseMap = std::move(cubeMap); +} diff --git a/src/Editor/Asset/EnvironmentLoader.h b/src/Editor/Asset/EnvironmentLoader.h new file mode 100644 index 0000000..74792d9 --- /dev/null +++ b/src/Editor/Asset/EnvironmentLoader.h @@ -0,0 +1,32 @@ +#pragma once +#include "MinimalEngine.h" +#include "Graphics/Graphics.h" +#include "Graphics/Shader.h" +#include + +namespace Seele +{ +DECLARE_REF(EnvironmentMapAsset) +struct EnvironmentImportArgs { + std::filesystem::path filePath; + std::string importPath; +}; +class EnvironmentLoader { + public: + EnvironmentLoader(Gfx::PGraphics graphic); + ~EnvironmentLoader(); + void importAsset(EnvironmentImportArgs args); + + private: + void import(EnvironmentImportArgs args, PEnvironmentMapAsset asset); + Gfx::PGraphics graphics; + Gfx::OVertexShader cubeRenderVertex; + Gfx::OFragmentShader cubeRenderFrag; + Gfx::ODescriptorLayout cubeRenderLayout; + Gfx::OPipelineLayout cubePipelineLayout; + Gfx::PGraphicsPipeline cubeRenderPipeline; + Gfx::ORenderPass cubeRenderPass; + Gfx::OViewport cubeRenderViewport; + Gfx::OSampler cubeSampler; +}; +} \ No newline at end of file diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index bc5775d..90e3841 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -4,6 +4,7 @@ #include "Asset/MaterialLoader.h" #include "Asset/MeshLoader.h" #include "Asset/TextureLoader.h" +#include "Asset/EnvironmentLoader.h" #include "Graphics/Initializer.h" #ifdef __APPLE__ #include "Graphics/Metal/Graphics.h" @@ -99,6 +100,9 @@ int main() { .filePath = sourcePath / "import/textures/skybox.jpg", .type = TextureImportType::TEXTURE_CUBEMAP, }); + AssetImporter::importEnvironmentMap(EnvironmentImportArgs{ + .filePath = sourcePath / "import/models/main1_sponza/textures/kloppenheim_05_4k.hdr", + }); // AssetImporter::importMesh(MeshImportArgs{ // .filePath = sourcePath / "import/models/ship.fbx", // .importPath = "ship", diff --git a/src/Engine/Asset/AssetRegistry.cpp b/src/Engine/Asset/AssetRegistry.cpp index b07d4a0..7535d13 100644 --- a/src/Engine/Asset/AssetRegistry.cpp +++ b/src/Engine/Asset/AssetRegistry.cpp @@ -1,18 +1,14 @@ #include "AssetRegistry.h" +#include "Asset/FontAsset.h" +#include "Asset/MaterialAsset.h" +#include "Asset/MaterialInstanceAsset.h" +#include "Asset/MeshAsset.h" +#include "Asset/EnvironmentMapAsset.h" +#include "Asset/SVGAsset.h" +#include "Asset/TextureAsset.h" #include "FontAsset.h" #include "Graphics/Graphics.h" #include "Graphics/Mesh.h" -#include "MaterialAsset.h" -#include "MaterialInstanceAsset.h" -#include "MeshAsset.h" -#include "SVGAsset.h" -#include "TextureAsset.h" -#include "Asset/TextureAsset.h" -#include "Asset/FontAsset.h" -#include "Asset/SVGAsset.h" -#include "Asset/MeshAsset.h" -#include "Asset/MaterialAsset.h" -#include "Asset/MaterialInstanceAsset.h" #include "Window/WindowManager.h" #include #include @@ -62,6 +58,15 @@ PSVGAsset AssetRegistry::findSVG(std::string_view folderPath, std::string_view f return folder->svgs.at(std::string(filePath)); } +PEnvironmentMapAsset AssetRegistry::findEnvironmentMap(std::string_view folderPath, std::string_view filePath) { + std::unique_lock l(get().assetLock); + AssetFolder* folder = get().assetRoot; + if (!folderPath.empty()) { + folder = get().getOrCreateFolder(folderPath); + } + return folder->envs.at(std::string(filePath)); +} + PMaterialAsset AssetRegistry::findMaterial(std::string_view folderPath, std::string_view filePath) { std::unique_lock l(get().assetLock); AssetFolder* folder = get().assetRoot; @@ -100,6 +105,11 @@ void AssetRegistry::registerSVG(OSVGAsset svg) { get().registerSVGInternal(std::move(svg)); } +void AssetRegistry::registerEnvironmentMap(OEnvironmentMapAsset env) { + std::unique_lock l(get().assetLock); + get().registerEnvironmentMapInternal(std::move(env)); +} + void AssetRegistry::registerMaterial(OMaterialAsset material) { std::unique_lock l(get().assetLock); get().registerMaterialInternal(std::move(material)); @@ -152,6 +162,9 @@ void AssetRegistry::loadAsset(ArchiveBuffer& buffer) { case SVGAsset::IDENTIFIER: asset = PSVGAsset(folder->svgs.at(name)); break; + case EnvironmentMapAsset::IDENTIFIER: + asset = PEnvironmentMapAsset(folder->envs.at(name)); + break; default: throw new std::logic_error("Unknown Identifier"); } @@ -182,13 +195,9 @@ AssetRegistry::AssetRegistry() : assetRoot(nullptr) {} AssetRegistry* AssetRegistry::getInstance() { return _instance; } -void AssetRegistry::loadRegistry() { - get().loadRegistryInternal(); -} +void AssetRegistry::loadRegistry() { get().loadRegistryInternal(); } -void AssetRegistry::saveRegistry() { - get().saveRegistryInternal(); -} +void AssetRegistry::saveRegistry() { get().saveRegistryInternal(); } AssetRegistry::AssetFolder* AssetRegistry::getOrCreateFolder(std::string_view fullPath) { AssetFolder* result = assetRoot; @@ -219,7 +228,7 @@ void AssetRegistry::initialize(const std::filesystem::path& _rootFolder, Gfx::PG } void AssetRegistry::loadRegistryInternal() { - Array> peeked; + Array> peeked; { std::unique_lock l(get().assetLock); peeked = peekFolder(assetRoot); @@ -301,13 +310,16 @@ Pair AssetRegistry::peekAsset(ArchiveBuffer& buffer) { folder->svgs[name] = new SVGAsset(folderPath, name); asset = PSVGAsset(folder->svgs[name]); break; + case EnvironmentMapAsset::IDENTIFIER: + folder->envs[name] = new EnvironmentMapAsset(folderPath, name); + asset = PEnvironmentMapAsset(folder->envs[name]); + break; default: throw new std::logic_error("Unknown Identifier"); } return {asset, std::move(buffer)}; } - void AssetRegistry::saveRegistryInternal() { saveFolder("", assetRoot); } void AssetRegistry::saveFolder(const std::filesystem::path& folderPath, AssetFolder* folder) { @@ -330,6 +342,9 @@ void AssetRegistry::saveFolder(const std::filesystem::path& folderPath, AssetFol for (const auto& [name, svg] : folder->svgs) { saveAsset(PSVGAsset(svg), SVGAsset::IDENTIFIER, folderPath, name); } + for (const auto& [name, env] : folder->envs) { + saveAsset(PEnvironmentMapAsset(env), EnvironmentMapAsset::IDENTIFIER, folderPath, name); + } for (auto& [name, child] : folder->children) { saveFolder(folderPath / name, child); } @@ -357,6 +372,11 @@ void AssetRegistry::registerSVGInternal(OSVGAsset svg) { folder->svgs[svg->getName()] = std::move(svg); } +void AssetRegistry::registerEnvironmentMapInternal(OEnvironmentMapAsset env) { + AssetFolder* folder = getOrCreateFolder(env->getFolderPath()); + folder->envs[env->getName()] = std::move(env); +} + void AssetRegistry::registerMaterialInternal(OMaterialAsset material) { AssetFolder* folder = getOrCreateFolder(material->getFolderPath()); folder->materials[material->getName()] = std::move(material); diff --git a/src/Engine/Asset/AssetRegistry.h b/src/Engine/Asset/AssetRegistry.h index e9a1424..00ad6ba 100644 --- a/src/Engine/Asset/AssetRegistry.h +++ b/src/Engine/Asset/AssetRegistry.h @@ -12,6 +12,7 @@ DECLARE_REF(TextureAsset) DECLARE_REF(FontAsset) DECLARE_REF(SVGAsset) DECLARE_REF(MeshAsset) +DECLARE_REF(EnvironmentMapAsset) DECLARE_REF(MaterialAsset) DECLARE_REF(MaterialInstanceAsset) DECLARE_NAME_REF(Gfx, Graphics) @@ -26,6 +27,7 @@ class AssetRegistry { static PTextureAsset findTexture(std::string_view folderPath, std::string_view filePath); static PFontAsset findFont(std::string_view folderPath, std::string_view name); static PSVGAsset findSVG(std::string_view folderPath, std::string_view name); + static PEnvironmentMapAsset findEnvironmentMap(std::string_view folder, std::string_view name); static PMaterialAsset findMaterial(std::string_view folderPath, std::string_view filePath); static PMaterialInstanceAsset findMaterialInstance(std::string_view folderPath, std::string_view filePath); @@ -33,6 +35,7 @@ class AssetRegistry { static void registerTexture(OTextureAsset texture); static void registerFont(OFontAsset font); static void registerSVG(OSVGAsset svg); + static void registerEnvironmentMap(OEnvironmentMapAsset env); static void registerMaterial(OMaterialAsset material); static void registerMaterialInstance(OMaterialInstanceAsset instance); @@ -52,6 +55,7 @@ class AssetRegistry { Map textures; Map fonts; Map svgs; + Map envs; Map meshes; Map materials; Map instances; @@ -75,6 +79,7 @@ class AssetRegistry { void registerTextureInternal(OTextureAsset texture); void registerFontInternal(OFontAsset font); void registerSVGInternal(OSVGAsset svg); + void registerEnvironmentMapInternal(OEnvironmentMapAsset env); void registerMaterialInternal(OMaterialAsset material); void registerMaterialInstanceInternal(OMaterialInstanceAsset instance); diff --git a/src/Engine/Asset/CMakeLists.txt b/src/Engine/Asset/CMakeLists.txt index 24ecfd4..c57326e 100644 --- a/src/Engine/Asset/CMakeLists.txt +++ b/src/Engine/Asset/CMakeLists.txt @@ -4,6 +4,8 @@ target_sources(Engine Asset.cpp AssetRegistry.h AssetRegistry.cpp + EnvironmentMapAsset.h + EnvironmentMapAsset.cpp FontAsset.h FontAsset.cpp LevelAsset.h diff --git a/src/Engine/Asset/EnvironmentMapAsset.cpp b/src/Engine/Asset/EnvironmentMapAsset.cpp new file mode 100644 index 0000000..58cdd32 --- /dev/null +++ b/src/Engine/Asset/EnvironmentMapAsset.cpp @@ -0,0 +1,13 @@ +#include "EnvironmentMapAsset.h" + +using namespace Seele; + +EnvironmentMapAsset::EnvironmentMapAsset() {} + +EnvironmentMapAsset::EnvironmentMapAsset(std::string_view folderPath, std::string_view name) : Asset(folderPath, name) {} + +EnvironmentMapAsset::~EnvironmentMapAsset() {} + +void EnvironmentMapAsset::save(ArchiveBuffer& buffer) const {} + +void EnvironmentMapAsset::load(ArchiveBuffer& buffer) {} diff --git a/src/Engine/Asset/EnvironmentMapAsset.h b/src/Engine/Asset/EnvironmentMapAsset.h new file mode 100644 index 0000000..db847c7 --- /dev/null +++ b/src/Engine/Asset/EnvironmentMapAsset.h @@ -0,0 +1,19 @@ +#pragma once +#include "Asset.h" +#include "Graphics/Texture.h" + +namespace Seele { +class EnvironmentMapAsset : public Asset { + public: + static constexpr uint64 IDENTIFIER = 0x80; + EnvironmentMapAsset(); + EnvironmentMapAsset(std::string_view folderPath, std::string_view name); + virtual ~EnvironmentMapAsset(); + virtual void save(ArchiveBuffer& buffer) const override; + virtual void load(ArchiveBuffer& buffer) override; + private: + Gfx::OTextureCube diffuseMap; + Gfx::OTextureCube specularMap; + friend class EnvironmentLoader; +}; +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Asset/LevelAsset.h b/src/Engine/Asset/LevelAsset.h index 1d34ec5..ece286c 100644 --- a/src/Engine/Asset/LevelAsset.h +++ b/src/Engine/Asset/LevelAsset.h @@ -5,7 +5,7 @@ namespace Seele { class LevelAsset : public Asset { public: - static constexpr uint64 IDENTIFIER = 0x20; + static constexpr uint64 IDENTIFIER = 0x40; LevelAsset(); LevelAsset(std::string_view folderPath, std::string_view name); virtual ~LevelAsset(); diff --git a/src/Engine/Asset/MaterialAsset.cpp b/src/Engine/Asset/MaterialAsset.cpp index 9a058a7..b90c64f 100644 --- a/src/Engine/Asset/MaterialAsset.cpp +++ b/src/Engine/Asset/MaterialAsset.cpp @@ -30,6 +30,6 @@ PMaterialInstanceAsset MaterialAsset::instantiate(const InstantiationParameter& asset->setBase(this); PMaterialInstanceAsset ref = asset; AssetRegistry::registerMaterialInstance(std::move(asset)); - AssetRegistry::saveAsset(ref, MaterialInstanceAsset::IDENTIFIER, ref->getFolderPath(), ref->getName()); + AssetRegistry::saveAsset(PAsset(ref), MaterialInstanceAsset::IDENTIFIER, ref->getFolderPath(), ref->getName()); return ref; } diff --git a/src/Engine/Graphics/Descriptor.h b/src/Engine/Graphics/Descriptor.h index 818d743..b454d9b 100644 --- a/src/Engine/Graphics/Descriptor.h +++ b/src/Engine/Graphics/Descriptor.h @@ -68,9 +68,7 @@ class DescriptorSet { virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer indexBuffer) = 0; virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) = 0; virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) = 0; - virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture2D texture) = 0; - virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture3D texture) = 0; - virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureCube texture) = 0; + virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture texture) = 0; virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) = 0; bool operator<(PDescriptorSet other); diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index a585f45..24a8c83 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -55,8 +55,8 @@ class Graphics { virtual OWindow createWindow(const WindowCreateInfo& createInfo) = 0; virtual OViewport createViewport(PWindow owner, const ViewportCreateInfo& createInfo) = 0; - virtual ORenderPass createRenderPass(RenderTargetLayout layout, Array dependencies, PViewport renderArea, - std::string name = "") = 0; + virtual ORenderPass createRenderPass(RenderTargetLayout layout, Array dependencies, URect renderArea, + std::string name = "", Array viewMasks = {}, Array correlationMasks = {}) = 0; virtual void beginRenderPass(PRenderPass renderPass) = 0; virtual void endRenderPass() = 0; virtual void waitDeviceIdle() = 0; diff --git a/src/Engine/Graphics/RayTracing.cpp b/src/Engine/Graphics/RayTracing.cpp index 454277e..79998c9 100644 --- a/src/Engine/Graphics/RayTracing.cpp +++ b/src/Engine/Graphics/RayTracing.cpp @@ -1,5 +1,4 @@ #include "RayTracing.h" -#include "RayTracing.h" using namespace Seele::Gfx; diff --git a/src/Engine/Graphics/RayTracing.h b/src/Engine/Graphics/RayTracing.h index adcc474..ac0d89b 100644 --- a/src/Engine/Graphics/RayTracing.h +++ b/src/Engine/Graphics/RayTracing.h @@ -1,5 +1,6 @@ #pragma once #include "Resources.h" +#include "Graphics/Descriptor.h" namespace Seele { namespace Gfx { diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 39d9458..4a47009 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -407,7 +407,7 @@ void BasePass::publishOutputs() { }); depthAttachment = - Gfx::RenderTargetAttachment(basePassDepth, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + Gfx::RenderTargetAttachment(Gfx::PTexture2D(basePassDepth), Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE); msDepthAttachment = @@ -472,7 +472,7 @@ void BasePass::createRenderPass() { Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, }, }; - renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport, "BasePass"); + renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport->getRenderArea(), "BasePass"); oLightIndexList = resources->requestBuffer("LIGHTCULLING_OLIGHTLIST"); tLightIndexList = resources->requestBuffer("LIGHTCULLING_TLIGHTLIST"); oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID"); diff --git a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp index 91cb737..f6f717c 100644 --- a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp +++ b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp @@ -1,5 +1,6 @@ #include "CachedDepthPass.h" #include "Graphics/Shader.h" +#include "Graphics/Pipeline.h" using namespace Seele; @@ -202,5 +203,5 @@ void CachedDepthPass::createRenderPass() { Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, }, }; - renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport, "CachedDepthPass"); + renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport->getRenderArea(), "CachedDepthPass"); } diff --git a/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp b/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp index 3d72469..d111540 100644 --- a/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp @@ -306,5 +306,5 @@ void DepthCullingPass::createRenderPass() { Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, }, }; - renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport, "DepthCullingPass"); + renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport->getRenderArea(), "DepthCullingPass"); } diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index 1c999e4..4835692 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -3,6 +3,7 @@ #include "Component/Camera.h" #include "Graphics/Command.h" #include "Graphics/Graphics.h" +#include "Graphics/Pipeline.h" #include "Math/Vector.h" #include "RenderGraph.h" #include "Scene/Scene.h" @@ -48,8 +49,8 @@ void LightCullingPass::render() { cullingDescriptorSet->updateBuffer(TLIGHTINDEXCOUNTER_NAME, 0, tLightIndexCounter); cullingDescriptorSet->updateBuffer(OLIGHTINDEXLIST_NAME, 0, oLightIndexList); cullingDescriptorSet->updateBuffer(TLIGHTINDEXLIST_NAME, 0, tLightIndexList); - cullingDescriptorSet->updateTexture(OLIGHTGRID_NAME, 0, oLightGrid); - cullingDescriptorSet->updateTexture(TLIGHTGRID_NAME, 0, tLightGrid); + cullingDescriptorSet->updateTexture(OLIGHTGRID_NAME, 0, Gfx::PTexture2D(oLightGrid)); + cullingDescriptorSet->updateTexture(TLIGHTGRID_NAME, 0, Gfx::PTexture2D(tLightGrid)); cullingDescriptorSet->writeChanges(); Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand"); if (getGlobals().useLightCulling) { diff --git a/src/Engine/Graphics/RenderPass/RayTracingPass.cpp b/src/Engine/Graphics/RenderPass/RayTracingPass.cpp index 67a99aa..01eb342 100644 --- a/src/Engine/Graphics/RenderPass/RayTracingPass.cpp +++ b/src/Engine/Graphics/RenderPass/RayTracingPass.cpp @@ -151,8 +151,8 @@ void RayTracingPass::render() { }); Gfx::PDescriptorSet desc = paramsLayout->allocateDescriptorSet(); desc->updateAccelerationStructure(TLAS_NAME, 0, tlas); - desc->updateTexture(ACCUMULATOR_NAME, 0, radianceAccumulator); - desc->updateTexture(TEXTURE_NAME, 0, texture); + desc->updateTexture(ACCUMULATOR_NAME, 0, Gfx::PTexture2D(radianceAccumulator)); + desc->updateTexture(TEXTURE_NAME, 0, Gfx::PTexture2D(texture)); desc->updateBuffer(INDEXBUFFER_NAME, 0, StaticMeshVertexData::getInstance()->getIndexBuffer()); desc->updateTexture(SKYBOX_NAME, 0, skyBox); desc->updateSampler(SKYSAMPLER_NAME, 0, skyBoxSampler); diff --git a/src/Engine/Graphics/RenderPass/ToneMappingPass.cpp b/src/Engine/Graphics/RenderPass/ToneMappingPass.cpp index 6eb6f34..8b343df 100644 --- a/src/Engine/Graphics/RenderPass/ToneMappingPass.cpp +++ b/src/Engine/Graphics/RenderPass/ToneMappingPass.cpp @@ -216,7 +216,7 @@ void ToneMappingPass::createRenderPass() { .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, }, }; - renderPass = graphics->createRenderPass(targetLayout, dependency, viewport, "ToneMappingPass"); + renderPass = graphics->createRenderPass(targetLayout, dependency, viewport->getRenderArea(), "ToneMappingPass"); pipeline = graphics->createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo{ .vertexShader = vert, .fragmentShader = frag, diff --git a/src/Engine/Graphics/RenderPass/UIPass.cpp b/src/Engine/Graphics/RenderPass/UIPass.cpp index 0a27bbb..0d64159 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.cpp +++ b/src/Engine/Graphics/RenderPass/UIPass.cpp @@ -170,7 +170,7 @@ void UIPass::createRenderPass() { Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, }, }; - renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport, "TextPass"); + renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport->getRenderArea(), "TextPass"); graphics->beginShaderCompilation(ShaderCompilationInfo{ .name = "TextVertex", diff --git a/src/Engine/Graphics/RenderTarget.cpp b/src/Engine/Graphics/RenderTarget.cpp index d2ec3e0..4651da7 100644 --- a/src/Engine/Graphics/RenderTarget.cpp +++ b/src/Engine/Graphics/RenderTarget.cpp @@ -9,6 +9,12 @@ RenderTargetAttachment::RenderTargetAttachment(PTexture2D texture, SeImageLayout : clear(), componentFlags(0), texture(texture), initialLayout(initialLayout), finalLayout(finalLayout), loadOp(loadOp), storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp) {} +RenderTargetAttachment::RenderTargetAttachment(PTextureCube texture, SeImageLayout initialLayout, SeImageLayout finalLayout, + SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp, + SeAttachmentStoreOp stencilStoreOp) + : clear(), componentFlags(0), texture(texture), initialLayout(initialLayout), finalLayout(finalLayout), loadOp(loadOp), + storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp) {} + RenderTargetAttachment::RenderTargetAttachment(PViewport viewport, SeImageLayout initialLayout, SeImageLayout finalLayout, SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp, SeAttachmentStoreOp stencilStoreOp) diff --git a/src/Engine/Graphics/RenderTarget.h b/src/Engine/Graphics/RenderTarget.h index 6aed4b4..2224912 100644 --- a/src/Engine/Graphics/RenderTarget.h +++ b/src/Engine/Graphics/RenderTarget.h @@ -14,16 +14,21 @@ class RenderTargetAttachment { SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE); - + RenderTargetAttachment(PTextureCube texture, SeImageLayout initialLayout, SeImageLayout finalLayout, + SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD, + SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, + SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, + SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE); RenderTargetAttachment(PViewport viewport, SeImageLayout initialLayout, SeImageLayout finalLayout, SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD, SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE); ~RenderTargetAttachment(); - PTexture2D getTexture() const { + void setTexture(PTexture _texture) { texture = _texture; } + PTexture getTexture() const { if (viewport != nullptr) { - return viewport->getOwner()->getBackBuffer(); + return PTexture(viewport->getOwner()->getBackBuffer()); } return texture; } @@ -68,7 +73,7 @@ class RenderTargetAttachment { SeColorComponentFlags componentFlags = 0; protected: - PTexture2D texture = nullptr; + PTexture texture = nullptr; PViewport viewport = nullptr; SeImageLayout initialLayout = SE_IMAGE_LAYOUT_UNDEFINED; SeImageLayout finalLayout = SE_IMAGE_LAYOUT_UNDEFINED; @@ -103,6 +108,7 @@ class RenderPass { RenderPass(RenderPass&&) = default; RenderPass& operator=(RenderPass&&) = default; const RenderTargetLayout& getLayout() const { return layout; } + void updateColorAttachment(uint32 index, Gfx::PTextureCube attachment) { layout.colorAttachments[index].setTexture(attachment); } protected: RenderTargetLayout layout; diff --git a/src/Engine/Graphics/Vulkan/Descriptor.cpp b/src/Engine/Graphics/Vulkan/Descriptor.cpp index 975c596..0278935 100644 --- a/src/Engine/Graphics/Vulkan/Descriptor.cpp +++ b/src/Engine/Graphics/Vulkan/Descriptor.cpp @@ -312,63 +312,7 @@ void DescriptorSet::updateSampler(const std::string& mappingName, uint32 index, boundResources[binding][index] = vulkanSampler->getHandle(); } -void DescriptorSet::updateTexture(const std::string& mappingName, uint32 index, Gfx::PTexture2D texture) { - TextureBase* vulkanTexture = texture.cast().getHandle(); - const auto& map = owner->getLayout()->mappings[mappingName]; - uint32 binding = map.binding; - if (boundResources[binding][index] == vulkanTexture->getHandle()) { - return; - } - - // It is assumed that the image is in the correct layout - imageInfos.add(VkDescriptorImageInfo{ - .sampler = VK_NULL_HANDLE, - .imageView = vulkanTexture->getView(), - .imageLayout = cast(vulkanTexture->getLayout()), - }); - writeDescriptors.add(VkWriteDescriptorSet{ - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = setHandle, - .dstBinding = binding, - .dstArrayElement = index, - .descriptorCount = 1, - .descriptorType = map.type, - .pImageInfo = &imageInfos.back(), - }); - - boundResources[binding][index] = vulkanTexture->getHandle(); -} - -void DescriptorSet::updateTexture(const std::string& mappingName, uint32 index, Gfx::PTexture3D texture) { - TextureBase* vulkanTexture = texture.cast().getHandle(); - const auto& map = owner->getLayout()->mappings[mappingName]; - uint32 binding = map.binding; - if (boundResources[binding][index] == vulkanTexture->getHandle()) { - return; - } - - // It is assumed that the image is in the correct layout - imageInfos.add(VkDescriptorImageInfo{ - .sampler = VK_NULL_HANDLE, - .imageView = vulkanTexture->getView(), - .imageLayout = cast(vulkanTexture->getLayout()), - }); - writeDescriptors.add(VkWriteDescriptorSet{ - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = setHandle, - .dstBinding = binding, - .dstArrayElement = index, - .descriptorCount = 1, - .descriptorType = map.type, - .pImageInfo = &imageInfos.back(), - }); - - boundResources[binding][index] = vulkanTexture->getHandle(); -} - -void DescriptorSet::updateTexture(const std::string& mappingName, uint32 index, Gfx::PTextureCube texture) { +void DescriptorSet::updateTexture(const std::string& mappingName, uint32 index, Gfx::PTexture texture) { TextureBase* vulkanTexture = texture.cast().getHandle(); const auto& map = owner->getLayout()->mappings[mappingName]; uint32 binding = map.binding; diff --git a/src/Engine/Graphics/Vulkan/Descriptor.h b/src/Engine/Graphics/Vulkan/Descriptor.h index 5c8188c..23cf191 100644 --- a/src/Engine/Graphics/Vulkan/Descriptor.h +++ b/src/Engine/Graphics/Vulkan/Descriptor.h @@ -64,9 +64,7 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource { virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer indexBuffer) override; virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) override; virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) override; - virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture2D texture) override; - virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture3D texture) override; - virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureCube texture) override; + virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture texture) override; virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) override; constexpr VkDescriptorSet getHandle() const { return setHandle; } diff --git a/src/Engine/Graphics/Vulkan/Framebuffer.cpp b/src/Engine/Graphics/Vulkan/Framebuffer.cpp index 7c4f00b..564da50 100644 --- a/src/Engine/Graphics/Vulkan/Framebuffer.cpp +++ b/src/Engine/Graphics/Vulkan/Framebuffer.cpp @@ -17,35 +17,35 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::Render uint32 width = 0; uint32 height = 0; for (auto inputAttachment : layout.inputAttachments) { - PTexture2D vkInputAttachment = inputAttachment.getTexture().cast(); + PTextureBase vkInputAttachment = inputAttachment.getTexture().cast(); attachments.add(vkInputAttachment->getView()); description.inputAttachments[description.numInputAttachments++] = vkInputAttachment->getView(); width = std::max(width, vkInputAttachment->getWidth()); height = std::max(height, vkInputAttachment->getHeight()); } for (auto colorAttachment : layout.colorAttachments) { - PTexture2D vkColorAttachment = colorAttachment.getTexture().cast(); + PTextureBase vkColorAttachment = colorAttachment.getTexture().cast(); attachments.add(vkColorAttachment->getView()); description.colorAttachments[description.numColorAttachments++] = vkColorAttachment->getView(); width = std::max(width, vkColorAttachment->getWidth()); height = std::max(height, vkColorAttachment->getHeight()); } for (auto resolveAttachment : layout.resolveAttachments) { - PTexture2D vkResolveAttachment = resolveAttachment.getTexture().cast(); + PTextureBase vkResolveAttachment = resolveAttachment.getTexture().cast(); attachments.add(vkResolveAttachment->getView()); description.resolveAttachments[description.numResolveAttachments++] = vkResolveAttachment->getView(); width = std::max(width, vkResolveAttachment->getWidth()); height = std::max(height, vkResolveAttachment->getHeight()); } if (layout.depthAttachment.getTexture() != nullptr) { - PTexture2D vkDepthAttachment = layout.depthAttachment.getTexture().cast(); + PTextureBase vkDepthAttachment = layout.depthAttachment.getTexture().cast(); attachments.add(vkDepthAttachment->getView()); description.depthAttachment = vkDepthAttachment->getView(); width = std::max(width, vkDepthAttachment->getWidth()); height = std::max(height, vkDepthAttachment->getHeight()); } if (layout.depthResolveAttachment.getTexture() != nullptr) { - PTexture2D vkDepthAttachment = layout.depthResolveAttachment.getTexture().cast(); + PTextureBase vkDepthAttachment = layout.depthResolveAttachment.getTexture().cast(); attachments.add(vkDepthAttachment->getView()); description.depthResolveAttachment = vkDepthAttachment->getView(); width = std::max(width, vkDepthAttachment->getWidth()); diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index 9a1de05..a1441ed 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -172,8 +172,9 @@ Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreate } Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array dependencies, - Gfx::PViewport renderArea, std::string name) { - return new RenderPass(this, std::move(layout), std::move(dependencies), renderArea, name); + URect renderArea, std::string name, Array viewMasks, + Array correlationMasks) { + return new RenderPass(this, std::move(layout), std::move(dependencies), renderArea, name, std::move(viewMasks), std::move(correlationMasks)); } void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) { PRenderPass rp = renderPass.cast(); @@ -824,6 +825,7 @@ void Graphics::pickPhysicalDevice() { .pNext = &features12, .storageBuffer16BitAccess = true, .uniformAndStorageBuffer16BitAccess = true, + .multiview = true, }; features = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, @@ -950,6 +952,7 @@ void Graphics::createDevice(GraphicsInitializer initializer) { initializer.deviceExtensions.add(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME); initializer.deviceExtensions.add(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); } + initializer.deviceExtensions.add(VK_KHR_MULTIVIEW_EXTENSION_NAME); #ifdef __APPLE__ initializer.deviceExtensions.add("VK_KHR_portability_subset"); #endif diff --git a/src/Engine/Graphics/Vulkan/Graphics.h b/src/Engine/Graphics/Vulkan/Graphics.h index 58cb080..74dfe70 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.h +++ b/src/Engine/Graphics/Vulkan/Graphics.h @@ -35,7 +35,8 @@ class Graphics : public Gfx::Graphics { virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo& createInfo) override; virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array dependencies, - Gfx::PViewport renderArea, std::string name) override; + URect renderArea, std::string name, Array viewMasks, + Array correlationMasks) override; virtual void beginRenderPass(Gfx::PRenderPass renderPass) override; virtual void endRenderPass() override; virtual void waitDeviceIdle() override; diff --git a/src/Engine/Graphics/Vulkan/RenderPass.cpp b/src/Engine/Graphics/Vulkan/RenderPass.cpp index 613ddcf..a9f7c4b 100644 --- a/src/Engine/Graphics/Vulkan/RenderPass.cpp +++ b/src/Engine/Graphics/Vulkan/RenderPass.cpp @@ -6,17 +6,16 @@ #include "Resources.h" #include "Texture.h" - using namespace Seele; using namespace Seele::Vulkan; RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array _dependencies, - Gfx::PViewport viewport, std::string name) + URect viewport, std::string name, Array viewMasks, Array correlationMasks) : Gfx::RenderPass(std::move(_layout), std::move(_dependencies)), graphics(graphics) { - renderArea.extent.width = viewport->getWidth(); - renderArea.extent.height = viewport->getHeight(); - renderArea.offset.x = viewport->getOffsetX(); - renderArea.offset.y = viewport->getOffsetY(); + renderArea.extent.width = viewport.size.x; + renderArea.extent.height = viewport.size.y; + renderArea.offset.x = viewport.offset.x; + renderArea.offset.y = viewport.offset.y; subpassContents = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS; Array attachments; Array inputRefs; @@ -198,7 +197,18 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra .dependencyCount = (uint32)dep.size(), .pDependencies = dep.data(), }; - + VkRenderPassMultiviewCreateInfo multiViewInfo; + if (!viewMasks.empty()) { + multiViewInfo = { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, + .pNext = nullptr, + .subpassCount = 1, + .pViewMasks = viewMasks.data(), + .correlationMaskCount = (uint32)correlationMasks.size(), + .pCorrelationMasks = correlationMasks.data(), + }; + info.pNext = &multiViewInfo; + } VK_CHECK(vkCreateRenderPass2(graphics->getDevice(), &info, nullptr, &renderPass)); VkDebugUtilsObjectNameInfoEXT nameInfo = { .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, @@ -220,23 +230,23 @@ uint32 RenderPass::getFramebufferHash() { FramebufferDescription description; std::memset(&description, 0, sizeof(FramebufferDescription)); for (auto& inputAttachment : layout.inputAttachments) { - PTexture2D tex = inputAttachment.getTexture().cast(); + PTextureBase tex = inputAttachment.getTexture().cast(); description.inputAttachments[description.numInputAttachments++] = tex->getView(); } for (auto& colorAttachment : layout.colorAttachments) { - PTexture2D tex = colorAttachment.getTexture().cast(); + PTextureBase tex = colorAttachment.getTexture().cast(); description.colorAttachments[description.numColorAttachments++] = tex->getView(); } for (auto& resolveAttachment : layout.resolveAttachments) { - PTexture2D tex = resolveAttachment.getTexture().cast(); - description.resolveAttachments[description.numResolveAttachments++] = tex->getView(); + PTextureBase tex = resolveAttachment.getTexture().cast(); + description.resolveAttachments[description.numResolveAttachments++] = tex->getView(); } if (layout.depthAttachment.getTexture() != nullptr) { - PTexture2D tex = layout.depthAttachment.getTexture().cast(); + PTextureBase tex = layout.depthAttachment.getTexture().cast(); description.depthAttachment = tex->getView(); } if (layout.depthResolveAttachment.getTexture() != nullptr) { - PTexture2D tex = layout.depthResolveAttachment.getTexture().cast(); + PTextureBase tex = layout.depthResolveAttachment.getTexture().cast(); description.depthResolveAttachment = tex->getView(); } return CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32()); @@ -244,23 +254,23 @@ uint32 RenderPass::getFramebufferHash() { void RenderPass::endRenderPass() { for (auto& inputAttachment : layout.inputAttachments) { - PTexture2D tex = inputAttachment.getTexture().cast(); + PTextureBase tex = inputAttachment.getTexture().cast(); tex->setLayout(inputAttachment.getFinalLayout()); } for (auto& colorAttachment : layout.colorAttachments) { - PTexture2D tex = colorAttachment.getTexture().cast(); + PTextureBase tex = colorAttachment.getTexture().cast(); tex->setLayout(colorAttachment.getFinalLayout()); } for (auto& resolveAttachment : layout.resolveAttachments) { - PTexture2D tex = resolveAttachment.getTexture().cast(); + PTextureBase tex = resolveAttachment.getTexture().cast(); tex->setLayout(resolveAttachment.getFinalLayout()); } if (layout.depthAttachment.getTexture() != nullptr) { - PTexture2D tex = layout.depthAttachment.getTexture().cast(); + PTextureBase tex = layout.depthAttachment.getTexture().cast(); tex->setLayout(layout.depthAttachment.getFinalLayout()); } if (layout.depthResolveAttachment.getTexture() != nullptr) { - PTexture2D tex = layout.depthResolveAttachment.getTexture().cast(); + PTextureBase tex = layout.depthResolveAttachment.getTexture().cast(); tex->setLayout(layout.depthResolveAttachment.getFinalLayout()); } } diff --git a/src/Engine/Graphics/Vulkan/RenderPass.h b/src/Engine/Graphics/Vulkan/RenderPass.h index 66fbf19..ee5c5cf 100644 --- a/src/Engine/Graphics/Vulkan/RenderPass.h +++ b/src/Engine/Graphics/Vulkan/RenderPass.h @@ -6,7 +6,8 @@ namespace Seele { namespace Vulkan { class RenderPass : public Gfx::RenderPass { public: - RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array dependencies, Gfx::PViewport viewport, std::string name); + RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array dependencies, URect viewport, + std::string name, Array viewMasks = {}, Array correlationMasks = {}); virtual ~RenderPass(); uint32 getFramebufferHash(); void endRenderPass(); diff --git a/src/Engine/Graphics/Vulkan/Texture.cpp b/src/Engine/Graphics/Vulkan/Texture.cpp index ec16f74..9b69cae 100644 --- a/src/Engine/Graphics/Vulkan/Texture.cpp +++ b/src/Engine/Graphics/Vulkan/Texture.cpp @@ -29,10 +29,10 @@ VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format) { } TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, VkImage existingImage) - : CommandBoundResource(graphics, createInfo.name), image(existingImage), owner(createInfo.sourceData.owner), width(createInfo.width), - height(createInfo.height), depth(createInfo.depth), arrayCount(createInfo.elements), layerCount(createInfo.layers), mipLevels(1), - samples(createInfo.samples), format(createInfo.format), usage(createInfo.usage), - layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), aspect(getAspectFromFormat(createInfo.format)), ownsImage(false) { + : CommandBoundResource(graphics, createInfo.name), image(existingImage), imageView(VK_NULL_HANDLE), allocation(nullptr), + owner(createInfo.sourceData.owner), width(createInfo.width), height(createInfo.height), depth(createInfo.depth), + arrayCount(createInfo.elements), layerCount(createInfo.layers), mipLevels(1), samples(createInfo.samples), format(createInfo.format), + usage(createInfo.usage), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), aspect(getAspectFromFormat(createInfo.format)), ownsImage(false) { if (createInfo.useMip) { mipLevels = static_cast(std::floor(std::log2(std::max(width, height)))) + 1; } @@ -95,7 +95,8 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const .pObjectName = name.c_str(), }; vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo); - ownsImage = true;const DataSource& sourceData = createInfo.sourceData; + ownsImage = true; + const DataSource& sourceData = createInfo.sourceData; if (sourceData.size > 0) { changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); @@ -117,7 +118,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const vmaMapMemory(graphics->getAllocator(), stagingAlloc->allocation, &data); std::memcpy(data, sourceData.data, sourceData.size); vmaUnmapMemory(graphics->getAllocator(), stagingAlloc->allocation); - + PCommandPool commandPool = graphics->getQueueCommands(owner); VkBufferImageCopy region = { .bufferOffset = 0, @@ -138,10 +139,10 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const }, .imageExtent = {.width = width, .height = height, .depth = depth}, }; - - vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), stagingAlloc->buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, ®ion); - + + vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), stagingAlloc->buffer, image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + commandPool->getCommands()->bindResource(PBufferAllocation(stagingAlloc)); generateMipmaps(); // When loading a texture from a file, we will almost always use it as a texture map for fragment shaders @@ -150,7 +151,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const graphics->getDestructionManager()->queueResourceForDestruction(std::move(stagingAlloc)); } } - + VkImageViewCreateInfo viewInfo = { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, .pNext = nullptr, @@ -385,7 +386,10 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType, const Tex : handle(new TextureHandle(graphics, viewType, createInfo, existingImage)), graphics(graphics), initialOwner(createInfo.sourceData.owner) {} -TextureBase::~TextureBase() { graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle)); } +TextureBase::~TextureBase() { + graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle)); + handle = nullptr; +} void TextureBase::pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) { diff --git a/src/Engine/Graphics/Vulkan/Texture.h b/src/Engine/Graphics/Vulkan/Texture.h index 7865c5f..8104c72 100644 --- a/src/Engine/Graphics/Vulkan/Texture.h +++ b/src/Engine/Graphics/Vulkan/Texture.h @@ -6,15 +6,13 @@ #include "Resources.h" #include - namespace Seele { namespace Vulkan { class TextureHandle : public CommandBoundResource { public: TextureHandle(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, VkImage existingImage); virtual ~TextureHandle(); - void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, - VkPipelineStageFlags dstStage); + void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); void transferOwnership(Gfx::QueueType newOwner); void changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); @@ -37,11 +35,15 @@ class TextureHandle : public CommandBoundResource { VkImageAspectFlags aspect; uint8 ownsImage; }; -DECLARE_REF(TextureHandle) +DEFINE_REF(TextureHandle) + +DECLARE_REF(TextureBase) +DECLARE_REF(Texture2D) +DECLARE_REF(Texture3D) +DECLARE_REF(TextureCube) class TextureBase { public: - TextureBase(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, - VkImage existingImage = VK_NULL_HANDLE); + TextureBase(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE); virtual ~TextureBase(); uint32 getWidth() const { return handle->width; } uint32 getHeight() const { return handle->height; } @@ -58,13 +60,13 @@ class TextureBase { constexpr uint32 getMipLevels() const { return handle->mipLevels; } constexpr bool isDepthStencil() const { return handle->aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); } - void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, - VkPipelineStageFlags dstStage); + void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); void transferOwnership(Gfx::QueueType newOwner); void changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer); void generateMipmaps(); + protected: OTextureHandle handle; // Updates via reference diff --git a/src/Engine/Graphics/Window.cpp b/src/Engine/Graphics/Window.cpp index 70bd098..34da7a2 100644 --- a/src/Engine/Graphics/Window.cpp +++ b/src/Engine/Graphics/Window.cpp @@ -8,8 +8,7 @@ Window::Window() {} Window::~Window() {} Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo) - : sizeX(std::min(owner->getFramebufferWidth(), viewportInfo.dimensions.size.x)), - sizeY(std::min(owner->getFramebufferHeight(), viewportInfo.dimensions.size.y)), offsetX(viewportInfo.dimensions.offset.x), + : sizeX(viewportInfo.dimensions.size.x), sizeY(viewportInfo.dimensions.size.y), offsetX(viewportInfo.dimensions.offset.x), offsetY(viewportInfo.dimensions.offset.y), fieldOfView(viewportInfo.fieldOfView), owner(owner) {} Viewport::~Viewport() {} diff --git a/src/Engine/Graphics/Window.h b/src/Engine/Graphics/Window.h index 11dfded..7effa72 100644 --- a/src/Engine/Graphics/Window.h +++ b/src/Engine/Graphics/Window.h @@ -53,6 +53,12 @@ class Viewport { constexpr float getContentScaleX() const { return owner->getContentScaleX(); } constexpr float getContentScaleY() const { return owner->getContentScaleY(); } Matrix4 getProjectionMatrix() const; + URect getRenderArea() const { + return URect{ + .size = {sizeX, sizeY}, + .offset = {offsetX, offsetY}, + }; + } protected: uint32 sizeX; diff --git a/src/Engine/ThreadPool.cpp b/src/Engine/ThreadPool.cpp index 205efcc..950b640 100644 --- a/src/Engine/ThreadPool.cpp +++ b/src/Engine/ThreadPool.cpp @@ -1,5 +1,6 @@ #include "ThreadPool.h" #include "MinimalEngine.h" +#include "Graphics/Texture.h" using namespace Seele; @@ -7,6 +8,8 @@ Globals globals; Globals& Seele::getGlobals() { return globals; } +void test(Gfx::PTexture base) { (void)base; } + ThreadPool::ThreadPool(uint32 numWorkers) { for (uint32 i = 0; i < numWorkers; ++i) { workers.add(std::thread(&ThreadPool::work, this)); diff --git a/tests/Engine/MinimalEngine.cpp b/tests/Engine/MinimalEngine.cpp new file mode 100644 index 0000000..76d1098 --- /dev/null +++ b/tests/Engine/MinimalEngine.cpp @@ -0,0 +1,11 @@ +#include "EngineTest.h" + +struct Foo {}; + +struct Derivate : public Foo {}; + +TEST(RefPtr, ImplicitUpcast) { + OwningPtr owner = new Derivate(); + RefPtr der = owner; + RefPtr foo = der; +} \ No newline at end of file