Esempio n. 1
0
            protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
            {
                var graphicsCompositor = new GraphicsCompositor();

                foreach (var cameraSlot in Parameters.Cameras)
                {
                    graphicsCompositor.Cameras.Add(cameraSlot);
                }
                foreach (var renderStage in Parameters.RenderStages)
                {
                    graphicsCompositor.RenderStages.Add(renderStage);
                }
                foreach (var renderFeature in Parameters.RenderFeatures)
                {
                    graphicsCompositor.RenderFeatures.Add(renderFeature);
                }
                graphicsCompositor.Game       = Parameters.Game;
                graphicsCompositor.SingleView = Parameters.SingleView;
                graphicsCompositor.Editor     = Parameters.Editor;

                var assetManager = new ContentManager();

                assetManager.Save(Url, graphicsCompositor);

                return(Task.FromResult(ResultStatus.Successful));
            }
Esempio n. 2
0
 /// <summary>
 /// Request a thumbnail build action to the preview game.
 /// </summary>
 /// <param name="thumbnailUrl">The url of the thumbnail on the storage</param>
 /// <param name="scene">The scene to use to draw the thumbnail</param>
 /// <param name="graphicsCompositor">The graphics compositor used to render the scene</param>
 /// <param name="provider">The file provider to use when executing the build request.</param>
 /// <param name="thumbnailSize">The size of the thumbnail to create</param>
 /// <param name="colorSpace"></param>
 /// <param name="renderingMode">the rendering mode (hdr or ldr).</param>
 /// <param name="logger">The logger</param>
 /// <param name="logLevel">The dependency build status log level</param>
 /// <param name="postProcessThumbnail">The post-process code to customize thumbnail.</param>
 /// <returns>A task on which the user can wait for the thumbnail completion</returns>
 public ResultStatus BuildThumbnail(string thumbnailUrl, Scene scene, GraphicsCompositor graphicsCompositor, DatabaseFileProvider provider, Int2 thumbnailSize, ColorSpace colorSpace, RenderingMode renderingMode, ILogger logger, LogMessageType logLevel, PostProcessThumbnailDelegate postProcessThumbnail = null)
 {
     return(ProcessThumbnailRequests(new ThumbnailBuildRequest(thumbnailUrl, scene, graphicsCompositor, provider, thumbnailSize, colorSpace, renderingMode, logger, logLevel)
     {
         PostProcessThumbnail = postProcessThumbnail
     }));
 }
Esempio n. 3
0
        protected virtual CameraComponent CreateCamera(GraphicsCompositor graphicsCompositor)
        {
            var cameraComponent = new CameraComponent
            {
                Slot = new SceneCameraSlotId(graphicsCompositor.Cameras[0].Id),
                UseCustomAspectRatio = true,
                AspectRatio          = Parameters.ThumbnailSize.X / (float)Parameters.ThumbnailSize.Y,
            };

            // setup the camera
            var cameraEntity = new Entity("Thumbnail Camera")
            {
                cameraComponent
            };
            var cameraToFront = new Vector2(1f / (float)Math.Tan(MathUtil.DegreesToRadians(cameraComponent.VerticalFieldOfView / 2 * cameraComponent.AspectRatio)),
                                            1f / (float)Math.Tan(MathUtil.DegreesToRadians(cameraComponent.VerticalFieldOfView / 2)));
            var cameraDistanceFromCenter = 1f + Math.Max(cameraToFront.X, cameraToFront.Y); // we want the front face of the element to be fully visible (not only center)

            cameraEntity.Transform.Position = new Vector3(0, 0, cameraDistanceFromCenter);

            // rotate a bit the camera to have a nice viewing angle.
            var rotationQuaternion = Quaternion.RotationX(-MathUtil.Pi / 6) * Quaternion.RotationY(-MathUtil.Pi / 4);

            rotationQuaternion.Rotate(ref cameraEntity.Transform.Position);
            cameraEntity.Transform.Rotation = Quaternion.RotationX(-MathUtil.Pi / 6) * Quaternion.RotationY(-MathUtil.Pi / 4);

            cameraComponent.NearClipPlane = cameraDistanceFromCenter / 50f;
            cameraComponent.FarClipPlane  = cameraDistanceFromCenter * 50f;

            return(cameraComponent);
        }
Esempio n. 4
0
        private void AttachCameraToSlot(GraphicsCompositor graphicsCompositor, CameraComponent camera)
        {
            if (!camera.Enabled)
            {
                throw new InvalidOperationException($"The camera [{camera.Entity.Name}] is disabled and can't be attached");
            }
            if (camera.Slot.AttachedCompositor != null)
            {
                throw new InvalidOperationException($"The camera [{camera.Entity.Name}] is already attached");
            }

            for (var i = 0; i < graphicsCompositor.Cameras.Count; ++i)
            {
                var slot = graphicsCompositor.Cameras[i];
                if (slot.Id == camera.Slot.Id)
                {
                    if (slot.Camera != null)
                    {
                        throw new InvalidOperationException($"Unable to attach camera [{camera.Entity.Name}] to the graphics compositor. Another camera, [{slot.Camera.Entity.Name}], is enabled and already attached to this slot.");
                    }

                    slot.Camera = camera;
                    camera.Slot.AttachedCompositor = graphicsCompositor;
                    break;
                }
            }
        }
Esempio n. 5
0
        public GraphicsCompositor Compile(bool copyRenderers)
        {
            var graphicsCompositor = new GraphicsCompositor();

            foreach (var cameraSlot in Cameras)
            {
                graphicsCompositor.Cameras.Add(cameraSlot);
            }
            foreach (var renderStage in RenderStages)
            {
                graphicsCompositor.RenderStages.Add(renderStage);
            }
            foreach (var renderFeature in RenderFeatures)
            {
                graphicsCompositor.RenderFeatures.Add(renderFeature);
            }

            if (copyRenderers)
            {
                graphicsCompositor.Game       = Game;
                graphicsCompositor.SingleView = SingleView;
            }

            return(graphicsCompositor);
        }
Esempio n. 6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GameSystemBase" /> class.
 /// </summary>
 /// <param name="registry">The registry.</param>
 /// <remarks>The GameSystem is expecting the following services to be registered: <see cref="IGame" /> and <see cref="IContentManager" />.</remarks>
 public SceneSystem(IServiceRegistry registry)
     : base(registry)
 {
     Enabled            = true;
     Visible            = true;
     GraphicsCompositor = new GraphicsCompositor();
 }
        public static GraphicsCompositor GetFirstForwardRenderer(this GraphicsCompositor compositor, out ForwardRenderer forwardRenderer)
        {
            var topChildRenderer = ((SceneCameraRenderer)compositor.Game).Child;

            forwardRenderer = (topChildRenderer as SceneRendererCollection)?.Children.OfType <ForwardRenderer>().FirstOrDefault() ?? (ForwardRenderer)topChildRenderer;
            return(compositor);
        }
            protected override CameraComponent CreateCamera(GraphicsCompositor graphicsCompositor)
            {
                var camera = base.CreateCamera(graphicsCompositor);

                // Reset rotation, we want to be facing camera
                camera.Entity.Transform.Rotation = Quaternion.Identity;
                return(camera);
            }
Esempio n. 9
0
 /// <summary>
 /// Create a new instance of scene camera.
 /// </summary>
 public TestCamera(GraphicsCompositor graphicsCompositor)
 {
     MoveSpeed     = 10f;
     RotationSpeed = MathUtil.Pi / 2f;
     SceneUnit     = 1;
     Camera.UseCustomAspectRatio = true;
     Camera.Slot = graphicsCompositor.Cameras[0].ToSlotId();
 }
Esempio n. 10
0
        public override void UpdateGraphicsCompositor(GraphicsCompositor graphicsCompositor)
        {
            base.UpdateGraphicsCompositor(graphicsCompositor);

            // We do not want cameras of the scene to attach to any camera slots, so let's remove all the slots.
            // Resolving properly the editor camera is done by EditorTopLevelCompositor anyway
            // Note: make sure to do that after base call so that services can access cameras
            graphicsCompositor.Cameras.Clear();
        }
Esempio n. 11
0
        /// <summary>
        /// Load a preview scene into the preview game.
        /// </summary>
        /// <param name="previewScene">The scene to load as preview</param>
        /// <param name="logger">The logger to use in case of errors.</param>
        /// <returns>The result of the scene load</returns>
        public async Task <ResultStatus> LoadPreviewScene(Scene previewScene, GraphicsCompositor graphicsCompositor, ILogger logger)
        {
            lock (requestLock)
            {
                previewRequest = new PreviewRequest(previewScene, graphicsCompositor, logger);
            }

            return(await previewRequest.RequestCompletion.Task);
        }
Esempio n. 12
0
        protected override void Destroy()
        {
            if (GraphicsCompositor != null)
            {
                GraphicsCompositor.Dispose();
                GraphicsCompositor = null;
            }

            base.Destroy();
        }
Esempio n. 13
0
            protected override CameraComponent CreateCamera(GraphicsCompositor graphicsCompositor)
            {
                var camera        = base.CreateCamera(graphicsCompositor);
                var renderingSize = designResolution / UIEditorController.DesignDensity;

                // Use an orthographic camera
                camera.Projection       = CameraProjectionMode.Orthographic;
                camera.OrthographicSize = Math.Max(renderingSize.X, renderingSize.Y);

                return(camera);
            }
Esempio n. 14
0
 private static void DetachCameraFromAllSlots(CameraComponent camera, GraphicsCompositor graphicsCompositor)
 {
     for (var i = 0; i < graphicsCompositor.Cameras.Count; ++i)
     {
         var slot = graphicsCompositor.Cameras[i];
         if (slot.Camera == camera)
         {
             slot.Camera = null;
         }
     }
     camera.Slot.AttachedCompositor = null;
 }
Esempio n. 15
0
        public virtual void UpdateGraphicsCompositor(GraphicsCompositor graphicsCompositor)
        {
            SceneSystem.GraphicsCompositor      = graphicsCompositor;
            SceneSystem.GraphicsCompositor.Game = new EditorTopLevelCompositor {
                Child = SceneSystem.GraphicsCompositor.Editor, PreviewGame = SceneSystem.GraphicsCompositor.Game
            };

            foreach (var service in EditorServices.Services)
            {
                service.UpdateGraphicsCompositor(this);
            }
        }
Esempio n. 16
0
 /// <summary>
 /// Create a new thumbnail request from entity.
 /// </summary>
 /// <param name="thumbnailUrl">The Url of the thumbnail</param>
 /// <param name="scene">The scene describing the thumbnail to draw</param>
 /// <param name="provider">The provider to use for the request.</param>
 /// <param name="thumbnailSize">The desired size of the thumbnail</param>
 /// <param name="colorSpace">The color space.</param>
 /// <param name="renderingMode">the rendering mode (hdr or ldr).</param>
 /// <param name="logger">The logger</param>
 /// <param name="logLevel">The dependency build status log level</param>
 public ThumbnailBuildRequest(string thumbnailUrl, Scene scene, GraphicsCompositor graphicsCompositor, DatabaseFileProvider provider, Int2 thumbnailSize, ColorSpace colorSpace, RenderingMode renderingMode, ILogger logger, LogMessageType logLevel)
 {
     Logger                = logger;
     Url                   = thumbnailUrl;
     Size                  = thumbnailSize;
     Scene                 = scene;
     GraphicsCompositor    = graphicsCompositor;
     FileProvider          = provider;
     DependencyBuildStatus = logLevel;
     ColorSpace            = colorSpace;
     RenderingMode         = renderingMode;
 }
Esempio n. 17
0
        private void SwitchToScene(string sceneUrl, GraphicsCompositor compositor)
        {
            if (timeout >= 0.0f && sceneUrl == currentSceneUrl)
            {
                return;
            }

            /* don't load ourselves again */
            if (currentScene != null)
            {
                Content.TryGetAssetUrl(currentScene, out string currentUrl);
                if (currentUrl == sceneUrl)
                {
                    timeout = 1.0f;
                    return;
                }
            }

            loadingInProgress = true;
            var localLoadingTask = loadingTask = Content.LoadAsync <Scene>(sceneUrl);

            Log.Info($"Loading: {sceneUrl}");

            Script.AddTask(async() => {
                await loadingTask;

                if (currentScene != null)
                {
                    Content.Unload(currentScene);
                    currentScene.Parent = null;
                }

                /* HACK */
                if (Camera.Enabled)
                {
                    Camera.Enabled = false;
                }

                /* switch compositor, if necessary */
                var currentCompositor = SceneSystem.GraphicsCompositor;
                if (currentCompositor != compositor)
                {
                    SceneSystem.GraphicsCompositor = compositor;
                }

                currentScene        = loadingTask.Result;
                currentScene.Parent = Entity.Scene;
                currentSceneUrl     = sceneUrl;
                loadingInProgress   = false;
            });
        }
Esempio n. 18
0
        public void Init()
        {
            var services = new ServiceRegistry();

            // Create entity manager and camera
            entityManager = new CustomEntityManager(services);

            // Create graphics compositor
            graphicsCompositor = new GraphicsCompositor();
            sceneSystem        = new SceneSystem(services)
            {
                GraphicsCompositor = graphicsCompositor
            };
            services.AddService(typeof(SceneSystem), sceneSystem);
        }
Esempio n. 19
0
        public TestCameraProcessor()
        {
            var services = new ServiceRegistry();

            // Create entity manager and camera
            entityManager = new CustomEntityManager(services);

            // Create graphics compositor
            graphicsCompositor = new GraphicsCompositor();
            sceneSystem        = new SceneSystem(services)
            {
                GraphicsCompositor = graphicsCompositor
            };
            services.AddService(sceneSystem);
        }
Esempio n. 20
0
        protected override void LoadContent()
        {
            var content         = Services.GetSafeServiceAs <ContentManager>();
            var graphicsContext = Services.GetSafeServiceAs <GraphicsContext>();

            if (SplashScreenUrl != null && content.Exists(SplashScreenUrl))
            {
                splashScreenTexture = content.Load <Texture>(SplashScreenUrl, ContentManagerLoaderSettings.StreamingDisabled);
                splashScreenState   = splashScreenTexture != null ? SplashScreenState.Intro : SplashScreenState.Invalid;
                SplashScreenEnabled = true;
            }

            // Preload the scene if it exists and show splash screen
            if (InitialSceneUrl != null && content.Exists(InitialSceneUrl))
            {
                if (SplashScreenEnabled)
                {
                    sceneTask = content.LoadAsync <Scene>(InitialSceneUrl);
                }
                else
                {
                    SceneInstance = new SceneInstance(Services, content.Load <Scene>(InitialSceneUrl));
                }
            }
            else
            {
                SceneInstance ??= new SceneInstance(Services)
                {
                    RootScene = new Scene()
                };
            }

            if (InitialGraphicsCompositorUrl != null && content.Exists(InitialGraphicsCompositorUrl))
            {
                if (SplashScreenEnabled)
                {
                    compositorTask = content.LoadAsync <GraphicsCompositor>(InitialGraphicsCompositorUrl);
                }
                else
                {
                    GraphicsCompositor = content.Load <GraphicsCompositor>(InitialGraphicsCompositorUrl);
                }
            }

            // Create the drawing context
            renderContext     = RenderContext.GetShared(Services);
            renderDrawContext = new RenderDrawContext(Services, renderContext, graphicsContext);
        }
        private async Task ReloadGraphicsCompositor(bool forceIfSame)
        {
            var graphicsCompositorId    = AttachedReferenceManager.GetAttachedReference(settingsProvider.CurrentGameSettings.GraphicsCompositor)?.Id;
            var graphicsCompositorAsset = (GraphicsCompositorViewModel)(graphicsCompositorId.HasValue ? editor.Session.GetAssetById(graphicsCompositorId.Value) : null);

            // Same compositor as before?
            if (graphicsCompositorAsset == currentGraphicsCompositorAsset && !forceIfSame)
            {
                return;
            }

            // TODO: Start listening for changes in this compositor
            currentGraphicsCompositorAsset = graphicsCompositorAsset;

            // TODO: If nothing, fallback to default compositor, or stop rendering?
            if (graphicsCompositorAsset == null)
            {
                return;
            }

            // TODO: Prevent reentrency
            var database = editor.ServiceProvider.Get <GameStudioDatabase>();
            await database.Build(graphicsCompositorAsset.AssetItem);

            await controller.InvokeTask(async() =>
            {
                using (await database.MountInCurrentMicroThread())
                {
                    // Unlaod previous graphics compositor
                    if (loadedGraphicsCompositor != null)
                    {
                        game.Content.Unload(loadedGraphicsCompositor);
                        loadedGraphicsCompositor = null;
                    }
                    else
                    {
                        // Should only happen when graphics compositor is fallback one (i.e. first load or failure)
                        game.SceneSystem.GraphicsCompositor?.Dispose();
                    }

                    game.SceneSystem.GraphicsCompositor = null;

                    // Load and set new graphics compositor
                    loadedGraphicsCompositor = game.Content.Load <GraphicsCompositor>(graphicsCompositorAsset.AssetItem.Location);
                    game.UpdateGraphicsCompositor(loadedGraphicsCompositor);
                }
            });
        }
Esempio n. 22
0
        protected override void Destroy()
        {
            if (SceneInstance != null)
            {
                ((IReferencable)SceneInstance).Release();
                SceneInstance = null;
            }

            if (GraphicsCompositor != null)
            {
                GraphicsCompositor.Dispose();
                GraphicsCompositor = null;
            }

            base.Destroy();
        }
Esempio n. 23
0
        public override void Start()
        {
            if (OutlineGraphicsCompositor != null)
            {
                originalGraphicsCompositor     = SceneSystem.GraphicsCompositor;
                SceneSystem.GraphicsCompositor = OutlineGraphicsCompositor;

                hoverEntity = OutlinePrefab.InstantiateSingle();
                hoverEntity.Get <OutlineEntity>().Material = HoverMaterial;

                selectEntity = OutlinePrefab.InstantiateSingle();
                selectEntity.Get <OutlineEntity>().Material = SelectMaterial;
            }

            entitySelected = new EventReceiver <Entity>(CameraExtensionsDemo.EntitySelected);
            entityHover    = new EventReceiver <Entity>(CameraExtensionsDemo.EntityHover);
        }
Esempio n. 24
0
        public TestCameraProcessor()
        {
            var services = new ServiceRegistry();

            // Create entity manager and camera
            entityManager = new CustomEntityManager(services);

            // Create graphics compositor
            graphicsCompositor = new GraphicsCompositor();
            var graphicsDevice = GraphicsDevice.New(DeviceCreationFlags.Debug);

            services.AddService <IGraphicsDeviceService>(new GraphicsDeviceServiceLocal(graphicsDevice));
            services.AddService(new EffectSystem(services));
            services.AddService(new GraphicsContext(graphicsDevice));
            context = RenderContext.GetShared(services);
            context.PushTagAndRestore(GraphicsCompositor.Current, graphicsCompositor);
        }
Esempio n. 25
0
        protected override Scene CreateScene(GraphicsCompositor graphicsCompositor)
        {
            // create the entity preview scene
            var entityScene = new Scene();

            Entity = CreateEntity();
            if (Entity == null)
            {
                return(null);
            }

            AdjustEntity();

            var camera = CreateCamera(graphicsCompositor);

            entityScene.Entities.Add(camera.Entity);

            SetupLighting(entityScene);

            entityScene.Entities.Add(Entity);

            return(entityScene);
        }
Esempio n. 26
0
        public void ChangeGraphicsCompositor()
        {
            graphicsCompositor.Cameras.Add(new SceneCameraSlot());

            var camera = AddCamera(true, graphicsCompositor.Cameras[0].ToSlotId());

            // Run camera processor
            var cameraProcessor = entityManager.Processors.OfType <CameraProcessor>().Single();

            cameraProcessor.Draw(null);

            // Check if attached to slot 0
            Assert.AreEqual(graphicsCompositor, camera.Slot.AttachedCompositor);
            Assert.AreEqual(camera, graphicsCompositor.Cameras[0].Camera);

            // Change graphics compositor
            var newGraphicsCompositor = new GraphicsCompositor();

            sceneSystem.GraphicsCompositor = newGraphicsCompositor;

            cameraProcessor.Draw(null);

            // Check if detached
            Assert.IsNull(camera.Slot.AttachedCompositor);
            Assert.IsNull(graphicsCompositor.Cameras[0].Camera);

            // Add slot to new graphics compositor and check if attached
            newGraphicsCompositor.Cameras.Add(new SceneCameraSlot {
                Id = camera.Slot.Id
            });

            cameraProcessor.Draw(null);

            // Check if attached to slot 0
            Assert.AreEqual(newGraphicsCompositor, camera.Slot.AttachedCompositor);
            Assert.AreEqual(camera, newGraphicsCompositor.Cameras[0].Camera);
        }
Esempio n. 27
0
 public TestUICamera(GraphicsCompositor graphicsCompositor)
     : base(graphicsCompositor)
 {
 }
Esempio n. 28
0
 public PreviewRequest(Scene scene, GraphicsCompositor graphicsCompositor, ILogger logger)
 {
     Logger             = logger;
     Scene              = scene;
     GraphicsCompositor = graphicsCompositor;
 }
Esempio n. 29
0
        public override void Draw(RenderContext context)
        {
            var graphicsCompositor = Services.GetService <SceneSystem>()?.GraphicsCompositor;

            // Monitor changes in the camera slots of the current compositor
            if (graphicsCompositor != currentCompositor)
            {
                if (currentCompositor != null)
                {
                    currentCompositor.Cameras.CollectionChanged -= OnCameraSlotsChanged;
                }
                currentCompositor = graphicsCompositor;
                if (currentCompositor != null)
                {
                    currentCompositor.Cameras.CollectionChanged += OnCameraSlotsChanged;
                }
                cameraSlotsDirty = true;
            }

            // The compositor, or at least the list of slots, has changed. Let's detach everything
            if (cameraSlotsDirty)
            {
                cameraSlotsDirty = false;
                if (currentCompositor != null)
                {
                    // If we have a current compositor, let's clear all camera that are attached to it.
                    for (var i = 0; i < currentCompositor.Cameras.Count; ++i)
                    {
                        var cameraSlot = currentCompositor.Cameras[i];
                        if (cameraSlot.Camera != null)
                        {
                            cameraSlot.Camera.Slot.AttachedCompositor = null;
                            cameraSlot.Camera = null;
                        }
                    }
                }
                // Let's also check on all cameras if they are still attached to a compositor, then let's detach them.
                foreach (var matchingCamera in ComponentDatas)
                {
                    var camera = matchingCamera.Value;
                    if (camera.Slot.AttachedCompositor != null)
                    {
                        DetachCameraFromSlot(camera);
                    }
                }
            }

            // First pass, handle proper detach when Enabled changed
            foreach (var matchingCamera in ComponentDatas)
            {
                var camera = matchingCamera.Value;
                if (graphicsCompositor != null)
                {
                    if (camera.Enabled && camera.Slot.AttachedCompositor == null)
                    {
                        // Either the slot has been changed and need to be re-attached, or the camera has just been enabled.
                        // Make sure this camera is detached from all slots, we'll re-attach it in the second pass.
                        DetachCameraFromAllSlots(camera, graphicsCompositor);
                    }
                    else if (!camera.Enabled && camera.Slot.AttachedCompositor == graphicsCompositor)
                    {
                        // The camera has been disabled and need to be detached.
                        DetachCameraFromSlot(camera);
                    }
                }
            }

            // Second pass, handle proper attach
            foreach (var matchingCamera in ComponentDatas)
            {
                var camera = matchingCamera.Value;

                if (graphicsCompositor != null)
                {
                    if (camera.Enabled && camera.Slot.AttachedCompositor == null)
                    {
                        // Attach to the new slot
                        AttachCameraToSlot(camera);
                    }
                }

                // In case the camera has a custom aspect ratio, we can update it here
                // otherwise it is screen-dependent and we can only update it in the CameraComponentRenderer.
                if (camera.Enabled && camera.UseCustomAspectRatio)
                {
                    camera.Update();
                }
            }
        }
Esempio n. 30
0
        public override void Draw(GameTime gameTime)
        {
            // Reset the context
            renderContext.Reset();

            var renderTarget = renderDrawContext.CommandList.RenderTarget;

            // If the width or height changed, we have to recycle all temporary allocated resources.
            // NOTE: We assume that they are mostly resolution dependent.
            if (previousWidth != renderTarget.ViewWidth || previousHeight != renderTarget.ViewHeight)
            {
                // Force a recycle of all allocated temporary textures
                renderContext.Allocator.Recycle(link => true);
            }

            previousWidth  = renderTarget.ViewWidth;
            previousHeight = renderTarget.ViewHeight;

            // Update the entities at draw time.
            renderContext.Time = gameTime;

            // The camera processor needs the graphics compositor
            using (renderContext.PushTagAndRestore(GraphicsCompositor.Current, GraphicsCompositor))
            {
                // Execute Draw step of SceneInstance
                // This will run entity processors
                SceneInstance?.Draw(renderContext);
            }

            // Render phase
            // TODO GRAPHICS REFACTOR
            //context.GraphicsDevice.Parameters.Set(GlobalKeys.Time, (float)gameTime.Total.TotalSeconds);
            //context.GraphicsDevice.Parameters.Set(GlobalKeys.TimeStep, (float)gameTime.Elapsed.TotalSeconds);

            renderDrawContext.ResourceGroupAllocator.Flush();
            renderDrawContext.QueryManager.Flush();

            // Push context (pop after using)
            using (renderDrawContext.RenderContext.PushTagAndRestore(SceneInstance.Current, SceneInstance))
            {
                GraphicsCompositor?.Draw(renderDrawContext);
            }

            //do this here, make sure GCompositor and Scene are updated/rendered the next frame!
            if (sceneTask != null && compositorTask != null)
            {
                switch (splashScreenState)
                {
                case SplashScreenState.Invalid:
                {
                    if (sceneTask.IsCompleted && compositorTask.IsCompleted)
                    {
                        SceneInstance      = new SceneInstance(Services, sceneTask.Result);
                        GraphicsCompositor = compositorTask.Result;
                        sceneTask          = null;
                        compositorTask     = null;
                    }
                    break;
                }

                case SplashScreenState.Intro:
                {
                    Game.GraphicsContext.CommandList.Clear(Game.GraphicsContext.CommandList.RenderTarget, SplashScreenColor);

                    if (gameTime.Total.TotalSeconds > SplashScreenFadeTime)
                    {
                        splashScreenState = SplashScreenState.FadingIn;
                        fadeTime          = 0.0f;
                    }
                    break;
                }

                case SplashScreenState.FadingIn:
                {
                    var color  = Color4.White;
                    var factor = MathUtil.SmoothStep((float)fadeTime / SplashScreenFadeTime);
                    color *= factor;
                    if (factor >= 1.0f)
                    {
                        splashScreenState = SplashScreenState.Showing;
                    }

                    fadeTime += gameTime.Elapsed.TotalSeconds;

                    RenderSplashScreen(color, BlendStates.AlphaBlend);
                    break;
                }

                case SplashScreenState.Showing:
                {
                    RenderSplashScreen(Color4.White, BlendStates.Default);

                    if (gameTime.Total.TotalSeconds > MinSplashScreenTime && sceneTask.IsCompleted && compositorTask.IsCompleted)
                    {
                        splashScreenState = SplashScreenState.FadingOut;
                        fadeTime          = 0.0f;
                    }
                    break;
                }

                case SplashScreenState.FadingOut:
                {
                    var color  = Color4.White;
                    var factor = (MathUtil.SmoothStep((float)fadeTime / SplashScreenFadeTime) * -1) + 1;
                    color *= factor;
                    if (factor <= 0.0f)
                    {
                        splashScreenState = SplashScreenState.Invalid;
                    }

                    fadeTime += gameTime.Elapsed.TotalSeconds;

                    RenderSplashScreen(color, BlendStates.AlphaBlend);
                    break;
                }
                }
            }
        }