diff --git a/managed/CMakeLists.txt b/managed/CMakeLists.txt index 0c6c20c8..36b731a9 100644 --- a/managed/CMakeLists.txt +++ b/managed/CMakeLists.txt @@ -200,6 +200,7 @@ set(XCENGINE_SCRIPT_CORE_SOURCES set(XCENGINE_RENDER_PIPELINES_UNIVERSAL_SOURCES # Rendering renderer model ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Renderer/RenderingData.cs + ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Renderer/RendererCameraRequestContext.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Renderer/RendererBackedRenderPipeline.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Renderer/RendererBackedRenderPipelineAsset.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Renderer/RendererRecordingContext.cs @@ -240,6 +241,7 @@ set(XCENGINE_GAME_SCRIPT_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/GameScripts/PhysicsApiProbe.cs ${CMAKE_CURRENT_SOURCE_DIR}/GameScripts/PhysicsEventProbe.cs ${CMAKE_CURRENT_SOURCE_DIR}/GameScripts/RenderPipelineApiProbe.cs + ${CMAKE_CURRENT_SOURCE_DIR}/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs ${CMAKE_CURRENT_SOURCE_DIR}/GameScripts/SerializeFieldProbe.cs ${CMAKE_CURRENT_SOURCE_DIR}/GameScripts/TagLayerProbe.cs ${CMAKE_CURRENT_SOURCE_DIR}/GameScripts/TickLogProbe.cs diff --git a/managed/GameScripts/RenderPipelineApiProbe.cs b/managed/GameScripts/RenderPipelineApiProbe.cs index 51525781..ec77f2a5 100644 --- a/managed/GameScripts/RenderPipelineApiProbe.cs +++ b/managed/GameScripts/RenderPipelineApiProbe.cs @@ -800,24 +800,38 @@ namespace Gameplay } } - public sealed class ManagedCameraRequestConfiguredRenderPipelineProbeAsset - : ScriptableRenderPipelineAsset + internal sealed class ManagedCameraRequestConfiguredRendererData + : ScriptableRendererData { - protected override ScriptableRenderPipeline CreatePipeline() + protected override ScriptableRenderer CreateRenderer() { - return new ManagedRenderPipelineProbe(); + return new ProbeSceneRenderer(); } protected override void ConfigureCameraRenderRequest( - ScriptableRenderPipelineCameraRequestContext context) + RendererCameraRequestContext context) { - if (context != null && context.hasDirectionalShadow) + if (context != null && + context.hasDirectionalShadow) { context.ClearDirectionalShadow(); } } } + public sealed class ManagedCameraRequestConfiguredRenderPipelineProbeAsset + : RendererBackedRenderPipelineAsset + { + private readonly ManagedCameraRequestConfiguredRendererData + m_rendererData = + new ManagedCameraRequestConfiguredRendererData(); + + protected override ScriptableRendererData GetRendererData() + { + return m_rendererData; + } + } + public sealed class ManagedRenderContextCameraDataProbeAsset : ScriptableRenderPipelineAsset { diff --git a/managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs b/managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs new file mode 100644 index 00000000..9a595ab0 --- /dev/null +++ b/managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs @@ -0,0 +1,77 @@ +using System.Reflection; +using XCEngine; +using XCEngine.Rendering; +using XCEngine.Rendering.Renderer; + +namespace Gameplay +{ + public sealed class ScriptableRenderContextApiSurfaceProbe + : MonoBehaviour + { + public bool HasPublicContextRecordScene; + public bool HasPublicContextRecordOpaqueScenePhase; + public bool HasPublicContextRecordBeforeOpaqueInjection; + public bool HasPublicContextRecordShaderVectorFullscreenPass; + public bool HasPublicRendererRecordOpaqueScenePhase; + public bool HasPublicRendererRecordShaderVectorFullscreenPass; + public bool HasPublicCameraRequestContextHasDirectionalShadow; + public bool HasPublicCameraRequestContextClearDirectionalShadow; + public bool HasPublicRendererCameraRequestContextHasDirectionalShadow; + public bool HasPublicRendererCameraRequestContextClearDirectionalShadow; + + public void Start() + { + const BindingFlags PublicInstanceMethodFlags = + BindingFlags.Instance | BindingFlags.Public; + System.Type contextType = + typeof(ScriptableRenderContext); + System.Type rendererContextType = + typeof(RendererRecordingContext); + System.Type cameraRequestContextType = + typeof(ScriptableRenderPipelineCameraRequestContext); + System.Type rendererCameraRequestContextType = + typeof(RendererCameraRequestContext); + + HasPublicContextRecordScene = + contextType.GetMethod( + "RecordScene", + PublicInstanceMethodFlags) != null; + HasPublicContextRecordOpaqueScenePhase = + contextType.GetMethod( + "RecordOpaqueScenePhase", + PublicInstanceMethodFlags) != null; + HasPublicContextRecordBeforeOpaqueInjection = + contextType.GetMethod( + "RecordBeforeOpaqueInjection", + PublicInstanceMethodFlags) != null; + HasPublicContextRecordShaderVectorFullscreenPass = + contextType.GetMethod( + "RecordShaderVectorFullscreenPass", + PublicInstanceMethodFlags) != null; + HasPublicRendererRecordOpaqueScenePhase = + rendererContextType.GetMethod( + "RecordOpaqueScenePhase", + PublicInstanceMethodFlags) != null; + HasPublicRendererRecordShaderVectorFullscreenPass = + rendererContextType.GetMethod( + "RecordShaderVectorFullscreenPass", + PublicInstanceMethodFlags) != null; + HasPublicCameraRequestContextHasDirectionalShadow = + cameraRequestContextType.GetProperty( + "hasDirectionalShadow", + PublicInstanceMethodFlags) != null; + HasPublicCameraRequestContextClearDirectionalShadow = + cameraRequestContextType.GetMethod( + "ClearDirectionalShadow", + PublicInstanceMethodFlags) != null; + HasPublicRendererCameraRequestContextHasDirectionalShadow = + rendererCameraRequestContextType.GetProperty( + "hasDirectionalShadow", + PublicInstanceMethodFlags) != null; + HasPublicRendererCameraRequestContextClearDirectionalShadow = + rendererCameraRequestContextType.GetMethod( + "ClearDirectionalShadow", + PublicInstanceMethodFlags) != null; + } + } +} diff --git a/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderContext.cs b/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderContext.cs index b68c38cb..0b69a09d 100644 --- a/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderContext.cs +++ b/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderContext.cs @@ -73,61 +73,61 @@ namespace XCEngine.Rendering m_nativeHandle); } - public bool RecordOpaqueScenePhase() + internal bool RecordOpaqueScenePhase() { return RecordScenePhaseInternal( RecordedScenePhase.Opaque); } - public bool RecordSkyboxScenePhase() + internal bool RecordSkyboxScenePhase() { return RecordScenePhaseInternal( RecordedScenePhase.Skybox); } - public bool RecordTransparentScenePhase() + internal bool RecordTransparentScenePhase() { return RecordScenePhaseInternal( RecordedScenePhase.Transparent); } - public bool RecordBeforeOpaqueInjection() + internal bool RecordBeforeOpaqueInjection() { return RecordSceneInjectionPointInternal( RecordedSceneInjectionPoint.BeforeOpaque); } - public bool RecordAfterOpaqueInjection() + internal bool RecordAfterOpaqueInjection() { return RecordSceneInjectionPointInternal( RecordedSceneInjectionPoint.AfterOpaque); } - public bool RecordBeforeSkyboxInjection() + internal bool RecordBeforeSkyboxInjection() { return RecordSceneInjectionPointInternal( RecordedSceneInjectionPoint.BeforeSkybox); } - public bool RecordAfterSkyboxInjection() + internal bool RecordAfterSkyboxInjection() { return RecordSceneInjectionPointInternal( RecordedSceneInjectionPoint.AfterSkybox); } - public bool RecordBeforeTransparentInjection() + internal bool RecordBeforeTransparentInjection() { return RecordSceneInjectionPointInternal( RecordedSceneInjectionPoint.BeforeTransparent); } - public bool RecordAfterTransparentInjection() + internal bool RecordAfterTransparentInjection() { return RecordSceneInjectionPointInternal( RecordedSceneInjectionPoint.AfterTransparent); } - public bool RecordColorScaleFullscreenPass( + internal bool RecordColorScaleFullscreenPass( Vector4 colorScale) { return RecordFullscreenPassInternal( @@ -137,7 +137,7 @@ namespace XCEngine.Rendering colorScale); } - public bool RecordShaderVectorFullscreenPass( + internal bool RecordShaderVectorFullscreenPass( string shaderPath, Vector4 vectorPayload, string passName = null) diff --git a/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelineCameraRequestContext.cs b/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelineCameraRequestContext.cs index 76690f87..7e3b706e 100644 --- a/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelineCameraRequestContext.cs +++ b/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelineCameraRequestContext.cs @@ -21,12 +21,12 @@ namespace XCEngine.Rendering .Rendering_ScriptableRenderPipelineCameraRequestContext_GetRenderedRequestCount( m_nativeHandle); - public bool hasDirectionalShadow => + internal bool hasDirectionalShadow => InternalCalls .Rendering_ScriptableRenderPipelineCameraRequestContext_GetHasDirectionalShadow( m_nativeHandle); - public void ClearDirectionalShadow() + internal void ClearDirectionalShadow() { InternalCalls .Rendering_ScriptableRenderPipelineCameraRequestContext_ClearDirectionalShadow( diff --git a/managed/XCEngine.ScriptCore/Rendering/FirstParty/DisableDirectionalShadowRendererFeature.cs b/managed/XCEngine.ScriptCore/Rendering/FirstParty/DisableDirectionalShadowRendererFeature.cs index 08ec100a..f47a4a9d 100644 --- a/managed/XCEngine.ScriptCore/Rendering/FirstParty/DisableDirectionalShadowRendererFeature.cs +++ b/managed/XCEngine.ScriptCore/Rendering/FirstParty/DisableDirectionalShadowRendererFeature.cs @@ -8,7 +8,7 @@ namespace XCEngine.Rendering.FirstParty : ScriptableRendererFeature { public override void ConfigureCameraRenderRequest( - ScriptableRenderPipelineCameraRequestContext context) + RendererCameraRequestContext context) { if (context != null && context.hasDirectionalShadow) diff --git a/managed/XCEngine.ScriptCore/Rendering/Renderer/RendererBackedRenderPipelineAsset.cs b/managed/XCEngine.ScriptCore/Rendering/Renderer/RendererBackedRenderPipelineAsset.cs index 2f7454a5..504f3ed0 100644 --- a/managed/XCEngine.ScriptCore/Rendering/Renderer/RendererBackedRenderPipelineAsset.cs +++ b/managed/XCEngine.ScriptCore/Rendering/Renderer/RendererBackedRenderPipelineAsset.cs @@ -26,8 +26,10 @@ namespace XCEngine.Rendering.Renderer ResolveRendererData(); if (rendererData != null) { + RendererCameraRequestContext rendererContext = + new RendererCameraRequestContext(context); rendererData.ConfigureCameraRenderRequestInstance( - context); + rendererContext); } } diff --git a/managed/XCEngine.ScriptCore/Rendering/Renderer/RendererCameraRequestContext.cs b/managed/XCEngine.ScriptCore/Rendering/Renderer/RendererCameraRequestContext.cs new file mode 100644 index 00000000..9742d182 --- /dev/null +++ b/managed/XCEngine.ScriptCore/Rendering/Renderer/RendererCameraRequestContext.cs @@ -0,0 +1,39 @@ +using XCEngine; +using XCEngine.Rendering; + +namespace XCEngine.Rendering.Renderer +{ + public sealed class RendererCameraRequestContext + { + private readonly ScriptableRenderPipelineCameraRequestContext + m_requestContext; + + internal RendererCameraRequestContext( + ScriptableRenderPipelineCameraRequestContext requestContext) + { + m_requestContext = requestContext; + } + + public int renderedBaseCameraCount => + m_requestContext != null + ? m_requestContext.renderedBaseCameraCount + : 0; + + public int renderedRequestCount => + m_requestContext != null + ? m_requestContext.renderedRequestCount + : 0; + + public bool hasDirectionalShadow => + m_requestContext != null && + m_requestContext.hasDirectionalShadow; + + public void ClearDirectionalShadow() + { + if (m_requestContext != null) + { + m_requestContext.ClearDirectionalShadow(); + } + } + } +} diff --git a/managed/XCEngine.ScriptCore/Rendering/Renderer/ScriptableRendererData.cs b/managed/XCEngine.ScriptCore/Rendering/Renderer/ScriptableRendererData.cs index db8a2a21..ccc0d932 100644 --- a/managed/XCEngine.ScriptCore/Rendering/Renderer/ScriptableRendererData.cs +++ b/managed/XCEngine.ScriptCore/Rendering/Renderer/ScriptableRendererData.cs @@ -23,7 +23,7 @@ namespace XCEngine.Rendering.Renderer } internal void ConfigureCameraRenderRequestInstance( - ScriptableRenderPipelineCameraRequestContext context) + RendererCameraRequestContext context) { ConfigureCameraRenderRequest(context); @@ -72,7 +72,7 @@ namespace XCEngine.Rendering.Renderer } protected virtual void ConfigureCameraRenderRequest( - ScriptableRenderPipelineCameraRequestContext context) + RendererCameraRequestContext context) { } diff --git a/managed/XCEngine.ScriptCore/Rendering/Renderer/ScriptableRendererFeature.cs b/managed/XCEngine.ScriptCore/Rendering/Renderer/ScriptableRendererFeature.cs index 0e259ef1..7cb10dbe 100644 --- a/managed/XCEngine.ScriptCore/Rendering/Renderer/ScriptableRendererFeature.cs +++ b/managed/XCEngine.ScriptCore/Rendering/Renderer/ScriptableRendererFeature.cs @@ -16,7 +16,7 @@ namespace XCEngine.Rendering.Renderer } public virtual void ConfigureCameraRenderRequest( - ScriptableRenderPipelineCameraRequestContext context) + RendererCameraRequestContext context) { } diff --git a/tests/scripting/test_mono_script_runtime.cpp b/tests/scripting/test_mono_script_runtime.cpp index 1285f6f2..b78a9c0c 100644 --- a/tests/scripting/test_mono_script_runtime.cpp +++ b/tests/scripting/test_mono_script_runtime.cpp @@ -1133,6 +1133,88 @@ TEST_F( EXPECT_FALSE(request.directionalShadow.IsValid()); } +TEST_F( + MonoScriptRuntimeTest, + ScriptableRenderContextPublicApiSurfaceKeepsRendererHelpersOutOfCore) { + Scene* runtimeScene = + CreateScene("ScriptableRenderContextApiSurfaceScene"); + GameObject* selectionObject = + runtimeScene->CreateGameObject( + "ScriptableRenderContextApiSurfaceSelection"); + ScriptComponent* selectionScript = + AddScript( + selectionObject, + "Gameplay", + "ScriptableRenderContextApiSurfaceProbe"); + ASSERT_NE(selectionScript, nullptr); + + engine->OnRuntimeStart(runtimeScene); + engine->OnUpdate(0.016f); + + bool hasPublicContextRecordScene = false; + bool hasPublicContextRecordOpaqueScenePhase = false; + bool hasPublicContextRecordBeforeOpaqueInjection = false; + bool hasPublicContextRecordShaderVectorFullscreenPass = false; + bool hasPublicRendererRecordOpaqueScenePhase = false; + bool hasPublicRendererRecordShaderVectorFullscreenPass = false; + bool hasPublicCameraRequestContextHasDirectionalShadow = false; + bool hasPublicCameraRequestContextClearDirectionalShadow = false; + bool hasPublicRendererCameraRequestContextHasDirectionalShadow = false; + bool hasPublicRendererCameraRequestContextClearDirectionalShadow = false; + + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasPublicContextRecordScene", + hasPublicContextRecordScene)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasPublicContextRecordOpaqueScenePhase", + hasPublicContextRecordOpaqueScenePhase)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasPublicContextRecordBeforeOpaqueInjection", + hasPublicContextRecordBeforeOpaqueInjection)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasPublicContextRecordShaderVectorFullscreenPass", + hasPublicContextRecordShaderVectorFullscreenPass)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasPublicRendererRecordOpaqueScenePhase", + hasPublicRendererRecordOpaqueScenePhase)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasPublicRendererRecordShaderVectorFullscreenPass", + hasPublicRendererRecordShaderVectorFullscreenPass)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasPublicCameraRequestContextHasDirectionalShadow", + hasPublicCameraRequestContextHasDirectionalShadow)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasPublicCameraRequestContextClearDirectionalShadow", + hasPublicCameraRequestContextClearDirectionalShadow)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasPublicRendererCameraRequestContextHasDirectionalShadow", + hasPublicRendererCameraRequestContextHasDirectionalShadow)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasPublicRendererCameraRequestContextClearDirectionalShadow", + hasPublicRendererCameraRequestContextClearDirectionalShadow)); + + EXPECT_TRUE(hasPublicContextRecordScene); + EXPECT_FALSE(hasPublicContextRecordOpaqueScenePhase); + EXPECT_FALSE(hasPublicContextRecordBeforeOpaqueInjection); + EXPECT_FALSE(hasPublicContextRecordShaderVectorFullscreenPass); + EXPECT_TRUE(hasPublicRendererRecordOpaqueScenePhase); + EXPECT_TRUE(hasPublicRendererRecordShaderVectorFullscreenPass); + EXPECT_FALSE(hasPublicCameraRequestContextHasDirectionalShadow); + EXPECT_FALSE(hasPublicCameraRequestContextClearDirectionalShadow); + EXPECT_TRUE(hasPublicRendererCameraRequestContextHasDirectionalShadow); + EXPECT_TRUE(hasPublicRendererCameraRequestContextClearDirectionalShadow); +} + TEST_F( MonoScriptRuntimeTest, ManagedRenderContextExposesCameraDataThroughRenderingData) {