Move scene viewport shaders into editor resources

This commit is contained in:
2026-04-03 15:43:21 +08:00
parent f1981dd523
commit 24a200e126
22 changed files with 248 additions and 137 deletions

View File

@@ -791,3 +791,20 @@ ISceneViewportGizmoProvider
这会比“看到哪改哪、边做边塞进现有 builder”稳定得多。
---
## 11. 进度更新 2026-04-03
本轮已完成“SceneView pass ownership 回收”的最后一个收口步骤:
1. `engine` 不再注册 SceneView 专属的 `object-id-outline` / `infinite-grid` builtin shader
2. `BuiltinInfiniteGridPass``BuiltinObjectIdOutlinePass` 改为由调用方注入 shader 路径
3. SceneView grid / outline shader 已迁移到 `editor/resources/shaders/scene-viewport`
4. `editor` 通过自己的 shader 路径入口组装这两个 pass
5. 已补齐 editor 侧 shader 路径与加载测试,并回归验证 runtime builtin shader 测试
对应结论:
- Phase 1已完成
- Phase 2已完成并收口
- Phase 3 及后续阶段:仍待继续推进

View File

@@ -86,6 +86,8 @@ add_executable(${PROJECT_NAME} WIN32
src/Viewport/SceneViewportOverlayBuilder.cpp
src/Viewport/SceneViewportOverlayRenderer.cpp
src/Viewport/Passes/SceneViewportEditorOverlayPass.cpp
src/Viewport/Passes/SceneViewportGridPass.cpp
src/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp
src/panels/GameViewPanel.cpp
src/panels/InspectorPanel.cpp
src/panels/ConsolePanel.cpp
@@ -102,7 +104,10 @@ target_include_directories(${PROJECT_NAME} PRIVATE
${imgui_SOURCE_DIR}/backends
)
target_compile_definitions(${PROJECT_NAME} PRIVATE UNICODE _UNICODE)
target_compile_definitions(${PROJECT_NAME} PRIVATE
UNICODE
_UNICODE
XCENGINE_EDITOR_REPO_ROOT="${XCENGINE_ROOT_DIR_CMAKE}")
target_compile_options(${PROJECT_NAME} PRIVATE /utf-8)
if(XCENGINE_ENABLE_MONO_SCRIPTING)

View File

@@ -1,4 +1,4 @@
// XC_BUILTIN_INFINITE_GRID_D3D12_PS
// XC_EDITOR_SCENE_VIEW_INFINITE_GRID_D3D12_PS
cbuffer GridConstants : register(b0) {
float4x4 gViewProjectionMatrix;
float4 gCameraPositionAndScale;

View File

@@ -1,5 +1,5 @@
{
"name": "Builtin Infinite Grid",
"name": "Scene View Infinite Grid",
"passes": [
{
"name": "InfiniteGrid",

View File

@@ -1,4 +1,4 @@
// XC_BUILTIN_INFINITE_GRID_D3D12_VS
// XC_EDITOR_SCENE_VIEW_INFINITE_GRID_D3D12_VS
cbuffer GridConstants : register(b0) {
float4x4 gViewProjectionMatrix;
float4 gCameraPositionAndScale;

View File

@@ -1,4 +1,4 @@
// XC_BUILTIN_OBJECT_ID_OUTLINE_D3D12_PS
// XC_EDITOR_SCENE_VIEW_OBJECT_ID_OUTLINE_D3D12_PS
cbuffer OutlineConstants : register(b0) {
float4 gViewportSizeAndTexelSize;
float4 gOutlineColor;

View File

@@ -1,5 +1,5 @@
{
"name": "Builtin Object Id Outline",
"name": "Scene View Object Id Outline",
"passes": [
{
"name": "ObjectIdOutline",

View File

@@ -1,4 +1,4 @@
// XC_BUILTIN_OBJECT_ID_OUTLINE_D3D12_VS
// XC_EDITOR_SCENE_VIEW_OBJECT_ID_OUTLINE_D3D12_VS
cbuffer OutlineConstants : register(b0) {
float4 gViewportSizeAndTexelSize;
float4 gOutlineColor;

View File

@@ -1,5 +1,7 @@
#include "Passes/SceneViewportGridPass.h"
#include "Viewport/SceneViewportShaderPaths.h"
namespace XCEngine {
namespace Editor {
@@ -32,6 +34,10 @@ private:
} // namespace
SceneViewportGridPassRenderer::SceneViewportGridPassRenderer()
: m_gridPass(GetSceneViewportInfiniteGridShaderPath()) {
}
void SceneViewportGridPassRenderer::Shutdown() {
m_gridPass.Shutdown();
}

View File

@@ -12,6 +12,7 @@ namespace Editor {
class SceneViewportGridPassRenderer {
public:
SceneViewportGridPassRenderer();
~SceneViewportGridPassRenderer() = default;
void Shutdown();

View File

@@ -1,5 +1,7 @@
#include "Passes/SceneViewportSelectionOutlinePass.h"
#include "Viewport/SceneViewportShaderPaths.h"
namespace XCEngine {
namespace Editor {
@@ -40,6 +42,10 @@ private:
} // namespace
SceneViewportSelectionOutlinePassRenderer::SceneViewportSelectionOutlinePassRenderer()
: m_outlinePass(GetSceneViewportObjectIdOutlineShaderPath()) {
}
void SceneViewportSelectionOutlinePassRenderer::Shutdown() {
m_outlinePass.Shutdown();
}

View File

@@ -14,6 +14,7 @@ namespace Editor {
class SceneViewportSelectionOutlinePassRenderer {
public:
SceneViewportSelectionOutlinePassRenderer();
~SceneViewportSelectionOutlinePassRenderer() = default;
void Shutdown();

View File

@@ -0,0 +1,47 @@
#pragma once
#include <XCEngine/Core/Containers/String.h>
#include <filesystem>
namespace XCEngine {
namespace Editor {
namespace Detail {
inline Containers::String NormalizeSceneViewportShaderPath(const std::filesystem::path& path) {
return Containers::String(path.lexically_normal().generic_string().c_str());
}
inline std::filesystem::path GetSceneViewportShaderRepoRootPath() {
#ifdef XCENGINE_EDITOR_REPO_ROOT
return std::filesystem::path(XCENGINE_EDITOR_REPO_ROOT);
#else
return std::filesystem::path(__FILE__).parent_path().parent_path().parent_path();
#endif
}
inline Containers::String BuildSceneViewportShaderPath(const std::filesystem::path& relativePath) {
return NormalizeSceneViewportShaderPath(
GetSceneViewportShaderRepoRootPath() /
"editor" /
"resources" /
"shaders" /
"scene-viewport" /
relativePath);
}
} // namespace Detail
inline Containers::String GetSceneViewportInfiniteGridShaderPath() {
return Detail::BuildSceneViewportShaderPath(
std::filesystem::path("infinite-grid") / "infinite-grid.shader");
}
inline Containers::String GetSceneViewportObjectIdOutlineShaderPath() {
return Detail::BuildSceneViewportShaderPath(
std::filesystem::path("object-id-outline") / "object-id-outline.shader");
}
} // namespace Editor
} // namespace XCEngine

View File

@@ -1,5 +1,6 @@
#pragma once
#include <XCEngine/Core/Containers/String.h>
#include <XCEngine/Core/Math/Vector3.h>
#include <XCEngine/Core/Asset/ResourceHandle.h>
#include <XCEngine/Core/Asset/ResourceManager.h>
@@ -40,8 +41,12 @@ InfiniteGridParameters BuildInfiniteGridParameters(const InfiniteGridPassData& d
class BuiltinInfiniteGridPass {
public:
explicit BuiltinInfiniteGridPass(Containers::String shaderPath = Containers::String());
~BuiltinInfiniteGridPass() = default;
void SetShaderPath(const Containers::String& shaderPath);
const Containers::String& GetShaderPath() const;
void Shutdown();
bool Render(
@@ -60,6 +65,7 @@ private:
RHI::RHIPipelineState* m_pipelineState = nullptr;
RHI::RHIDescriptorPool* m_constantPool = nullptr;
RHI::RHIDescriptorSet* m_constantSet = nullptr;
Containers::String m_shaderPath;
Resources::ResourceHandle<Resources::Shader> m_builtinInfiniteGridShader;
};

View File

@@ -1,5 +1,6 @@
#pragma once
#include <XCEngine/Core/Containers/String.h>
#include <XCEngine/Core/Math/Color.h>
#include <XCEngine/Core/Math/Vector3.h>
#include <XCEngine/Core/Math/Vector4.h>
@@ -32,7 +33,7 @@ struct ObjectIdOutlineStyle {
class BuiltinObjectIdOutlinePass {
public:
BuiltinObjectIdOutlinePass();
explicit BuiltinObjectIdOutlinePass(Containers::String shaderPath = Containers::String());
~BuiltinObjectIdOutlinePass() = default;
BuiltinObjectIdOutlinePass(const BuiltinObjectIdOutlinePass&) = delete;
BuiltinObjectIdOutlinePass& operator=(const BuiltinObjectIdOutlinePass&) = delete;
@@ -41,6 +42,9 @@ public:
static constexpr uint32_t kMaxSelectedObjectCount = 256u;
void SetShaderPath(const Containers::String& shaderPath);
const Containers::String& GetShaderPath() const;
void Shutdown();
bool Render(
@@ -72,6 +76,7 @@ private:
RHI::RHIDescriptorSet* m_constantSet = nullptr;
RHI::RHIDescriptorPool* m_texturePool = nullptr;
RHI::RHIDescriptorSet* m_textureSet = nullptr;
Containers::String m_shaderPath;
std::optional<Resources::ResourceHandle<Resources::Shader>> m_builtinObjectIdOutlineShader;
};

View File

@@ -25,8 +25,6 @@ Containers::String GetBuiltinPrimitiveMeshPath(BuiltinPrimitiveType primitiveTyp
Containers::String GetBuiltinDefaultPrimitiveMaterialPath();
Containers::String GetBuiltinForwardLitShaderPath();
Containers::String GetBuiltinObjectIdShaderPath();
Containers::String GetBuiltinObjectIdOutlineShaderPath();
Containers::String GetBuiltinInfiniteGridShaderPath();
Containers::String GetBuiltinDefaultPrimitiveTexturePath();
bool TryParseBuiltinPrimitiveType(const Containers::String& path, BuiltinPrimitiveType& outPrimitiveType);

View File

@@ -6,12 +6,12 @@
#include <XCEngine/Debug/Logger.h>
#include <XCEngine/RHI/RHICommandList.h>
#include <XCEngine/RHI/RHIDevice.h>
#include <XCEngine/Resources/BuiltinResources.h>
#include "Rendering/Detail/ShaderVariantUtils.h"
#include <algorithm>
#include <cmath>
#include <utility>
namespace XCEngine {
namespace Rendering {
@@ -140,6 +140,23 @@ InfiniteGridParameters BuildInfiniteGridParameters(const InfiniteGridPassData& d
return parameters;
}
BuiltinInfiniteGridPass::BuiltinInfiniteGridPass(Containers::String shaderPath)
: m_shaderPath(std::move(shaderPath)) {
}
void BuiltinInfiniteGridPass::SetShaderPath(const Containers::String& shaderPath) {
if (m_shaderPath == shaderPath) {
return;
}
DestroyResources();
m_shaderPath = shaderPath;
}
const Containers::String& BuiltinInfiniteGridPass::GetShaderPath() const {
return m_shaderPath;
}
void BuiltinInfiniteGridPass::Shutdown() {
DestroyResources();
}
@@ -243,14 +260,21 @@ bool BuiltinInfiniteGridPass::CreateResources(const RenderContext& renderContext
return false;
}
if (m_shaderPath.Empty()) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
"BuiltinInfiniteGridPass requires an injected shader path before resource creation");
return false;
}
m_device = renderContext.device;
m_backendType = renderContext.backendType;
m_builtinInfiniteGridShader = Resources::ResourceManager::Get().Load<Resources::Shader>(
Resources::GetBuiltinInfiniteGridShaderPath());
m_shaderPath);
if (!m_builtinInfiniteGridShader.IsValid()) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
"BuiltinInfiniteGridPass failed to load builtin infinite-grid shader resource");
"BuiltinInfiniteGridPass failed to load configured infinite-grid shader resource");
DestroyResources();
return false;
}

View File

@@ -6,7 +6,6 @@
#include "Rendering/Detail/ShaderVariantUtils.h"
#include "RHI/RHICommandList.h"
#include "RHI/RHIDevice.h"
#include "Resources/BuiltinResources.h"
#include <algorithm>
#include <utility>
@@ -86,10 +85,24 @@ RHI::GraphicsPipelineDesc CreatePipelineDesc(
} // namespace
BuiltinObjectIdOutlinePass::BuiltinObjectIdOutlinePass() {
BuiltinObjectIdOutlinePass::BuiltinObjectIdOutlinePass(Containers::String shaderPath)
: m_shaderPath(std::move(shaderPath)) {
ResetState();
}
void BuiltinObjectIdOutlinePass::SetShaderPath(const Containers::String& shaderPath) {
if (m_shaderPath == shaderPath) {
return;
}
DestroyResources();
m_shaderPath = shaderPath;
}
const Containers::String& BuiltinObjectIdOutlinePass::GetShaderPath() const {
return m_shaderPath;
}
void BuiltinObjectIdOutlinePass::Shutdown() {
DestroyResources();
}
@@ -197,12 +210,19 @@ bool BuiltinObjectIdOutlinePass::CreateResources(const RenderContext& renderCont
return false;
}
if (m_shaderPath.Empty()) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
"BuiltinObjectIdOutlinePass requires an injected shader path before resource creation");
return false;
}
Resources::ResourceHandle<Resources::Shader> shader = Resources::ResourceManager::Get().Load<Resources::Shader>(
Resources::GetBuiltinObjectIdOutlineShaderPath());
m_shaderPath);
if (!shader.IsValid()) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
"BuiltinObjectIdOutlinePass failed to load builtin object-id-outline shader resource");
"BuiltinObjectIdOutlinePass failed to load configured object-id-outline shader resource");
ResetState();
return false;
}

View File

@@ -29,8 +29,6 @@ constexpr const char* kBuiltinTexturePrefix = "builtin://textures/";
constexpr const char* kBuiltinDefaultPrimitiveMaterialPath = "builtin://materials/default-primitive";
constexpr const char* kBuiltinForwardLitShaderPath = "builtin://shaders/forward-lit";
constexpr const char* kBuiltinObjectIdShaderPath = "builtin://shaders/object-id";
constexpr const char* kBuiltinObjectIdOutlineShaderPath = "builtin://shaders/object-id-outline";
constexpr const char* kBuiltinInfiniteGridShaderPath = "builtin://shaders/infinite-grid";
constexpr const char* kBuiltinDefaultPrimitiveTexturePath = "builtin://textures/default-primitive-albedo";
constexpr float kPi = 3.14159265358979323846f;
@@ -45,10 +43,6 @@ constexpr const char* kBuiltinForwardLitShaderManifestRelativePath =
"engine/assets/builtin/shaders/forward-lit/forward-lit.shader";
constexpr const char* kBuiltinObjectIdShaderManifestRelativePath =
"engine/assets/builtin/shaders/object-id/object-id.shader";
constexpr const char* kBuiltinObjectIdOutlineShaderManifestRelativePath =
"engine/assets/builtin/shaders/object-id-outline/object-id-outline.shader";
constexpr const char* kBuiltinInfiniteGridShaderManifestRelativePath =
"engine/assets/builtin/shaders/infinite-grid/infinite-grid.shader";
Containers::String NormalizeBuiltinAssetPath(const std::filesystem::path& path) {
return Containers::String(path.lexically_normal().generic_string().c_str());
@@ -118,12 +112,6 @@ const char* GetBuiltinShaderManifestRelativePath(const Containers::String& built
if (builtinShaderPath == Containers::String(kBuiltinObjectIdShaderPath)) {
return kBuiltinObjectIdShaderManifestRelativePath;
}
if (builtinShaderPath == Containers::String(kBuiltinObjectIdOutlineShaderPath)) {
return kBuiltinObjectIdOutlineShaderManifestRelativePath;
}
if (builtinShaderPath == Containers::String(kBuiltinInfiniteGridShaderPath)) {
return kBuiltinInfiniteGridShaderManifestRelativePath;
}
return nullptr;
}
@@ -652,14 +640,6 @@ Shader* BuildBuiltinObjectIdShader(const Containers::String& path) {
return TryLoadBuiltinShaderFromManifest(path);
}
Shader* BuildBuiltinInfiniteGridShader(const Containers::String& path) {
return TryLoadBuiltinShaderFromManifest(path);
}
Shader* BuildBuiltinObjectIdOutlineShader(const Containers::String& path) {
return TryLoadBuiltinShaderFromManifest(path);
}
Material* BuildDefaultPrimitiveMaterial(const Containers::String& path) {
auto* material = new Material();
IResource::ConstructParams params;
@@ -766,14 +746,6 @@ Containers::String GetBuiltinObjectIdShaderPath() {
return Containers::String(kBuiltinObjectIdShaderPath);
}
Containers::String GetBuiltinObjectIdOutlineShaderPath() {
return Containers::String(kBuiltinObjectIdOutlineShaderPath);
}
Containers::String GetBuiltinInfiniteGridShaderPath() {
return Containers::String(kBuiltinInfiniteGridShaderPath);
}
Containers::String GetBuiltinDefaultPrimitiveTexturePath() {
return Containers::String(kBuiltinDefaultPrimitiveTexturePath);
}
@@ -866,10 +838,6 @@ LoadResult CreateBuiltinShaderResource(const Containers::String& path) {
shader = BuildBuiltinForwardLitShader(path);
} else if (path == GetBuiltinObjectIdShaderPath()) {
shader = BuildBuiltinObjectIdShader(path);
} else if (path == GetBuiltinObjectIdOutlineShaderPath()) {
shader = BuildBuiltinObjectIdOutlineShader(path);
} else if (path == GetBuiltinInfiniteGridShaderPath()) {
shader = BuildBuiltinInfiniteGridShader(path);
} else {
return LoadResult(Containers::String("Unknown builtin shader: ") + path);
}

View File

@@ -44,8 +44,6 @@ TEST(ShaderLoader, CanLoad) {
EXPECT_TRUE(loader.CanLoad("test.xcshader"));
EXPECT_TRUE(loader.CanLoad(GetBuiltinForwardLitShaderPath()));
EXPECT_TRUE(loader.CanLoad(GetBuiltinObjectIdShaderPath()));
EXPECT_TRUE(loader.CanLoad(GetBuiltinObjectIdOutlineShaderPath()));
EXPECT_TRUE(loader.CanLoad(GetBuiltinInfiniteGridShaderPath()));
EXPECT_FALSE(loader.CanLoad("test.txt"));
EXPECT_FALSE(loader.CanLoad("test.png"));
}
@@ -545,72 +543,6 @@ TEST(ShaderLoader, LoadBuiltinObjectIdShaderBuildsBackendVariants) {
delete shader;
}
TEST(ShaderLoader, LoadBuiltinInfiniteGridShaderBuildsD3D12Variants) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinInfiniteGridShaderPath());
ASSERT_TRUE(result);
ASSERT_NE(result.resource, nullptr);
Shader* shader = static_cast<Shader*>(result.resource);
ASSERT_NE(shader, nullptr);
ASSERT_TRUE(shader->IsValid());
const ShaderPass* pass = shader->FindPass("InfiniteGrid");
ASSERT_NE(pass, nullptr);
ASSERT_EQ(pass->variants.Size(), 2u);
ASSERT_EQ(pass->tags.Size(), 1u);
EXPECT_EQ(pass->tags[0].name, "LightMode");
EXPECT_EQ(pass->tags[0].value, "InfiniteGrid");
EXPECT_NE(shader->FindVariant("InfiniteGrid", ShaderType::Vertex, ShaderBackend::D3D12), nullptr);
EXPECT_NE(shader->FindVariant("InfiniteGrid", ShaderType::Fragment, ShaderBackend::D3D12), nullptr);
EXPECT_EQ(shader->FindVariant("InfiniteGrid", ShaderType::Vertex, ShaderBackend::OpenGL), nullptr);
EXPECT_EQ(shader->FindVariant("InfiniteGrid", ShaderType::Fragment, ShaderBackend::OpenGL), nullptr);
const ShaderStageVariant* d3d12Fragment = shader->FindVariant(
"InfiniteGrid",
ShaderType::Fragment,
ShaderBackend::D3D12);
ASSERT_NE(d3d12Fragment, nullptr);
EXPECT_NE(std::string(d3d12Fragment->sourceCode.CStr()).find("XC_BUILTIN_INFINITE_GRID_D3D12_PS"), std::string::npos);
delete shader;
}
TEST(ShaderLoader, LoadBuiltinObjectIdOutlineShaderBuildsD3D12Variants) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinObjectIdOutlineShaderPath());
ASSERT_TRUE(result);
ASSERT_NE(result.resource, nullptr);
Shader* shader = static_cast<Shader*>(result.resource);
ASSERT_NE(shader, nullptr);
ASSERT_TRUE(shader->IsValid());
const ShaderPass* pass = shader->FindPass("ObjectIdOutline");
ASSERT_NE(pass, nullptr);
ASSERT_EQ(pass->variants.Size(), 2u);
ASSERT_EQ(pass->tags.Size(), 1u);
EXPECT_EQ(pass->tags[0].name, "LightMode");
EXPECT_EQ(pass->tags[0].value, "ObjectIdOutline");
EXPECT_NE(shader->FindVariant("ObjectIdOutline", ShaderType::Vertex, ShaderBackend::D3D12), nullptr);
EXPECT_NE(shader->FindVariant("ObjectIdOutline", ShaderType::Fragment, ShaderBackend::D3D12), nullptr);
EXPECT_EQ(shader->FindVariant("ObjectIdOutline", ShaderType::Vertex, ShaderBackend::OpenGL), nullptr);
EXPECT_EQ(shader->FindVariant("ObjectIdOutline", ShaderType::Fragment, ShaderBackend::OpenGL), nullptr);
const ShaderStageVariant* d3d12Fragment = shader->FindVariant(
"ObjectIdOutline",
ShaderType::Fragment,
ShaderBackend::D3D12);
ASSERT_NE(d3d12Fragment, nullptr);
EXPECT_NE(
std::string(d3d12Fragment->sourceCode.CStr()).find("XC_BUILTIN_OBJECT_ID_OUTLINE_D3D12_PS"),
std::string::npos);
delete shader;
}
TEST(ShaderLoader, ResourceManagerLazilyLoadsBuiltinForwardLitShader) {
ResourceManager& manager = ResourceManager::Get();
manager.Shutdown();
@@ -624,14 +556,6 @@ TEST(ShaderLoader, ResourceManagerLazilyLoadsBuiltinForwardLitShader) {
ASSERT_TRUE(objectIdShaderHandle.IsValid());
ASSERT_NE(objectIdShaderHandle->FindPass("ObjectId"), nullptr);
ResourceHandle<Shader> objectIdOutlineShaderHandle = manager.Load<Shader>(GetBuiltinObjectIdOutlineShaderPath());
ASSERT_TRUE(objectIdOutlineShaderHandle.IsValid());
ASSERT_NE(objectIdOutlineShaderHandle->FindPass("ObjectIdOutline"), nullptr);
ResourceHandle<Shader> infiniteGridShaderHandle = manager.Load<Shader>(GetBuiltinInfiniteGridShaderPath());
ASSERT_TRUE(infiniteGridShaderHandle.IsValid());
ASSERT_NE(infiniteGridShaderHandle->FindPass("InfiniteGrid"), nullptr);
manager.Shutdown();
}
@@ -681,18 +605,6 @@ TEST(ShaderLoader, ResourceManagerLoadsBuiltinShadersOutsideProjectWorkingDirect
ShaderType::Fragment,
ShaderBackend::Vulkan,
"XC_BUILTIN_OBJECT_ID_VULKAN_PS");
expectBuiltinShader(
GetBuiltinObjectIdOutlineShaderPath(),
"ObjectIdOutline",
ShaderType::Fragment,
ShaderBackend::D3D12,
"XC_BUILTIN_OBJECT_ID_OUTLINE_D3D12_PS");
expectBuiltinShader(
GetBuiltinInfiniteGridShaderPath(),
"InfiniteGrid",
ShaderType::Fragment,
ShaderBackend::D3D12,
"XC_BUILTIN_INFINITE_GRID_D3D12_PS");
fs::current_path(previousPath);
manager.SetResourceRoot(previousResourceRoot);

View File

@@ -10,6 +10,7 @@ set(EDITOR_TEST_SOURCES
test_scene_viewport_rotate_gizmo.cpp
test_scene_viewport_scale_gizmo.cpp
test_scene_viewport_picker.cpp
test_scene_viewport_shader_paths.cpp
test_scene_viewport_overlay_renderer.cpp
test_script_component_editor_utils.cpp
test_viewport_host_surface_utils.cpp
@@ -17,8 +18,10 @@ set(EDITOR_TEST_SOURCES
test_viewport_render_targets.cpp
test_viewport_render_flow_utils.cpp
test_builtin_icon_layout_utils.cpp
test_editor_console_sink.cpp
test_editor_script_assembly_builder.cpp
test_editor_script_assembly_builder_utils.cpp
${CMAKE_SOURCE_DIR}/editor/src/Core/EditorConsoleSink.cpp
${CMAKE_SOURCE_DIR}/editor/src/Scripting/EditorScriptAssemblyBuilder.cpp
${CMAKE_SOURCE_DIR}/editor/src/Core/UndoManager.cpp
${CMAKE_SOURCE_DIR}/editor/src/Core/PlaySessionController.cpp

View File

@@ -0,0 +1,92 @@
#include <gtest/gtest.h>
#include "Viewport/SceneViewportShaderPaths.h"
#include <XCEngine/Core/Asset/ResourceManager.h>
#include <XCEngine/Resources/Shader/ShaderLoader.h>
#include <filesystem>
#include <string>
namespace {
using XCEngine::Editor::GetSceneViewportInfiniteGridShaderPath;
using XCEngine::Editor::GetSceneViewportObjectIdOutlineShaderPath;
using XCEngine::Resources::LoadResult;
using XCEngine::Resources::ResourceHandle;
using XCEngine::Resources::ResourceManager;
using XCEngine::Resources::Shader;
using XCEngine::Resources::ShaderBackend;
using XCEngine::Resources::ShaderLoader;
using XCEngine::Resources::ShaderPass;
using XCEngine::Resources::ShaderStageVariant;
using XCEngine::Resources::ShaderType;
TEST(SceneViewportShaderPathsTest, ResolvePathsUnderEditorResources) {
const std::filesystem::path gridPath(GetSceneViewportInfiniteGridShaderPath().CStr());
const std::filesystem::path outlinePath(GetSceneViewportObjectIdOutlineShaderPath().CStr());
EXPECT_TRUE(gridPath.is_absolute());
EXPECT_TRUE(outlinePath.is_absolute());
EXPECT_TRUE(std::filesystem::exists(gridPath));
EXPECT_TRUE(std::filesystem::exists(outlinePath));
EXPECT_NE(gridPath.generic_string().find("editor/resources/shaders/scene-viewport"), std::string::npos);
EXPECT_NE(outlinePath.generic_string().find("editor/resources/shaders/scene-viewport"), std::string::npos);
}
TEST(SceneViewportShaderPathsTest, ShaderLoaderLoadsSceneViewportInfiniteGridShader) {
ShaderLoader loader;
const auto shaderPath = GetSceneViewportInfiniteGridShaderPath();
EXPECT_TRUE(loader.CanLoad(shaderPath));
LoadResult result = loader.Load(shaderPath);
ASSERT_TRUE(result);
ASSERT_NE(result.resource, nullptr);
auto* shader = static_cast<Shader*>(result.resource);
ASSERT_NE(shader, nullptr);
ASSERT_TRUE(shader->IsValid());
const ShaderPass* pass = shader->FindPass("InfiniteGrid");
ASSERT_NE(pass, nullptr);
ASSERT_EQ(pass->variants.Size(), 2u);
ASSERT_EQ(pass->tags.Size(), 1u);
EXPECT_EQ(pass->tags[0].name, "LightMode");
EXPECT_EQ(pass->tags[0].value, "InfiniteGrid");
const ShaderStageVariant* fragment = shader->FindVariant(
"InfiniteGrid",
ShaderType::Fragment,
ShaderBackend::D3D12);
ASSERT_NE(fragment, nullptr);
EXPECT_NE(
std::string(fragment->sourceCode.CStr()).find("XC_EDITOR_SCENE_VIEW_INFINITE_GRID_D3D12_PS"),
std::string::npos);
delete shader;
}
TEST(SceneViewportShaderPathsTest, ResourceManagerLoadsSceneViewportOutlineShaderByResolvedPath) {
ResourceManager& manager = ResourceManager::Get();
manager.Shutdown();
const ResourceHandle<Shader> shaderHandle = manager.Load<Shader>(GetSceneViewportObjectIdOutlineShaderPath());
ASSERT_TRUE(shaderHandle.IsValid());
const ShaderPass* pass = shaderHandle->FindPass("ObjectIdOutline");
ASSERT_NE(pass, nullptr);
ASSERT_EQ(pass->variants.Size(), 2u);
const ShaderStageVariant* fragment = shaderHandle->FindVariant(
"ObjectIdOutline",
ShaderType::Fragment,
ShaderBackend::D3D12);
ASSERT_NE(fragment, nullptr);
EXPECT_NE(
std::string(fragment->sourceCode.CStr()).find("XC_EDITOR_SCENE_VIEW_OBJECT_ID_OUTLINE_D3D12_PS"),
std::string::npos);
manager.Shutdown();
}
} // namespace