using System; using XCEngine; namespace XCEngine.Rendering { public sealed class ScriptableRenderContext { private enum RecordedScenePhase { Opaque = 0, Skybox = 1, Transparent = 3 } private enum RecordedSceneInjectionPoint { BeforeOpaque = 0, AfterOpaque = 1, BeforeSkybox = 2, AfterSkybox = 3, BeforeTransparent = 4, AfterTransparent = 5 } private enum RecordedFullscreenPassType { ColorScale = 0, ShaderVector = 1 } private readonly ulong m_nativeHandle; private CameraData m_cameraData; private LightingData m_lightingData; private ShadowData m_shadowData; private EnvironmentData m_environmentData; private FinalColorData m_finalColorData; private StageColorData m_stageColorData; internal ScriptableRenderContext(ulong nativeHandle) { m_nativeHandle = nativeHandle; } public CameraFrameStage stage => (CameraFrameStage)InternalCalls.Rendering_ScriptableRenderContext_GetStage( m_nativeHandle); public CameraData cameraData => m_cameraData ?? (m_cameraData = ResolveCameraData()); public LightingData lightingData => m_lightingData ?? (m_lightingData = ResolveLightingData()); public ShadowData shadowData => m_shadowData ?? (m_shadowData = ResolveShadowData()); public EnvironmentData environmentData => m_environmentData ?? (m_environmentData = ResolveEnvironmentData()); public FinalColorData finalColorData => m_finalColorData ?? (m_finalColorData = ResolveFinalColorData()); public StageColorData stageColorData => m_stageColorData ?? (m_stageColorData = ResolveStageColorData()); public bool RecordScene() { return InternalCalls .Rendering_ScriptableRenderContext_RecordScene( m_nativeHandle); } public bool RecordOpaqueScenePhase() { return RecordScenePhaseInternal( RecordedScenePhase.Opaque); } public bool RecordSkyboxScenePhase() { return RecordScenePhaseInternal( RecordedScenePhase.Skybox); } public bool RecordTransparentScenePhase() { return RecordScenePhaseInternal( RecordedScenePhase.Transparent); } public bool RecordBeforeOpaqueInjection() { return RecordSceneInjectionPointInternal( RecordedSceneInjectionPoint.BeforeOpaque); } public bool RecordAfterOpaqueInjection() { return RecordSceneInjectionPointInternal( RecordedSceneInjectionPoint.AfterOpaque); } public bool RecordBeforeSkyboxInjection() { return RecordSceneInjectionPointInternal( RecordedSceneInjectionPoint.BeforeSkybox); } public bool RecordAfterSkyboxInjection() { return RecordSceneInjectionPointInternal( RecordedSceneInjectionPoint.AfterSkybox); } public bool RecordBeforeTransparentInjection() { return RecordSceneInjectionPointInternal( RecordedSceneInjectionPoint.BeforeTransparent); } public bool RecordAfterTransparentInjection() { return RecordSceneInjectionPointInternal( RecordedSceneInjectionPoint.AfterTransparent); } public bool RecordColorScaleFullscreenPass( Vector4 colorScale) { return RecordFullscreenPassInternal( RecordedFullscreenPassType.ColorScale, string.Empty, string.Empty, colorScale); } public bool RecordShaderVectorFullscreenPass( string shaderPath, Vector4 vectorPayload, string passName = null) { if (string.IsNullOrEmpty(shaderPath)) { throw new ArgumentException( "Fullscreen shader path cannot be null or empty.", nameof(shaderPath)); } return RecordFullscreenPassInternal( RecordedFullscreenPassType.ShaderVector, shaderPath, passName ?? string.Empty, vectorPayload); } private bool RecordScenePhaseInternal( RecordedScenePhase scenePhase) { return InternalCalls .Rendering_ScriptableRenderContext_RecordScenePhase( m_nativeHandle, (int)scenePhase); } private bool RecordSceneInjectionPointInternal( RecordedSceneInjectionPoint injectionPoint) { return InternalCalls .Rendering_ScriptableRenderContext_RecordSceneInjectionPoint( m_nativeHandle, (int)injectionPoint); } private bool RecordFullscreenPassInternal( RecordedFullscreenPassType passType, string shaderPath, string passName, Vector4 vectorPayload) { return InternalCalls .Rendering_ScriptableRenderContext_RecordFullscreenPass( m_nativeHandle, (int)passType, shaderPath, passName, ref vectorPayload); } private CameraData ResolveCameraData() { Matrix4x4 view; Matrix4x4 projection; Matrix4x4 viewProjection; Vector3 worldPosition; Vector3 worldRight; Vector3 worldUp; Vector3 worldForward; Color clearColor; InternalCalls .Rendering_ScriptableRenderContext_GetCameraView( m_nativeHandle, out view); InternalCalls .Rendering_ScriptableRenderContext_GetCameraProjection( m_nativeHandle, out projection); InternalCalls .Rendering_ScriptableRenderContext_GetCameraViewProjection( m_nativeHandle, out viewProjection); InternalCalls .Rendering_ScriptableRenderContext_GetCameraWorldPosition( m_nativeHandle, out worldPosition); InternalCalls .Rendering_ScriptableRenderContext_GetCameraWorldRight( m_nativeHandle, out worldRight); InternalCalls .Rendering_ScriptableRenderContext_GetCameraWorldUp( m_nativeHandle, out worldUp); InternalCalls .Rendering_ScriptableRenderContext_GetCameraWorldForward( m_nativeHandle, out worldForward); InternalCalls .Rendering_ScriptableRenderContext_GetCameraClearColor( m_nativeHandle, out clearColor); return new CameraData( view, projection, viewProjection, worldPosition, worldRight, worldUp, worldForward, clearColor, (RenderClearFlags)InternalCalls .Rendering_ScriptableRenderContext_GetCameraClearFlags( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetCameraPerspectiveProjection( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetCameraVerticalFovRadians( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetCameraOrthographicSize( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetCameraAspectRatio( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetCameraNearClipPlane( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetCameraFarClipPlane( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetCameraViewportWidth( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetCameraViewportHeight( m_nativeHandle)); } private LightingData ResolveLightingData() { Vector3 mainDirectionalLightDirection; Color mainDirectionalLightColor; InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalLightDirection( m_nativeHandle, out mainDirectionalLightDirection); InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalLightColor( m_nativeHandle, out mainDirectionalLightColor); return new LightingData( new DirectionalLightData( InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalLightEnabled( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalLightCastsShadows( m_nativeHandle), mainDirectionalLightDirection, mainDirectionalLightColor, InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalLightIntensity( m_nativeHandle)), InternalCalls .Rendering_ScriptableRenderContext_GetHasMainDirectionalShadow( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetAdditionalLightCount( m_nativeHandle)); } private EnvironmentData ResolveEnvironmentData() { Color skyboxTopColor; Color skyboxHorizonColor; Color skyboxBottomColor; InternalCalls .Rendering_ScriptableRenderContext_GetEnvironmentSkyboxTopColor( m_nativeHandle, out skyboxTopColor); InternalCalls .Rendering_ScriptableRenderContext_GetEnvironmentSkyboxHorizonColor( m_nativeHandle, out skyboxHorizonColor); InternalCalls .Rendering_ScriptableRenderContext_GetEnvironmentSkyboxBottomColor( m_nativeHandle, out skyboxBottomColor); return new EnvironmentData( (RenderEnvironmentMode)InternalCalls .Rendering_ScriptableRenderContext_GetEnvironmentMode( m_nativeHandle), skyboxTopColor, skyboxHorizonColor, skyboxBottomColor); } private ShadowData ResolveShadowData() { Matrix4x4 viewProjection; InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalShadowViewProjection( m_nativeHandle, out viewProjection); return new ShadowData( new DirectionalShadowData( InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalShadowEnabled( m_nativeHandle), viewProjection, InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalShadowOrthographicHalfExtent( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalShadowNearClipPlane( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalShadowFarClipPlane( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalShadowMapWidth( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalShadowMapHeight( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalShadowWorldTexelSize( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalShadowReceiverDepthBias( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalShadowNormalBiasScale( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalShadowStrength( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalShadowDepthBiasFactor( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetMainDirectionalShadowDepthBiasUnits( m_nativeHandle))); } private FinalColorData ResolveFinalColorData() { Vector4 finalColorScale; InternalCalls .Rendering_ScriptableRenderContext_GetFinalColorScale( m_nativeHandle, out finalColorScale); FinalColorSettings settings = FinalColorSettings.CreateDefault(); settings.outputTransferMode = (FinalColorOutputTransferMode)InternalCalls .Rendering_ScriptableRenderContext_GetFinalColorOutputTransferMode( m_nativeHandle); settings.exposureMode = (FinalColorExposureMode)InternalCalls .Rendering_ScriptableRenderContext_GetFinalColorExposureMode( m_nativeHandle); settings.exposureValue = InternalCalls .Rendering_ScriptableRenderContext_GetFinalColorExposureValue( m_nativeHandle); settings.toneMappingMode = (FinalColorToneMappingMode)InternalCalls .Rendering_ScriptableRenderContext_GetFinalColorToneMappingMode( m_nativeHandle); settings.finalColorScale = finalColorScale; return new FinalColorData( settings, InternalCalls .Rendering_ScriptableRenderContext_GetFinalColorHasPipelineDefaults( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetFinalColorHasCameraOverrides( m_nativeHandle)); } private StageColorData ResolveStageColorData() { return new StageColorData( (CameraFrameColorSource)InternalCalls .Rendering_ScriptableRenderContext_GetStageColorSource( m_nativeHandle), InternalCalls .Rendering_ScriptableRenderContext_GetStageUsesGraphManagedOutputColor( m_nativeHandle)); } } }