Example #1
0
        /// <summary>
        /// Draws this pass using the specified drawing context.
        /// </summary>
        public override void Draw(DrawingContext context, IList <IDrawableObject> drawables)
        {
            if (shadowCasterQuery == null)
            {
                shadowCasterQuery = context.CreateSpatialQuery <IDrawableObject>(drawable => drawable.CastShadow);
            }

            light.UpdateShadowFrustum(context, shadowCasterQuery);
            shadowCasterQuery.FindAll(light.ShadowFrustum, shadowCasters);

            Matrix oldView       = context.matrices.view;
            Matrix oldProjection = context.matrices.projection;

            Begin();

            // Leave the border pixels untouched so the shadow will not be stretched
            // when using clamped sampling.
            var viewport = context.graphics.Viewport;

            context.graphics.Viewport = new Viewport(viewport.X + 1, viewport.Y + 1, viewport.Width - 2, viewport.Height - 2);

            context.matrices.View       = light.ShadowFrustum.Matrix;
            context.matrices.Projection = Matrix.Identity;

            context.graphics.SamplerStates[0]  = SamplerState.PointClamp;
            context.graphics.BlendState        = BlendState.Opaque;
            context.graphics.DepthStencilState = DepthStencilState.Default;

            for (int i = 0; i < shadowCasters.Count; ++i)
            {
                var shadowCaster = shadowCasters[i];
                if (!shadowCaster.OnAddedToView(context))
                {
                    continue;
                }

                var material = shadowCaster.Material;
                if (material == null)
                {
                    material = depthMaterial;
                }
                else
                {
                    material = material.GetMaterialByUsage(MaterialUsage.Depth);
                }

                if (material != null)
                {
                    shadowCaster.Draw(context, material);
                }
            }

            shadowCasters.Clear();
            End(context);

            context.matrices.View       = oldView;
            context.matrices.Projection = oldProjection;
        }