/// <summary>
        /// Update per frame data
        /// </summary>
        /// <param name="world">World matrix</param>
        /// <param name="context">Context</param>
        public override void UpdatePerFrame(
            Matrix world,
            DrawContextShadows context)
        {
            var viewProjection = context.ShadowMap.FromLightViewProjectionArray;

            if (viewProjection != null && viewProjection.Length > 0)
            {
                if (viewProjection.Length != MaxCascades)
                {
                    throw new EngineException($"The matrix array must have a length of {MaxCascades}");
                }

                var m = new Matrix[viewProjection.Length];
                for (int i = 0; i < viewProjection.Length; i++)
                {
                    m[i] = world * viewProjection[i];
                }

                this.WorldViewProjectionArray = m;
            }
            else
            {
                this.WorldViewProjectionArray = null;
            }
        }
示例#2
0
        /// <summary>
        /// Draws the gardener shadows
        /// </summary>
        /// <param name="context">Context</param>
        public override void DrawShadows(DrawContextShadows context)
        {
            if (this.visibleNodes.Any())
            {
                var graphics = this.Game.Graphics;

                graphics.SetBlendDefaultAlpha();

                foreach (var item in this.visibleNodes)
                {
                    this.DrawShadowsNode(context, item);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Sets thecnique for vegetation drawing in shadow mapping
        /// </summary>
        /// <param name="context">Drawing context</param>
        /// <param name="channel">Channel</param>
        /// <returns>Returns the selected technique</returns>
        private EngineEffectTechnique SetTechniqueVegetationShadowMap(DrawContextShadows context, int channel)
        {
            var channelData = this.foliageMapChannels[channel];

            var effect = DrawerPool.EffectShadowFoliage;

            #region Per frame update

            effect.UpdatePerFrame(
                context.ViewProjection,
                context.EyePosition,
                this.WindDirection,
                this.WindStrength * channelData.WindEffect,
                this.windTime * channelData.WindEffect,
                channelData.Delta,
                this.textureRandom);

            #endregion

            #region Per object update

            effect.UpdatePerObject(
                channelData.StartRadius,
                channelData.EndRadius,
                channelData.TextureCount,
                channelData.Textures);

            #endregion

            if (channelData.Count == 1)
            {
                return(effect.ShadowMapFoliage4);
            }
            if (channelData.Count == 2)
            {
                return(effect.ShadowMapFoliage8);
            }
            if (channelData.Count == 4)
            {
                return(effect.ShadowMapFoliage16);
            }
            else
            {
                return(null);
            }
        }
示例#4
0
        /// <summary>
        /// Draws the node shadows
        /// </summary>
        /// <param name="context">Context</param>
        /// <param name="item">Node</param>
        private void DrawShadowsNode(DrawContextShadows context, QuadTreeNode item)
        {
            var buffers = this.foliageBuffers.FindAll(b => b.CurrentPatch?.CurrentNode == item);

            if (buffers.Count > 0)
            {
                foreach (var buffer in buffers)
                {
                    var vegetationTechnique = this.SetTechniqueVegetationShadowMap(context, buffer.CurrentPatch.Channel);
                    if (vegetationTechnique != null)
                    {
                        this.BufferManager.SetInputAssembler(
                            vegetationTechnique,
                            buffer.VertexBuffer.Slot,
                            Topology.PointList);

                        buffer.DrawFoliageShadows(vegetationTechnique);
                    }
                }
            }
        }
示例#5
0
        /// <summary>
        /// Draw shadows
        /// </summary>
        /// <param name="context"></param>
        public override void DrawShadows(DrawContextShadows context)
        {
            if (this.DrawingData == null)
            {
                return;
            }

            var effect = context.ShadowMap.GetEffect();

            if (effect == null)
            {
                return;
            }

            int count = 0;

            foreach (string meshName in this.DrawingData.Meshes.Keys)
            {
                count += DrawMeshShadow(context, effect, meshName);
            }
        }
示例#6
0
        /// <summary>
        /// Draw shadows
        /// </summary>
        /// <param name="context">Context</param>
        public override void DrawShadows(DrawContextShadows context)
        {
            if (this.visibleNodes.Any())
            {
                var graphics = this.Game.Graphics;

                var sceneryEffect = context.ShadowMap.GetEffect();
                if (sceneryEffect != null)
                {
                    sceneryEffect.UpdatePerFrame(Matrix.Identity, context);

                    graphics.SetBlendDefault();

                    foreach (var node in visibleNodes)
                    {
                        this.patchDictionary[node.Id].Current = node;
                        this.patchDictionary[node.Id].DrawSceneryShadows(sceneryEffect, this.BufferManager);
                    }
                }
            }
        }
示例#7
0
        /// <summary>
        /// Draws a mesh shadow
        /// </summary>
        /// <param name="context">Context</param>
        /// <param name="effect">Effect</param>
        /// <param name="meshName">Mesh name</param>
        /// <returns>Returns the number of drawn triangles</returns>
        private int DrawMeshShadow(DrawContextShadows context, IShadowMapDrawer effect, string meshName)
        {
            int count = 0;

            var graphics = this.Game.Graphics;

            var meshDict = this.DrawingData.Meshes[meshName];

            var localTransform = this.GetTransformByName(meshName);

            effect.UpdatePerFrame(localTransform, context);

            foreach (string materialName in meshDict.Keys)
            {
                var mesh     = meshDict[materialName];
                var material = this.DrawingData.Materials[materialName];

                effect.UpdatePerObject(this.AnimationOffset, material, this.TextureIndex);

                this.BufferManager.SetIndexBuffer(mesh.IndexBuffer.Slot);

                var technique = effect.GetTechnique(mesh.VertextType, false, material.Material.IsTransparent);
                this.BufferManager.SetInputAssembler(technique, mesh.VertexBuffer.Slot, mesh.Topology);

                count += mesh.IndexBuffer.Count > 0 ? mesh.IndexBuffer.Count / 3 : mesh.VertexBuffer.Count / 3;

                for (int p = 0; p < technique.PassCount; p++)
                {
                    graphics.EffectPassApply(technique, p, 0);

                    mesh.Draw(graphics);
                }
            }

            return(count);
        }
示例#8
0
 /// <summary>
 /// Draw shadows
 /// </summary>
 /// <param name="context">Context</param>
 public virtual void DrawShadows(DrawContextShadows context)
 {
 }
示例#9
0
 /// <summary>
 /// Update per frame data
 /// </summary>
 /// <param name="world">World matrix</param>
 /// <param name="context">Context</param>
 public abstract void UpdatePerFrame(
     Matrix world,
     DrawContextShadows context);
示例#10
0
        /// <summary>
        /// Shadow Drawing
        /// </summary>
        /// <param name="context">Context</param>
        public override void DrawShadows(DrawContextShadows context)
        {
            if (this.hasDataToWrite)
            {
                this.BufferManager.WriteInstancingData(this.instancingData);
            }

            if (this.VisibleCount <= 0)
            {
                return;
            }

            var effect = context.ShadowMap.GetEffect();

            if (effect == null)
            {
                return;
            }

            int count         = 0;
            int instanceCount = 0;

            effect.UpdatePerFrame(Matrix.Identity, context);

            int maxCount = this.GetMaxCount();

            //Render by level of detail
            for (int l = 1; l < (int)LevelOfDetail.Minimum + 1; l *= 2)
            {
                if (maxCount <= 0)
                {
                    break;
                }

                LevelOfDetail lod = (LevelOfDetail)l;

                //Get instances in this LOD
                var lodInstances = Array.FindAll(this.instancesTmp, i => i != null && i.LevelOfDetail == lod);
                if (lodInstances.Length <= 0)
                {
                    continue;
                }

                var drawingData = this.GetDrawingData(lod);
                if (drawingData == null)
                {
                    continue;
                }

                var index  = Array.IndexOf(this.instancesTmp, lodInstances[0]);
                var length = Math.Min(maxCount, lodInstances.Length);
                if (length <= 0)
                {
                    continue;
                }

                maxCount      -= length;
                instanceCount += length;

                foreach (string meshName in drawingData.Meshes.Keys)
                {
                    count += this.DrawMeshShadow(effect, drawingData, meshName, index, length);
                    count *= instanceCount;
                }
            }
        }
示例#11
0
 /// <summary>
 /// Update per frame data
 /// </summary>
 /// <param name="world">World matrix</param>
 /// <param name="context">Context</param>
 public override void UpdatePerFrame(
     Matrix world,
     DrawContextShadows context)
 {
     this.WorldViewProjection = world * context.ShadowMap.FromLightViewProjectionArray[0];
 }