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”稳定得多。 这会比“看到哪改哪、边做边塞进现有 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/SceneViewportOverlayBuilder.cpp
src/Viewport/SceneViewportOverlayRenderer.cpp src/Viewport/SceneViewportOverlayRenderer.cpp
src/Viewport/Passes/SceneViewportEditorOverlayPass.cpp src/Viewport/Passes/SceneViewportEditorOverlayPass.cpp
src/Viewport/Passes/SceneViewportGridPass.cpp
src/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp
src/panels/GameViewPanel.cpp src/panels/GameViewPanel.cpp
src/panels/InspectorPanel.cpp src/panels/InspectorPanel.cpp
src/panels/ConsolePanel.cpp src/panels/ConsolePanel.cpp
@@ -102,7 +104,10 @@ target_include_directories(${PROJECT_NAME} PRIVATE
${imgui_SOURCE_DIR}/backends ${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) target_compile_options(${PROJECT_NAME} PRIVATE /utf-8)
if(XCENGINE_ENABLE_MONO_SCRIPTING) 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) { cbuffer GridConstants : register(b0) {
float4x4 gViewProjectionMatrix; float4x4 gViewProjectionMatrix;
float4 gCameraPositionAndScale; float4 gCameraPositionAndScale;

View File

@@ -1,5 +1,5 @@
{ {
"name": "Builtin Infinite Grid", "name": "Scene View Infinite Grid",
"passes": [ "passes": [
{ {
"name": "InfiniteGrid", "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) { cbuffer GridConstants : register(b0) {
float4x4 gViewProjectionMatrix; float4x4 gViewProjectionMatrix;
float4 gCameraPositionAndScale; 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) { cbuffer OutlineConstants : register(b0) {
float4 gViewportSizeAndTexelSize; float4 gViewportSizeAndTexelSize;
float4 gOutlineColor; float4 gOutlineColor;

View File

@@ -1,5 +1,5 @@
{ {
"name": "Builtin Object Id Outline", "name": "Scene View Object Id Outline",
"passes": [ "passes": [
{ {
"name": "ObjectIdOutline", "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) { cbuffer OutlineConstants : register(b0) {
float4 gViewportSizeAndTexelSize; float4 gViewportSizeAndTexelSize;
float4 gOutlineColor; float4 gOutlineColor;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,12 +6,12 @@
#include <XCEngine/Debug/Logger.h> #include <XCEngine/Debug/Logger.h>
#include <XCEngine/RHI/RHICommandList.h> #include <XCEngine/RHI/RHICommandList.h>
#include <XCEngine/RHI/RHIDevice.h> #include <XCEngine/RHI/RHIDevice.h>
#include <XCEngine/Resources/BuiltinResources.h>
#include "Rendering/Detail/ShaderVariantUtils.h" #include "Rendering/Detail/ShaderVariantUtils.h"
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <utility>
namespace XCEngine { namespace XCEngine {
namespace Rendering { namespace Rendering {
@@ -140,6 +140,23 @@ InfiniteGridParameters BuildInfiniteGridParameters(const InfiniteGridPassData& d
return parameters; 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() { void BuiltinInfiniteGridPass::Shutdown() {
DestroyResources(); DestroyResources();
} }
@@ -243,14 +260,21 @@ bool BuiltinInfiniteGridPass::CreateResources(const RenderContext& renderContext
return false; 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_device = renderContext.device;
m_backendType = renderContext.backendType; m_backendType = renderContext.backendType;
m_builtinInfiniteGridShader = Resources::ResourceManager::Get().Load<Resources::Shader>( m_builtinInfiniteGridShader = Resources::ResourceManager::Get().Load<Resources::Shader>(
Resources::GetBuiltinInfiniteGridShaderPath()); m_shaderPath);
if (!m_builtinInfiniteGridShader.IsValid()) { if (!m_builtinInfiniteGridShader.IsValid()) {
Debug::Logger::Get().Error( Debug::Logger::Get().Error(
Debug::LogCategory::Rendering, Debug::LogCategory::Rendering,
"BuiltinInfiniteGridPass failed to load builtin infinite-grid shader resource"); "BuiltinInfiniteGridPass failed to load configured infinite-grid shader resource");
DestroyResources(); DestroyResources();
return false; return false;
} }

View File

@@ -6,7 +6,6 @@
#include "Rendering/Detail/ShaderVariantUtils.h" #include "Rendering/Detail/ShaderVariantUtils.h"
#include "RHI/RHICommandList.h" #include "RHI/RHICommandList.h"
#include "RHI/RHIDevice.h" #include "RHI/RHIDevice.h"
#include "Resources/BuiltinResources.h"
#include <algorithm> #include <algorithm>
#include <utility> #include <utility>
@@ -86,10 +85,24 @@ RHI::GraphicsPipelineDesc CreatePipelineDesc(
} // namespace } // namespace
BuiltinObjectIdOutlinePass::BuiltinObjectIdOutlinePass() { BuiltinObjectIdOutlinePass::BuiltinObjectIdOutlinePass(Containers::String shaderPath)
: m_shaderPath(std::move(shaderPath)) {
ResetState(); 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() { void BuiltinObjectIdOutlinePass::Shutdown() {
DestroyResources(); DestroyResources();
} }
@@ -197,12 +210,19 @@ bool BuiltinObjectIdOutlinePass::CreateResources(const RenderContext& renderCont
return false; 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::ResourceHandle<Resources::Shader> shader = Resources::ResourceManager::Get().Load<Resources::Shader>(
Resources::GetBuiltinObjectIdOutlineShaderPath()); m_shaderPath);
if (!shader.IsValid()) { if (!shader.IsValid()) {
Debug::Logger::Get().Error( Debug::Logger::Get().Error(
Debug::LogCategory::Rendering, Debug::LogCategory::Rendering,
"BuiltinObjectIdOutlinePass failed to load builtin object-id-outline shader resource"); "BuiltinObjectIdOutlinePass failed to load configured object-id-outline shader resource");
ResetState(); ResetState();
return false; 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* kBuiltinDefaultPrimitiveMaterialPath = "builtin://materials/default-primitive";
constexpr const char* kBuiltinForwardLitShaderPath = "builtin://shaders/forward-lit"; constexpr const char* kBuiltinForwardLitShaderPath = "builtin://shaders/forward-lit";
constexpr const char* kBuiltinObjectIdShaderPath = "builtin://shaders/object-id"; 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 const char* kBuiltinDefaultPrimitiveTexturePath = "builtin://textures/default-primitive-albedo";
constexpr float kPi = 3.14159265358979323846f; constexpr float kPi = 3.14159265358979323846f;
@@ -45,10 +43,6 @@ constexpr const char* kBuiltinForwardLitShaderManifestRelativePath =
"engine/assets/builtin/shaders/forward-lit/forward-lit.shader"; "engine/assets/builtin/shaders/forward-lit/forward-lit.shader";
constexpr const char* kBuiltinObjectIdShaderManifestRelativePath = constexpr const char* kBuiltinObjectIdShaderManifestRelativePath =
"engine/assets/builtin/shaders/object-id/object-id.shader"; "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) { Containers::String NormalizeBuiltinAssetPath(const std::filesystem::path& path) {
return Containers::String(path.lexically_normal().generic_string().c_str()); 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)) { if (builtinShaderPath == Containers::String(kBuiltinObjectIdShaderPath)) {
return kBuiltinObjectIdShaderManifestRelativePath; return kBuiltinObjectIdShaderManifestRelativePath;
} }
if (builtinShaderPath == Containers::String(kBuiltinObjectIdOutlineShaderPath)) {
return kBuiltinObjectIdOutlineShaderManifestRelativePath;
}
if (builtinShaderPath == Containers::String(kBuiltinInfiniteGridShaderPath)) {
return kBuiltinInfiniteGridShaderManifestRelativePath;
}
return nullptr; return nullptr;
} }
@@ -652,14 +640,6 @@ Shader* BuildBuiltinObjectIdShader(const Containers::String& path) {
return TryLoadBuiltinShaderFromManifest(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) { Material* BuildDefaultPrimitiveMaterial(const Containers::String& path) {
auto* material = new Material(); auto* material = new Material();
IResource::ConstructParams params; IResource::ConstructParams params;
@@ -766,14 +746,6 @@ Containers::String GetBuiltinObjectIdShaderPath() {
return Containers::String(kBuiltinObjectIdShaderPath); return Containers::String(kBuiltinObjectIdShaderPath);
} }
Containers::String GetBuiltinObjectIdOutlineShaderPath() {
return Containers::String(kBuiltinObjectIdOutlineShaderPath);
}
Containers::String GetBuiltinInfiniteGridShaderPath() {
return Containers::String(kBuiltinInfiniteGridShaderPath);
}
Containers::String GetBuiltinDefaultPrimitiveTexturePath() { Containers::String GetBuiltinDefaultPrimitiveTexturePath() {
return Containers::String(kBuiltinDefaultPrimitiveTexturePath); return Containers::String(kBuiltinDefaultPrimitiveTexturePath);
} }
@@ -866,10 +838,6 @@ LoadResult CreateBuiltinShaderResource(const Containers::String& path) {
shader = BuildBuiltinForwardLitShader(path); shader = BuildBuiltinForwardLitShader(path);
} else if (path == GetBuiltinObjectIdShaderPath()) { } else if (path == GetBuiltinObjectIdShaderPath()) {
shader = BuildBuiltinObjectIdShader(path); shader = BuildBuiltinObjectIdShader(path);
} else if (path == GetBuiltinObjectIdOutlineShaderPath()) {
shader = BuildBuiltinObjectIdOutlineShader(path);
} else if (path == GetBuiltinInfiniteGridShaderPath()) {
shader = BuildBuiltinInfiniteGridShader(path);
} else { } else {
return LoadResult(Containers::String("Unknown builtin shader: ") + path); 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("test.xcshader"));
EXPECT_TRUE(loader.CanLoad(GetBuiltinForwardLitShaderPath())); EXPECT_TRUE(loader.CanLoad(GetBuiltinForwardLitShaderPath()));
EXPECT_TRUE(loader.CanLoad(GetBuiltinObjectIdShaderPath())); 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.txt"));
EXPECT_FALSE(loader.CanLoad("test.png")); EXPECT_FALSE(loader.CanLoad("test.png"));
} }
@@ -545,72 +543,6 @@ TEST(ShaderLoader, LoadBuiltinObjectIdShaderBuildsBackendVariants) {
delete shader; 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) { TEST(ShaderLoader, ResourceManagerLazilyLoadsBuiltinForwardLitShader) {
ResourceManager& manager = ResourceManager::Get(); ResourceManager& manager = ResourceManager::Get();
manager.Shutdown(); manager.Shutdown();
@@ -624,14 +556,6 @@ TEST(ShaderLoader, ResourceManagerLazilyLoadsBuiltinForwardLitShader) {
ASSERT_TRUE(objectIdShaderHandle.IsValid()); ASSERT_TRUE(objectIdShaderHandle.IsValid());
ASSERT_NE(objectIdShaderHandle->FindPass("ObjectId"), nullptr); 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(); manager.Shutdown();
} }
@@ -681,18 +605,6 @@ TEST(ShaderLoader, ResourceManagerLoadsBuiltinShadersOutsideProjectWorkingDirect
ShaderType::Fragment, ShaderType::Fragment,
ShaderBackend::Vulkan, ShaderBackend::Vulkan,
"XC_BUILTIN_OBJECT_ID_VULKAN_PS"); "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); fs::current_path(previousPath);
manager.SetResourceRoot(previousResourceRoot); manager.SetResourceRoot(previousResourceRoot);

View File

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