/// <summary>
 /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SimulatedPostProcess"/> component needs render itself.
 /// </summary>
 /// <param name="gameTime">Time passed since the last call to Draw.</param>
 /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param>
 public void Draw(GameTime gameTime, DeferredRenderSystem renderSystem)
 {
     if (this.GetWorldDrawBounds().Intersects(renderSystem.GetCameraRenderBounds()))
     {
         this.Render(gameTime, renderSystem);
     }
 }
 /// <summary>
 /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to draw its options map.
 /// Override this method with component-specific drawing code.
 /// </summary>
 /// <param name="gameTime">Time passed since the last call to DrawOptionsMap.</param>
 /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param>
 public override void DrawOptionsMap(GameTime gameTime, DeferredRenderSystem renderSystem)
 {
     if (this.currentAnimation != null && !this.currentAnimation.IsStopped)
     {
         base.DrawOptionsMap(gameTime, renderSystem, this.currentAnimation.GetCurrentFrameBounds());
     }
 }
Example #3
0
 /// <summary>
 /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to draw its options map.
 /// Override this method with component-specific drawing code.
 /// </summary>
 /// <param name="gameTime">Time passed since the last call to DrawOptionsMap.</param>
 /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param>
 /// <param name="drawBoundingBox">The bounding box of the sprite within the texture.</param>
 protected void DrawOptionsMap(GameTime gameTime, DeferredRenderSystem renderSystem, Rectangle drawBoundingBox)
 {
     renderSystem.BeginRender(this.optionMapFlagsShader);
     this.optionMapFlagsShader.ConfigureShaderAndApplyPass(renderSystem, this);
     renderSystem.DrawSprite(this.spriteTexture, this.Position, drawBoundingBox, Color.White, this.Rotation, Vector2.Zero, this.RenderScale, SpriteEffects.None);
     renderSystem.EndRender();
 }
Example #4
0
        /// <summary>
        /// Called when the shader parameters are to be configured before rendering.
        /// </summary>
        /// <param name="renderSystem">Instance of the <see cref="DeferredRenderSystem"/> we are using to render</param>
        /// <param name="technique">Technique to use (can be null)</param>
        protected override void ConfigureShader(DeferredRenderSystem renderSystem, EffectTechnique technique)
        {
            base.ConfigureShader(renderSystem, technique);

            this.ShaderAsset.Parameters["colorMap"].SetValue(renderSystem.RenderTargets.ColorMap);
            this.ShaderAsset.Parameters["lightMap"].SetValue(renderSystem.RenderTargets.LightMap);
        }
Example #5
0
        /// <summary>
        /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SimulatedPostProcess"/> component needs render itself.
        /// Override this method with component-specific drawing code.
        /// </summary>
        /// <param name="gameTime">Time passed since the last call to Draw.</param>
        /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param>
        protected override void Render(GameTime gameTime, DeferredRenderSystem renderSystem)
        {
            RenderTarget2D shadowMap = renderSystem.RenderTargets.GetTemporaryRenderTarget(SurfaceFormat.Color); // The core shadow map

            this.GenerateShadowMap(renderSystem, shadowMap);

            renderSystem.SetRenderTargets(RenderTargetTypes.LightMap, 1); // Request light map as output
            this.PostProcessEffect.ConfigureShader(renderSystem);         // Configure the shader

            // Set parameters
            this.PostProcessEffect.GetParameter("viewProjection").SetValue(renderSystem.GameCamera.GetViewProjectionMatrix(renderSystem));
            this.PostProcessEffect.GetParameter("cameraPosition").SetValue(renderSystem.GameCamera.PixelPosition);
            this.PostProcessEffect.GetParameter("lightPosition").SetValue(this.PixelPosition);
            this.PostProcessEffect.GetParameter("lightPower").SetValue(this.Power);
            this.PostProcessEffect.GetParameter("lightRange").SetValue(this.World.GetPixelFromWorld(this.Range));
            this.PostProcessEffect.GetParameter("lightDecay").SetValue(this.Decay);
            this.PostProcessEffect.GetParameter("lightColor").SetValue(this.Color.ToVector4());
            this.PostProcessEffect.GetParameter("specularStrength").SetValue(this.SpecularStrength);
            this.PostProcessEffect.GetParameter("normalMap").SetValue(renderSystem.RenderTargets.NormalMap);
            this.PostProcessEffect.GetParameter("optionsMap").SetValue(renderSystem.RenderTargets.OptionsMap);
            this.PostProcessEffect.GetParameter("shadowMap").SetValue(shadowMap);

            // Render
            this.PostProcessEffect.ApplyPass(0);
            renderSystem.DirectScreenPaint(this.GetWorldDrawBounds());

            renderSystem.SetRenderTargets(RenderTargetTypes.None, 0); // Resolve the render target

            renderSystem.RenderTargets.ReleaseTemporaryRenderTarget(shadowMap);
        }
        /// <summary>
        /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to be drawn.
        /// Override this method with component-specific drawing code.
        /// </summary>
        /// <param name="gameTime">Time passed since the last call to DrawColorMap.</param>
        /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param>
        public override void DrawColorMap(GameTime gameTime, DeferredRenderSystem renderSystem)
        {
            renderSystem.BeginRender();

            this.ForEachTile((pos, rect) => renderSystem.DrawSprite(this.SpriteTexture, pos, rect, this.RenderColor, this.Rotation, Vector2.Zero, this.RenderScale, SpriteEffects.None));

            renderSystem.EndRender();
        }
 /// <summary>
 /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to be drawn.
 /// Override this method with component-specific drawing code.
 /// </summary>
 /// <param name="gameTime">Time passed since the last call to DrawColorMap.</param>
 /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param>
 public override void DrawColorMap(GameTime gameTime, DeferredRenderSystem renderSystem)
 {
     renderSystem.BeginRender(this.shaderAsset);
     this.shaderAsset.ConfigureShader(renderSystem);
     this.shaderAsset.ApplyPass(0);
     renderSystem.DrawSprite(this.SpriteTexture, this.Position, null, this.RenderColor, this.Rotation, Vector2.Zero, this.RenderScale, SpriteEffects.None);
     renderSystem.EndRender();
 }
Example #8
0
        /// <summary>
        /// Gets the transform matrix used when rendering the scene.
        /// </summary>
        /// <param name="renderSystem">The render system that requires it.</param>
        /// <returns>The transformation matrix to use when rendering.</returns>
        public Matrix GetViewMatrix(DeferredRenderSystem renderSystem)
        {
            Rectangle screenSize = renderSystem.RenderTargets.ScreenRectangle;

            return(Matrix.CreateTranslation(new Vector3(-this.PixelPosition.X, -this.PixelPosition.Y, 0)) *      // Translate into screen space
                   Matrix.CreateRotationZ(-this.Rotation) *                                                      // Rotate counter to camera rotation
                   Matrix.CreateScale(new Vector3(this.cameraZoom, this.cameraZoom, 1)) *                        // Scale based on camera zoom
                   Matrix.CreateTranslation(new Vector3(screenSize.Width * 0.5f, screenSize.Height * 0.5f, 0))); // Translate to center on the screen
        }
Example #9
0
        /// <summary>
        /// Gets the inverted transform matrix used when rendering the scene.
        /// </summary>
        /// <param name="renderSystem">The render system that requires it.</param>
        /// <returns>The inversion of the transformation matrix to use when rendering.</returns>
        public Matrix GetInvertedViewMatrix(DeferredRenderSystem renderSystem)
        {
            Rectangle screenSize = renderSystem.RenderTargets.ScreenRectangle;

            return(Matrix.CreateTranslation(new Vector3(this.PixelPosition.X, this.PixelPosition.Y, 0)) *
                   Matrix.CreateRotationZ(this.Rotation) *
                   Matrix.CreateScale(new Vector3(1 / this.cameraZoom, 1 / this.cameraZoom, 1)) *
                   Matrix.CreateTranslation(new Vector3(-screenSize.Width * 0.5f, -screenSize.Height * 0.5f, 0)));
        }
        /// <summary>
        /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to draw its options map.
        /// Override this method with component-specific drawing code.
        /// </summary>
        /// <param name="gameTime">Time passed since the last call to DrawOptionsMap.</param>
        /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param>
        public override void DrawOptionsMap(GameTime gameTime, DeferredRenderSystem renderSystem)
        {
            renderSystem.BeginRender(this.OptionMapFlagsShader);
            this.OptionMapFlagsShader.ConfigureShaderAndApplyPass(renderSystem, this);

            this.ForEachTile((pos, rect) => renderSystem.DrawSprite(this.SpriteTexture, pos, rect, Color.White, this.Rotation, Vector2.Zero, this.RenderScale, SpriteEffects.None));

            renderSystem.EndRender();
        }
Example #11
0
        /// <summary>
        /// Called when the shader parameters are to be configured before rendering.
        /// </summary>
        /// <param name="renderSystem">Instance of the <see cref="DeferredRenderSystem"/> we are using to render</param>
        /// <param name="technique">Technique to use</param>
        protected virtual void ConfigureShader(DeferredRenderSystem renderSystem, EffectTechnique technique)
        {
            if (!this.isConfigured)
            {
                this.InitConfigure(renderSystem);
            }

            this.shaderAsset.CurrentTechnique = technique;
        }
Example #12
0
        /// <summary>
        /// Called when the shader parameters are to be configured before rendering.
        /// </summary>
        /// <param name="renderSystem">Instance of the <see cref="DeferredRenderSystem"/> we are using to render</param>
        /// <param name="sprite">The sprite we are rendering.</param>
        public void ConfigureShaderAndApplyPass(DeferredRenderSystem renderSystem, SpriteBase sprite)
        {
            base.ConfigureShader(renderSystem, "ApplyFlagsToOptionsMap");

            this.ShaderAsset.Parameters["viewProjection"].SetValue(renderSystem.GameCamera.GetViewProjectionMatrix(renderSystem));
            this.ShaderAsset.Parameters["cameraPosition"].SetValue(renderSystem.GameCamera.PixelPosition);
            this.ShaderAsset.Parameters["pixelOptions"].SetValue((int)sprite.RenderOptions / 255.0f);
            this.ShaderAsset.Parameters["specularReflectivity"].SetValue(sprite.SpecularReflectivity);
            this.ApplyPass(0);
        }
        /// <summary>
        /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to draw its options map.
        /// Override this method with component-specific drawing code.
        /// </summary>
        /// <param name="gameTime">Time passed since the last call to DrawColorMap.</param>
        /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param>
        public override void DrawOptionsMap(GameTime gameTime, DeferredRenderSystem renderSystem)
        {
            renderSystem.BeginRender(this.optionMapFlagsShader);
            this.optionMapFlagsShader.ConfigureShaderAndApplyPass(renderSystem, this);

            RectangleF posRect = new RectangleF(this.targetSprite.Position.X - this.lineWidth * 2.0f, this.targetSprite.Position.Y - this.lineWidth * 2.0f, this.lineWidth * 4.0f, this.lineWidth * 4.0f);

            renderSystem.DrawFilledRectangle(posRect, Color.Black, this.Rotation);                                                                   // Draw position
            renderSystem.DrawRectangleBorder(this.targetSprite.SpriteWorldBounds, Color.Black, this.lineWidth, 0.0f);                                // Draw bounding rectangle
            renderSystem.DrawLine(this.targetSprite.Position, this.targetSprite.Position + this.targetSprite.Velocity, Color.Black, this.lineWidth); // Draw velocity line

            renderSystem.EndRender();
        }
        /// <summary>
        /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to draw its color map.
        /// Override this method with component-specific drawing code.
        /// </summary>
        /// <param name="gameTime">Time passed since the last call to DrawColorMap.</param>
        /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param>
        public override void DrawColorMap(GameTime gameTime, DeferredRenderSystem renderSystem)
        {
            renderSystem.BeginRender();

            RectangleF posRect = new RectangleF(this.targetPostProcess.Position.X - this.lineWidth * 2.0f, this.targetPostProcess.Position.Y - this.lineWidth * 2.0f, this.lineWidth * 4.0f, this.lineWidth * 4.0f);
            float      lineMag = this.targetPostProcess.Velocity.Length();

            renderSystem.DrawFilledRectangle(posRect, Color.White, this.targetPostProcess.Rotation);                                                               // Draw position
            renderSystem.DrawRectangleBorder(this.targetPostProcess.GetWorldDrawBounds(), Color.Green, this.lineWidth, 0.0f);                                      // Draw bounding rectangle
            renderSystem.DrawLine(this.targetPostProcess.Position, this.targetPostProcess.Position + this.targetPostProcess.Velocity, Color.Blue, this.lineWidth); // Draw velocity line
            renderSystem.DrawLine(this.targetPostProcess.Position, this.targetPostProcess.Position + (lineMag * this.targetPostProcess.RotationVector), Color.OrangeRed, this.lineWidth);

            renderSystem.EndRender();
        }
Example #15
0
        /// <summary>
        /// Called when the shader parameters are to be configured before rendering.
        /// </summary>
        /// <param name="renderSystem">Instance of the <see cref="DeferredRenderSystem"/> we are using to render</param>
        /// <param name="technique">Technique to use (can be null)</param>
        protected override void ConfigureShader(DeferredRenderSystem renderSystem, EffectTechnique technique)
        {
            if (!technique.Name.Equals("ApplyFlagsToOptionsMap"))
            {
                throw new ArgumentException("You dun goofed.");
            }

            base.ConfigureShader(renderSystem, technique);

            this.ShaderAsset.Parameters["viewProjection"].SetValue(renderSystem.GameCamera.GetViewProjectionMatrix(renderSystem));
            this.ShaderAsset.Parameters["cameraPosition"].SetValue(renderSystem.GameCamera.PixelPosition);
            this.ShaderAsset.Parameters["pixelOptions"].SetValue((float)SpriteRenderOptions.None);
            this.ShaderAsset.Parameters["specularReflectivity"].SetValue(0.5f);
        }
        /// <summary>
        /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to draw its options map.
        /// Override this method with component-specific drawing code.
        /// </summary>
        /// <param name="gameTime">Time passed since the last call to DrawColorMap.</param>
        /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param>
        public override void DrawOptionsMap(GameTime gameTime, DeferredRenderSystem renderSystem)
        {
            renderSystem.BeginRender(this.optionMapFlagsShader);
            this.optionMapFlagsShader.ConfigureShaderAndApplyPass(renderSystem, this);

            RectangleF posRect = new RectangleF(this.targetPostProcess.Position.X - this.lineWidth * 2.0f, this.targetPostProcess.Position.Y - this.lineWidth * 2.0f, this.lineWidth * 4.0f, this.lineWidth * 4.0f);
            float      lineMag = this.targetPostProcess.Velocity.Length();

            renderSystem.DrawFilledRectangle(posRect, Color.Black, this.targetPostProcess.Rotation);                                                                // Draw position
            renderSystem.DrawRectangleBorder(this.targetPostProcess.GetWorldDrawBounds(), Color.Black, this.lineWidth, 0.0f);                                       // Draw bounding rectangle
            renderSystem.DrawLine(this.targetPostProcess.Position, this.targetPostProcess.Position + this.targetPostProcess.Velocity, Color.Black, this.lineWidth); // Draw velocity line
            renderSystem.DrawLine(this.targetPostProcess.Position, this.targetPostProcess.Position + (lineMag * this.targetPostProcess.RotationVector), Color.Black, this.lineWidth);

            renderSystem.EndRender();
        }
        /// <summary>
        /// Called by the <see cref="DeferredRenderSystem" /> when this <see cref="StaticPostProcess" /> component needs render itself.
        /// Override this method with component-specific drawing code.
        /// </summary>
        /// <param name="gameTime">Time passed since the last call to Draw.</param>
        /// <param name="renderSystem"><see cref="DeferredRenderSystem" /> to render with.</param>
        public override void Draw(GameTime gameTime, DeferredRenderSystem renderSystem)
        {
            RenderTarget2D intermediateColorMap = renderSystem.RenderTargets.GetTemporaryRenderTarget(SurfaceFormat.Color); // Intermediate map used for selective sampling

            renderSystem.GraphicsDevice.SetRenderTarget(intermediateColorMap);
            this.PostProcessEffect.ConfigureShader(renderSystem);
            this.PostProcessEffect.GetParameter("spriteTexture").SetValue(renderSystem.RenderTargets.ColorMap);
            this.PostProcessEffect.ApplyPass(0);
            renderSystem.DirectScreenPaint();

            renderSystem.SetRenderTargets(RenderTargetTypes.ColorMap, 1);
            this.PostProcessEffect.ConfigureShader(renderSystem);
            this.PostProcessEffect.GetParameter("spriteTexture").SetValue(intermediateColorMap);
            this.PostProcessEffect.ApplyPass(0);
            renderSystem.DirectScreenPaint();
            renderSystem.RenderTargets.ReleaseTemporaryRenderTarget(intermediateColorMap);
        }
        /// <summary>
        /// Removes a shadow from sprite or fully covers the sprite in shadow, depending on the layer depth transition.
        /// </summary>
        /// <param name="renderSystem">The render system.</param>
        /// <param name="sprite">The sprite.</param>
        private void ProcessSpriteDepthTransition(DeferredRenderSystem renderSystem, SpriteBase sprite)
        {
            // Remove the shadow map that overlaps with the sprite (or fully cover it)
            if (sprite.LayerDepth <= this.layerDepth)
            {
                this.shadowMapShader.ApplyPass(1); // Remove
            }

            if (sprite.SpriteWorldPrimitives != null)
            {
                foreach (var currShape in sprite.SpriteWorldPrimitives)
                {
                    renderSystem.DirectScreenPaint(currShape);
                }
            }
            else
            {
                renderSystem.DirectScreenPaint(sprite.SpriteWorldBounds);
            }
        }
        /// <summary>
        /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to draw its color map.
        /// Override this method with component-specific drawing code.
        /// </summary>
        /// <param name="gameTime">Time passed since the last call to DrawColorMap.</param>
        /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param>
        public override void DrawColorMap(GameTime gameTime, DeferredRenderSystem renderSystem)
        {
            renderSystem.BeginRender();

            RectangleF posRect = new RectangleF(this.targetSprite.Position.X - this.lineWidth * 2.0f, this.targetSprite.Position.Y - this.lineWidth * 2.0f, this.lineWidth * 4.0f, this.lineWidth * 4.0f);

            renderSystem.DrawFilledRectangle(posRect, Color.White, this.Rotation); // Draw position

            // Draw shape outline if it exists
            if (this.targetSprite.SpriteWorldShape != null)
            {
                for (int index = 0; index < this.targetSprite.SpriteWorldShape.Count - 1; index++)
                {
                    renderSystem.DrawLine(this.targetSprite.SpriteWorldShape[index], this.targetSprite.SpriteWorldShape[index + 1], Color.Red, this.lineWidth);
                }
            }

            renderSystem.DrawRectangleBorder(this.targetSprite.SpriteWorldBounds, Color.Green, this.lineWidth, 0.0f);                               // Draw bounding rectangle
            renderSystem.DrawLine(this.targetSprite.Position, this.targetSprite.Position + this.targetSprite.Velocity, Color.Blue, this.lineWidth); // Draw velocity line

            renderSystem.EndRender();
        }
Example #20
0
 /// <summary>
 /// Called when the shader parameters are to be configured before rendering.
 /// </summary>
 /// <param name="renderSystem">Instance of the <see cref="DeferredRenderSystem"/> we are using to render</param>
 /// <param name="technique">Technique to use</param>
 public void ConfigureShader(DeferredRenderSystem renderSystem, string technique)
 {
     this.ConfigureShader(renderSystem, this.shaderAsset.Techniques[technique]);
 }
 /// <summary>
 /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="StaticPostProcess"/> component needs render itself.
 /// Override this method with component-specific drawing code.
 /// </summary>
 /// <param name="gameTime">Time passed since the last call to Draw.</param>
 /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param>
 public abstract void Draw(GameTime gameTime, DeferredRenderSystem renderSystem);
Example #22
0
 /// <summary>
 /// Gets the inverted view projection matrix for the camera.
 /// </summary>
 /// <param name="renderSystem">The render system that requires it.</param>
 /// <returns>The inversion of the product of the view matrix for the camera and the projection matrix used by SpriteBatch when rendering.</returns>
 public Matrix GetInvertedViewProjectionMatrix(DeferredRenderSystem renderSystem)
 {
     return(this.GetInvertedViewMatrix(renderSystem) * this.GetInvertedProjectionMatrix(renderSystem));
 }
Example #23
0
 /// <summary>
 /// Gets the inverted projection matrix for the camera.
 /// </summary>
 /// <param name="renderSystem">The render system that requires it.</param>
 /// <returns>The inversion of the projection matrix used by SpriteBatch when rendering.</returns>
 public Matrix GetInvertedProjectionMatrix(DeferredRenderSystem renderSystem)
 {
     return(Matrix.Invert(this.GetProjectionMatrix(renderSystem)));
 }
Example #24
0
        /// <summary>
        /// Gets the projection matrix for the camera.
        /// </summary>
        /// <param name="renderSystem">The render system that requires it.</param>
        /// <returns>The projection matrix used by SpriteBatch when rendering.</returns>
        public Matrix GetProjectionMatrix(DeferredRenderSystem renderSystem)
        {
            Rectangle screenSize = renderSystem.RenderTargets.ScreenRectangle;

            return(Matrix.CreateTranslation(-0.5f, -0.5f, 0) * Matrix.CreateOrthographicOffCenter(0, screenSize.Width, screenSize.Height, 0, 0, 1));
        }
 /// <summary>
 /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SpriteBase"/> component needs to draw its normal map.
 /// Override this method with component-specific drawing code.
 /// </summary>
 /// <param name="gameTime">Time passed since the last call to DrawColorMap.</param>
 /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param>
 public override void DrawNormalMap(GameTime gameTime, DeferredRenderSystem renderSystem)
 {
     return;
 }
 /// <summary>
 /// Called by the <see cref="DeferredRenderSystem"/> when this <see cref="SimulatedPostProcess"/> component needs render itself.
 /// Override this method with component-specific drawing code.
 /// </summary>
 /// <param name="gameTime">Time passed since the last call to Draw.</param>
 /// <param name="renderSystem"><see cref="DeferredRenderSystem"/> to render with.</param>
 protected abstract void Render(GameTime gameTime, DeferredRenderSystem renderSystem);
        /// <summary>
        /// Generates the shadow map to be used when rendering this light.
        /// </summary>
        /// <remarks>If this instance is not to cast shadows the shadow map is cleared.</remarks>
        /// <param name="renderSystem">The render system to render with.</param>
        /// <param name="shadowMap">The shadow map to render on</param>
        protected virtual void GenerateShadowMap(DeferredRenderSystem renderSystem, RenderTarget2D shadowMap)
        {
            RenderTarget2D intermediateShadowMap = renderSystem.RenderTargets.GetTemporaryRenderTarget(SurfaceFormat.Color); // Intermediate map used for selective sampling
            RectangleF     lightDrawBounds       = this.GetWorldDrawBounds();

            renderSystem.GraphicsDevice.SetRenderTarget(shadowMap);
            renderSystem.ClearCurrentRenderTarget(Color.White); // Clear the core shadow map

            // Only render the shadows if we are to cast them
            if (this.CastsShadows)
            {
                // Render the shadow caused by each object within the lights range
                List <SpriteBase> objectList = this.World.GetSpriteObjectsInArea(lightDrawBounds).Where(currObj => (currObj.RenderOptions & SpriteRenderOptions.CastsShadows) != 0).OrderBy(s => s.LayerDepth).ToList();

                if (objectList.Count > 0)
                {
                    int  lastLayerDepth      = 0;
                    int  lastLayerDepthIndex = 0;
                    bool renderedShadow      = false; // This is used so that we don't bother occluding objects if we didn't even render anything

                    lastLayerDepth = (int)objectList[0].LayerDepth;

                    for (int objectIndex = 0; objectIndex < objectList.Count; objectIndex++)
                    {
                        SpriteBase currObj           = objectList[objectIndex];
                        RectangleF spriteWorldBounds = currObj.SpriteWorldBounds;

                        // If the object we found doesn't cast shadows (or we're inside it), skip it
                        if (spriteWorldBounds.Contains(base.Position))
                        {
                            continue;
                        }

                        this.shadowMapShader.ConfigureShader(renderSystem); // Configure the shader
                        this.shadowMapShader.GetParameter("viewProjection").SetValue(renderSystem.GameCamera.GetViewProjectionMatrix(renderSystem));
                        this.shadowMapShader.GetParameter("cameraPosition").SetValue(renderSystem.GameCamera.PixelPosition);

                        // If we switched light planes remove occlusion from all previous objects
                        if (lastLayerDepth != (int)currObj.LayerDepth)
                        {
                            // Only occlude if we actually rendered something
                            if (renderedShadow)
                            {
                                // Loop through all the objects between the last layer index and the current index
                                for (int clearObjIndex = lastLayerDepthIndex; clearObjIndex < objectIndex; clearObjIndex++)
                                {
                                    this.ProcessSpriteDepthTransition(renderSystem, objectList[clearObjIndex]);
                                }
                            }

                            // Save the last values
                            lastLayerDepth      = (int)currObj.LayerDepth;
                            lastLayerDepthIndex = objectIndex;
                            renderedShadow      = false; // Reset this
                        }

                        // Create the shadow map caused by the current sprite
                        this.shadowMapShader.ApplyPass(0);

                        // Construct the vertex primitive to mask with
                        Vector2[] extrema;
                        if (currObj.SpriteWorldShape != null)
                        {
                            extrema = currObj.SpriteWorldShape.GetRelativeExtrema(base.Position); // Get the extrema that cause the shadow
                        }
                        else
                        {
                            extrema = spriteWorldBounds.GetRelativeExtrema(base.Position); // Get the extrema that cause the shadow
                        }

                        Vector2 widthVector  = Vector2.Normalize(extrema[0] - base.Position); // Get the vector to the first extrema
                        Vector2 heightVector = Vector2.Normalize(extrema[1] - base.Position); // Get the vector to the second extrema

                        VertexPrimitive shadowArea = new VertexPrimitive(PrimitiveType.TriangleStrip, 4);
                        shadowArea.Add(extrema[0]);
                        shadowArea.Add(extrema[1]);

                        // Let's extend the shadow vector until it hits the edge of the draw bounds
                        shadowArea.Add(lightDrawBounds.CastInternalRay(extrema[0], widthVector));
                        shadowArea.Add(lightDrawBounds.CastInternalRay(extrema[1], heightVector));

                        // Let's get the remaining verts that might exist to finish up the rect
                        List <Vector2> interiorVerts = lightDrawBounds.GetInteriorVertices(base.Position, widthVector, heightVector);
                        shadowArea.Add(interiorVerts);              // Add the interior verts (if any exist)

                        renderSystem.DirectScreenPaint(shadowArea); // Render the shadow
                        renderedShadow = true;                      // We just rendered a shadow; keep track of that
                    }

                    // Loop through all the objects between the last layer index and the current index
                    if (renderedShadow)
                    {
                        // Remove the shadows over the LAST shadow plane
                        for (int clearObjIndex = lastLayerDepthIndex; clearObjIndex < objectList.Count; clearObjIndex++)
                        {
                            this.ProcessSpriteDepthTransition(renderSystem, objectList[clearObjIndex]);
                        }

                        // Blur the shadow map if enabled
                        if (!float.IsPositiveInfinity(this.minShadowBlurDistance))
                        {
                            renderSystem.GraphicsDevice.SetRenderTarget(intermediateShadowMap); // We need to render to a temp target

                            // Configure the shader
                            this.shadowMapShader.ConfigureShader(renderSystem, 1);

                            // Set parameters
                            this.shadowMapShader.GetParameter("viewProjection").SetValue(renderSystem.GameCamera.GetViewProjectionMatrix(renderSystem));
                            this.shadowMapShader.GetParameter("cameraPosition").SetValue(renderSystem.GameCamera.PixelPosition);
                            this.shadowMapShader.GetParameter("lightPosition").SetValue(base.PixelPosition);
                            this.shadowMapShader.GetParameter("maxBlurDistance").SetValue(this.World.GetPixelFromWorld(this.maxShadowBlurDistance));
                            this.shadowMapShader.GetParameter("minBlurDistance").SetValue(this.World.GetPixelFromWorld(this.maxShadowBlurDistance));
                            this.shadowMapShader.GetParameter("shadowMap").SetValue(shadowMap);

                            this.shadowMapShader.ApplyPass(0);
                            renderSystem.DirectScreenPaint(lightDrawBounds);        // Render the shadow

                            renderSystem.GraphicsDevice.SetRenderTarget(shadowMap); // Set the shadow map for final render

                            // Update shadow map
                            this.shadowMapShader.GetParameter("shadowMap").SetValue(intermediateShadowMap);

                            this.shadowMapShader.ApplyPass(0);
                            renderSystem.DirectScreenPaint(lightDrawBounds); // Render
                        }
                    }
                }
            }

            renderSystem.SetRenderTargets(RenderTargetTypes.None, 0); // Resolve the render target
            renderSystem.RenderTargets.ReleaseTemporaryRenderTarget(intermediateShadowMap);
        }
Example #28
0
 /// <summary>
 /// Called when the shader parameters are to be configured initially.
 /// </summary>
 /// <param name="renderSystem">Instance of the <see cref="DeferredRenderSystem"/> we are using to render</param>
 protected virtual void InitConfigure(DeferredRenderSystem renderSystem)
 {
     this.isConfigured = true;
 }
Example #29
0
 /// <summary>
 /// Called when the shader parameters are to be configured before rendering.
 /// </summary>
 /// <param name="renderSystem">Instance of the <see cref="DeferredRenderSystem"/> we are using to render</param>
 /// <param name="techniqueIndex">Index of the technique to use</param>
 public void ConfigureShader(DeferredRenderSystem renderSystem, int techniqueIndex)
 {
     this.ConfigureShader(renderSystem, this.shaderAsset.Techniques[techniqueIndex]);
 }
Example #30
0
 /// <summary>
 /// Called when the shader parameters are to be configured before rendering.
 /// </summary>
 /// <param name="renderSystem">Instance of the <see cref="DeferredRenderSystem"/> we are using to render</param>
 public void ConfigureShader(DeferredRenderSystem renderSystem)
 {
     this.ConfigureShader(renderSystem, 0);
 }