protected override void DrawCore(RenderContext context, RenderFrame output)
        {
            var input = Input.GetSafeRenderFrame(context);

            // If RenderFrame input or output are null, we can't do anything
            if (input == null)
            {
                return;
            }

            // If an effect is set, we are using it
            if (Effect != null)
            {
                Effect.SetInput(0, input);
                if (input.DepthStencil != null)
                {
                    Effect.SetInput(1, input.DepthStencil);
                }
                Effect.SetOutput(output);
                Effect.Draw(context);
            }
            else if (input != output)
            {
                // Else only use a scaler if input and output don't match
                // TODO: Is this something we want by default or we just don't output anything?
                var effect = context.GetSharedEffect<ImageScaler>();
                effect.SetInput(0, input);
                effect.SetOutput(output);
                effect.Draw(context);
            }
        }
        protected override void DrawCore(RenderContext context, RenderFrame output)
        {
            var graphicsDevice = context.GraphicsDevice;

            // clear the targets
            if (output.DepthStencil != null && (ClearFlags == ClearRenderFrameFlags.ColorAndDepth || ClearFlags == ClearRenderFrameFlags.DepthOnly))
            {
                const DepthStencilClearOptions ClearOptions = DepthStencilClearOptions.DepthBuffer | DepthStencilClearOptions.Stencil;
                graphicsDevice.Clear(output.DepthStencil, ClearOptions, Depth, Stencil);
            }

            if (ClearFlags == ClearRenderFrameFlags.ColorAndDepth || ClearFlags == ClearRenderFrameFlags.ColorOnly)
            {
                foreach (var renderTarget in output.RenderTargets)
                {
                    if (renderTarget != null)
                    {
                        // If color is in GammeSpace and rendertarget is either SRgb or HDR, use a linear value to clear the buffer.
                        // TODO: We will need to move this color transform code to a shareable component
                        var color = Color.ToColorSpace(ColorSpace, (renderTarget.Format.IsSRgb() || renderTarget.Format.IsHDR()) ? ColorSpace.Linear : graphicsDevice.ColorSpace);
                        graphicsDevice.Clear(renderTarget, color);
                    }
                }
            }
        }
        protected override void DrawCore(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex)
        {
            var graphicsDevice = context.GraphicsDevice;
            var destination = new RectangleF(0, 0, 1, 1);

            // find the last background to display with valid texture
            BackgroundComponent background = null;
            for (var i = toIndex; i >= fromIndex; --i)
            {
                background = (BackgroundComponent)renderItems[i].DrawContext;
                if (background.Texture != null)
                    break;
            }

            // Abort if not valid background component
            if (background == null || background.Texture == null)
                return;

            var texture = background.Texture;
            var target = CurrentRenderFrame;
            var imageBufferMinRatio = Math.Min(texture.ViewWidth / (float)target.Width, texture.ViewHeight / (float)target.Height);
            var sourceSize = new Vector2(target.Width * imageBufferMinRatio, target.Height * imageBufferMinRatio);
            var source = new RectangleF((texture.ViewWidth - sourceSize.X) / 2, (texture.ViewHeight - sourceSize.Y) / 2, sourceSize.X, sourceSize.Y);

            spriteBatch.Parameters.Add(BackgroundEffectKeys.Intensity, background.Intensity);
            spriteBatch.Begin(SpriteSortMode.FrontToBack, graphicsDevice.BlendStates.Opaque, graphicsDevice.SamplerStates.LinearClamp, graphicsDevice.DepthStencilStates.None, null, backgroundEffect);
            spriteBatch.Draw(texture, destination, source, Color.White, 0, Vector2.Zero);
            spriteBatch.End();
        }
Exemple #4
0
        protected override void LoadContent()
        {
            var assetManager = Services.GetSafeServiceAs<ContentManager>();
            var graphicsContext = Services.GetSafeServiceAs<GraphicsContext>();

            // Preload the scene if it exists
            if (InitialSceneUrl != null && assetManager.Exists(InitialSceneUrl))
            {
                SceneInstance = new SceneInstance(Services, assetManager.Load<Scene>(InitialSceneUrl));
            }

            if (MainRenderFrame == null)
            {
                // TODO GRAPHICS REFACTOR Check if this is a good idea to use Presenter targets
                MainRenderFrame = RenderFrame.FromTexture(GraphicsDevice.Presenter?.BackBuffer, GraphicsDevice.Presenter?.DepthStencilBuffer);
                if (MainRenderFrame != null)
                {
                    previousWidth = MainRenderFrame.Width;
                    previousHeight = MainRenderFrame.Height;
                }
            }

            // Create the drawing context
            renderContext = RenderContext.GetShared(Services);
            renderDrawContext = new RenderDrawContext(Services, renderContext, graphicsContext);
        }
        public static void UpdateParameters(RenderContext context, CameraComponent camera)
        {
            if (camera == null) throw new ArgumentNullException("camera");

            // Setup viewport size
            var currentViewport = context.GraphicsDevice.Viewport;
            var aspectRatio = currentViewport.AspectRatio;

            // Update the aspect ratio
            if (camera.UseCustomAspectRatio)
            {
                aspectRatio = camera.AspectRatio;
            }

            // If the aspect ratio is calculated automatically from the current viewport, update matrices here
            camera.Update(aspectRatio);

            // Store the current view/projection matrix in the context
            var viewParameters = context.Parameters;
            viewParameters.Set(TransformationKeys.View, camera.ViewMatrix);
            viewParameters.Set(TransformationKeys.Projection, camera.ProjectionMatrix);
            viewParameters.Set(TransformationKeys.ViewProjection, camera.ViewProjectionMatrix);
            viewParameters.Set(CameraKeys.NearClipPlane, camera.NearClipPlane);
            viewParameters.Set(CameraKeys.FarClipPlane, camera.FarClipPlane);
            viewParameters.Set(CameraKeys.VerticalFieldOfView, camera.VerticalFieldOfView);
            viewParameters.Set(CameraKeys.OrthoSize, camera.OrthographicSize);
            viewParameters.Set(CameraKeys.ViewSize, new Vector2(currentViewport.Width, currentViewport.Height));
            viewParameters.Set(CameraKeys.AspectRatio, aspectRatio);

            //viewParameters.Set(CameraKeys.FocusDistance, camera.FocusDistance);
        }
 protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
 {
     if (lightComponentForwardRenderer != null)
     {
         lightComponentForwardRenderer.Draw(context);
     }
 }
Exemple #7
0
        public static void UpdateCameraToRenderView(RenderContext context, RenderView renderView)
        {
            var camera = context.Tags.Get(CameraComponentRendererExtensions.Current);
            var sceneCameraRenderer = context.Tags.Get(SceneCameraRenderer.Current);

            if (camera == null || sceneCameraRenderer == null)
                return;

            // Setup viewport size
            var currentViewport = sceneCameraRenderer.ComputedViewport;
            var aspectRatio = currentViewport.AspectRatio;

            // Update the aspect ratio
            if (camera.UseCustomAspectRatio)
            {
                aspectRatio = camera.AspectRatio;
            }

            // If the aspect ratio is calculated automatically from the current viewport, update matrices here
            camera.Update(aspectRatio);

            // Copy camera data
            renderView.View = camera.ViewMatrix;
            renderView.Projection = camera.ProjectionMatrix;
            renderView.NearClipPlane = camera.NearClipPlane;
            renderView.FarClipPlane = camera.FarClipPlane;
            renderView.Frustum = camera.Frustum;

            // Copy scene camera renderer data
            renderView.CullingMask = sceneCameraRenderer.CullingMask;
            renderView.CullingMode = sceneCameraRenderer.CullingMode;
            renderView.ViewSize = new Vector2(sceneCameraRenderer.ComputedViewport.Width, sceneCameraRenderer.ComputedViewport.Height);

            Matrix.Multiply(ref renderView.View, ref renderView.Projection, out renderView.ViewProjection);
        }
 public void ClearRenderTarget(RenderContext context)
 {
     if (!IsRenderTargetCleared)
     {
         context.GraphicsDevice.Clear(Texture, DepthStencilClearOptions.DepthBuffer);
         IsRenderTargetCleared = true;
     }
 }
Exemple #9
0
 /// <summary>
 /// Setups the current material using the graphics device.
 /// </summary>
 /// <param name="graphicsDevice">Graphics device to setup</param>
 /// <param name="viewMatrix">The camera's View matrix</param>
 /// <param name="projMatrix">The camera's Projection matrix</param>
 public virtual void Setup(RenderContext context)
 {
     if (!IsInitialized)
     {
         InitializeCore(context);
         IsInitialized = true;
     }          
 }
 /// <summary>
 /// Activates the output to the current <see cref="GraphicsDevice"/>.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="disableDepth">if set to <c>true</c> [disable depth].</param>
 public void ActivateOutput(RenderContext context, bool disableDepth = false)
 {
     var output = GetOutput(context);
     if (output != null)
     {
         ActivateOutputCore(context, output, disableDepth);
     }
 }
 public void Draw(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex)
 {
     if (Enabled)
     {
         PreDrawCoreInternal(context);
         DrawCore(context, renderItems, fromIndex, toIndex);
         PostDrawCoreInternal(context);
     }
 }
Exemple #12
0
 /// <summary>
 /// Draws this renderer with the specified context.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <exception cref="System.ArgumentNullException">context</exception>
 /// <exception cref="System.InvalidOperationException">Cannot use a different context between Load and Draw</exception>
 public void Draw(RenderContext context)
 {
     if (Enabled)
     {
         PreDrawCoreInternal(context);
         DrawCore(context);
         PostDrawCoreInternal(context);
     }
 }
        protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            var cameraState = context.GetCurrentCamera();

            if (cameraState == null)
                return;

            UpdateParameters(context, cameraState);
        }
        protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            skyboxProcessor = SceneInstance.GetProcessor<SkyboxProcessor>();
            if (skyboxProcessor == null)
            {
                return;
            }

            var skybox = skyboxProcessor.ActiveSkyboxBackground;

            // do not draw if no active skybox or the skybox is not included in the current entity group
            if (skybox == null || !CurrentCullingMask.Contains(skybox.Entity.Group))
                return;

            // Copy camera/pass parameters
            context.Parameters.CopySharedTo(skyboxEffect.Parameters);

            // Show irradiance in the background
            if (skybox.Background == SkyboxBackground.Irradiance)
            {
                foreach (var parameterKeyValue in skybox.Skybox.DiffuseLightingParameters)
                {
                    if (parameterKeyValue.Key == SkyboxKeys.Shader)
                    {
                        skyboxEffect.Parameters.Set(SkyboxKeys.Shader, (ShaderSource)parameterKeyValue.Value);
                    }
                    else
                    {
                        skyboxEffect.Parameters.SetObject(parameterKeyValue.Key.ComposeWith("skyboxColor"), parameterKeyValue.Value);
                    }
                }
            }
            else
            {
                // TODO: Should we better use composition on "skyboxColor" for parameters?

                // Copy Skybox parameters
                if (skybox.Skybox != null)
                {
                    foreach (var parameterKeyValue in skybox.Skybox.Parameters)
                    {
                        if (parameterKeyValue.Key == SkyboxKeys.Shader)
                        {
                            skyboxEffect.Parameters.Set(SkyboxKeys.Shader, (ShaderSource)parameterKeyValue.Value);
                        }
                        else
                        {
                            skyboxEffect.Parameters.SetObject(parameterKeyValue.Key, parameterKeyValue.Value);
                        }
                    }
                }
            }

            // Fake as the skybox was in front of all others (as opaque are rendered back to front)
            opaqueList.Add(new RenderItem(this, skybox, float.NegativeInfinity));
        }
        protected override void DrawCore(RenderContext context)
        {
            // TODO: Find a better extensibility point for PixelStageSurfaceFilter
            var currentFilter = context.Parameters.Get(MaterialKeys.PixelStageSurfaceFilter);
            if (!ReferenceEquals(currentFilter, MaterialFilter))
            {
                context.Parameters.Set(MaterialKeys.PixelStageSurfaceFilter, MaterialFilter);
            }

            base.DrawCore(context);
        }
        public override void Collect(RenderContext context)
        {
            base.Collect(context);

            // Update view parameters
            UpdateCameraToRenderView(context, MainRenderView);

            // Collect render objects
            var visibilityGroup = context.Tags.Get(SceneInstance.CurrentVisibilityGroup);
            visibilityGroup.Collect(MainRenderView);
        }
        protected override async Task LoadContent()
        {
            await base.LoadContent();

            hdrTexture = Content.Load<Texture>("HdrTexture");
            hdrRenderTexture = Texture.New2D(GraphicsDevice, hdrTexture.Width, hdrTexture.Height, 1, hdrTexture.Description.Format, TextureFlags.ShaderResource | TextureFlags.RenderTarget);
            drawEffectContext = RenderContext.GetShared(Services);
            postProcessingEffects = new PostProcessingEffects(drawEffectContext);
            postProcessingEffects.BrightFilter.Threshold = 100.0f;
            postProcessingEffects.Bloom.DownScale = 2;
            postProcessingEffects.Bloom.Enabled = true;
            postProcessingEffects.Bloom.ShowOnlyBloom = true;
        }
        protected override async Task LoadContent()
        {
            await base.LoadContent();

            spriteBatch = new SpriteBatch(GraphicsDevice);
            
            inputTexture = Asset.Load<Texture>("uv");
            var groupCounts = new Int3(inputTexture.Width / ReductionRatio, inputTexture.Height / ReductionRatio, 1);
            outputTexture = Texture.New2D(GraphicsDevice, groupCounts.X, groupCounts.Y, 1, PixelFormat.R8G8B8A8_UNorm, TextureFlags.UnorderedAccess | TextureFlags.ShaderResource);
            displayedTexture = outputTexture;

            drawEffectContext = RenderContext.GetShared(Services);
            computeShaderEffect = new ComputeEffectShader(drawEffectContext) { ShaderSourceName = "ComputeShaderTestEffect", ThreadGroupCounts = groupCounts };
        }
        protected override async Task LoadContent()
        {
            await base.LoadContent();

            cubemapSpriteEffect = EffectSystem.LoadEffect("CubemapSprite").WaitForResult();

            drawEffectContext = RenderContext.GetShared(Services);
            lamberFilter = new LambertianPrefilteringSH(drawEffectContext);
            renderSHEffect = new SphericalHarmonicsRendererEffect();
            renderSHEffect.Initialize(drawEffectContext);

            spriteBatch = new SpriteBatch(GraphicsDevice);
            inputCubemap = Asset.Load<Texture>("CubeMap");
            outputCubemap = Texture.NewCube(GraphicsDevice, 256, 1, PixelFormat.R8G8B8A8_UNorm, TextureFlags.RenderTarget | TextureFlags.ShaderResource).DisposeBy(this);
            displayedCubemap = outputCubemap;
        }
        protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            var backgroundProcessor = SceneInstance.GetProcessor<BackgroundComponentProcessor>();
            if (backgroundProcessor == null)
                return;

            foreach (var backgroundComponent in backgroundProcessor.Backgrounds)
            {
                // Perform culling on group and accept
                if (!CurrentCullingMask.Contains(backgroundComponent.Entity.Group))
                    continue;

                opaqueList.Add(new RenderItem(this, backgroundComponent, float.NegativeInfinity)); // render background first so that it can replace a clear frame
                return; // draw only one background by group
            }
        }
        protected override async Task LoadContent()
        {
            await base.LoadContent();

            drawEffectContext = RenderContext.GetShared(Services);
            radianceFilter = new RadiancePrefilteringGGX(drawEffectContext);
            skipHighestLevel = radianceFilter.DoNotFilterHighestLevel;

            spriteBatch = new SpriteBatch(GraphicsDevice);
            inputCubemap = Asset.Load<Texture>("CubeMap");
            outputCubemap = Texture.New2D(GraphicsDevice, outputSize, outputSize, MathUtil.Log2(outputSize), PixelFormat.R16G16B16A16_Float, TextureFlags.ShaderResource | TextureFlags.UnorderedAccess, 6).DisposeBy(this);
            CreateViewsFor(outputCubemap);

            //RenderSystem.Pipeline.Renderers.Add(new DelegateRenderer(Services) { Render = PrefilterCubeMap });
            //RenderSystem.Pipeline.Renderers.Add(new RenderTargetSetter(Services) { ClearColor = Color.Zero });
            //RenderSystem.Pipeline.Renderers.Add(new DelegateRenderer(Services) { Render = RenderCubeMap });
        }
        public override void Collect(RenderContext context)
        {
            base.Collect(context);

            var rect = Viewport;

            var output = GetOutput(context);

            // Setup the viewport
            if (!ForceAspectRatio)
            {

                if (IsViewportInPercentage)
                {
                    var width = output.Width;
                    var height = output.Height;
                    ComputedViewport = new Viewport((int)(rect.X*width/100.0f), (int)(rect.Y*height/100.0f), (int)(rect.Width*width/100.0f), (int)(rect.Height*height/100.0f));
                }
                else
                {
                    ComputedViewport = new Viewport((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height);
                }
            }
            else
            {
                var currentAr = output.Width / (float)output.Height;
                var requiredAr = FixedAspectRatio;

                var arDiff = currentAr - requiredAr;

                // Pillarbox 
                if (arDiff > 0.0f)
                {
                    var newWidth = (float)Math.Max(1.0f, Math.Round(output.Height * requiredAr));
                    var adjX = (float)Math.Round(0.5f * (output.Width - newWidth));
                    ComputedViewport = new Viewport((int)adjX, 0, (int)newWidth, output.Height);
                }
                // Letterbox
                else
                {
                    var newHeight = (float)Math.Max(1.0f, Math.Round(output.Width / requiredAr));
                    var adjY = (float)Math.Round(0.5f * (output.Height - newHeight));
                    ComputedViewport = new Viewport(0, (int)adjY, output.Width, (int)newHeight);
                }
            }
        }
        public override RenderFrame GetRenderFrame(RenderContext context)
        {
            // Get the relative frame
            var relativeFrame = context.Tags.Get(RelativeSizeSource == RenderFrameRelativeMode.Current ? RenderFrame.Current : SceneGraphicsLayer.Master);

            // Check if we need to resize it
            if (currentFrame != null && (currentFrame.Descriptor != Descriptor || currentFrame.CheckIfResizeRequired(relativeFrame) || Descriptor.Format == RenderFrameFormat.LDR && colorSpace != context.GraphicsDevice.ColorSpace))
            {
                Dispose();
            }

            // Store the colorSpace
            colorSpace = context.GraphicsDevice.ColorSpace;

            // Allocate the render frame if necessary
            // TODO: Should we use allocated shared textures from RenderContext?
            return currentFrame ?? (currentFrame = RenderFrame.New(context.GraphicsDevice, Descriptor, relativeFrame));
        }
Exemple #24
0
        public void Initialize(RenderContext context)
        {
            if (context == null) throw new ArgumentNullException("context");

            if (Context != null)
            {
                Unload();
            }

            Context = context;

            InitializeCore();

            Initialized = true;

            // Notify that a particular renderer has been initialized.
            context.OnRendererInitialized(this);
        }
        protected override void ActivateOutputCore(RenderContext context, RenderFrame output, bool disableDepth)
        {
            base.ActivateOutputCore(context, output, disableDepth);

            Viewport viewport;
            var rect = Viewport;
            // Setup the viewport
            if (IsViewportInPercentage)
            {
                var width = output.Width;
                var height = output.Height;
                viewport = new Viewport((int)(rect.X * width / 100.0f), (int)(rect.Y * height / 100.0f), (int)(rect.Width * width / 100.0f), (int)(rect.Height * height / 100.0f));
            }
            else
            {
                viewport = new Viewport((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height);
            }
            context.GraphicsDevice.SetViewport(viewport);
        }
        protected override void DrawCore(RenderContext context, RenderFrame output)
        {
            if (ChildScene == null || !ChildScene.Enabled)
            {
                return;
            }

            currentSceneInstance = SceneInstance.GetCurrent(Context);

            childSceneProcessor = childSceneProcessor ?? currentSceneInstance.GetProcessor<ChildSceneProcessor>();

            if (childSceneProcessor == null)
            {
                return;
            }

            SceneInstance sceneInstance = childSceneProcessor.GetSceneInstance(ChildScene);
            if (sceneInstance != null)
            {
                sceneInstance.Draw(context, output, GraphicsCompositorOverride);
            }
        }
        protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            var uiProcessor = SceneInstance.GetProcessor<UIComponentProcessor>();
            if (uiProcessor == null)
                return;

            foreach (var uiRoot in uiProcessor.UIRoots)
            {
                // Perform culling on group and accept
                if (!CurrentCullingMask.Contains(uiRoot.UIComponent.Entity.Group))
                    continue;

                // skips empty UI elements
                if(uiRoot.UIComponent.RootElement == null)
                    continue;

                // Project the position
                // TODO: This code is duplicated from SpriteComponent -> unify it at higher level?
                var worldPosition = new Vector4(uiRoot.TransformComponent.WorldMatrix.TranslationVector, 1.0f);

                float projectedZ;
                if (uiRoot.UIComponent.IsFullScreen)
                {
                    projectedZ = -uiRoot.TransformComponent.WorldMatrix.M43;
                }
                else
                {
                    Vector4 projectedPosition;
                    var cameraComponent = context.Tags.Get(CameraComponentRenderer.Current);
                    if (cameraComponent == null)
                        continue;

                    Vector4.Transform(ref worldPosition, ref cameraComponent.ViewProjectionMatrix, out projectedPosition);
                    projectedZ = projectedPosition.Z / projectedPosition.W;
                }

                transparentList.Add(new RenderItem(this, uiRoot, projectedZ));
            }
        }
        protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            spriteProcessor = SceneInstance.GetProcessor<SpriteProcessor>();
            if (spriteProcessor == null)
            {
                return;
            }

            // If no camera, early exit
            var camera = context.GetCurrentCamera();
            if (camera == null)
            {
                return;
            }
            var viewProjectionMatrix = camera.ViewProjectionMatrix;

            foreach (var spriteState in spriteProcessor.Sprites)
            {
                var sprite = spriteState.SpriteComponent.CurrentSprite;
                if(sprite == null || sprite.Texture == null || sprite.Region.Width <= 0 || sprite.Region.Height <= 0f)
                    continue;

                // Perform culling on group and accept
                if (!CurrentCullingMask.Contains(spriteState.SpriteComponent.Entity.Group))
                    continue;

                // Project the position
                // TODO: This could be done in a SIMD batch, but we need to figure-out how to plugin in with RenderMesh object
                var worldPosition = new Vector4(spriteState.TransformComponent.WorldMatrix.TranslationVector, 1.0f);

                Vector4 projectedPosition;
                Vector4.Transform(ref worldPosition, ref viewProjectionMatrix, out projectedPosition);
                var projectedZ = projectedPosition.Z / projectedPosition.W;

                var list = sprite.IsTransparent ? transparentList : opaqueList;

                list.Add(new RenderItem(this, spriteState, projectedZ));
            }
        }
        protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            // If no camera, early exit
            var camera = context.GetCurrentCamera();
            if (camera == null)
            {
                return;
            }

            // Copy the ViewProjectionMatrix from the camera as it is not automatically picked up by the ModelComponentRenderer
            modelRenderer.ViewProjectionMatrix = camera.ViewProjectionMatrix;
            var sceneCameraRenderer = context.Tags.Get(SceneCameraRenderer.Current);
            var cameraRenderMode = sceneCameraRenderer != null ? sceneCameraRenderer.Mode : null;

            if (cameraRenderMode != null)
            {
                modelRenderer.RasterizerState = cameraRenderMode.GetDefaultRasterizerState(false);
                modelRenderer.RasterizerStateForInvertedGeometry = cameraRenderMode.GetDefaultRasterizerState(true);
            }                   

            modelRenderer.Prepare(context, opaqueList, transparentList);
        }
Exemple #30
0
        protected override void LoadContent()
        {
            var assetManager = Services.GetSafeServiceAs<AssetManager>();

            // Preload the scene if it exists
            if (InitialSceneUrl != null && assetManager.Exists(InitialSceneUrl))
            {
                SceneInstance = new SceneInstance(Services, assetManager.Load<Scene>(InitialSceneUrl));
            }

            if (MainRenderFrame == null)
            {
                MainRenderFrame = RenderFrame.FromTexture(GraphicsDevice.BackBuffer, GraphicsDevice.DepthStencilBuffer);
                if (MainRenderFrame != null)
                {
                    previousWidth = MainRenderFrame.Width;
                    previousHeight = MainRenderFrame.Height;
                }
            }

            // Create the drawing context
            renderContext = RenderContext.GetShared(Services);
        }
Exemple #31
0
 /// <param name="context"></param>
 /// <inheritdoc/>
 public virtual void Collect(RenderContext context)
 {
     EnsureContext(context);
 }
Exemple #32
0
 /// <summary>
 /// Gets the current output <see cref="RenderFrame"/> output.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <returns>RenderFrame.</returns>
 public RenderFrame GetOutput(RenderContext context)
 {
     return(Output.GetSafeRenderFrame(context));
 }
Exemple #33
0
 protected abstract void DrawCore(RenderContext context, RenderFrame output);
Exemple #34
0
 /// <summary>
 /// Activates the output to the current <see cref="GraphicsDevice" />.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="output">The output.</param>
 /// <param name="disableDepth">if set to <c>true</c> [disable depth].</param>
 protected virtual void ActivateOutputCore(RenderContext context, RenderFrame output, bool disableDepth)
 {
     // Setup the render target
     context.GraphicsDevice.SetDepthAndRenderTargets(disableDepth ? null : output.DepthStencil, output.RenderTargets);
 }
Exemple #35
0
        /// <summary>
        /// Extract data from entities, should be as fast as possible to not block simulation loop. It should be mostly copies, and the actual processing should be part of Prepare().
        /// </summary>
        public void Extract(RenderContext context)
        {
            // Prepare views
            for (int index = 0; index < Views.Count; index++)
            {
                // Update indices
                var view = Views[index];
                view.Index = index;

                // Create missing RenderViewFeature
                while (view.Features.Count < RenderFeatures.Count)
                {
                    view.Features.Add(new RenderViewFeature());
                }

                for (int i = 0; i < RenderFeatures.Count; i++)
                {
                    var renderViewFeature = view.Features[i];
                    renderViewFeature.RootFeature = RenderFeatures[i];
                }
            }

            foreach (var view in Views)
            {
                for (int index = 0; index < view.RenderStages.Count; index++)
                {
                    var renderViewStage = view.RenderStages[index];
                    renderViewStage.RenderNodes       = renderNodePool.Acquire();
                    renderViewStage.SortedRenderNodes = sortedRenderNodePool.Acquire();
                    view.RenderStages[index]          = renderViewStage;
                }
            }

            // Create nodes for objects to render
            Dispatcher.ForEach(Views, view =>
            {
                // Sort per render feature (used for later sorting)
                // We'll be able to process data more efficiently for the next steps
                Dispatcher.Sort(view.RenderObjects, RenderObjectFeatureComparer.Default);

                Dispatcher.ForEach(view.RenderObjects, () => extractThreadLocals.Value, (renderObject, batch) =>
                {
                    var renderFeature = renderObject.RenderFeature;
                    var viewFeature   = view.Features[renderFeature.Index];

                    // Create object node
                    renderFeature.GetOrCreateObjectNode(renderObject);

                    // Let's create the view object node
                    var renderViewNode = renderFeature.CreateViewObjectNode(view, renderObject);
                    viewFeature.ViewObjectNodes.Add(renderViewNode, batch.ViewFeatureObjectNodeCache);

                    // Collect object
                    // TODO: Check which stage it belongs to (and skip everything if it doesn't belong to any stage)
                    // TODO: For now, we build list and then copy. Another way would be to count and then fill (might be worse, need to check)
                    var activeRenderStages = renderObject.ActiveRenderStages;
                    foreach (var renderViewStage in view.RenderStages)
                    {
                        // Check if this RenderObject wants to be rendered for this render stage
                        var renderStageIndex = renderViewStage.Index;
                        if (!activeRenderStages[renderStageIndex].Active)
                        {
                            continue;
                        }

                        var renderStage = RenderStages[renderStageIndex];
                        if (renderStage.Filter != null && !renderStage.Filter.IsVisible(renderObject, view, renderViewStage))
                        {
                            continue;
                        }

                        var renderNode = renderFeature.CreateRenderNode(renderObject, view, renderViewNode, renderStage);

                        // Note: Used mostly during updating
                        viewFeature.RenderNodes.Add(renderNode, batch.ViewFeatureRenderNodeCache);

                        // Note: Used mostly during rendering
                        renderViewStage.RenderNodes.Add(new RenderNodeFeatureReference(renderFeature, renderNode, renderObject), batch.ViewStageRenderNodeCache);
                    }
                }, batch => batch.Flush());

                // Finish collectin of view feature nodes
                foreach (var viewFeature in view.Features)
                {
                    viewFeature.ViewObjectNodes.Close();
                    viewFeature.RenderNodes.Close();
                }

                // Also sort view|stage per render feature
                foreach (var renderViewStage in view.RenderStages)
                {
                    renderViewStage.RenderNodes.Close();

                    Dispatcher.Sort(renderViewStage.RenderNodes, RenderNodeFeatureReferenceComparer.Default);
                }
            });

            // Finish collection of render feature nodes
            foreach (var renderFeature in RenderFeatures)
            {
                renderFeature.CloseNodeCollectors();
            }

            // Ensure size of data arrays per objects
            PrepareDataArrays();

            // Generate and execute extract jobs
            foreach (var renderFeature in RenderFeatures)
            // We might be able to parallelize too as long as we resepect render feature dependency graph (probably very few dependencies in practice)
            {
                // Divide into task chunks for parallelism
                renderFeature.Extract();
            }

            // Ensure size of all other data arrays
            PrepareDataArrays();
        }
Exemple #36
0
        protected override void DrawCore(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex)
        {
            var viewParameters = context.Parameters;

            var device         = context.GraphicsDevice;
            var viewInverse    = Matrix.Invert(viewParameters.Get(TransformationKeys.View));
            var viewProjection = viewParameters.Get(TransformationKeys.ViewProjection);

            BlendState        previousBlendState        = null;
            DepthStencilState previousDepthStencilState = null;
            Effect            previousEffect            = null;

            var isPicking = context.IsPicking();

            bool hasBegin = false;

            for (var i = fromIndex; i <= toIndex; i++)
            {
                var renderItem        = renderItems[i];
                var spriteState       = (SpriteProcessor.SpriteComponentState)renderItem.DrawContext;
                var spriteComp        = spriteState.SpriteComponent;
                var transfoComp       = spriteState.TransformComponent;
                var depthStencilState = spriteState.SpriteComponent.IgnoreDepth ? device.DepthStencilStates.None : device.DepthStencilStates.Default;

                var sprite = spriteComp.CurrentSprite;
                if (sprite == null)
                {
                    continue;
                }

                // Update the sprite batch
                var blendState    = isPicking ? device.BlendStates.Opaque : renderItems.HasTransparency ? (spriteComp.PremultipliedAlpha ? device.BlendStates.AlphaBlend : device.BlendStates.NonPremultiplied) : device.BlendStates.Opaque;
                var currentEffect = isPicking? GetOrCreatePickingSpriteEffect(): spriteComp.Tags.Get(IsEntitySelected)? GetOrCreateSelectedSpriteEffect(): null; // TODO remove this code when material are available
                if (previousEffect != currentEffect || blendState != previousBlendState || depthStencilState != previousDepthStencilState)
                {
                    if (hasBegin)
                    {
                        sprite3DBatch.End();
                    }
                    sprite3DBatch.Begin(viewProjection, SpriteSortMode.Deferred, blendState, null, depthStencilState, device.RasterizerStates.CullNone, currentEffect);
                    hasBegin = true;
                }
                previousEffect            = currentEffect;
                previousBlendState        = blendState;
                previousDepthStencilState = depthStencilState;

                var sourceRegion = sprite.Region;
                var texture      = sprite.Texture;
                var color        = spriteComp.Color;
                if (isPicking) // TODO move this code corresponding to picking out of the runtime code.
                {
                    color = new Color4(RuntimeIdHelper.ToRuntimeId(spriteComp));
                }

                // skip the sprite if no texture is set.
                if (texture == null)
                {
                    continue;
                }

                // determine the element world matrix depending on the type of sprite
                var worldMatrix = transfoComp.WorldMatrix;
                if (spriteComp.SpriteType == SpriteType.Billboard)
                {
                    worldMatrix = viewInverse;

                    // remove scale of the camera
                    worldMatrix.Row1 /= ((Vector3)viewInverse.Row1).Length();
                    worldMatrix.Row2 /= ((Vector3)viewInverse.Row2).Length();

                    // set the scale of the object
                    worldMatrix.Row1 *= ((Vector3)transfoComp.WorldMatrix.Row1).Length();
                    worldMatrix.Row2 *= ((Vector3)transfoComp.WorldMatrix.Row2).Length();

                    // set the position
                    worldMatrix.TranslationVector = transfoComp.WorldMatrix.TranslationVector;
                }

                // calculate normalized position of the center of the sprite (takes into account the possible rotation of the image)
                var normalizedCenter = new Vector2(sprite.Center.X / sourceRegion.Width - 0.5f, 0.5f - sprite.Center.Y / sourceRegion.Height);
                if (sprite.Orientation == ImageOrientation.Rotated90)
                {
                    var oldCenterX = normalizedCenter.X;
                    normalizedCenter.X = -normalizedCenter.Y;
                    normalizedCenter.Y = oldCenterX;
                }
                // apply the offset due to the center of the sprite
                var centerOffset = Vector2.Modulate(normalizedCenter, sprite.SizeInternal);
                worldMatrix.M41 -= centerOffset.X * worldMatrix.M11 + centerOffset.Y * worldMatrix.M21;
                worldMatrix.M42 -= centerOffset.X * worldMatrix.M12 + centerOffset.Y * worldMatrix.M22;
                worldMatrix.M43 -= centerOffset.X * worldMatrix.M13 + centerOffset.Y * worldMatrix.M23;

                // draw the sprite
                sprite3DBatch.Draw(texture, ref worldMatrix, ref sourceRegion, ref sprite.SizeInternal, ref color, sprite.Orientation, SwizzleMode.None, renderItem.Depth);
            }

            sprite3DBatch.End();
        }
Exemple #37
0
 /// <summary>
 /// Main drawing method for this renderer that must be implemented.
 /// </summary>
 /// <param name="context">The context.</param>
 protected abstract void DrawCore(RenderContext context);
Exemple #38
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DrawEffect" /> class.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="name">The name.</param>
 protected DrawEffect(RenderContext context, string name = null)
     : this(name)
 {
     Initialize(context);
 }