diff --git a/Assets/Fonts/ALGER.shfont b/Assets/Fonts/ALGER.shfont new file mode 100644 index 00000000..1acab9da Binary files /dev/null and b/Assets/Fonts/ALGER.shfont differ diff --git a/Assets/Fonts/ALGER.shfont.shmeta b/Assets/Fonts/ALGER.shfont.shmeta new file mode 100644 index 00000000..e6350c15 --- /dev/null +++ b/Assets/Fonts/ALGER.shfont.shmeta @@ -0,0 +1,3 @@ +Name: ALGER +ID: 182525173 +Type: 10 diff --git a/Assets/Fonts/ALGER.ttf b/Assets/Fonts/ALGER.ttf new file mode 100644 index 00000000..dcc72ae9 Binary files /dev/null and b/Assets/Fonts/ALGER.ttf differ diff --git a/Assets/Fonts/SegoeUI.shfont b/Assets/Fonts/SegoeUI.shfont index 3f709c2a..321f62c8 100644 Binary files a/Assets/Fonts/SegoeUI.shfont and b/Assets/Fonts/SegoeUI.shfont differ diff --git a/Assets/Shaders/Text_FS.glsl b/Assets/Shaders/Text_FS.glsl index 87e29de8..fdf32583 100644 --- a/Assets/Shaders/Text_FS.glsl +++ b/Assets/Shaders/Text_FS.glsl @@ -45,15 +45,14 @@ void main() float screenPxDistance = 2 * (sd - 0.5f); float opacity = clamp (screenPxDistance + 0.5f, 0.0f, 2.0f); - vec4 fragColor = vec4 (1.0f); + vec4 fragColor; - if (opacity > 0.02f && opacity < 1.9f) - { - fragColor = vec4(0.0f, 1.0f, 1.0f, 1.0f); - } - - fragColor = mix(vec4(0.0f), vec4(In2.textColor, 1.0f), min (opacity, 1.0f)); + if (opacity < 0.2f) + discard; + else + fragColor = mix(vec4(0.0f), vec4(In2.textColor, 1.0f), min (opacity, 1.0f)); + // fragColor = vec4 (1.0f); color = fragColor; outEntityID = In2.eid; diff --git a/Assets/Shaders/Text_FS.shshaderb b/Assets/Shaders/Text_FS.shshaderb index 96c8c587..d9b47d6e 100644 Binary files a/Assets/Shaders/Text_FS.shshaderb and b/Assets/Shaders/Text_FS.shshaderb differ diff --git a/Assets/Shaders/Text_VS.glsl b/Assets/Shaders/Text_VS.glsl index 6263aba6..3501a13d 100644 --- a/Assets/Shaders/Text_VS.glsl +++ b/Assets/Shaders/Text_VS.glsl @@ -68,7 +68,7 @@ void main() // Generate UV coords and vertex positions Out.uv = CreateQuad(gl_VertexIndex); - vec3 vertexPos = vec3(Out.uv, 1.0f); + vec3 vertexPos = vec3(Out.uv, 0.0f); // Get the local matrices mat4 localModel = testPushConstant.worldTransform; @@ -87,16 +87,15 @@ void main() toFontSpace[2][0] = positionalOffset.x; toFontSpace[2][1] = positionalOffset.y; - mat4 PVMatrix = cameraData.vpMat; - // Initialize variables for use in FS //characterIndex = gl_InstanceID; // Transform the vertices to font space - vertexPos = toFontSpace * vertexPos; + vertexPos = toFontSpace * vec3(vertexPos.xy, 1.0f); Out2.textColor = testPushConstant.textColor; // transform the vertex position to font space - gl_Position = PVMatrix * localModel * vec4(vertexPos, 1.0f); + gl_Position = cameraData.orthoMat * localModel * vec4(vertexPos, 1.0f); + // gl_Position = vec4(vertexPos, 1.0f); } \ No newline at end of file diff --git a/Assets/Shaders/Text_VS.shshaderb b/Assets/Shaders/Text_VS.shshaderb index 3f612654..25eff84a 100644 Binary files a/Assets/Shaders/Text_VS.shshaderb and b/Assets/Shaders/Text_VS.shshaderb differ diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index a8871cd8..44d39c1f 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -81,6 +81,7 @@ namespace Sandbox SHSystemManager::CreateSystem(); std::system("FontCompiler.exe ../../Assets/Fonts/SegoeUI.ttf"); + std::system("FontCompiler.exe ../../Assets/Fonts/ALGER.ttf"); SHSystemManager::CreateSystem(); SHGraphicsSystem* graphicsSystem = static_cast(SHSystemManager::GetSystem()); @@ -141,7 +142,7 @@ namespace Sandbox //SHComponentManager::CreateComponentSparseSet(); SHAssetManager::Load(); - auto font = SHAssetManager::GetData(176667660); + //auto font = SHAssetManager::GetData(176667660); SHSystemManager::RegisterRoutine(); diff --git a/SHADE_Application/src/Scenes/SBMainScene.cpp b/SHADE_Application/src/Scenes/SBMainScene.cpp index 9da68729..a0e80556 100644 --- a/SHADE_Application/src/Scenes/SBMainScene.cpp +++ b/SHADE_Application/src/Scenes/SBMainScene.cpp @@ -42,19 +42,6 @@ namespace Sandbox void SBMainScene::Init() { sceneName = SHSerialization::DeserializeSceneFromFile(sceneAssetID); - - /*-----------------------------------------------------------------------*/ - /* TESTING CODE */ - /*-----------------------------------------------------------------------*/ - //testText = SHEntityManager::CreateEntity(MAX_EID, "Test Text"); - //auto gfxSystem =SHSystemManager::GetSystem(); - - //auto textComp = SHComponentManager::GetComponent(testText); - - //textComp->SetFont(gfxSystem->GetFontLibrary().GetFonts()[0]); - /*-----------------------------------------------------------------------*/ - /* TESTING CODE */ - /*-----------------------------------------------------------------------*/ } void SBMainScene::Update(float dt) diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHFontLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHFontLoader.cpp index 9bbd3a71..7217b551 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHFontLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHFontLoader.cpp @@ -22,6 +22,14 @@ namespace SHADE return nullptr; } + // Attempt to load font geometry for advance data + auto ttfFilePath = path.string(); + ttfFilePath = ttfFilePath.substr(0, ttfFilePath.find_last_of('.')); + ttfFilePath += TTF_EXTENSION.data(); + msdfgen::FontHandle* fontHandle = nullptr; + fontHandle = msdfgen::loadFont(SHFreetypeInstance::GetFreetypeHandle(), ttfFilePath.c_str()); + newFontAsset->fontGeometry.loadCharset(fontHandle, 1.0f, msdf_atlas::Charset::ASCII); + uint32_t numGlyphs = 0; // read how many glyphs we have diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index ab844b88..386f0988 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -495,4 +495,52 @@ namespace SHADE } ImGui::PopID(); } + + template<> + static void DrawComponent(SHTextRendererComponent* component) + { + if (!component) + return; + ImGui::PushID(SHFamilyID::GetID()); + const auto componentType = rttr::type::get(*component); + SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); + ImGui::SameLine(); + if (ImGui::CollapsingHeader(componentType.get_name().data())) + { + DrawContextMenu(component); + Handle const& font = component->GetFont(); + const auto FONT_NAME = SHResourceManager::GetAssetName(font).value_or(""); + SHEditorWidgets::DragDropReadOnlyField("Font", FONT_NAME, [component]() + { + Handle const& font = component->GetFont(); + return SHResourceManager::GetAssetID(font).value_or(0); + }, + [component](AssetID const& id) + { + if (SHAssetManager::GetType(id) != AssetType::FONT) + { + SHLOG_WARNING("Attempted to assign non font asset to TextRendererComponent Font property!") + return; + } + component->SetFont(SHResourceManager::LoadOrGet(id)); + SHResourceManager::FinaliseChanges(); + }, SHDragDrop::DRAG_RESOURCE); + + SHEditorWidgets::InputText("Text", + [component](void) + { + return component->GetText(); + }, + [component](std::string const& val) + { + component->SetText(val); + } + ); + } + else + { + DrawContextMenu(component); + } + ImGui::PopID(); + } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index 655ad68a..b08d27f6 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -22,6 +22,7 @@ #include "UI/SHCanvasComponent.h" #include "SHEditorComponentView.h" #include "AudioSystem/SHAudioListenerComponent.h" +#include "Graphics/MiddleEnd/TextRendering/SHTextRendererComponent.h" namespace SHADE { @@ -144,6 +145,10 @@ namespace SHADE { DrawComponent(uiComponent); } + if (auto textRendererComponent = SHComponentManager::GetComponent_s(eid)) + { + DrawComponent(textRendererComponent); + } ImGui::Separator(); // Render Scripts SHScriptEngine* scriptEngine = static_cast(SHSystemManager::GetSystem()); @@ -162,6 +167,7 @@ namespace SHADE DrawAddComponentWithEnforcedComponentButton(eid); DrawAddComponentWithEnforcedComponentButton(eid); DrawAddComponentWithEnforcedComponentButton(eid); + DrawAddComponentWithEnforcedComponentButton(eid); ImGui::EndMenu(); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 3932298c..160e82c6 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -117,6 +117,8 @@ namespace SHADE // Create generic command buffer graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true); + SHFreetypeInstance::Init(); + SHAssetManager::CompileAsset("../../Assets/Shaders/Text_VS.glsl", false); SHAssetManager::CompileAsset("../../Assets/Shaders/Text_FS.glsl", false); SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_VS.glsl", false); @@ -135,7 +137,6 @@ namespace SHADE static constexpr AssetID SSAO_BLUR = 39760835; ssaoBlurShader = SHResourceManager::LoadOrGet(SSAO_BLUR); static constexpr AssetID TEXT_VS = 39816727; textVS = SHResourceManager::LoadOrGet(TEXT_VS); static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet(TEXT_FS); - static constexpr AssetID SEGOE_UI_FONT = 176667660; testFont = SHResourceManager::LoadOrGet(SEGOE_UI_FONT); } void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept @@ -379,7 +380,6 @@ namespace SHADE screenRenderer->BindDescSet(cmdBuffer, frameIndex); }); - SHFreetypeInstance::Init(); } void SHGraphicsSystem::InitBuiltInResources(void) @@ -1041,7 +1041,8 @@ namespace SHADE worldViewport->SetWidth(static_cast(resizeWidth)); worldViewport->SetHeight(static_cast(resizeHeight)); - worldCamera->SetPerspective(90.0f, static_cast(resizeWidth), static_cast(resizeHeight), 0.0f, 100.0f); + //worldCamera->SetPerspective(90.0f, static_cast(resizeWidth), static_cast(resizeHeight), 0.0f, 100.0f); + //screenCamera->SetOrthographic(static_cast(resizeWidth), static_cast(resizeHeight), 0.01f, 100.0f); auto cameraSystem = SHSystemManager::GetSystem(); #ifdef SHEDITOR @@ -1053,8 +1054,6 @@ namespace SHADE for (auto& semaHandle : graphSemaphores) semaHandle = device->CreateSemaphore(); - - } void SHGraphicsSystem::AwaitGraphicsExecution() diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRendererComponent.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRendererComponent.cpp index ac1dd73f..26fb97aa 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRendererComponent.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRendererComponent.cpp @@ -24,7 +24,7 @@ namespace SHADE /***************************************************************************/ void SHTextRendererComponent::OnCreate(void) { - text = "Text"; + text = "My name is Brandon."; requiresRecompute = true; // Default white color. @@ -58,6 +58,7 @@ namespace SHADE void SHTextRendererComponent::SetFont(Handle font) noexcept { fontHandle = font; + MakeDirty(); } /***************************************************************************/ @@ -76,4 +77,19 @@ namespace SHADE return text; } -} \ No newline at end of file + Handle SHTextRendererComponent::GetFont(void) const noexcept + { + return fontHandle; + } + +} + +namespace rttr +{ + RTTR_REGISTRATION + { + using namespace SHADE; + + registration::class_("Text Renderer Component"); + }; +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRendererComponent.h b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRendererComponent.h index 242253ec..45738e93 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRendererComponent.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRendererComponent.h @@ -5,6 +5,7 @@ #include "ECS_Base/Components/SHComponent.h" #include "Math/SHColour.h" #include "Resource/SHHandle.h" +#include namespace SHADE { @@ -53,9 +54,12 @@ namespace SHADE void SetFont (Handle font) noexcept; std::string const& GetText (void) const noexcept; + Handle GetFont (void) const noexcept; friend class SHTextRenderingSubSystem; + RTTR_ENABLE() + }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.cpp index ed7314ba..8fbdd33b 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.cpp @@ -16,7 +16,7 @@ namespace SHADE { void SHTextRenderingSubSystem::RecomputePositions(SHTextRendererComponent& textComp) noexcept { - if (textComp.text.empty() || textComp.fontHandle) + if (textComp.text.empty() || !textComp.fontHandle) return; // Create the buffer @@ -24,7 +24,7 @@ namespace SHADE textComp.indexingDataBuffer = logicalDevice->CreateBuffer(SHTextRendererComponent::MAX_CHARACTERS * sizeof(uint32_t), nullptr, SHTextRendererComponent::MAX_CHARACTERS * sizeof(uint32_t), vk::BufferUsageFlagBits::eVertexBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); if (!textComp.charPositionDataBuffer) - textComp.indexingDataBuffer = logicalDevice->CreateBuffer(SHTextRendererComponent::MAX_CHARACTERS * sizeof(SHVec4), nullptr, SHTextRendererComponent::MAX_CHARACTERS * sizeof(SHVec4), vk::BufferUsageFlagBits::eVertexBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); + textComp.charPositionDataBuffer = logicalDevice->CreateBuffer(SHTextRendererComponent::MAX_CHARACTERS * sizeof(SHVec4), nullptr, SHTextRendererComponent::MAX_CHARACTERS * sizeof(SHVec4), vk::BufferUsageFlagBits::eVertexBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); // For indexing font transformation in the shader std::vector indexingData; @@ -115,8 +115,8 @@ namespace SHADE SHVertexInputState vertexInputState; // Configure vertex attributes - vertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_4D) }); // location = 0 (character position data) - vertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::UINT32_1D) }); // location = 1 (glyph index to index matrices) + vertexInputState.AddBinding(true, false, { SHVertexAttribute(SHAttribFormat::FLOAT_4D) }); // location = 0 (character position data) + vertexInputState.AddBinding(true, false, { SHVertexAttribute(SHAttribFormat::UINT32_1D) }); // location = 1 (glyph index to index matrices) // Set vertex state for new pipeline pipeline->GetPipelineState().SetVertexInputState(vertexInputState); @@ -146,6 +146,13 @@ namespace SHADE pipeline->GetPipelineState().SetColorBlenState(colorBlendState); + SHInputAssemblyState inputAssembly{}; + inputAssembly.topology = vk::PrimitiveTopology::eTriangleFan; + pipeline->GetPipelineState().SetInputAssemblyState(inputAssembly); + + SHRasterizationState rasterState{}; + rasterState.frontFacingOrientation = vk::FrontFace::eClockwise; + pipeline->GetPipelineState().SetRasterizationState(rasterState); // Construct pipeline pipeline->ConstructPipeline(); diff --git a/SHADE_Engine/src/Serialization/SHSerialization.cpp b/SHADE_Engine/src/Serialization/SHSerialization.cpp index 3ed96d7d..607b4666 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.cpp +++ b/SHADE_Engine/src/Serialization/SHSerialization.cpp @@ -211,6 +211,7 @@ namespace SHADE AddComponentToComponentNode(components, eid); AddComponentToComponentNode(components, eid); AddConvComponentToComponentNode(components, eid); + AddConvComponentToComponentNode(components, eid); node[ComponentsNode] = components; @@ -262,6 +263,7 @@ namespace SHADE AddComponentID(componentIDList, componentsNode); AddComponentID(componentIDList, componentsNode); AddComponentID(componentIDList, componentsNode); + AddComponentID(componentIDList, componentsNode); return componentIDList; } @@ -338,6 +340,7 @@ namespace SHADE SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); SHSerializationHelper::ConvertNodeToComponent(componentsNode, eid); SHSerializationHelper::ConvertNodeToComponent(componentsNode, eid); + SHSerializationHelper::ConvertNodeToComponent(componentsNode, eid); SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); } } diff --git a/SHADE_Engine/src/Serialization/SHYAMLConverters.h b/SHADE_Engine/src/Serialization/SHYAMLConverters.h index d66a7506..eb273a15 100644 --- a/SHADE_Engine/src/Serialization/SHYAMLConverters.h +++ b/SHADE_Engine/src/Serialization/SHYAMLConverters.h @@ -12,6 +12,9 @@ #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" #include "SHSerializationTools.h" #include "Physics/Interface/SHColliderComponent.h" +#include "Graphics/MiddleEnd/TextRendering/SHTextRendererComponent.h" +#include "Graphics/MiddleEnd/TextRendering/SHFont.h" + namespace YAML { using namespace SHADE; @@ -322,4 +325,45 @@ namespace YAML return true; } }; + + template<> + struct convert + { + static constexpr std::string_view TEXT_YAML_TAG = "Text"; + static constexpr std::string_view FONT_YAML_TAG = "Font"; + + static YAML::Node encode(SHTextRendererComponent const& rhs) + { + YAML::Node node; + node[TEXT_YAML_TAG.data()] = rhs.GetText(); + auto font = rhs.GetFont(); + if (font) + { + node[FONT_YAML_TAG.data()] = SHResourceManager::GetAssetID(rhs.GetFont()).value_or(0); + } + else + { + node[FONT_YAML_TAG.data()] = 0; + } + return node; + } + static bool decode(YAML::Node const& node, SHTextRendererComponent& rhs) + { + if (node[TEXT_YAML_TAG.data()].IsDefined()) + { + rhs.SetText(node[TEXT_YAML_TAG.data()].as()); + } + if (node[FONT_YAML_TAG.data()].IsDefined()) + { + + // Temporarily, use default material + auto gfxSystem = SHSystemManager::GetSystem(); + if (!gfxSystem) + return false; + + rhs.SetFont(SHResourceManager::LoadOrGet(node[TEXT_YAML_TAG.data()].as())); + } + return true; + } + }; }