From e487867f96d550cb07e6abb725f8b83d4eec6faf Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Wed, 8 Jan 2025 19:15:12 +0100 Subject: [PATCH] Refactoring basic text rendering --- cpp.hint | 4 + res/shaders/TextPass.slang | 56 ++-- res/shaders/UIPass.slang | 8 +- src/AssetViewer/CMakeLists.txt | 2 +- src/Benchmark/CMakeLists.txt | 2 +- src/Editor/Asset/CMakeLists.txt | 2 +- src/Editor/Asset/FontLoader.cpp | 23 +- src/Editor/Window/InspectorView.cpp | 29 +- src/Editor/Window/InspectorView.h | 10 +- src/Editor/main.cpp | 85 +++--- src/Engine/Asset/FontAsset.cpp | 106 ++------ src/Engine/Asset/FontAsset.h | 15 +- src/Engine/Asset/MeshAsset.cpp | 4 +- src/Engine/CMakeLists.txt | 2 +- src/Engine/Graphics/Graphics.h | 4 +- src/Engine/Graphics/Mesh.cpp | 10 +- src/Engine/Graphics/RenderPass/BasePass.cpp | 2 +- src/Engine/Graphics/RenderPass/BasePass.h | 1 + src/Engine/Graphics/RenderPass/CMakeLists.txt | 3 - .../Graphics/RenderPass/CachedDepthPass.cpp | 2 +- .../Graphics/RenderPass/CachedDepthPass.h | 1 + .../Graphics/RenderPass/DepthCullingPass.cpp | 2 +- .../Graphics/RenderPass/DepthCullingPass.h | 1 + .../Graphics/RenderPass/LightCullingPass.cpp | 2 +- .../Graphics/RenderPass/LightCullingPass.h | 2 + .../Graphics/RenderPass/RayTracingPass.cpp | 2 +- .../Graphics/RenderPass/RayTracingPass.h | 1 + src/Engine/Graphics/RenderPass/RenderPass.cpp | 2 +- src/Engine/Graphics/RenderPass/RenderPass.h | 3 +- src/Engine/Graphics/RenderPass/TextPass.cpp | 202 -------------- src/Engine/Graphics/RenderPass/TextPass.h | 78 ------ src/Engine/Graphics/RenderPass/UIPass.cpp | 255 ++++++++++-------- src/Engine/Graphics/RenderPass/UIPass.h | 66 ++++- .../Graphics/RenderPass/VisibilityPass.cpp | 2 +- .../Graphics/RenderPass/VisibilityPass.h | 2 +- src/Engine/Graphics/Vulkan/Graphics.cpp | 68 +++-- src/Engine/Graphics/Vulkan/Window.cpp | 5 +- src/Engine/Graphics/Window.cpp | 2 +- src/Engine/Graphics/Window.h | 6 + src/Engine/Serialization/Serialization.h | 8 + src/Engine/UI/Attributes.h | 11 + src/Engine/UI/CMakeLists.txt | 27 +- src/Engine/UI/Element.cpp | 19 ++ src/Engine/UI/Element.h | 25 ++ src/Engine/UI/Element/CMakeLists.txt | 4 + src/Engine/UI/Element/Div.h | 15 ++ src/Engine/UI/Element/Text.h | 16 ++ src/Engine/UI/Elements/Button.cpp | 4 - src/Engine/UI/Elements/Button.h | 8 - src/Engine/UI/Elements/CMakeLists.txt | 18 -- src/Engine/UI/Elements/Element.cpp | 35 --- src/Engine/UI/Elements/Element.h | 43 --- src/Engine/UI/Elements/Label.h | 15 -- src/Engine/UI/Elements/Panel.cpp | 9 - src/Engine/UI/Elements/Panel.h | 18 -- src/Engine/UI/HorizontalLayout.cpp | 25 -- src/Engine/UI/HorizontalLayout.h | 15 -- src/Engine/UI/Layout.cpp | 9 - src/Engine/UI/Layout.h | 17 -- src/Engine/UI/RenderHierarchy.cpp | 58 ---- src/Engine/UI/RenderHierarchy.h | 76 ------ src/Engine/UI/Style/CMakeLists.txt | 4 + src/Engine/UI/Style/Class.h | 27 ++ src/Engine/UI/Style/Style.h | 49 ++++ src/Engine/UI/System.cpp | 21 -- src/Engine/UI/System.h | 36 +-- src/Engine/UI/VerticalLayout.cpp | 25 -- src/Engine/UI/VerticalLayout.h | 15 -- src/Engine/Window/GameView.cpp | 14 +- .../Label.cpp => tests/Engine/UI/Element.cpp | 3 +- 70 files changed, 608 insertions(+), 1133 deletions(-) create mode 100644 cpp.hint delete mode 100644 src/Engine/Graphics/RenderPass/TextPass.cpp delete mode 100644 src/Engine/Graphics/RenderPass/TextPass.h create mode 100644 src/Engine/UI/Attributes.h create mode 100644 src/Engine/UI/Element.cpp create mode 100644 src/Engine/UI/Element.h create mode 100644 src/Engine/UI/Element/CMakeLists.txt create mode 100644 src/Engine/UI/Element/Div.h create mode 100644 src/Engine/UI/Element/Text.h delete mode 100644 src/Engine/UI/Elements/Button.cpp delete mode 100644 src/Engine/UI/Elements/Button.h delete mode 100644 src/Engine/UI/Elements/CMakeLists.txt delete mode 100644 src/Engine/UI/Elements/Element.cpp delete mode 100644 src/Engine/UI/Elements/Element.h delete mode 100644 src/Engine/UI/Elements/Label.h delete mode 100644 src/Engine/UI/Elements/Panel.cpp delete mode 100644 src/Engine/UI/Elements/Panel.h delete mode 100644 src/Engine/UI/HorizontalLayout.cpp delete mode 100644 src/Engine/UI/HorizontalLayout.h delete mode 100644 src/Engine/UI/Layout.cpp delete mode 100644 src/Engine/UI/Layout.h delete mode 100644 src/Engine/UI/RenderHierarchy.cpp delete mode 100644 src/Engine/UI/RenderHierarchy.h create mode 100644 src/Engine/UI/Style/CMakeLists.txt create mode 100644 src/Engine/UI/Style/Class.h create mode 100644 src/Engine/UI/Style/Style.h delete mode 100644 src/Engine/UI/System.cpp delete mode 100644 src/Engine/UI/VerticalLayout.cpp delete mode 100644 src/Engine/UI/VerticalLayout.h rename src/Engine/UI/Elements/Label.cpp => tests/Engine/UI/Element.cpp (50%) diff --git a/cpp.hint b/cpp.hint new file mode 100644 index 0000000..4abe4a3 --- /dev/null +++ b/cpp.hint @@ -0,0 +1,4 @@ +// Hint files help the Visual Studio IDE interpret Visual C++ identifiers +// such as names of functions and macros. +// For more information see https://go.microsoft.com/fwlink/?linkid=865984 +#define DECLARE_REF(x) diff --git a/res/shaders/TextPass.slang b/res/shaders/TextPass.slang index 17463b0..f7ec62c 100644 --- a/res/shaders/TextPass.slang +++ b/res/shaders/TextPass.slang @@ -1,39 +1,21 @@ import Common; -struct GlyphData -{ - float4 bearingSize; -}; -struct TextData -{ - float4 textColor; - float scale; -} -struct GlyphSampler -{ - SamplerState s; -} -ParameterBlock glyphSampler; -//layout(set = 1) -//ShaderBuffer glyphData; -struct GlyphTextures -{ - Texture2D[256] textures; -} -ParameterBlock pGlyphTextures; - struct GlyphInstanceData { - float2 position; - float2 widthHeight; + float x; + float y; + float width; + float height; uint glyphIndex; }; -struct TextRender + +struct TextData { - StructuredBuffer instances; - TextData textData; -} -ParameterBlock pRender; + StructuredBuffer glyphs; + SamplerState glyphSampler; + Texture2D glyphTextures[]; +}; +ParameterBlock pText; struct VertexInput { @@ -51,23 +33,23 @@ struct VertexOutput [shader("vertex")] VertexOutput vertexMain(VertexInput input) { - float xpos = pRender.instances[input.instanceId].position.x; - float ypos = pRender.instances[input.instanceId].position.y; + float xpos = pText.glyphs[input.instanceId].x; + float ypos = pText.glyphs[input.instanceId].y; - float w = pRender.instances[input.instanceId].widthHeight.x; - float h = pRender.instances[input.instanceId].widthHeight.y; + float w = pText.glyphs[input.instanceId].width; + float h = pText.glyphs[input.instanceId].height; - float4 coordinates[4] = { + const float4 coordinates[4] = { float4(xpos, ypos, 0, 1), float4(xpos, ypos + h, 0, 0), float4(xpos + w, ypos, 1, 1), - float4(xpos + w, ypos + h, 1, 0) + float4(xpos + w, ypos + h, 1, 0), }; float4 vertex = coordinates[input.vertexId]; VertexOutput output; output.texCoords = vertex.zw; output.position = mul(pViewParams.projectionMatrix, float4(vertex.xy, 0, 1)); - output.glyphIndex = pRender.instances[input.instanceId].glyphIndex; + output.glyphIndex = pText.glyphs[input.instanceId].glyphIndex; return output; } @@ -78,5 +60,5 @@ float4 fragmentMain( uint glyphIndex : GLYPHINDEX ) : SV_Target { - return pRender.textData.textColor * pGlyphTextures.textures[glyphIndex].Sample(glyphSampler.s, texCoords); + return float4(1, 0, 0, pText.glyphTextures[glyphIndex].Sample(pText.glyphSampler, texCoords)); } \ No newline at end of file diff --git a/res/shaders/UIPass.slang b/res/shaders/UIPass.slang index 4d65646..e68b8ed 100644 --- a/res/shaders/UIPass.slang +++ b/res/shaders/UIPass.slang @@ -47,7 +47,7 @@ VertexOutput vertexMain(uint vertexId : SV_VertexID, RenderElementStyle style) float4(xMax, yMax, 1, 1) }; VertexOutput output; - output.position = mul(pViewData.projectionMatrix, float4(coordinates[vertexId].xy, style.position.z, 1)); + output.position = mul(pViewParams.projectionMatrix, float4(coordinates[vertexId].xy, style.position.z, 1)); output.texCoords = coordinates[vertexId].zw; output.style = style; return output; @@ -62,9 +62,5 @@ float4 fragmentMain( { float4 bgTextureColor = float4(1, 1, 1, 1); uint imageIndex = style.backgroundImageIndex; - if(imageIndex < numBackgroundTextures) - { - bgTextureColor = pParams.backgroundTextures[imageIndex].Sample(pParams.backgroundSampler, texCoords); - } - return float4(style.backgroundColor, style.opacity) * bgTextureColor; + return float4(0, 1, 0, 1); } \ No newline at end of file diff --git a/src/AssetViewer/CMakeLists.txt b/src/AssetViewer/CMakeLists.txt index 3d58048..be2107d 100644 --- a/src/AssetViewer/CMakeLists.txt +++ b/src/AssetViewer/CMakeLists.txt @@ -1,3 +1,3 @@ target_sources(AssetViewer PRIVATE - main.cpp) \ No newline at end of file + main.cpp "../../tests/Engine/UI/Element.cpp") \ No newline at end of file diff --git a/src/Benchmark/CMakeLists.txt b/src/Benchmark/CMakeLists.txt index 038a7ae..a4f6516 100644 --- a/src/Benchmark/CMakeLists.txt +++ b/src/Benchmark/CMakeLists.txt @@ -2,4 +2,4 @@ target_sources(Benchmark PUBLIC main.cpp PlayView.h - PlayView.cpp) \ No newline at end of file + PlayView.cpp "../../tests/Engine/UI/Element.cpp") \ No newline at end of file diff --git a/src/Editor/Asset/CMakeLists.txt b/src/Editor/Asset/CMakeLists.txt index 616e629..42de029 100644 --- a/src/Editor/Asset/CMakeLists.txt +++ b/src/Editor/Asset/CMakeLists.txt @@ -9,4 +9,4 @@ target_sources(Editor MeshLoader.h MeshLoader.cpp TextureLoader.h - TextureLoader.cpp) \ No newline at end of file + TextureLoader.cpp "../../../tests/Engine/UI/Element.cpp") \ No newline at end of file diff --git a/src/Editor/Asset/FontLoader.cpp b/src/Editor/Asset/FontLoader.cpp index 65d0c8e..47fa480 100644 --- a/src/Editor/Asset/FontLoader.cpp +++ b/src/Editor/Asset/FontLoader.cpp @@ -30,7 +30,6 @@ void FontLoader::importAsset(FontImportArgs args) { // in case of the space character there is no bitmap // so we create a single pixel empty texture -uint8 transparentPixel = 0; void FontLoader::import(FontImportArgs args, PFontAsset asset) { FT_Library ft; FT_Error error = FT_Init_FreeType(&ft); @@ -39,7 +38,6 @@ void FontLoader::import(FontImportArgs args, PFontAsset asset) { error = FT_New_Face(ft, args.filePath.string().c_str(), 0, &face); assert(!error); FT_Set_Pixel_Sizes(face, 0, 48); - Array usedTextures; for (uint32 c = 0; c < 256; ++c) { if (FT_Load_Char(face, c, FT_LOAD_RENDER)) { std::cout << "error loading " << (char)c << std::endl; @@ -49,28 +47,17 @@ void FontLoader::import(FontImportArgs args, PFontAsset asset) { glyph.size = IVector2(face->glyph->bitmap.width, face->glyph->bitmap.rows); glyph.bearing = IVector2(face->glyph->bitmap_left, face->glyph->bitmap_top); glyph.advance = face->glyph->advance.x; - TextureCreateInfo imageData; - imageData.format = Gfx::SE_FORMAT_R8_UINT; - imageData.width = face->glyph->bitmap.width; - imageData.height = face->glyph->bitmap.rows; - imageData.sourceData.data = face->glyph->bitmap.buffer; - imageData.sourceData.size = imageData.width * imageData.height; - if (imageData.width == 0 || imageData.height == 0) { + glyph.textureData.resize(glyph.size.x * glyph.size.y); + if (glyph.textureData.size() == 0) { glyph.size.x = 1; glyph.size.y = 1; - glyph.bearing.x = 0; - glyph.bearing.y = 0; - imageData.width = 1; - imageData.height = 1; - imageData.sourceData.size = sizeof(uint8); - imageData.sourceData.data = &transparentPixel; + glyph.textureData.add(0); // load a single transparent pixel, so that we dont have to handle empty textures later + } else { + std::memcpy(glyph.textureData.data(), face->glyph->bitmap.buffer, glyph.textureData.size()); } - glyph.textureIndex = usedTextures.size(); - usedTextures.add(graphics->createTexture2D(imageData)); } FT_Done_Face(face); FT_Done_FreeType(ft); - asset->setUsedTextures(std::move(usedTextures)); AssetRegistry::saveAsset(asset, FontAsset::IDENTIFIER, asset->getFolderPath(), asset->getName()); diff --git a/src/Editor/Window/InspectorView.cpp b/src/Editor/Window/InspectorView.cpp index de73fdd..29b84e7 100644 --- a/src/Editor/Window/InspectorView.cpp +++ b/src/Editor/Window/InspectorView.cpp @@ -3,40 +3,31 @@ #include "Asset/AssetRegistry.h" #include "Asset/FontLoader.h" #include "Graphics/Graphics.h" -#include "UI/System.h" -#include "Window/Window.h" - +#include "UI/Element/Text.h" using namespace Seele; using namespace Seele::Editor; InspectorView::InspectorView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& createInfo) - : View(graphics, std::move(window), std::move(createInfo), "InspectorView") - //, renderGraph(RenderGraphBuilder::build( - // UIPass(graphics), - // TextPass(graphics) - //)) - , - uiSystem(new UI::System()) { - // renderGraph.updateViewport(viewport); - uiSystem->updateViewport(viewport); + : View(graphics, window, createInfo, "InspectorView"), uiSystem(new UI::System(new UI::Text("Test"))) { + renderGraph.addPass(new UIPass(graphics, uiSystem)); + renderGraph.setViewport(viewport); + renderGraph.createRenderPass(); } InspectorView::~InspectorView() {} -void InspectorView::beginUpdate() { - // co_return; -} +void InspectorView::beginUpdate() {} -void InspectorView::update() { - // co_return; -} +void InspectorView::update() {} void InspectorView::commitUpdate() {} void InspectorView::prepareRender() {} -void InspectorView::render() {} +void InspectorView::render() { renderGraph.render(Component::Camera()); } + +void InspectorView::applyArea(URect area) {} void InspectorView::keyCallback(KeyCode, InputAction, KeyModifier) {} diff --git a/src/Editor/Window/InspectorView.h b/src/Editor/Window/InspectorView.h index 0c151f6..ffd8f8e 100644 --- a/src/Editor/Window/InspectorView.h +++ b/src/Editor/Window/InspectorView.h @@ -1,10 +1,8 @@ #pragma once #include "Graphics/RenderPass/RenderGraph.h" -#include "Graphics/RenderPass/TextPass.h" #include "Graphics/RenderPass/UIPass.h" -#include "UI/Elements/Panel.h" #include "Window/View.h" - +#include "UI/System.h" namespace Seele { DECLARE_REF(Actor) @@ -20,11 +18,13 @@ class InspectorView : public View { virtual void prepareRender() override; virtual void render() override; - void selectActor(); + protected: + virtual void applyArea(URect area) override; UI::PSystem uiSystem; - PActor selectedActor; + RenderGraph renderGraph; + Component::Camera cam; virtual void keyCallback(KeyCode code, InputAction action, KeyModifier modifier) override; virtual void mouseMoveCallback(double xPos, double yPos) override; diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index 6234590..04b0ecc 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -11,6 +11,7 @@ #include "Graphics/Vulkan/Graphics.h" #endif #include "Graphics/StaticMeshVertexData.h" +#include "Window/InspectorView.h" #include "Window/PlayView.h" #include "Window/WindowManager.h" #include @@ -36,9 +37,9 @@ Array generateEdges() { Array edges; for (auto ind : indices) { uint32 baseIndex = edges.size(); - edges.add(Halfedge{ind.x, baseIndex+1, baseIndex+2, UINT32_MAX}); - edges.add(Halfedge{ind.y, baseIndex+2, baseIndex, UINT32_MAX}); - edges.add(Halfedge{ind.z, baseIndex, baseIndex+1, UINT32_MAX}); + edges.add(Halfedge{ind.x, baseIndex + 1, baseIndex + 2, UINT32_MAX}); + edges.add(Halfedge{ind.y, baseIndex + 2, baseIndex, UINT32_MAX}); + edges.add(Halfedge{ind.z, baseIndex, baseIndex + 1, UINT32_MAX}); } for (uint32 i = 0; i < edges.size(); ++i) { if (edges[i].twinID == UINT32_MAX) { @@ -83,9 +84,9 @@ int main() { OWindowManager windowManager = new WindowManager(); AssetRegistry::init(sourcePath / "Assets", graphics); AssetImporter::init(graphics); - // AssetImporter::importFont(FontImportArgs{ - // .filePath = "./fonts/Calibri.ttf", - // }); + AssetImporter::importFont(FontImportArgs{ + .filePath = "./fonts/arial.ttf", + }); AssetImporter::importMesh(MeshImportArgs{ .filePath = sourcePath / "import/models/cube.fbx", }); @@ -100,35 +101,35 @@ int main() { // .filePath = sourcePath / "import/models/ship.fbx", // .importPath = "ship", // }); - //AssetImporter::importTexture(TextureImportArgs{ + // AssetImporter::importTexture(TextureImportArgs{ // .filePath = sourcePath / "import/textures/azeroth.png", //}); - //AssetImporter::importTexture(TextureImportArgs{ + // AssetImporter::importTexture(TextureImportArgs{ // .filePath = sourcePath / "import/textures/azeroth_height.png", //}); - //AssetImporter::importTexture(TextureImportArgs{ + // AssetImporter::importTexture(TextureImportArgs{ // .filePath = sourcePath / "import/textures/wgen.png", //}); - AssetImporter::importMesh(MeshImportArgs{ - .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb", - .importPath = "Whitechapel", - }); - //AssetImporter::importMesh(MeshImportArgs{ - // .filePath = sourcePath / "import/models/plane.obj", - // .importPath = "", - //}); - // AssetImporter::importMesh(MeshImportArgs{ - // .filePath = sourcePath / "import/models/city-suburbs/source/city-suburbs.obj", - // .importPath = "suburbs", - // }); - // AssetImporter::importMesh(MeshImportArgs{ - // .filePath = sourcePath / "import/models/minecraft-medieval-city.fbx", - // .importPath = "minecraft", - // }); // AssetImporter::importMesh(MeshImportArgs{ - // .filePath = sourcePath / "import/models/Volvo/Volvo.fbx", - // .importPath = "Volvo", + // .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb", + // .importPath = "Whitechapel", + //}); + // AssetImporter::importMesh(MeshImportArgs{ + // .filePath = sourcePath / "import/models/plane.obj", + // .importPath = "", // }); + // AssetImporter::importMesh(MeshImportArgs{ + // .filePath = sourcePath / "import/models/city-suburbs/source/city-suburbs.obj", + // .importPath = "suburbs", + // }); + // AssetImporter::importMesh(MeshImportArgs{ + // .filePath = sourcePath / "import/models/minecraft-medieval-city.fbx", + // .importPath = "minecraft", + // }); + // AssetImporter::importMesh(MeshImportArgs{ + // .filePath = sourcePath / "import/models/Volvo/Volvo.fbx", + // .importPath = "Volvo", + // }); getThreadPool().waitIdle(); vd->commitMeshes(); WindowCreateInfo mainWindowInfo = { @@ -138,16 +139,26 @@ int main() { .preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_SRGB, }; auto window = windowManager->addWindow(graphics, mainWindowInfo); - ViewportCreateInfo sceneViewInfo = { - .dimensions = - { - .size = {1920, 1080}, - .offset = {0, 0}, - }, - .numSamples = Gfx::SE_SAMPLE_COUNT_4_BIT, - }; - OGameView sceneView = new Editor::PlayView(graphics, window, sceneViewInfo, binaryPath.generic_string()); - sceneView->setFocused(); + // ViewportCreateInfo sceneViewInfo = { + // .dimensions = + // { + // .size = {1920, 1080}, + // .offset = {0, 0}, + // }, + // .numSamples = Gfx::SE_SAMPLE_COUNT_4_BIT, + // }; + // OGameView sceneView = new Editor::PlayView(graphics, window, sceneViewInfo, binaryPath.generic_string()); + // sceneView->setFocused(); + OInspectorView inspectorView = new Editor::InspectorView(graphics, window, + ViewportCreateInfo{ + .dimensions = + { + .size = {1920, 1080}, + .offset = {0, 0}, + }, + .fieldOfView = 0, + .numSamples = Gfx::SE_SAMPLE_COUNT_1_BIT, + }); while (windowManager->isActive() && getGlobals().running) { windowManager->render(); diff --git a/src/Engine/Asset/FontAsset.cpp b/src/Engine/Asset/FontAsset.cpp index dcc65f8..dd72d64 100644 --- a/src/Engine/Asset/FontAsset.cpp +++ b/src/Engine/Asset/FontAsset.cpp @@ -1,7 +1,6 @@ #include "FontAsset.h" #include "Graphics/Graphics.h" #include "Graphics/Texture.h" -#include using namespace Seele; @@ -11,106 +10,31 @@ FontAsset::FontAsset(std::string_view folderPath, std::string_view name) : Asset FontAsset::~FontAsset() {} -void FontAsset::save(ArchiveBuffer& buffer) const { - Serialization::save(buffer, glyphs); - Serialization::save(buffer, usedTextures.size()); - for (uint32 x = 0; x < usedTextures.size(); ++x) { - Array textureData; - ktxTexture2* kTexture; - ktxTextureCreateInfo createInfo = { - .glInternalformat = 0, - .vkFormat = (uint32_t)usedTextures[x]->getFormat(), - .pDfd = nullptr, - .baseWidth = usedTextures[x]->getWidth(), - .baseHeight = usedTextures[x]->getHeight(), - .baseDepth = usedTextures[x]->getDepth(), - .numDimensions = usedTextures[x]->getDepth() > 1 ? 3u - : usedTextures[x]->getHeight() > 1 ? 2u - : 1u, - .numLevels = usedTextures[x]->getMipLevels(), - .numLayers = usedTextures[x]->getDepth(), - .numFaces = usedTextures[x]->getNumFaces(), - .isArray = false, - .generateMipmaps = false, - }; - ktxTexture2_Create(&createInfo, KTX_TEXTURE_CREATE_ALLOC_STORAGE, &kTexture); +void FontAsset::save(ArchiveBuffer& buffer) const { Serialization::save(buffer, glyphs); } - for (uint32 depth = 0; depth < usedTextures[x]->getDepth(); ++depth) { - for (uint32 face = 0; face < usedTextures[x]->getNumFaces(); ++face) { - // technically, downloading cant be const, because we have to allocate temporary buffers and change layouts - // but practically the texture stays the same - const_cast(*(usedTextures[x]))->download(0, depth, face, textureData); - ktxTexture_SetImageFromMemory(ktxTexture(kTexture), 0, depth, face, textureData.data(), textureData.size()); - } - } - char writer[100]; - snprintf(writer, sizeof(writer), "%s version %s", "SeeleEngine", "0.0.1"); - ktxHashList_AddKVPair(&kTexture->kvDataHead, KTX_WRITER_KEY, (ktx_uint32_t)strlen(writer) + 1, writer); - - ktxTexture2_TranscodeBasis(kTexture, KTX_TTF_ASTC_4x4_RGBA, 0); - - ktx_uint8_t* texData; - ktx_size_t texSize; - ktxTexture_WriteToMemory(ktxTexture(kTexture), &texData, &texSize); - - Array rawData(texSize); - std::memcpy(rawData.data(), texData, texSize); - - free(texData); - - Serialization::save(buffer, rawData); - } -} - -void FontAsset::load(ArchiveBuffer& buffer) { - Serialization::load(buffer, glyphs); - size_t numTextures; - Serialization::load(buffer, numTextures); - for (uint64 x = 0; x < numTextures; ++x) { - Array rawTex; - Serialization::load(buffer, rawTex); - - ktxTexture2* kTexture; - ktxTexture2_CreateFromMemory(rawTex.data(), rawTex.size(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &kTexture); - - ktxTexture2_TranscodeBasis(kTexture, KTX_TTF_BC7_RGBA, 0); - - TextureCreateInfo createInfo = { - .sourceData = - { - .size = ktxTexture_GetDataSize(ktxTexture(kTexture)), - .data = ktxTexture_GetData(ktxTexture(kTexture)), - .owner = Gfx::QueueType::GRAPHICS, - }, - .format = (Gfx::SeFormat)kTexture->vkFormat, - .width = kTexture->baseWidth, - .height = kTexture->baseHeight, - .depth = kTexture->baseDepth, - .layers = kTexture->numFaces, - .elements = kTexture->numLayers, - .useMip = true, - .usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT, - }; - - Gfx::OTexture2D texture = buffer.getGraphics()->createTexture2D(createInfo); - usedTextures.add(std::move(texture)); - - ktxTexture_Destroy(ktxTexture(kTexture)); - } -} - -void Seele::FontAsset::setUsedTextures(Array _usedTextures) { usedTextures = std::move(_usedTextures); } +void FontAsset::load(ArchiveBuffer& buffer) { Serialization::load(buffer, glyphs); } void FontAsset::Glyph::save(ArchiveBuffer& buffer) const { - Serialization::save(buffer, textureIndex); Serialization::save(buffer, size); Serialization::save(buffer, bearing); Serialization::save(buffer, advance); + Serialization::save(buffer, textureData); } void FontAsset::Glyph::load(ArchiveBuffer& buffer) { - Serialization::load(buffer, textureIndex); Serialization::load(buffer, size); Serialization::load(buffer, bearing); Serialization::load(buffer, advance); + Serialization::load(buffer, textureData); + texture = buffer.getGraphics()->createTexture2D(TextureCreateInfo{ + .sourceData = + { + .size = textureData.size(), + .data = textureData.data(), + }, + .format = Gfx::SE_FORMAT_R8_UNORM, + .width = size.x, + .height = size.y, + .name = "FontGlyph", + }); } diff --git a/src/Engine/Asset/FontAsset.h b/src/Engine/Asset/FontAsset.h index a17a6de..19888cc 100644 --- a/src/Engine/Asset/FontAsset.h +++ b/src/Engine/Asset/FontAsset.h @@ -2,6 +2,7 @@ #include "Asset.h" #include "Containers/Map.h" #include "Math/Math.h" +#include namespace Seele { DECLARE_NAME_REF(Gfx, Texture2D) @@ -15,19 +16,17 @@ class FontAsset : public Asset { virtual void load(ArchiveBuffer& buffer) override; struct Glyph { - uint32 textureIndex; - IVector2 size; - IVector2 bearing; - uint32 advance; + UVector2 size = {}; + UVector2 bearing = {}; + uint32 advance = 0; + Array textureData; + Gfx::OTexture2D texture = nullptr; void save(ArchiveBuffer& buffer) const; void load(ArchiveBuffer& buffer); }; - const Map getGlyphData() const { return glyphs; } - Gfx::PTexture2D getTexture(uint32 index) { return usedTextures[index]; } - void setUsedTextures(Array _usedTextures); + const Glyph& getGlyphData(char c) const { return glyphs[c]; } private: - Array usedTextures; Map glyphs; friend class FontLoader; }; diff --git a/src/Engine/Asset/MeshAsset.cpp b/src/Engine/Asset/MeshAsset.cpp index b290566..fac343e 100644 --- a/src/Engine/Asset/MeshAsset.cpp +++ b/src/Engine/Asset/MeshAsset.cpp @@ -3,7 +3,6 @@ #include "Graphics/Graphics.h" #include "Graphics/Mesh.h" - using namespace Seele; MeshAsset::MeshAsset() {} @@ -14,7 +13,8 @@ MeshAsset::~MeshAsset() {} void MeshAsset::save(ArchiveBuffer& buffer) const { Serialization::save(buffer, meshes); } -void MeshAsset::load(ArchiveBuffer& buffer) { Serialization::load(buffer, meshes); +void MeshAsset::load(ArchiveBuffer& buffer) { + Serialization::load(buffer, meshes); byteSize = 0; for (const auto& mesh : meshes) { byteSize += mesh->getCPUSize(); diff --git a/src/Engine/CMakeLists.txt b/src/Engine/CMakeLists.txt index b083a6c..abbf671 100644 --- a/src/Engine/CMakeLists.txt +++ b/src/Engine/CMakeLists.txt @@ -5,7 +5,7 @@ target_sources(Engine Game.h MinimalEngine.h ThreadPool.h - ThreadPool.cpp) + ThreadPool.cpp "../../tests/Engine/UI/Element.cpp") target_sources(Engine PUBLIC FILE_SET HEADERS diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index 2117048..aa549de 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -105,7 +105,8 @@ class Graphics { virtual void copyBuffer(Gfx::PShaderBuffer src, Gfx::PShaderBuffer dst) = 0; - bool supportMeshShading() const { return meshShadingEnabled; } + constexpr bool supportMeshShading() const { return meshShadingEnabled; } + constexpr bool supportRayTracing() const { return rayTracingEnabled; } // Ray Tracing virtual OBottomLevelAS createBottomLevelAccelerationStructure(const BottomLevelASCreateInfo& createInfo) = 0; @@ -122,6 +123,7 @@ class Graphics { QueueFamilyMapping queueMapping; OShaderCompiler shaderCompiler; bool meshShadingEnabled = false; + bool rayTracingEnabled = false; friend class Window; }; DEFINE_REF(Graphics) diff --git a/src/Engine/Graphics/Mesh.cpp b/src/Engine/Graphics/Mesh.cpp index f564c47..7c0249e 100644 --- a/src/Engine/Graphics/Mesh.cpp +++ b/src/Engine/Graphics/Mesh.cpp @@ -30,10 +30,12 @@ void Mesh::load(ArchiveBuffer& buffer) { referencedMaterial = AssetRegistry::findMaterialInstance(refFolder, refId); id = vertexData->allocateVertexData(vertexCount); byteSize = vertexData->deserializeMesh(id, buffer); - blas = buffer.getGraphics()->createBottomLevelAccelerationStructure(Gfx::BottomLevelASCreateInfo{ - .mesh = this, - }); - vertexData->registerBottomLevelAccelerationStructure(blas); + if (buffer.getGraphics()->supportRayTracing()) { + blas = buffer.getGraphics()->createBottomLevelAccelerationStructure(Gfx::BottomLevelASCreateInfo{ + .mesh = this, + }); + vertexData->registerBottomLevelAccelerationStructure(blas); + } } uint64 Mesh::getCPUSize() const { diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index bb9eb17..c65c12b 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -25,7 +25,7 @@ void Seele::addDebugVertex(DebugVertex vert) { gDebugVertices.add(vert); } void Seele::addDebugVertices(Array verts) { gDebugVertices.addAll(verts); } -BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) { +BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics), scene(scene) { //waterRenderer = new WaterRenderer(graphics, scene, viewParamsLayout); basePassLayout = graphics->createPipelineLayout("BasePassLayout"); diff --git a/src/Engine/Graphics/RenderPass/BasePass.h b/src/Engine/Graphics/RenderPass/BasePass.h index b0a5b65..361dc5b 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.h +++ b/src/Engine/Graphics/RenderPass/BasePass.h @@ -78,6 +78,7 @@ class BasePass : public RenderPass { } skyboxData; Gfx::OUniformBuffer skyboxBuffer; Component::Skybox skybox; + PScene scene; }; DEFINE_REF(BasePass) } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/CMakeLists.txt b/src/Engine/Graphics/RenderPass/CMakeLists.txt index c5916c1..06165ce 100644 --- a/src/Engine/Graphics/RenderPass/CMakeLists.txt +++ b/src/Engine/Graphics/RenderPass/CMakeLists.txt @@ -17,8 +17,6 @@ target_sources(Engine RenderPass.cpp TerrainRenderer.h TerrainRenderer.cpp - TextPass.h - TextPass.cpp UIPass.h UIPass.cpp VisibilityPass.h @@ -38,6 +36,5 @@ target_sources(Engine RenderGraphResources.h RenderPass.h TerrainRenderer.h - TextPass.h UIPass.h VisibilityPass.h) \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp index d88047a..7bec0eb 100644 --- a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp +++ b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp @@ -3,7 +3,7 @@ using namespace Seele; -CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) { +CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics), scene(scene) { depthPrepassLayout = graphics->createPipelineLayout("CachedDepthLayout"); depthPrepassLayout->addDescriptorLayout(viewParamsLayout); depthPrepassLayout->addPushConstants(Gfx::SePushConstantRange{ diff --git a/src/Engine/Graphics/RenderPass/CachedDepthPass.h b/src/Engine/Graphics/RenderPass/CachedDepthPass.h index f5fabf9..cb76d79 100644 --- a/src/Engine/Graphics/RenderPass/CachedDepthPass.h +++ b/src/Engine/Graphics/RenderPass/CachedDepthPass.h @@ -25,6 +25,7 @@ class CachedDepthPass : public RenderPass { Gfx::OTimestampQuery timestamps; Gfx::PShaderBuffer cullingBuffer; + PScene scene; }; DEFINE_REF(CachedDepthPass) } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp b/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp index 0794df0..c0d3343 100644 --- a/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp @@ -4,7 +4,7 @@ using namespace Seele; -DepthCullingPass::DepthCullingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) { +DepthCullingPass::DepthCullingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics), scene(scene) { depthAttachmentLayout = graphics->createDescriptorLayout("pDepthAttachment"); depthAttachmentLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, diff --git a/src/Engine/Graphics/RenderPass/DepthCullingPass.h b/src/Engine/Graphics/RenderPass/DepthCullingPass.h index 8daadc9..5479a2d 100644 --- a/src/Engine/Graphics/RenderPass/DepthCullingPass.h +++ b/src/Engine/Graphics/RenderPass/DepthCullingPass.h @@ -44,6 +44,7 @@ class DepthCullingPass : public RenderPass { Gfx::PComputePipeline depthReduceLevel; Gfx::PShaderBuffer cullingBuffer; + PScene scene; }; DEFINE_REF(DepthCullingPass) } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index 84b9a34..f715dd8 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -8,7 +8,7 @@ using namespace Seele; -LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {} +LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics), scene(scene) {} LightCullingPass::~LightCullingPass() {} diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.h b/src/Engine/Graphics/RenderPass/LightCullingPass.h index d6f2a71..c22d015 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.h +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.h @@ -58,6 +58,8 @@ class LightCullingPass : public RenderPass { Gfx::PComputePipeline cullingEnabledPipeline; Gfx::OPipelineStatisticsQuery query; Gfx::PTimestampQuery timestamps; + + PScene scene; }; DEFINE_REF(LightCullingPass) } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/RayTracingPass.cpp b/src/Engine/Graphics/RenderPass/RayTracingPass.cpp index f740f81..d5d9712 100644 --- a/src/Engine/Graphics/RenderPass/RayTracingPass.cpp +++ b/src/Engine/Graphics/RenderPass/RayTracingPass.cpp @@ -14,7 +14,7 @@ struct SampleParams { uint32 samplesPerPixel; }; -RayTracingPass::RayTracingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) { +RayTracingPass::RayTracingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics), scene(scene) { paramsLayout = graphics->createDescriptorLayout("pRayTracingParams"); paramsLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, diff --git a/src/Engine/Graphics/RenderPass/RayTracingPass.h b/src/Engine/Graphics/RenderPass/RayTracingPass.h index 5866142..775ec62 100644 --- a/src/Engine/Graphics/RenderPass/RayTracingPass.h +++ b/src/Engine/Graphics/RenderPass/RayTracingPass.h @@ -25,5 +25,6 @@ class RayTracingPass : public RenderPass { Gfx::OMissShader miss; Gfx::PRayTracingPipeline pipeline; Gfx::OTopLevelAS tlas; + PScene scene; }; } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/RenderPass.cpp b/src/Engine/Graphics/RenderPass/RenderPass.cpp index ae67932..baa7386 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.cpp +++ b/src/Engine/Graphics/RenderPass/RenderPass.cpp @@ -2,7 +2,7 @@ using namespace Seele; -RenderPass::RenderPass(Gfx::PGraphics graphics, PScene scene) : graphics(graphics), scene(scene) { +RenderPass::RenderPass(Gfx::PGraphics graphics) : graphics(graphics) { viewParamsLayout = graphics->createDescriptorLayout("pViewParams"); viewParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, diff --git a/src/Engine/Graphics/RenderPass/RenderPass.h b/src/Engine/Graphics/RenderPass/RenderPass.h index 0c2a425..bb8ac21 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.h +++ b/src/Engine/Graphics/RenderPass/RenderPass.h @@ -14,7 +14,7 @@ DECLARE_NAME_REF(Gfx, Graphics) DECLARE_NAME_REF(Gfx, RenderPass) class RenderPass { public: - RenderPass(Gfx::PGraphics graphics, PScene scene); + RenderPass(Gfx::PGraphics graphics); RenderPass(RenderPass&&) = default; RenderPass& operator=(RenderPass&&) = default; virtual ~RenderPass(); @@ -71,7 +71,6 @@ class RenderPass { Gfx::ORenderPass renderPass; Gfx::PGraphics graphics; Gfx::PViewport viewport; - PScene scene; }; DEFINE_REF(RenderPass) template diff --git a/src/Engine/Graphics/RenderPass/TextPass.cpp b/src/Engine/Graphics/RenderPass/TextPass.cpp deleted file mode 100644 index 3f9aa67..0000000 --- a/src/Engine/Graphics/RenderPass/TextPass.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include "TextPass.h" -#include "Graphics/Command.h" -#include "Graphics/Enums.h" -#include "Graphics/Graphics.h" -#include "Graphics/RenderTarget.h" -#include "RenderGraph.h" - -using namespace Seele; - -TextPass::TextPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {} - -TextPass::~TextPass() {} - -void TextPass::beginFrame(const Component::Camera& cam) { - RenderPass::beginFrame(cam); - for (TextRender& render : texts) { - FontData& fd = getFontData(render.font); - TextResources& res = textResources[render.font].add(); - Array instanceData; - float x = render.position.x; - float y = render.position.y; - for (uint32 c : render.text) { - const GlyphData& glyph = fd.glyphDataSet[fd.characterToGlyphIndex[c]]; - Vector2 bearing = glyph.bearing; - Vector2 size = glyph.size; - float xpos = x + bearing.x * render.scale; - float ypos = y - (size.y - bearing.y) * render.scale; - - float w = size.x * render.scale; - float h = size.y * render.scale; - - instanceData.add(GlyphInstanceData{ - .position = Vector2(xpos, ypos), - .widthHeight = Vector2(w, h), - .glyphIndex = fd.characterToGlyphIndex[c], - }); - x += (glyph.advance >> 6) * render.scale; - } - res.instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ - .sourceData = - { - .size = static_cast(instanceData.size() * sizeof(GlyphInstanceData)), - .data = reinterpret_cast(instanceData.data()), - }, - .numElements = instanceData.size(), - }); - - res.textureArraySet = fd.textureArraySet; - - res.textData = { - .textColor = render.textColor, - .scale = render.scale, - }; - } - auto proj = viewport->getProjectionMatrix(); - projectionBuffer->updateContents(0, sizeof(Matrix4), &proj); - generalSet->updateBuffer(1, 0, projectionBuffer); - generalSet->writeChanges(); - // co_return; -} - -void TextPass::render() { - graphics->beginRenderPass(renderPass); - Array commands; - for (const auto& [fontAsset, res] : textResources) { - Gfx::ORenderCommand command = graphics->createRenderCommand("TextPassCommand"); - command->setViewport(viewport); - command->bindPipeline(pipeline); - for (const auto& resource : res) { - command->bindDescriptor({generalSet, resource.textureArraySet}); - // command->bindVertexBuffer({resource.vertexBuffer}); - - command->pushConstants(Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(TextData), - &resource.textData); - // command->draw(4, static_cast(resource.vertexBuffer->getNumVertices()), 0, 0); - } - commands.add(std::move(command)); - } - graphics->executeCommands(std::move(commands)); - graphics->endRenderPass(); - textResources.clear(); - // co_return; -} - -void TextPass::endFrame() { - // co_return; -} - -void TextPass::publishOutputs() {} - -void TextPass::createRenderPass() { - renderTarget = resources->requestRenderTarget("UIPASS_COLOR"); - depthAttachment = resources->requestRenderTarget("UIPASS_DEPTH"); - - ShaderCompilationInfo createInfo = { - .name = "TextVertex", - .modules = {"TextPass"}, - .entryPoints = {{"vertexMain", "TextPass"}, {"fragmentMain", "TextFragment"}}, - }; - graphics->beginShaderCompilation(createInfo); - vertexShader = graphics->createVertexShader({0}); - fragmentShader = graphics->createFragmentShader({1}); - - generalLayout = graphics->createDescriptorLayout("pRender"); - generalLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = 0, - .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .uniformLength = sizeof(Matrix4), - }); - generalLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = 1, - .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER, - }); - generalLayout->create(); - - textureArrayLayout = graphics->createDescriptorLayout("pGlyphTextures"); - textureArrayLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = 0, - .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .textureType = Gfx::SE_IMAGE_VIEW_TYPE_2D_ARRAY, - .descriptorCount = 256, - .bindingFlags = Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT, - }); - textureArrayLayout->create(); - - projectionBuffer = graphics->createUniformBuffer({ - .sourceData = - { - .size = sizeof(Matrix4), - .data = nullptr, - }, - }); - - glyphSampler = 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, - }); - - generalSet = generalLayout->allocateDescriptorSet(); - generalSet->updateBuffer(0, 0, projectionBuffer); - generalSet->updateSampler(1, 0, glyphSampler); - generalSet->writeChanges(); - - pipelineLayout = graphics->createPipelineLayout(); - pipelineLayout->addDescriptorLayout(generalLayout); - pipelineLayout->addDescriptorLayout(textureArrayLayout); - pipelineLayout->addPushConstants( - {.stageFlags = Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, .offset = 0, .size = sizeof(TextData)}); - pipelineLayout->create(); - - Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{.colorAttachments = {renderTarget}, .depthAttachment = depthAttachment}; - renderPass = graphics->createRenderPass(std::move(layout), {}, viewport); - - Gfx::LegacyPipelineCreateInfo pipelineInfo; - pipelineInfo.vertexShader = vertexShader; - pipelineInfo.fragmentShader = fragmentShader; - pipelineInfo.renderPass = renderPass; - pipelineInfo.pipelineLayout = pipelineLayout; - pipelineInfo.rasterizationState.cullMode = Gfx::SE_CULL_MODE_NONE; - pipelineInfo.colorBlend.attachmentCount = 1; - pipelineInfo.colorBlend.blendAttachments[0].blendEnable = true; - pipelineInfo.colorBlend.blendAttachments[0].colorWriteMask = - Gfx::SE_COLOR_COMPONENT_R_BIT | Gfx::SE_COLOR_COMPONENT_G_BIT | Gfx::SE_COLOR_COMPONENT_B_BIT | Gfx::SE_COLOR_COMPONENT_A_BIT; - pipelineInfo.colorBlend.blendAttachments[0].srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; - pipelineInfo.colorBlend.blendAttachments[0].dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - pipelineInfo.colorBlend.blendAttachments[0].alphaBlendOp = Gfx::SE_BLEND_OP_ADD; - pipelineInfo.colorBlend.blendAttachments[0].srcAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - pipelineInfo.colorBlend.blendAttachments[0].dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_ZERO; - pipelineInfo.colorBlend.blendAttachments[0].alphaBlendOp = Gfx::SE_BLEND_OP_ADD; - pipelineInfo.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; - - pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); -} -TextPass::FontData& TextPass::getFontData(PFontAsset font) { - if (fontData.exists(font)) { - return fontData[font]; - } - const auto& fontGlyphs = font->getGlyphData(); - FontData& fd = fontData[font]; - Array glyphData; - Array textures; - glyphData.reserve(fontGlyphs.size()); - for (const auto& [key, value] : fontGlyphs) { - fd.characterToGlyphIndex[key] = static_cast(glyphData.size()); - GlyphData& gd = glyphData.add(); - gd.bearing = value.bearing; - gd.size = value.size; - gd.advance = value.advance; - textures.add(font->getTexture(value.textureIndex)); - } - fd.glyphDataSet = glyphData; - - textureArrayLayout->reset(); - fd.textureArraySet = textureArrayLayout->allocateDescriptorSet(); - for (uint32 i = 0; i < textures.size(); ++i) { - fd.textureArraySet->updateTexture(0, i, textures[i]); - } - fd.textureArraySet->writeChanges(); - return fontData[font]; -} diff --git a/src/Engine/Graphics/RenderPass/TextPass.h b/src/Engine/Graphics/RenderPass/TextPass.h deleted file mode 100644 index e4c1cd8..0000000 --- a/src/Engine/Graphics/RenderPass/TextPass.h +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once -#include "Asset/FontAsset.h" -#include "Graphics/Shader.h" -#include "RenderPass.h" -#include "UI/RenderHierarchy.h" - - -namespace Seele { -DECLARE_NAME_REF(Gfx, Texture2D) -DECLARE_NAME_REF(Gfx, ShaderBuffer) -struct TextRender { - std::string text; - PFontAsset font; - Vector4 textColor; - Vector2 position; - float scale; -}; -class TextPass : public RenderPass { - public: - TextPass(Gfx::PGraphics graphics, PScene scene); - TextPass(TextPass&&) = default; - TextPass& operator=(TextPass&&) = default; - virtual ~TextPass(); - virtual void beginFrame(const Component::Camera& cam) override; - virtual void render() override; - virtual void endFrame() override; - virtual void publishOutputs() override; - virtual void createRenderPass() override; - - private: - struct GlyphData { - Vector2 bearing; - Vector2 size; - uint32 advance; - }; - struct GlyphInstanceData { - Vector2 position; - Vector2 widthHeight; - uint32 glyphIndex; - }; - struct TextData { - Vector4 textColor; - float scale; - }; - struct FontData { - Gfx::PDescriptorSet textureArraySet; - Array glyphDataSet; - Map characterToGlyphIndex; - }; - FontData& getFontData(PFontAsset font); - Map fontData; - - struct TextResources { - Gfx::PShaderBuffer instanceBuffer; - Gfx::PDescriptorSet textureArraySet; - TextData textData; - }; - Map> textResources; - - Gfx::RenderTargetAttachment renderTarget; - Gfx::RenderTargetAttachment depthAttachment; - - Gfx::ODescriptorLayout generalLayout; - Gfx::ODescriptorLayout textureArrayLayout; - - Gfx::PDescriptorSet generalSet; - - Gfx::OUniformBuffer projectionBuffer; - Gfx::OSampler glyphSampler; - - Gfx::OVertexShader vertexShader; - Gfx::OFragmentShader fragmentShader; - Gfx::OPipelineLayout pipelineLayout; - Gfx::PGraphicsPipeline pipeline; - Array texts; -}; -DEFINE_REF(TextPass); -} // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/UIPass.cpp b/src/Engine/Graphics/RenderPass/UIPass.cpp index 98f9376..32f3a9c 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.cpp +++ b/src/Engine/Graphics/RenderPass/UIPass.cpp @@ -1,4 +1,5 @@ #include "UIPass.h" +#include "Asset/AssetRegistry.h" #include "Graphics/Command.h" #include "Graphics/Enums.h" #include "Graphics/Graphics.h" @@ -7,53 +8,100 @@ using namespace Seele; -UIPass::UIPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {} +UIPass::UIPass(Gfx::PGraphics graphics, UI::PSystem system) : RenderPass(graphics) { + glyphInstanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{.name = "GlyphInstanceBuffer"}); + textDescriptorLayout = graphics->createDescriptorLayout("pText"); + textDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .binding = 0, + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, + }); + textDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .binding = 1, + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER, + }); + textDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .binding = 2, + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .descriptorCount = 1024, + }); + textPipelineLayout = graphics->createPipelineLayout("TextPipeline"); + textPipelineLayout->addDescriptorLayout(viewParamsLayout); + textPipelineLayout->addDescriptorLayout(textDescriptorLayout); + + uiPipelineLayout = graphics->createPipelineLayout("UIPipeline"); + uiPipelineLayout->addDescriptorLayout(viewParamsLayout); + // todo: + texts.add(TextRender{ + .text = "TestText123", + .font = AssetRegistry::findFont("", "arial"), + .fontSize = 12, + .position = Vector2(0, 100), + }); +} UIPass::~UIPass() {} void UIPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); - VertexBufferCreateInfo info = { - .sourceData = - { - .size = (uint32)(sizeof(UI::RenderElementStyle) * renderElements.size()), - .data = (uint8*)renderElements.data(), - }, - .vertexSize = sizeof(UI::RenderElementStyle), - .numVertices = (uint32)renderElements.size(), - }; - elementBuffer = graphics->createVertexBuffer(info); - uint32 numTextures = static_cast(usedTextures.size()); - numTexturesBuffer->updateContents(0, sizeof(uint32), &numTextures); - descriptorSet->updateBuffer(2, 0, numTexturesBuffer); - for (uint32 i = 0; i < usedTextures.size(); ++i) { - descriptorSet->updateTexture(3, i, usedTextures[i]); + glyphs.clear(); + usedTextures.clear(); + for (TextRender& render : texts) { + TextResources& res = textResources[render.font].add(); + float x = render.position.x * viewport->getContentScaleX(); + float y = (viewport->getHeight() - render.position.y) * viewport->getContentScaleY(); + for (uint32 c : render.text) { + const FontAsset::Glyph& glyph = render.font->getGlyphData(c); + Vector2 bearing = Vector2(glyph.bearing) * viewport->getContentScaleX(); + Vector2 size = Vector2(glyph.size) * viewport->getContentScaleY(); + float xpos = x + glyph.bearing.x; + float ypos = y + (size.y - bearing.y); + + float w = size.x; + float h = size.y; + + glyphs.add(GlyphInstanceData{ + .x = xpos, + .y = ypos, + .width = w, + .height = h, + .glyphIndex = (uint32)usedTextures.size(), + }); + usedTextures.add(glyph.texture); + x += glyph.advance >> 6; + } } - descriptorSet->writeChanges(); - // co_return; + glyphInstanceBuffer->rotateBuffer(sizeof(GlyphInstanceData) * glyphs.size()); + glyphInstanceBuffer->updateContents(0, sizeof(GlyphInstanceData) * glyphs.size(), glyphs.data()); + glyphInstanceBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, + Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_VERTEX_SHADER_BIT); + textDescriptorLayout->reset(); + textDescriptorSet = textDescriptorLayout->allocateDescriptorSet(); + textDescriptorSet->updateBuffer(0, 0, glyphInstanceBuffer); + textDescriptorSet->updateSampler(1, 0, glyphSampler); + for (uint32 i = 0; i < usedTextures.size(); ++i) { + textDescriptorSet->updateTexture(2, i, usedTextures[i]); + } + textDescriptorSet->writeChanges(); } void UIPass::render() { graphics->beginRenderPass(renderPass); - Gfx::ORenderCommand command = graphics->createRenderCommand("UIPassCommand"); - command->setViewport(viewport); - command->bindPipeline(pipeline); - command->bindVertexBuffer({elementBuffer}); - command->bindDescriptor(descriptorSet); - command->draw(4, static_cast(renderElements.size()), 0, 0); Array commands; + Gfx::ORenderCommand command = graphics->createRenderCommand("TextPassCommand"); + command->setViewport(viewport); + command->bindPipeline(textPipeline); + command->bindDescriptor({viewParamsSet, textDescriptorSet}); + command->draw(4, glyphs.size(), 0, 0); commands.add(std::move(command)); graphics->executeCommands(std::move(commands)); graphics->endRenderPass(); - - // co_return; } -void UIPass::endFrame() { - // co_return; -} +void UIPass::endFrame() {} -void UIPass::publishOutputs() { +void UIPass::publishOutputs() {} + +void UIPass::createRenderPass() { TextureCreateInfo depthBufferInfo = { .format = Gfx::SE_FORMAT_D32_SFLOAT, .width = viewport->getWidth(), @@ -65,98 +113,69 @@ void UIPass::publishOutputs() { depthAttachment = Gfx::RenderTargetAttachment(depthBuffer, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE); - resources->registerRenderPassOutput("UIPASS_DEPTH", depthAttachment); + depthAttachment.clear.depthStencil.depth = 0; - TextureCreateInfo colorBufferInfo = { - .format = Gfx::SE_FORMAT_R16G16B16A16_SFLOAT, - .width = viewport->getWidth(), - .height = viewport->getHeight(), - .usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + colorAttachment = Gfx::RenderTargetAttachment(viewport, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE); + colorAttachment.clear.color = {{1.0f, 1.0f, 1.0f, 1.0f}}; + + Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{ + .colorAttachments = {colorAttachment}, + .depthAttachment = depthAttachment, }; - colorBuffer = graphics->createTexture2D(colorBufferInfo); - renderTarget = Gfx::RenderTargetAttachment(colorBuffer, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, - Gfx::SE_ATTACHMENT_STORE_OP_STORE); - renderTarget.clear.color = {{0.0f, 0.0f, 0.0f, 1.0f}}; - resources->registerRenderPassOutput("UIPASS_COLOR", renderTarget); -} + renderPass = graphics->createRenderPass(std::move(layout), {}, viewport, "TextPass"); -void UIPass::createRenderPass() { - ShaderCompilationInfo createInfo = { + graphics->beginShaderCompilation(ShaderCompilationInfo{ + .name = "TextVertex", + .modules = {"TextPass"}, + .entryPoints = {{"vertexMain", "TextPass"}, {"fragmentMain", "TextPass"}}, + .rootSignature = textPipelineLayout, + }); + textPipelineLayout->create(); + textVertexShader = graphics->createVertexShader({0}); + textFragmentShader = graphics->createFragmentShader({1}); + + glyphSampler = 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, + }); + + Gfx::LegacyPipelineCreateInfo pipelineInfo = { + .topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, + .vertexShader = textVertexShader, + .fragmentShader = textFragmentShader, + .renderPass = renderPass, + .pipelineLayout = textPipelineLayout, + .rasterizationState = + { + .cullMode = Gfx::SE_CULL_MODE_NONE, + }, + .colorBlend = + { + + .attachmentCount = 1, + .blendAttachments = {{ + .blendEnable = true, + .srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA, + .dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .srcAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_ZERO, + .alphaBlendOp = Gfx::SE_BLEND_OP_ADD, + .colorWriteMask = Gfx::SE_COLOR_COMPONENT_R_BIT | Gfx::SE_COLOR_COMPONENT_G_BIT | Gfx::SE_COLOR_COMPONENT_B_BIT | + Gfx::SE_COLOR_COMPONENT_A_BIT, + }}, + }, + }; + + textPipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); + graphics->beginShaderCompilation(ShaderCompilationInfo{ .name = "UIVertex", .modules = {"UIPass"}, - .entryPoints = - { - {"vertexMain", "UIPass"}, - {"fragmentMain", "UIFragment"}, - }, - }; - graphics->beginShaderCompilation(createInfo); - vertexShader = graphics->createVertexShader({0}); - fragmentShader = graphics->createFragmentShader({1}); - - descriptorLayout = graphics->createDescriptorLayout("pParams"); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = 0, - .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .uniformLength = sizeof(Matrix4), + .entryPoints = {{"vertexMain", "UIPass"}, {"fragmentMain", "UIPass"}}, + .rootSignature = uiPipelineLayout, }); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = 1, - .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER, - }); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = 2, - .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .uniformLength = sizeof(uint32) - }); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = 3, - .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .textureType = Gfx::SE_IMAGE_VIEW_TYPE_2D_ARRAY, - .descriptorCount = 256, - .bindingFlags = Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT | Gfx::SE_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT, - }); - descriptorLayout->create(); - - Matrix4 projectionMatrix = glm::ortho(0, 1, 1, 0); - - Gfx::OUniformBuffer uniformBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ - .sourceData = - { - .size = sizeof(Matrix4), - .data = (uint8*)&projectionMatrix, - }, - }); - Gfx::OSampler backgroundSampler = graphics->createSampler({}); - - numTexturesBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ - .sourceData = - { - .size = sizeof(uint32), - .data = nullptr, - }, - }); - - descriptorSet = descriptorLayout->allocateDescriptorSet(); - descriptorSet->updateBuffer(0, 0, uniformBuffer); - descriptorSet->updateSampler(1, 0, backgroundSampler); - descriptorSet->writeChanges(); - - pipelineLayout = graphics->createPipelineLayout(); - pipelineLayout->addDescriptorLayout(descriptorLayout); - pipelineLayout->create(); - - Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{.colorAttachments = {renderTarget}, .depthAttachment = depthAttachment}; - renderPass = graphics->createRenderPass(std::move(layout), {}, viewport); - - Gfx::LegacyPipelineCreateInfo pipelineInfo; - pipelineInfo.vertexShader = vertexShader; - pipelineInfo.fragmentShader = fragmentShader; - pipelineInfo.renderPass = renderPass; - pipelineInfo.pipelineLayout = pipelineLayout; - pipelineInfo.rasterizationState.cullMode = Gfx::SE_CULL_MODE_NONE; - pipelineInfo.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; - - pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); + uiVertexShader = graphics->createVertexShader({0}); + uiFragmentShader = graphics->createFragmentShader({1}); } diff --git a/src/Engine/Graphics/RenderPass/UIPass.h b/src/Engine/Graphics/RenderPass/UIPass.h index 055ee06..1c9ebce 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.h +++ b/src/Engine/Graphics/RenderPass/UIPass.h @@ -1,15 +1,22 @@ #pragma once #include "Graphics/Shader.h" #include "RenderPass.h" -#include "UI/RenderHierarchy.h" - +#include "Asset/FontAsset.h" +#include "UI/System.h" namespace Seele { DECLARE_NAME_REF(Gfx, Texture2D) DECLARE_NAME_REF(Gfx, RenderTargetAttachment) +struct TextRender { + std::string text; + PFontAsset font; + uint32 fontSize; + Vector4 textColor; + Vector2 position; +}; class UIPass : public RenderPass { public: - UIPass(Gfx::PGraphics graphics, PScene scene); + UIPass(Gfx::PGraphics graphics, UI::PSystem system); UIPass(UIPass&&) = default; UIPass& operator=(UIPass&&) = default; virtual ~UIPass(); @@ -20,23 +27,54 @@ class UIPass : public RenderPass { virtual void createRenderPass() override; private: - Gfx::RenderTargetAttachment renderTarget; - Gfx::OTexture2D colorBuffer; + struct GlyphData { + Vector2 bearing; + Vector2 size; + uint32 advance; + }; + struct GlyphInstanceData { + float x; + float y; + float width; + float height; + uint32 glyphIndex; + }; + struct TextData { + Vector4 textColor; + float scale; + }; + + struct TextResources { + Gfx::PShaderBuffer instanceBuffer; + Gfx::PDescriptorSet textureArraySet; + TextData textData; + }; + Map> textResources; + + Gfx::RenderTargetAttachment colorAttachment; Gfx::RenderTargetAttachment depthAttachment; Gfx::OTexture2D depthBuffer; - Gfx::ODescriptorLayout descriptorLayout; - Gfx::PDescriptorSet descriptorSet; + Gfx::ODescriptorLayout textDescriptorLayout; + Gfx::PDescriptorSet textDescriptorSet; - Gfx::OUniformBuffer numTexturesBuffer; - Gfx::OVertexBuffer elementBuffer; + Gfx::OVertexShader textVertexShader; + Gfx::OFragmentShader textFragmentShader; + Gfx::OPipelineLayout textPipelineLayout; + Gfx::PGraphicsPipeline textPipeline; - Gfx::OVertexShader vertexShader; - Gfx::OFragmentShader fragmentShader; - Gfx::PGraphicsPipeline pipeline; - Gfx::OPipelineLayout pipelineLayout; + Gfx::ODescriptorLayout uiDescriptorLayout; + Gfx::PDescriptorSet uiDescriptorSet; - Array renderElements; + Gfx::OVertexShader uiVertexShader; + Gfx::OFragmentShader uiFragmentShader; + Gfx::OPipelineLayout uiPipelineLayout; + Gfx::PGraphicsPipeline uiPipeline; + + Array texts; + Array glyphs; + Gfx::OShaderBuffer glyphInstanceBuffer; + Gfx::OSampler glyphSampler; Array usedTextures; }; DEFINE_REF(UIPass); diff --git a/src/Engine/Graphics/RenderPass/VisibilityPass.cpp b/src/Engine/Graphics/RenderPass/VisibilityPass.cpp index 09084e7..da7a64d 100644 --- a/src/Engine/Graphics/RenderPass/VisibilityPass.cpp +++ b/src/Engine/Graphics/RenderPass/VisibilityPass.cpp @@ -3,7 +3,7 @@ using namespace Seele; -VisibilityPass::VisibilityPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {} +VisibilityPass::VisibilityPass(Gfx::PGraphics graphics) : RenderPass(graphics) {} VisibilityPass::~VisibilityPass() {} diff --git a/src/Engine/Graphics/RenderPass/VisibilityPass.h b/src/Engine/Graphics/RenderPass/VisibilityPass.h index 75c681e..12c21ff 100644 --- a/src/Engine/Graphics/RenderPass/VisibilityPass.h +++ b/src/Engine/Graphics/RenderPass/VisibilityPass.h @@ -5,7 +5,7 @@ namespace Seele { class VisibilityPass : public RenderPass { public: - VisibilityPass(Gfx::PGraphics graphics, PScene scene); + VisibilityPass(Gfx::PGraphics graphics); VisibilityPass(VisibilityPass&&) = default; VisibilityPass& operator=(VisibilityPass&&) = default; virtual ~VisibilityPass(); diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index 3c1499b..2ff3536 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -142,6 +142,7 @@ Graphics::~Graphics() { void Graphics::init(GraphicsInitializer initInfo) { initInstance(initInfo); + //setupDebugCallback(); pickPhysicalDevice(); createDevice(initInfo); VmaAllocatorCreateInfo createInfo = { @@ -437,6 +438,8 @@ Gfx::OTopLevelAS Graphics::createTopLevelAccelerationStructure(const Gfx::TopLev } void Graphics::buildBottomLevelAccelerationStructures(Array data) { + if (!supportRayTracing()) + return; Gfx::PShaderBuffer verticesBuffer = StaticMeshVertexData::getInstance()->getPositionBuffer(); Gfx::PIndexBuffer indexBuffer = StaticMeshVertexData::getInstance()->getIndexBuffer(); @@ -790,14 +793,12 @@ void Graphics::pickPhysicalDevice() { }; meshShaderFeatures = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT, - .pNext = &accelerationFeatures, .taskShader = true, .meshShader = true, .meshShaderQueries = true, }; features12 = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, - .pNext = &meshShaderFeatures, .storageBuffer8BitAccess = true, .uniformAndStorageBuffer8BitAccess = true, .shaderBufferInt64Atomics = true, @@ -836,17 +837,36 @@ void Graphics::pickPhysicalDevice() { .inheritedQueries = true, }, }; - if (Gfx::useMeshShading) { - uint32 count = 0; - vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &count, nullptr); - Array extensionProps(count); - vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &count, extensionProps.data()); - for (size_t i = 0; i < count; ++i) { + bool rayTracingPipelineSupport = false; + bool accelerationStructureSupport = false; + uint32 count = 0; + vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &count, nullptr); + Array extensionProps(count); + vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &count, extensionProps.data()); + for (size_t i = 0; i < count; ++i) { + if (Gfx::useMeshShading) { if (std::strcmp(VK_EXT_MESH_SHADER_EXTENSION_NAME, extensionProps[i].extensionName) == 0) { meshShadingEnabled = true; break; } } + if (std::strcmp(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, extensionProps[i].extensionName) == 0) { + rayTracingPipelineSupport = true; + } + if (std::strcmp(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, extensionProps[i].extensionName) == 0) { + accelerationStructureSupport = true; + } + } + rayTracingEnabled = rayTracingPipelineSupport && accelerationStructureSupport; + if (meshShadingEnabled) { + features12.pNext = &meshShaderFeatures; + } + if (rayTracingEnabled) { + if (meshShadingEnabled) { + meshShaderFeatures.pNext = &accelerationFeatures; + } else { + features12.pNext = &accelerationFeatures; + } } } @@ -920,12 +940,14 @@ void Graphics::createDevice(GraphicsInitializer initializer) { if (supportMeshShading()) { initializer.deviceExtensions.add(VK_EXT_MESH_SHADER_EXTENSION_NAME); } + if (supportRayTracing()) { + initializer.deviceExtensions.add(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME); + initializer.deviceExtensions.add(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME); + initializer.deviceExtensions.add(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); + } #ifdef __APPLE__ initializer.deviceExtensions.add("VK_KHR_portability_subset"); #endif - initializer.deviceExtensions.add(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME); - initializer.deviceExtensions.add(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME); - initializer.deviceExtensions.add(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); VkDeviceCreateInfo deviceInfo = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .pNext = &features, @@ -963,15 +985,17 @@ void Graphics::createDevice(GraphicsInitializer initializer) { cmdBeginDebugUtilsLabelEXT = (PFN_vkCmdBeginDebugUtilsLabelEXT)vkGetInstanceProcAddr(instance, "vkCmdBeginDebugUtilsLabelEXT"); cmdEndDebugUtilsLabelEXT = (PFN_vkCmdEndDebugUtilsLabelEXT)vkGetInstanceProcAddr(instance, "vkCmdEndDebugUtilsLabelEXT"); - createAccelerationStructure = (PFN_vkCreateAccelerationStructureKHR)vkGetDeviceProcAddr(handle, "vkCreateAccelerationStructureKHR"); - cmdBuildAccelerationStructures = - (PFN_vkCmdBuildAccelerationStructuresKHR)vkGetDeviceProcAddr(handle, "vkCmdBuildAccelerationStructuresKHR"); - getAccelerationStructureBuildSize = - (PFN_vkGetAccelerationStructureBuildSizesKHR)vkGetDeviceProcAddr(handle, "vkGetAccelerationStructureBuildSizesKHR"); - createRayTracingPipelines = (PFN_vkCreateRayTracingPipelinesKHR)vkGetDeviceProcAddr(handle, "vkCreateRayTracingPipelinesKHR"); - getRayTracingShaderGroupHandles = - (PFN_vkGetRayTracingShaderGroupHandlesKHR)vkGetDeviceProcAddr(handle, "vkGetRayTracingShaderGroupHandlesKHR"); - cmdTraceRays = (PFN_vkCmdTraceRaysKHR)vkGetDeviceProcAddr(handle, "vkCmdTraceRaysKHR"); - getAccelerationStructureDeviceAddress = - (PFN_vkGetAccelerationStructureDeviceAddressKHR)vkGetDeviceProcAddr(handle, "vkGetAccelerationStructureDeviceAddressKHR"); + if (rayTracingEnabled) { + createAccelerationStructure = (PFN_vkCreateAccelerationStructureKHR)vkGetDeviceProcAddr(handle, "vkCreateAccelerationStructureKHR"); + cmdBuildAccelerationStructures = + (PFN_vkCmdBuildAccelerationStructuresKHR)vkGetDeviceProcAddr(handle, "vkCmdBuildAccelerationStructuresKHR"); + getAccelerationStructureBuildSize = + (PFN_vkGetAccelerationStructureBuildSizesKHR)vkGetDeviceProcAddr(handle, "vkGetAccelerationStructureBuildSizesKHR"); + createRayTracingPipelines = (PFN_vkCreateRayTracingPipelinesKHR)vkGetDeviceProcAddr(handle, "vkCreateRayTracingPipelinesKHR"); + getRayTracingShaderGroupHandles = + (PFN_vkGetRayTracingShaderGroupHandlesKHR)vkGetDeviceProcAddr(handle, "vkGetRayTracingShaderGroupHandlesKHR"); + cmdTraceRays = (PFN_vkCmdTraceRaysKHR)vkGetDeviceProcAddr(handle, "vkCmdTraceRaysKHR"); + getAccelerationStructureDeviceAddress = + (PFN_vkGetAccelerationStructureDeviceAddressKHR)vkGetDeviceProcAddr(handle, "vkGetAccelerationStructureDeviceAddressKHR"); + } } diff --git a/src/Engine/Graphics/Vulkan/Window.cpp b/src/Engine/Graphics/Vulkan/Window.cpp index 1136075..0fbdda8 100644 --- a/src/Engine/Graphics/Vulkan/Window.cpp +++ b/src/Engine/Graphics/Vulkan/Window.cpp @@ -57,10 +57,9 @@ void glfwFramebufferResizeCallback(GLFWwindow* handle, int width, int height) { Window::Window(PGraphics graphics, const WindowCreateInfo& createInfo) : graphics(graphics), preferences(createInfo), instance(graphics->getInstance()), swapchain(VK_NULL_HANDLE) { - float xscale, yscale; - glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xscale, &yscale); + glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &contentScaleX, &contentScaleY); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - GLFWwindow* handle = glfwCreateWindow(createInfo.width / xscale, createInfo.height / yscale, createInfo.title, nullptr, nullptr); + GLFWwindow* handle = glfwCreateWindow(createInfo.width / contentScaleX, createInfo.height / contentScaleY, createInfo.title, nullptr, nullptr); windowHandle = handle; glfwSetWindowUserPointer(handle, this); diff --git a/src/Engine/Graphics/Window.cpp b/src/Engine/Graphics/Window.cpp index 960e4db..5b1b939 100644 --- a/src/Engine/Graphics/Window.cpp +++ b/src/Engine/Graphics/Window.cpp @@ -30,6 +30,6 @@ Matrix4 Viewport::getProjectionMatrix() const { //); return glm::perspective(fieldOfView, sizeX / static_cast(sizeY), 0.1f, 1000.0f); } else { - return glm::ortho(0.0f, (float)sizeX, (float)sizeY, 0.0f); + return glm::ortho(0.0f, (float)sizeX, 0.0f, (float)sizeY); } } \ No newline at end of file diff --git a/src/Engine/Graphics/Window.h b/src/Engine/Graphics/Window.h index cde88dd..58fe943 100644 --- a/src/Engine/Graphics/Window.h +++ b/src/Engine/Graphics/Window.h @@ -24,12 +24,16 @@ class Window { constexpr SeFormat getSwapchainFormat() const { return framebufferFormat; } constexpr uint32 getFramebufferWidth() const { return framebufferWidth; } constexpr uint32 getFramebufferHeight() const { return framebufferHeight; } + constexpr float getContentScaleX() const { return contentScaleX; } + constexpr float getContentScaleY() const { return contentScaleY; } constexpr bool isPaused() const { return paused; } protected: SeFormat framebufferFormat; uint32 framebufferWidth; uint32 framebufferHeight; + float contentScaleX; + float contentScaleY; bool paused = false; }; DEFINE_REF(Window) @@ -45,6 +49,8 @@ class Viewport { constexpr uint32 getHeight() const { return sizeY; } constexpr uint32 getOffsetX() const { return offsetX; } constexpr uint32 getOffsetY() const { return offsetY; } + constexpr float getContentScaleX() const { return owner->getContentScaleX(); } + constexpr float getContentScaleY() const { return owner->getContentScaleY(); } constexpr Gfx::SeSampleCountFlags getSamples() const { return samples; } Matrix4 getProjectionMatrix() const; diff --git a/src/Engine/Serialization/Serialization.h b/src/Engine/Serialization/Serialization.h index 4342930..ca78e4d 100644 --- a/src/Engine/Serialization/Serialization.h +++ b/src/Engine/Serialization/Serialization.h @@ -10,6 +10,14 @@ template static void save(ArchiveBuffer& buffer, const T& type template static void load(ArchiveBuffer& buffer, T& type) { buffer.readBytes(&type, sizeof(type)); } template static void save(ArchiveBuffer& buffer, const T& type) { buffer.writeBytes(&type, sizeof(type)); } template static void load(ArchiveBuffer& buffer, T& type) { buffer.readBytes(&type, sizeof(type)); } +static void save(ArchiveBuffer& buffer, const UVector2& vec) { + save(buffer, vec.x); + save(buffer, vec.y); +} +static void load(ArchiveBuffer& buffer, UVector2& vec) { + load(buffer, vec.x); + load(buffer, vec.y); +} static void save(ArchiveBuffer& buffer, const IVector2& vec) { save(buffer, vec.x); save(buffer, vec.y); diff --git a/src/Engine/UI/Attributes.h b/src/Engine/UI/Attributes.h new file mode 100644 index 0000000..e7f2e68 --- /dev/null +++ b/src/Engine/UI/Attributes.h @@ -0,0 +1,11 @@ +#pragma once +#include "MinimalEngine.h" +#include + +namespace Seele { +namespace UI { +struct Attributes { + std::function onClick; +}; +} // namespace UI +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/UI/CMakeLists.txt b/src/Engine/UI/CMakeLists.txt index 5f7c12c..4c2a971 100644 --- a/src/Engine/UI/CMakeLists.txt +++ b/src/Engine/UI/CMakeLists.txt @@ -1,24 +1,17 @@ target_sources(Engine PRIVATE - HorizontalLayout.h - HorizontalLayout.cpp - Layout.h - Layout.cpp - RenderHierarchy.h - RenderHierarchy.cpp - System.h - System.cpp - VerticalLayout.h - VerticalLayout.cpp) + Attributes.h + Element.h + Element.cpp + + ) target_sources(Engine PUBLIC FILE_SET HEADERS FILES - HorizontalLayout.h - Layout.h - RenderHierarchy.h - System.h - VerticalLayout.h) + Attributes.h + Element.h +) - -add_subdirectory(Elements/) \ No newline at end of file +add_subdirectory(Style/) +add_subdirectory(Element/) \ No newline at end of file diff --git a/src/Engine/UI/Element.cpp b/src/Engine/UI/Element.cpp new file mode 100644 index 0000000..5c0d8fc --- /dev/null +++ b/src/Engine/UI/Element.cpp @@ -0,0 +1,19 @@ +#include "Element.h" +#include "System.h" + +using namespace Seele; +using namespace Seele::UI; + +Array Element::render() { + RenderElement result; + result.position = UVector2(0, 0); + result.size = UVector2(style.width, style.height); + result.backgroundColor = style.backgroundColor; + result.fontSize = style.fontSize; + result.fontFamily = style.fontFamily; + return {result}; +} + +Element::Element(Attributes attr, Array children) : attr(attr), children(std::move(children)) {} + +Element::~Element() {} \ No newline at end of file diff --git a/src/Engine/UI/Element.h b/src/Engine/UI/Element.h new file mode 100644 index 0000000..cb6257e --- /dev/null +++ b/src/Engine/UI/Element.h @@ -0,0 +1,25 @@ +#pragma once +#include "Attributes.h" +#include "Containers/Array.h" +#include "MinimalEngine.h" +#include "Style/Style.h" + +namespace Seele { +namespace UI { +struct RenderElement; +DECLARE_REF(Element) +class Element { + public: + Element(Attributes attr, Array children); + virtual ~Element(); + virtual void calcStyle(Style parentStyle) = 0; + Array render(); + + protected: + Style style; + Attributes attr; + Array children; +}; +DEFINE_REF(Element) +} // namespace UI +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/UI/Element/CMakeLists.txt b/src/Engine/UI/Element/CMakeLists.txt new file mode 100644 index 0000000..1745eef --- /dev/null +++ b/src/Engine/UI/Element/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(Engine + PRIVATE + Div.h + Text.h) \ No newline at end of file diff --git a/src/Engine/UI/Element/Div.h b/src/Engine/UI/Element/Div.h new file mode 100644 index 0000000..ea51379 --- /dev/null +++ b/src/Engine/UI/Element/Div.h @@ -0,0 +1,15 @@ +#pragma once +#include "UI/Element.h" +#include "UI/Style/Class.h" + +namespace Seele { +namespace UI { +template +class Div : public Element { + public: + Div(Attributes attr, std::initializer_list children) : Element(attr, children) { style.displayType = DisplayType::Block; } + virtual ~Div() {} + private: +}; +} // namespace UI +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/UI/Element/Text.h b/src/Engine/UI/Element/Text.h new file mode 100644 index 0000000..f3292c9 --- /dev/null +++ b/src/Engine/UI/Element/Text.h @@ -0,0 +1,16 @@ +#pragma once +#include "UI/Element.h" +#include "UI/Style/Class.h" + +namespace Seele { +namespace UI { +class Text : public Element { + public: + Text(std::string text) : Element({}, {}), text(text) {} + virtual void calcStyle(Style parentStyle) override { style = parentStyle; } + + private: + std::string text; +}; +} // namespace UI +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/UI/Elements/Button.cpp b/src/Engine/UI/Elements/Button.cpp deleted file mode 100644 index b14610d..0000000 --- a/src/Engine/UI/Elements/Button.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "Button.h" - -using namespace Seele; -using namespace Seele::UI; diff --git a/src/Engine/UI/Elements/Button.h b/src/Engine/UI/Elements/Button.h deleted file mode 100644 index 87c4e7a..0000000 --- a/src/Engine/UI/Elements/Button.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include "Element.h" - -namespace Seele { -namespace UI { -class Button : public Element {}; -} // namespace UI -} // namespace Seele diff --git a/src/Engine/UI/Elements/CMakeLists.txt b/src/Engine/UI/Elements/CMakeLists.txt deleted file mode 100644 index 8cc1a34..0000000 --- a/src/Engine/UI/Elements/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -target_sources(Engine - PRIVATE - Button.h - Button.cpp - Element.h - Element.cpp - Label.h - Label.cpp - Panel.h - Panel.cpp) - -target_sources(Engine - PUBLIC FILE_SET HEADERS - FILES - Button.h - Element.h - Label.h - Panel.h) diff --git a/src/Engine/UI/Elements/Element.cpp b/src/Engine/UI/Elements/Element.cpp deleted file mode 100644 index a838378..0000000 --- a/src/Engine/UI/Elements/Element.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "Element.h" -#include "Graphics/Graphics.h" -#include "UI/System.h" - -using namespace Seele; -using namespace Seele::UI; - -Element::Element() : dirty(false), enabled(false) {} - -Element::~Element() {} - -void Element::setParent(PElement element) { - if (parent != nullptr) { - parent->removeChild(this); - } - parent = element; -} - -PElement Element::getParent() const { return parent; } - -void Element::addChild(PElement element) { children.add(element); } - -void Element::removeChild(PElement element) { children.remove(element, false); } - -const Array Element::getChildren() { return children; } - -void Element::clear() { children.clear(); } - -void Element::setEnabled(bool newEnabled) { enabled = newEnabled; } - -bool Element::isEnabled() const { return enabled; } - -Rect& Element::getBoundingBox() { return boundingBox; } - -const Rect Element::getBoundingBox() const { return boundingBox; } \ No newline at end of file diff --git a/src/Engine/UI/Elements/Element.h b/src/Engine/UI/Elements/Element.h deleted file mode 100644 index ba0908f..0000000 --- a/src/Engine/UI/Elements/Element.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once -#include "Containers/Array.h" -#include "Math/Math.h" -#include "MinimalEngine.h" - -namespace Seele { -namespace UI { -// Element defines any part of the UI -DECLARE_REF(Element) -DECLARE_REF(System) -class Element { - public: - Element(); - virtual ~Element(); - void setParent(PElement element); - PElement getParent() const; - void addChild(PElement element); - void removeChild(PElement element); - const Array getChildren(); - void clear(); - void setEnabled(bool newEnabled); - bool isEnabled() const; - // maybe not the healthiest inteface - // non-const version - Rect& getBoundingBox(); - // The bounding box describes the relative size of any Element - // relative to the total view, meaning a bounding box of (0,0), (1,1) - // would take up the entire view - const Rect getBoundingBox() const; - - protected: - Rect boundingBox; - bool dirty; - - bool enabled; - PSystem system; - PElement parent; - Array children; - friend class RenderElement; -}; -DEFINE_REF(Element) -} // namespace UI -} // namespace Seele diff --git a/src/Engine/UI/Elements/Label.h b/src/Engine/UI/Elements/Label.h deleted file mode 100644 index a9cda6e..0000000 --- a/src/Engine/UI/Elements/Label.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include "Element.h" - -namespace Seele { -namespace UI { -class Label : public Element { - public: - Label(); - ~Label(); - - private: - std::string text; -}; -} // namespace UI -} // namespace Seele diff --git a/src/Engine/UI/Elements/Panel.cpp b/src/Engine/UI/Elements/Panel.cpp deleted file mode 100644 index 3a0643c..0000000 --- a/src/Engine/UI/Elements/Panel.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "Panel.h" -#include "UI/Layout.h" - -using namespace Seele; -using namespace Seele::UI; - -Panel::Panel() {} - -Panel::~Panel() {} \ No newline at end of file diff --git a/src/Engine/UI/Elements/Panel.h b/src/Engine/UI/Elements/Panel.h deleted file mode 100644 index 834bc1f..0000000 --- a/src/Engine/UI/Elements/Panel.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once -#include "Element.h" - -namespace Seele { -namespace UI { -DECLARE_REF(Layout) -class Panel : Element { - public: - Panel(); - virtual ~Panel(); - - private: - PLayout activeLayout; -}; - -DEFINE_REF(Panel); -} // namespace UI -} // namespace Seele diff --git a/src/Engine/UI/HorizontalLayout.cpp b/src/Engine/UI/HorizontalLayout.cpp deleted file mode 100644 index 58f62c5..0000000 --- a/src/Engine/UI/HorizontalLayout.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "HorizontalLayout.h" -#include "Elements/Element.h" - -using namespace Seele; -using namespace Seele::UI; - -HorizontalLayout::HorizontalLayout(PElement element) : Layout(element) {} - -HorizontalLayout::~HorizontalLayout() {} - -void HorizontalLayout::apply() { - Array children = element->getChildren(); - const Rect parent = element->getBoundingBox(); - float xOffset = parent.offset.x; - float yOffset = parent.offset.y; - float xSize = parent.size.x / children.size(); - float ySize = parent.size.y; - for (uint32 index = 0; index < children.size(); ++index) { - Rect& child = children[index]->getBoundingBox(); - child.offset.x = xOffset + (index * xSize); - child.offset.y = yOffset; - child.size.x = xSize; - child.size.y = ySize; - } -} \ No newline at end of file diff --git a/src/Engine/UI/HorizontalLayout.h b/src/Engine/UI/HorizontalLayout.h deleted file mode 100644 index b442e42..0000000 --- a/src/Engine/UI/HorizontalLayout.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include "Layout.h" - -namespace Seele { -namespace UI { -class HorizontalLayout : Layout { - public: - HorizontalLayout(PElement element); - ~HorizontalLayout(); - virtual void apply() override; - - private: -}; -} // namespace UI -} // namespace Seele \ No newline at end of file diff --git a/src/Engine/UI/Layout.cpp b/src/Engine/UI/Layout.cpp deleted file mode 100644 index 557412a..0000000 --- a/src/Engine/UI/Layout.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "Layout.h" -#include "Elements/Element.h" - -using namespace Seele; -using namespace Seele::UI; - -Layout::Layout(PElement element) : element(element) {} - -Layout::~Layout() {} \ No newline at end of file diff --git a/src/Engine/UI/Layout.h b/src/Engine/UI/Layout.h deleted file mode 100644 index 25cee6c..0000000 --- a/src/Engine/UI/Layout.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include "MinimalEngine.h" - -namespace Seele { -namespace UI { -DECLARE_REF(Element); -class Layout { - public: - Layout(PElement element); - virtual ~Layout(); - virtual void apply() = 0; - - protected: - PElement element; -}; -} // namespace UI -} // namespace Seele diff --git a/src/Engine/UI/RenderHierarchy.cpp b/src/Engine/UI/RenderHierarchy.cpp deleted file mode 100644 index 62e245c..0000000 --- a/src/Engine/UI/RenderHierarchy.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "RenderHierarchy.h" - -using namespace Seele; -using namespace Seele::UI; - -void AddElementRenderHierarchyUpdate::apply(Array& elements) { - auto parentIt = elements.find([this](RenderElement e) { return e.parent == parent; }); - parentIt->referencedElement->addChild(addedElement); - addedElement->setParent(parentIt->referencedElement); - - elements.emplace(parentIt->referencedElement, addedElement); -} - -void RemoveElementRenderHierarchyUpdate::apply(Array& elements) { - auto elementIt = elements.find([this](RenderElement e) { return e.referencedElement == element; }); - if (!removeChildren) { - for (auto child : elementIt->referencedElement->getChildren()) { - child->setParent(elementIt->referencedElement->getParent()); - } - } - elementIt->referencedElement->setParent(nullptr); - - elements.remove(elementIt); -} - -RenderHierarchy::RenderHierarchy() {} - -RenderHierarchy::~RenderHierarchy() {} - -void RenderHierarchy::addElement(PElement addedElement) { - std::scoped_lock lock(updateLock); - updates.add(new AddElementRenderHierarchyUpdate{addedElement.getHandle(), addedElement->getParent().getHandle()}); -} - -void RenderHierarchy::removeElement(PElement elementToRemove) { - std::scoped_lock lock(updateLock); - updates.add(new RemoveElementRenderHierarchyUpdate{ - elementToRemove.getHandle(), - }); -} - -void RenderHierarchy::moveElement(PElement elementToMove, PElement newParent) { - std::scoped_lock lock(updateLock); - updates.add(new AddElementRenderHierarchyUpdate{elementToMove.getHandle(), newParent.getHandle()}); - updates.add(new RemoveElementRenderHierarchyUpdate{elementToMove.getHandle()}); -} - -void RenderHierarchy::updateHierarchy() { - List localUpdates; - { // make a local copy of the updates so we dont hold the lock for too long - std::scoped_lock lock(updateLock); - localUpdates = updates; - updates.clear(); - } - for (auto update : localUpdates) { - update->apply(drawElements); - } -} diff --git a/src/Engine/UI/RenderHierarchy.h b/src/Engine/UI/RenderHierarchy.h deleted file mode 100644 index 9cb47c9..0000000 --- a/src/Engine/UI/RenderHierarchy.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once -#include "Containers/List.h" -#include "Elements/Element.h" -#include "Graphics/Resources.h" -#include "Graphics/Texture.h" - - -namespace Seele { -namespace UI { -struct RenderElementStyle { - Vector position = Vector(0, 0, 0); - uint32 backgroundImageIndex = UINT32_MAX; - Vector backgroundColor = Vector(1, 1, 1); - float opacity = 1.0f; - // Vector4 borderBottomColor = Vector4(1, 1, 1, 1); - // Vector4 borderLeftColor = Vector4(1, 1, 1, 1); - // Vector4 borderRightColor = Vector4(1, 1, 1, 1); - // Vector4 borderTopColor = Vector4(1, 1, 1, 1); - // float borderBottomLeftRadius = 0; - // float borderBottomRightRadius = 0; - // float borderTopLeftRadius = 0; - // float borderTopRightRadius = 0; - Vector2 dimensions = Vector2(1, 1); -}; -class RenderElement { - public: - RenderElement() = default; - RenderElement(Element* parent, Element* referencedElement) : parent(parent), referencedElement(referencedElement) {} - ~RenderElement() = default; - Element* parent; - Element* referencedElement; -}; - -struct RenderHierarchyUpdate { - virtual void apply(Array& elements) = 0; -}; - -struct AddElementRenderHierarchyUpdate : public RenderHierarchyUpdate { - Element* addedElement; - Element* parent; - AddElementRenderHierarchyUpdate(Element* addedElement, Element* parent) : addedElement(addedElement), parent(parent) {} - virtual void apply(Array& elements) override; -}; - -struct RemoveElementRenderHierarchyUpdate : public RenderHierarchyUpdate { - Element* element; - bool removeChildren; - RemoveElementRenderHierarchyUpdate(Element* elementToRemove, bool removeChildren = false) - : element(elementToRemove), removeChildren(removeChildren) {} - virtual void apply(Array& elements) override; -}; -class RenderHierarchy { - public: - RenderHierarchy(); - ~RenderHierarchy(); - // logic thread interface, queue hierarchy changes - void addElement(PElement addedElement); - void removeElement(PElement elementToRemove); - void moveElement(PElement elementToMove, PElement newParent); - - // render thread interface, apply changes - void updateHierarchy(); - - private: - static_assert(std::is_trivially_copyable_v); - // List of all drawable elements in draw order - Array drawElements; - // Shader data used for styling elements - Array elementStyles; - Array usedTextures; - - List updates; - std::mutex updateLock; -}; -} // namespace UI -} // namespace Seele diff --git a/src/Engine/UI/Style/CMakeLists.txt b/src/Engine/UI/Style/CMakeLists.txt new file mode 100644 index 0000000..8a6f0b4 --- /dev/null +++ b/src/Engine/UI/Style/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(Engine + PRIVATE + Class.h + Style.h) \ No newline at end of file diff --git a/src/Engine/UI/Style/Class.h b/src/Engine/UI/Style/Class.h new file mode 100644 index 0000000..40e0fd4 --- /dev/null +++ b/src/Engine/UI/Style/Class.h @@ -0,0 +1,27 @@ +#pragma once +#include "MinimalEngine.h" +#include "Style.h" + +namespace Seele { +namespace UI { +template +concept StyleClass = requires(C c, Style& s) { c.apply(s); }; + +template struct WidthClass { + static void apply(Style& s) { + s.width = w; + s.widthType = widthType; + } +}; +using W_Full = WidthClass<100, DimensionType::Percent>; +using W_1 = WidthClass<2, DimensionType::Pixel>; + +template struct DisplayClass { + static void apply(Style& s) { s.displayType = displayType; } +}; +using Hidden = DisplayClass; +using Block = DisplayClass; +using Flex = DisplayClass; + +} // namespace UI +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/UI/Style/Style.h b/src/Engine/UI/Style/Style.h new file mode 100644 index 0000000..b30779e --- /dev/null +++ b/src/Engine/UI/Style/Style.h @@ -0,0 +1,49 @@ +#pragma once +#include "Math/Vector.h" +#include "Asset/FontAsset.h" +#include "MinimalEngine.h" + +namespace Seele { +namespace UI { +enum class DimensionType { + Pixel, + Percent, // EM, PEM, etc... +}; +enum class PositionType { + Relative, + Static, + Absolute, + Sticky, +}; +enum class DisplayType { + Inline, + Hidden, + Block, + Flex, + Grid, +}; +struct Style { + DimensionType widthType = DimensionType::Pixel; + uint32 width = 0; + DimensionType heightType = DimensionType::Pixel; + uint32 height = 0; + uint32 z = 0; + Vector backgroundColor = Vector(1, 1, 1); + DisplayType displayType = DisplayType::Inline; + PositionType position = PositionType::Relative; + PFontAsset fontFamily; + uint32 lineHeight = 12; + uint32 fontSize = 12; + uint32 fontWeight = 0; + uint32 paddingTop = 0; + uint32 paddingBottom = 0; + uint32 paddingLeft = 0; + uint32 paddingRight = 0; + uint32 marginTop = 0; + uint32 marginBottom = 0; + uint32 marginLeft = 0; + uint32 marginRight = 0; + uint32 gap = 0; +}; +} // namespace UI +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/UI/System.cpp b/src/Engine/UI/System.cpp deleted file mode 100644 index 3f5573c..0000000 --- a/src/Engine/UI/System.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "System.h" -#include "Asset/AssetRegistry.h" -#include "Asset/TextureAsset.h" -#include "Elements/Panel.h" -#include "Graphics/Graphics.h" - - -using namespace Seele; -using namespace Seele::UI; - -System::System() {} - -System::~System() {} - -void System::update() {} - -void System::updateViewport(Gfx::PViewport) { - // TODO set viewport FoV to 0 -} - -Component::Camera System::getVirtualCamera() const { return virtualCamera; } diff --git a/src/Engine/UI/System.h b/src/Engine/UI/System.h index 785400d..8b57e7b 100644 --- a/src/Engine/UI/System.h +++ b/src/Engine/UI/System.h @@ -1,26 +1,32 @@ #pragma once -#include "Graphics/RenderPass/TextPass.h" -#include "Graphics/RenderPass/UIPass.h" -#include "MinimalEngine.h" -#include "RenderHierarchy.h" - +#include "Element.h" namespace Seele { namespace UI { -DECLARE_REF(Panel) +struct RenderElement { + // position relative to target viewport in pixels + UVector2 position; + // size relative to target viewport in pixels + UVector2 size; + // background color of area + Vector backgroundColor; + // text to render + std::string text; + // font size in pixels + uint32 fontSize; + // font family + PFontAsset fontFamily; +}; class System { public: - System(); - virtual ~System(); - void update(); - void updateViewport(Gfx::PViewport viewport); - Component::Camera getVirtualCamera() const; + System(OElement rootElement) : rootElement(std::move(rootElement)) {} + ~System(); + Array render(UVector2 viewport) { + } private: - Component::Camera virtualCamera; - PPanel rootPanel; - RenderHierarchy hierarchy; + OElement rootElement; }; DEFINE_REF(System) } // namespace UI -} // namespace Seele +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/UI/VerticalLayout.cpp b/src/Engine/UI/VerticalLayout.cpp deleted file mode 100644 index 298aed0..0000000 --- a/src/Engine/UI/VerticalLayout.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "VerticalLayout.h" -#include "Elements/Element.h" - -using namespace Seele; -using namespace Seele::UI; - -VerticalLayout::VerticalLayout(PElement element) : Layout(element) {} - -VerticalLayout::~VerticalLayout() {} - -void VerticalLayout::apply() { - Array children = element->getChildren(); - const Rect parent = element->getBoundingBox(); - float xOffset = parent.offset.x; - float yOffset = parent.offset.y; - float xSize = parent.size.x; - float ySize = parent.size.y / children.size(); - for (uint32 index = 0; index < children.size(); ++index) { - Rect& child = children[index]->getBoundingBox(); - child.offset.x = xOffset; - child.offset.y = yOffset + (index * ySize); - child.size.x = xSize; - child.size.y = ySize; - } -} \ No newline at end of file diff --git a/src/Engine/UI/VerticalLayout.h b/src/Engine/UI/VerticalLayout.h deleted file mode 100644 index 07b557e..0000000 --- a/src/Engine/UI/VerticalLayout.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include "Layout.h" - -namespace Seele { -namespace UI { -class VerticalLayout : Layout { - public: - VerticalLayout(PElement element); - ~VerticalLayout(); - virtual void apply() override; - - private: -}; -} // namespace UI -} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Window/GameView.cpp b/src/Engine/Window/GameView.cpp index 5b381f1..ee1981b 100644 --- a/src/Engine/Window/GameView.cpp +++ b/src/Engine/Window/GameView.cpp @@ -25,15 +25,17 @@ GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate reloadGame(); renderGraph.addPass(new CachedDepthPass(graphics, scene)); renderGraph.addPass(new DepthCullingPass(graphics, scene)); - renderGraph.addPass(new VisibilityPass(graphics, scene)); + renderGraph.addPass(new VisibilityPass(graphics)); renderGraph.addPass(new LightCullingPass(graphics, scene)); renderGraph.addPass(new BasePass(graphics, scene)); renderGraph.setViewport(viewport); renderGraph.createRenderPass(); - - rayTracingGraph.addPass(new RayTracingPass(graphics, scene)); - rayTracingGraph.setViewport(viewport); - rayTracingGraph.createRenderPass(); + if (graphics->supportRayTracing()) { + rayTracingGraph.addPass(new RayTracingPass(graphics, scene)); + rayTracingGraph.setViewport(viewport); + rayTracingGraph.createRenderPass(); + } + } GameView::~GameView() {} @@ -67,7 +69,7 @@ void GameView::render() { if (c.mainCamera) cam = c; }); - if (getGlobals().useRayTracing) { + if (getGlobals().useRayTracing && graphics->supportRayTracing()) { rayTracingGraph.render(cam); } else { renderGraph.render(cam); diff --git a/src/Engine/UI/Elements/Label.cpp b/tests/Engine/UI/Element.cpp similarity index 50% rename from src/Engine/UI/Elements/Label.cpp rename to tests/Engine/UI/Element.cpp index 8a23d82..e9dd3a3 100644 --- a/src/Engine/UI/Elements/Label.cpp +++ b/tests/Engine/UI/Element.cpp @@ -1,4 +1,5 @@ -#include "Label.h" +#include "UI/Style/Class.h" +#include using namespace Seele; using namespace Seele::UI; \ No newline at end of file