Esempio n. 1
0
        public VisionEffect(Effect effect, SamplerState samplerState = null)
        {
            GraphicsDevice = effect.GraphicsDevice;
            Effect = effect;
            Name = effect.Name;

            _epTextureSampler = effect.Parameters["TextureSampler"];
            if(_epTextureSampler!=null)
                Sampler = samplerState ?? GraphicsDevice.SamplerStates.LinearWrap;

            _epWorld = effect.Parameters["World"];
            _epWorldInverseTranspose = effect.Parameters["WorldInverseTranspose"];
            _epView = effect.Parameters["View"];
            _epProjection = effect.Parameters["Projection"];
            _epCameraPosition = effect.Parameters["CameraPosition"];
            _epClipPlane = effect.Parameters["ClipPlane"];
            _epSunlightDirection = effect.Parameters["SunlightDirection"];
            _epTexture = effect.Parameters["Texture"];
            _epDiffuseColor = effect.Parameters["DiffuseColor"];

            _epDoShadowMapping = effect.Parameters["DoShadowMapping"];
            _epShadowMap = effect.Parameters["ShadowMap"];
            _epShadowViewProjection = effect.Parameters["ShadowViewProjection"];
            _epShadowFarPlane = effect.Parameters["ShadowFarPlane"];
            _epShadowMult = effect.Parameters["ShadowMult"];

            _techStandard = effect.Techniques["TechStandard"];
            _techClipPlane = effect.Techniques["TechClipPlane"];
            _techDepthMap = effect.Techniques["TechDepthMap"];

            //Debug.Assert( _epView != null );
            //Debug.Assert(_techDepthMap != null);

            if ( _epSunlightDirection != null)
                _epSunlightDirection.SetValue(VisionContent.SunlightDirection);
        }
Esempio n. 2
0
        /// <summary>
        ///   Initializes a new instance of the <see cref="EffectPass" /> class.
        /// </summary>
        /// <param name="logger">The logger used to log errors.</param>
        /// <param name="effect"> The effect. </param>
        /// <param name="pass"> The pass. </param>
        /// <param name="name"> The name. </param>
        internal EffectPass(Logger logger, Effect effect, EffectTechnique technique, EffectData.Pass pass, string name)
            : base(name)
        {
            this.Technique = technique;
            this.pass = pass;
            this.Effect = effect;
            this.graphicsDevice = effect.GraphicsDevice;
            pipeline = new PipelineBlock()
                           {
                               Stages = new StageBlock[EffectPass.StageCount],
                           };

            Attributes = PrepareAttributes(logger, pass.Attributes);
            IsSubPass = pass.IsSubPass;
            // Don't create SubPasses collection for subpass.
            if (!IsSubPass)
                SubPasses = new EffectPassCollection();
        }
Esempio n. 3
0
        /// <summary>
        /// Binds the specified effect data to this instance.
        /// </summary>
        /// <param name="effectDataArg">The effect data arg.</param>
        /// <param name="cloneFromEffect">The clone from effect.</param>
        /// <exception cref="System.InvalidOperationException">If no techniques found in this effect.</exception>
        /// <exception cref="System.ArgumentException">If unable to find effect [effectName] from the EffectPool.</exception>
        internal void InitializeFrom(EffectData.Effect effectDataArg, Effect cloneFromEffect)
        {
            RawEffectData = effectDataArg;

            // Clean any previously allocated resources
            if (DisposeCollector != null)
            {
                DisposeCollector.DisposeAndClear();
            }
            ConstantBuffers.Clear();
            Parameters.Clear();
            Techniques.Clear();
            ResourceLinker = ToDispose(new EffectResourceLinker());
            if (effectConstantBuffersCache != null)
            {
                effectConstantBuffersCache.Clear();
            }

            // Copy data
            IsSupportingDynamicCompilation = RawEffectData.Arguments != null;
            ShareConstantBuffers           = RawEffectData.ShareConstantBuffers;

            // Create the local effect constant buffers cache
            if (!ShareConstantBuffers)
            {
                effectConstantBuffersCache = new Dictionary <EffectConstantBufferKey, EffectConstantBuffer>();
            }

            var        logger         = new Logger();
            int        techniqueIndex = 0;
            int        totalPassCount = 0;
            EffectPass parentPass     = null;

            foreach (var techniqueRaw in RawEffectData.Techniques)
            {
                var name = techniqueRaw.Name;
                if (string.IsNullOrEmpty(name))
                {
                    name = string.Format("${0}", techniqueIndex++);
                }

                var technique = new EffectTechnique(this, name);
                Techniques.Add(technique);

                int passIndex = 0;
                foreach (var passRaw in techniqueRaw.Passes)
                {
                    name = passRaw.Name;
                    if (string.IsNullOrEmpty(name))
                    {
                        name = string.Format("${0}", passIndex++);
                    }

                    var pass = new EffectPass(logger, this, technique, passRaw, name);

                    pass.Initialize(logger);

                    // If this is a subpass, add it to the parent pass
                    if (passRaw.IsSubPass)
                    {
                        if (parentPass == null)
                        {
                            logger.Error("Pass [{0}] is declared as a subpass but has no parent.");
                        }
                        else
                        {
                            parentPass.SubPasses.Add(pass);
                        }
                    }
                    else
                    {
                        technique.Passes.Add(pass);
                        parentPass = pass;
                    }
                }

                // Count the number of passes
                totalPassCount += technique.Passes.Count;
            }

            if (totalPassCount == 0)
            {
                throw new InvalidOperationException("No passes found in this effect.");
            }

            // Log all the exception in a single throw
            if (logger.HasErrors)
            {
                throw new InvalidOperationException(Utilities.Join("\n", logger.Messages));
            }

            // Initialize the resource linker when we are done with all pass/parameters
            ResourceLinker.Initialize();

            //// Sort all parameters by their resource types
            //// in order to achieve better local cache coherency in resource linker
            Parameters.Items.Sort((left, right) =>
            {
                // First, order first all value types, then resource type
                var comparison = left.IsValueType != right.IsValueType ? left.IsValueType ? -1 : 1 : 0;

                // If same type
                if (comparison == 0)
                {
                    // Order by resource type
                    comparison = ((int)left.ResourceType).CompareTo((int)right.ResourceType);

                    // If same, order by resource index
                    if (comparison == 0)
                    {
                        comparison = left.Offset.CompareTo(right.Offset);
                    }
                }
                return(comparison);
            });

            // Prelink constant buffers
            int resourceIndex = 0;

            foreach (var parameter in Parameters)
            {
                // Recalculate parameter resource index
                if (!parameter.IsValueType)
                {
                    parameter.Offset = resourceIndex;
                    resourceIndex   += parameter.ElementCount;
                }

                // Set the default values
                parameter.SetDefaultValue();

                if (parameter.ResourceType == EffectResourceType.ConstantBuffer)
                {
                    parameter.SetResource(ConstantBuffers[parameter.Name]);
                }
            }

            // Compute slot links
            foreach (var technique in Techniques)
            {
                foreach (var pass in technique.Passes)
                {
                    foreach (var subPass in pass.SubPasses)
                    {
                        subPass.ComputeSlotLinks();
                    }
                    pass.ComputeSlotLinks();
                }
            }

            // Setup the first Current Technique.
            CurrentTechnique = this.Techniques[0];

            // Initialize predefined parameters used by Model.Draw (to speedup things internally)
            DefaultParameters = new EffectDefaultParameters(this);

            // If this is a clone, we need to
            if (cloneFromEffect != null)
            {
                // Copy the content of the constant buffers to the new instance.
                for (int i = 0; i < ConstantBuffers.Count; i++)
                {
                    cloneFromEffect.ConstantBuffers[i].CopyTo(ConstantBuffers[i]);
                }

                // Copy back all bound resources except constant buffers
                // that are already initialized with InitializeFrom method.
                for (int i = 0; i < cloneFromEffect.ResourceLinker.Count; i++)
                {
                    if (cloneFromEffect.ResourceLinker.BoundResources[i] is EffectConstantBuffer)
                    {
                        continue;
                    }

                    ResourceLinker.BoundResources[i] = cloneFromEffect.ResourceLinker.BoundResources[i];
                    unsafe
                    {
                        ResourceLinker.Pointers[i] = cloneFromEffect.ResourceLinker.Pointers[i];
                    }
                }

                // If everything was fine, then we can register it into the pool
                Pool.AddEffect(this);
            }

            // Allow subclasses to complete initialization.
            Initialize();

            OnInitialized();
        }
Esempio n. 4
0
        /// <summary>
        /// Binds the specified effect data to this instance.
        /// </summary>
        /// <param name="effectDataArg">The effect data arg.</param>
        /// <param name="cloneFromEffect">The clone from effect.</param>
        /// <exception cref="System.InvalidOperationException">If no techniques found in this effect.</exception>
        /// <exception cref="System.ArgumentException">If unable to find effect [effectName] from the EffectPool.</exception>
        internal void InitializeFrom(EffectData.Effect effectDataArg, Effect cloneFromEffect)
        {
            RawEffectData = effectDataArg;

            // Clean any previously allocated resources
            if (DisposeCollector != null)
            {
                DisposeCollector.DisposeAndClear();
            }
            ConstantBuffers.Clear();
            Parameters.Clear();
            Techniques.Clear();
            ResourceLinker = ToDispose(new EffectResourceLinker());
            if (effectConstantBuffersCache != null)
            {
                effectConstantBuffersCache.Clear();
            }

            // Copy data
            IsSupportingDynamicCompilation = RawEffectData.Arguments != null;
            ShareConstantBuffers = RawEffectData.ShareConstantBuffers;

            // Create the local effect constant buffers cache
            if (!ShareConstantBuffers)
                effectConstantBuffersCache = new Dictionary<EffectConstantBufferKey, EffectConstantBuffer>();

            var logger = new Logger();
            int techniqueIndex = 0;
            int totalPassCount = 0;
            EffectPass parentPass = null;
            foreach (var techniqueRaw in RawEffectData.Techniques)
            {
                var name = techniqueRaw.Name;
                if (string.IsNullOrEmpty(name))
                    name = string.Format("${0}", techniqueIndex++);

                var technique = new EffectTechnique(this, name);
                Techniques.Add(technique);

                int passIndex = 0;
                foreach (var passRaw in techniqueRaw.Passes)
                {
                    name = passRaw.Name;
                    if (string.IsNullOrEmpty(name))
                        name = string.Format("${0}", passIndex++);

                    var pass = new EffectPass(logger, this, technique, passRaw, name);

                    pass.Initialize(logger);

                    // If this is a subpass, add it to the parent pass
                    if (passRaw.IsSubPass)
                    {
                        if (parentPass == null)
                        {
                            logger.Error("Pass [{0}] is declared as a subpass but has no parent.");
                        }
                        else
                        {
                            parentPass.SubPasses.Add(pass);
                        }
                    }
                    else
                    {
                        technique.Passes.Add(pass);
                        parentPass = pass;
                    }
                }

                // Count the number of passes
                totalPassCount += technique.Passes.Count;
            }

            if (totalPassCount == 0)
                throw new InvalidOperationException("No passes found in this effect.");

            // Log all the exception in a single throw
            if (logger.HasErrors)
                throw new InvalidOperationException(Utilities.Join("\n", logger.Messages));

            // Initialize the resource linker when we are done with all pass/parameters
            ResourceLinker.Initialize();

            //// Sort all parameters by their resource types
            //// in order to achieve better local cache coherency in resource linker
            Parameters.Items.Sort((left, right) =>
                {
                    // First, order first all value types, then resource type
                    var comparison = left.IsValueType != right.IsValueType ? left.IsValueType ? -1 : 1 : 0;

                    // If same type
                    if (comparison == 0)
                    {
                        // Order by resource type
                        comparison = ((int)left.ResourceType).CompareTo((int)right.ResourceType);

                        // If same, order by resource index
                        if (comparison == 0)
                        {
                            comparison = left.Offset.CompareTo(right.Offset);
                        }
                    }
                    return comparison;
                });

            // Prelink constant buffers
            int resourceIndex = 0;
            foreach (var parameter in Parameters)
            {
                // Recalculate parameter resource index
                if (!parameter.IsValueType)
                {
                    parameter.Offset = resourceIndex++;
                }

                // Set the default values 
                parameter.SetDefaultValue();

                if (parameter.ResourceType == EffectResourceType.ConstantBuffer)
                    parameter.SetResource(ConstantBuffers[parameter.Name]);
            }

            // Compute slot links
            foreach (var technique in Techniques)
            {
                foreach (var pass in technique.Passes)
                {
                    foreach (var subPass in pass.SubPasses)
                    {
                        subPass.ComputeSlotLinks();
                    }
                    pass.ComputeSlotLinks();
                }
            }

            // Setup the first Current Technique.
            CurrentTechnique = this.Techniques[0];

            // Initialize predefined parameters used by Model.Draw (to speedup things internally)
            DefaultParameters = new EffectDefaultParameters(this);

            // If this is a clone, we need to 
            if (cloneFromEffect != null)
            {
                // Copy the content of the constant buffers to the new instance.
                for (int i = 0; i < ConstantBuffers.Count; i++)
                {
                    cloneFromEffect.ConstantBuffers[i].CopyTo(ConstantBuffers[i]);
                }

                // Copy back all bound resources except constant buffers
                // that are already initialized with InitializeFrom method.
                for (int i = 0; i < cloneFromEffect.ResourceLinker.Count; i++)
                {
                    if (cloneFromEffect.ResourceLinker.BoundResources[i] is EffectConstantBuffer)
                        continue;

                    ResourceLinker.BoundResources[i] = cloneFromEffect.ResourceLinker.BoundResources[i];
                    unsafe
                    {
                        ResourceLinker.Pointers[i] = cloneFromEffect.ResourceLinker.Pointers[i];
                    }
                }

                // If everything was fine, then we can register it into the pool
                Pool.AddEffect(this);
            }

            // Allow subclasses to complete initialization.
            Initialize();
        }
Esempio n. 5
0
        /// <summary>
        /// Initializes the specified effect bytecode.
        /// </summary>
        /// <param name="effectDataArg">The effect bytecode.</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        private void Initialize(EffectData.Effect effectDataArg)
        {
            if (effectDataArg == null)
                throw new ArgumentException(string.Format("Unable to find effect [{0}] from the EffectPool", Name), "effectName");

            rawEffect = effectDataArg;

            ShareConstantBuffers = effectDataArg.ShareConstantBuffers;

            // Create the local effect constant buffers cache
            if (!ShareConstantBuffers)
                effectConstantBuffersCache = new Dictionary<EffectConstantBufferKey, EffectConstantBuffer>();

            if (effectDataArg.Techniques.Count == 0)
                throw new InvalidOperationException("No techniques found in this effect");

            var logger = new Logger();
            int techniqueIndex = 0;
            int totalPassCount = 0;
            EffectPass parentPass = null;
            foreach (var techniqueRaw in effectDataArg.Techniques)
            {
                var name = techniqueRaw.Name;
                if (string.IsNullOrEmpty(name))
                    name = string.Format("${0}", techniqueIndex++);

                var technique = new EffectTechnique(this, name);
                Techniques.Add(technique);

                int passIndex = 0;
                foreach (var passRaw in techniqueRaw.Passes)
                {
                    name = passRaw.Name;
                    if (string.IsNullOrEmpty(name))
                        name = string.Format("${0}", passIndex++);

                    var pass = new EffectPass(logger, this, technique, passRaw, name);

                    pass.Initialize(logger);

                    // If this is a subpass, add it to the parent pass
                    if (passRaw.IsSubPass)
                    {
                        if (parentPass == null)
                        {
                            logger.Error("Pass [{0}] is declared as a subpass but has no parent");
                        }
                        else
                        {
                            parentPass.SubPasses.Add(pass);
                        }
                    }
                    else
                    {
                        technique.Passes.Add(pass);
                        parentPass = pass;
                    }
                }

                // Count the number of passes
                totalPassCount += technique.Passes.Count;
            }

            if (totalPassCount == 0)
                throw new InvalidOperationException("No passes found in this effect");

            // Log all the exception in a single throw
            if (logger.HasErrors)
                throw new InvalidOperationException(Utilities.Join("\n", logger.Messages));

            // Initialize the resource linker when we are done with all pass/parameters
            ResourceLinker.Initialize();

            //// Sort all parameters by their resource types
            //// in order to achieve better local cache coherency in resource linker
            Parameters.Items.Sort((left, right) =>
                {
                    // First, order first all value types, then resource type
                    var comparison = left.IsValueType != right.IsValueType ? left.IsValueType ? -1 : 1 : 0;

                    // If same type
                    if (comparison == 0)
                    {
                        // Order by resource type
                        comparison = ((int)left.ResourceType).CompareTo((int)right.ResourceType);

                        // If same, order by resource index
                        if (comparison == 0)
                        {
                            comparison = left.Offset.CompareTo(right.Offset);
                        }
                    }
                    return comparison;
                });

            // Prelink constant buffers
            int resourceIndex = 0;
            foreach (var parameter in Parameters)
            {
                // Recalculate parameter resource index
                if (!parameter.IsValueType)
                {
                    parameter.Offset = resourceIndex++;
                }

                // Set the default values 
                parameter.SetDefaultValue();

                if (parameter.ResourceType == EffectResourceType.ConstantBuffer)
                    parameter.SetResource(0, ConstantBuffers[parameter.Name]);
            }

            // Compute slot links
            foreach (var technique in Techniques)
            {
                foreach (var pass in technique.Passes)
                {
                    foreach (var subPass in pass.SubPasses)
                    {
                        subPass.ComputeSlotLinks();
                    }
                    pass.ComputeSlotLinks();
                }
            }

            // Setup the first Current Technique.
            CurrentTechnique = this.Techniques[0];
        }