/// <summary>
        /// Update a dynamic effect instance based on its parameters.
        /// </summary>
        /// <param name="effectInstance">A dynmaic effect instance</param>
        /// <param name="passParameters">The pass parameters.</param>
        /// <returns><c>true</c> if the effect was recomiled on the effect instance, <c>false</c> otherwise.</returns>
        public bool Update(DynamicEffectInstance effectInstance, ParameterCollection passParameters)
        {
            bool effectChanged = false;

            var currentlyCompilingEffect = effectInstance.CurrentlyCompilingEffect;

            if (currentlyCompilingEffect != null)
            {
                if (currentlyCompilingEffect.IsCompleted)
                {
                    if (currentlyCompilingEffect.IsFaulted)
                    {
                        var compilerParameters = new CompilerParameters();
                        effectInstance.CurrentlyCompilingUsedParameters.CopyTo(compilerParameters);

                        SwitchFallbackEffect(FallbackEffectType.Error, effectInstance, passParameters, compilerParameters);
                    }
                    else
                    {
                        effectInstance.HasErrors = false;
                        // Do not update effect right away: passParameters might have changed since last compilation; just try to go through a CreateEffect that will properly update the effect synchronously
                        // TODO: This class (and maybe whole ParameterCollection system) need a complete rethink and rewrite with newest assumptions...
                        //UpdateEffect(effectInstance, currentlyCompilingEffect.Result, effectInstance.CurrentlyCompilingUsedParameters, passParameters);
                    }

                    effectChanged = true;

                    // Effect has been updated
                    effectInstance.CurrentlyCompilingEffect         = null;
                    effectInstance.CurrentlyCompilingUsedParameters = null;
                }
            }

            if (effectChanged || // Check again, in case effect was just finished async compilation
                (effectInstance.Effect == null || !EffectSystem.IsValid(effectInstance.Effect) || HasCollectionChanged(effectInstance, passParameters) || effectInstance.HasErrors))
            {
                if (effectInstance.HasErrors)
                {
#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
                    var currentTime = DateTime.Now;
                    if (currentTime < effectInstance.LastErrorCheck + ErrorCheckTimeSpan)
                    {
                        // Wait a regular interval before retrying to compile effect (i.e. every second)
                        return(false);
                    }

                    // Update last check time
                    effectInstance.LastErrorCheck = currentTime;
#else
                    // Other platforms: never try to recompile failed effects for now
                    return(false);
#endif
                }

                CreateEffect(effectInstance, passParameters);
                effectChanged = true;
            }

            return(effectChanged);
        }
Beispiel #2
0
        private Effect GetOrCreatePickingSpriteEffect()
        {
            if (pickingSpriteEffect == null)
            {
                pickingSpriteEffect = EffectSystem.LoadEffect("SpritePicking").WaitForResult();
            }

            return(pickingSpriteEffect);
        }
Beispiel #3
0
        private Effect GetOrCreateSelectedSpriteEffect()
        {
            if (selectedSpriteEffect == null)
            {
                selectedSpriteEffect = EffectSystem.LoadEffect("SelectedSprite").WaitForResult();
            }

            return(selectedSpriteEffect);
        }
Beispiel #4
0
 public SkyboxGeneratorContext()
 {
     Services = new ServiceRegistry();
     Assets = new AssetManager(Services);
     GraphicsDevice = GraphicsDevice.New();
     GraphicsDeviceService = new GraphicsDeviceServiceLocal(Services, GraphicsDevice);
     EffectSystem = new EffectSystem(Services);
     EffectSystem.Initialize();
     ((IContentable)EffectSystem).LoadContent();
     ((EffectCompilerCache)EffectSystem.Compiler).CompileEffectAsynchronously = false;
     DrawEffectContext = RenderContext.GetShared(Services);
 }
Beispiel #5
0
        private Effect GetOrCreateSelectedSpriteEffect(ref Effect effect, bool isSRgb)
        {
            if (effect == null)
            {
                var compilerParameters = new CompilerParameters {
                    [SpriteBaseKeys.ColorIsSRgb] = isSRgb
                };
                effect = EffectSystem.LoadEffect("SelectedSprite", compilerParameters).WaitForResult();
            }

            return(effect);
        }
Beispiel #6
0
        internal static IEffectCompiler CreateEffectCompiler(EffectSystem effectSystem, Guid?packageId, EffectCompilationMode effectCompilationMode, bool recordEffectRequested, TaskSchedulerSelector taskSchedulerSelector = null)
        {
            EffectCompilerBase compiler = null;

#if SILICONSTUDIO_PARADOX_EFFECT_COMPILER
            if ((effectCompilationMode & EffectCompilationMode.Local) != 0)
            {
                // Local allowed and available, let's use that
                compiler = new EffectCompiler
                {
                    SourceDirectories = { EffectCompilerBase.DefaultSourceShaderFolder },
                };
            }
#endif

            // Nothing to do remotely
            bool needRemoteCompiler = (compiler == null && (effectCompilationMode & EffectCompilationMode.Remote) != 0);
            if (needRemoteCompiler || recordEffectRequested)
            {
                // Create the object that handles the connection
                var shaderCompilerTarget = new RemoteEffectCompilerClient(packageId);

                if (recordEffectRequested)
                {
                    // Let's notify effect compiler server for each new effect requested
                    effectSystem.EffectUsed += shaderCompilerTarget.NotifyEffectUsed;
                }

                // Use remote only if nothing else was found before (i.e. a local compiler)
                if (needRemoteCompiler)
                {
                    // Create a remote compiler
                    compiler = new RemoteEffectCompiler(shaderCompilerTarget);
                }
            }

            // Local not possible or allowed, and remote not allowed either => switch back to null compiler
            if (compiler == null)
            {
                compiler = new NullEffectCompiler();
            }

            return(new EffectCompilerCache(compiler, taskSchedulerSelector));
        }
        private void CreateEffect(DynamicEffectInstance effectInstance, ParameterCollection passParameters)
        {
            var compilerParameters = BuildCompilerParameters(effectInstance, passParameters);

            // Compile shader
            // possible exception in LoadEffect
            TaskOrResult <Effect> effect;
            ParameterCollection   usedParameters;

            try
            {
                effect = EffectSystem.LoadEffect(EffectName, compilerParameters, out usedParameters);
            }
            catch (Exception)
            {
                SwitchFallbackEffect(FallbackEffectType.Error, effectInstance, passParameters, compilerParameters);
                return;
            }

            // Do we have an async compilation?
            if (asyncEffectCompiler && effect.Task != null)
            {
                effectInstance.CurrentlyCompilingEffect         = effect.Task;
                effectInstance.CurrentlyCompilingUsedParameters = usedParameters;

                if (!effectInstance.HasErrors) // If there was an error, stay in that state (we don't want to switch between reloading and error states)
                {
                    // Fallback to default effect
                    var fallbackEffect = ComputeFallbackEffect(this, FallbackEffectType.Compiling, EffectName, compilerParameters);
                    UpdateEffect(effectInstance, fallbackEffect.Effect, fallbackEffect.UsedParameters, passParameters);
                }
                return;
            }

            var compiledEffect = effect.WaitForResult();

            UpdateEffect(effectInstance, compiledEffect, usedParameters, passParameters);

            // Effect has been updated
            effectInstance.CurrentlyCompilingEffect         = null;
            effectInstance.CurrentlyCompilingUsedParameters = null;
        }
Beispiel #8
0
        protected override void Initialize()
        {
            base.Initialize();

            EffectSystem = new EffectSystem(Services);

            // If requested in game settings, compile effects remotely and/or notify new shader requests
            if (gameSettings != null)
            {
                EffectSystem.Compiler = EffectSystem.CreateEffectCompiler(EffectSystem, gameSettings.PackageId, gameSettings.EffectCompilation, gameSettings.RecordUsedEffects);
            }

            GameSystems.Add(EffectSystem);

            GameSystems.Add(SceneSystem);

            // TODO: data-driven?
            Asset.Serializer.RegisterSerializer(new ImageSerializer());
            Asset.Serializer.RegisterSerializer(new SoundEffectSerializer(Audio.AudioEngine));
            Asset.Serializer.RegisterSerializer(new SoundMusicSerializer(Audio.AudioEngine));

            // enable multi-touch by default
            Input.MultiTouchEnabled = true;
        }
        private void CreateEffect(DynamicEffectInstance effectInstance, ParameterCollection passParameters)
        {
            var compilerParameters = new CompilerParameters();

            parameterCollections.Clear();
            if (passParameters != null)
            {
                parameterCollections.Add(passParameters);
            }
            effectInstance.FillParameterCollections(ref parameterCollections);

            foreach (var parameterCollection in parameterCollections)
            {
                if (parameterCollection != null)
                {
                    foreach (var parameter in parameterCollection.InternalValues)
                    {
                        compilerParameters.SetObject(parameter.Key, parameter.Value.Object);
                    }
                }
            }

            compilerParameters.TaskPriority = taskPriority;

            foreach (var parameter in GraphicsDevice.Parameters.InternalValues)
            {
                compilerParameters.SetObject(parameter.Key, parameter.Value.Object);
            }

            // Compile shader
            // possible exception in LoadEffect
            TaskOrResult <Effect> effect;
            ParameterCollection   usedParameters;

            try
            {
                effect = EffectSystem.LoadEffect(EffectName, compilerParameters, out usedParameters);
            }
            catch (Exception)
            {
                effectInstance.HasErrors = true;

                // Fallback to error effect
                var fallbackEffect = ComputeFallbackEffect(this, FallbackEffectType.Error, EffectName, compilerParameters);
                UpdateEffect(effectInstance, fallbackEffect.Effect, fallbackEffect.UsedParameters, passParameters);

                return;
            }

            // Do we have an async compilation?
            if (asyncEffectCompiler && effect.Task != null)
            {
                effectInstance.CurrentlyCompilingEffect         = effect.Task;
                effectInstance.CurrentlyCompilingUsedParameters = usedParameters;

                if (!effectInstance.HasErrors) // If there was an error, stay in that state (we don't want to switch between reloading and error states)
                {
                    // Fallback to default effect
                    var fallbackEffect = ComputeFallbackEffect(this, FallbackEffectType.Compiling, EffectName, compilerParameters);
                    UpdateEffect(effectInstance, fallbackEffect.Effect, fallbackEffect.UsedParameters, passParameters);
                }
                return;
            }

            var compiledEffect = effect.WaitForResult();

            UpdateEffect(effectInstance, compiledEffect, usedParameters, passParameters);

            // Effect has been updated
            effectInstance.CurrentlyCompilingEffect         = null;
            effectInstance.CurrentlyCompilingUsedParameters = null;
        }
Beispiel #10
0
        protected override void Initialize()
        {
            base.Initialize(); 

            EffectSystem = new EffectSystem(Services);
            GameSystems.Add(EffectSystem);

            GameSystems.Add(SceneSystem);

            // TODO: data-driven?
            //Asset.Serializer.RegisterSerializer(new GpuTextureSerializer2(GraphicsDevice));
            //Asset.Serializer.RegisterSerializer(new GpuSamplerStateSerializer2(GraphicsDevice));
            //Asset.Serializer.RegisterSerializer(new GpuBlendStateSerializer(GraphicsDevice));
            //Asset.Serializer.RegisterSerializer(new GpuRasterizerStateSerializer(GraphicsDevice));
            //Asset.Serializer.RegisterSerializer(new GpuDepthStencilStateSerializer(GraphicsDevice));
            Asset.Serializer.RegisterSerializer(new ImageSerializer());
            Asset.Serializer.RegisterSerializer(new SoundEffectSerializer(Audio.AudioEngine));
            Asset.Serializer.RegisterSerializer(new SoundMusicSerializer(Audio.AudioEngine));

            // enable multi-touch by default
            Input.MultiTouchEnabled = true;
        }
        /// <summary>
        /// Creates an effect.
        /// </summary>
        /// <param name="effectSystem">The effect system.</param>
        /// <param name="effectName">Name of the effect.</param>
        /// <returns>A new instance of an effect.</returns>
        public static TaskOrResult <Effect> LoadEffect(this EffectSystem effectSystem, string effectName)
        {
            var compilerParameters = new CompilerParameters();

            return(effectSystem.LoadEffect(effectName, compilerParameters));
        }
Beispiel #12
0
        internal static IEffectCompiler CreateEffectCompiler(EffectSystem effectSystem, Guid? packageId, EffectCompilationMode effectCompilationMode, bool recordEffectRequested, TaskSchedulerSelector taskSchedulerSelector = null)
        {
            EffectCompilerBase compiler = null;

#if SILICONSTUDIO_PARADOX_EFFECT_COMPILER
            if ((effectCompilationMode & EffectCompilationMode.Local) != 0)
            {
                // Local allowed and available, let's use that
                compiler = new EffectCompiler
                {
                    SourceDirectories = { EffectCompilerBase.DefaultSourceShaderFolder },
                };
            }
#endif               

            // Nothing to do remotely
            bool needRemoteCompiler = (compiler == null && (effectCompilationMode & EffectCompilationMode.Remote) != 0);
            if (needRemoteCompiler || recordEffectRequested)
            {
                // Create the object that handles the connection
                var shaderCompilerTarget = new RemoteEffectCompilerClient(packageId);

                if (recordEffectRequested)
                {
                    // Let's notify effect compiler server for each new effect requested
                    effectSystem.EffectUsed += shaderCompilerTarget.NotifyEffectUsed;
                }

                // Use remote only if nothing else was found before (i.e. a local compiler)
                if (needRemoteCompiler)
                {
                    // Create a remote compiler
                    compiler = new RemoteEffectCompiler(shaderCompilerTarget);
                }
            }

            // Local not possible or allowed, and remote not allowed either => switch back to null compiler
            if (compiler == null)
            {
                compiler = new NullEffectCompiler();
            }

            return new EffectCompilerCache(compiler, taskSchedulerSelector);
        }