Beispiel #1
0
        /// <summary>
        /// Processes the string representation of the specified effect into a platform-specific binary format using the specified context.
        /// </summary>
        /// <param name="input">The effect string to be processed.</param>
        /// <param name="context">Context for the specified processor.</param>
        /// <returns>A platform-specific compiled binary effect.</returns>
        /// <remarks>If you get an error during processing, compilation stops immediately. The effect processor displays an error message. Once you fix the current error, it is possible you may get more errors on subsequent compilation attempts.</remarks>
        public override CompiledEffectContent Process(EffectContent input, ContentProcessorContext context)
        {
#if WINDOWS
            var options = new Options();
            options.SourceFile = input.Identity.SourceFilename;

            options.Profile = ShaderProfile.ForPlatform(context.TargetPlatform.ToString());
            if (options.Profile == null)
            {
                throw new InvalidContentException(string.Format("{0} effects are not supported.", context.TargetPlatform), input.Identity);
            }

            options.Debug      = DebugMode == EffectProcessorDebugMode.Debug;
            options.Defines    = Defines;
            options.OutputFile = context.OutputFilename;

            // Parse the MGFX file expanding includes, macros, and returning the techniques.
            ShaderResult shaderResult;
            try
            {
                shaderResult = ShaderResult.FromFile(options.SourceFile, options,
                                                     new ContentPipelineEffectCompilerOutput(context));

                // Add the include dependencies so that if they change
                // it will trigger a rebuild of this effect.
                foreach (var dep in shaderResult.Dependencies)
                {
                    context.AddDependency(dep);
                }
            }
            catch (InvalidContentException)
            {
                throw;
            }
            catch (Exception ex)
            {
                // TODO: Extract good line numbers from mgfx parser!
                throw new InvalidContentException(ex.Message, input.Identity, ex);
            }

            // Create the effect object.
            EffectObject effect = null;
            var          shaderErrorsAndWarnings = string.Empty;
            try
            {
                effect = EffectObject.CompileEffect(shaderResult, out shaderErrorsAndWarnings);

                // If there were any additional output files we register
                // them so that the cleanup process can manage them.
                foreach (var outfile in shaderResult.AdditionalOutputFiles)
                {
                    context.AddOutputFile(outfile);
                }
            }
            catch (ShaderCompilerException)
            {
                // This will log any warnings and errors and throw.
                ProcessErrorsAndWarnings(true, shaderErrorsAndWarnings, input, context);
            }

            // Process any warning messages that the shader compiler might have produced.
            ProcessErrorsAndWarnings(false, shaderErrorsAndWarnings, input, context);

            // Write out the effect to a runtime format.
            CompiledEffectContent result;
            try
            {
                using (var stream = new MemoryStream())
                {
                    using (var writer = new BinaryWriter(stream))
                        effect.Write(writer, options);

                    result = new CompiledEffectContent(stream.GetBuffer());
                }
            }
            catch (Exception ex)
            {
                throw new InvalidContentException("Failed to serialize the effect!", input.Identity, ex);
            }

            return(result);
#else
            throw new NotImplementedException();
#endif
        }
Beispiel #2
0
        public static int Main(string[] args)
        {
            if (!Environment.Is64BitProcess &&
                Environment.OSVersion.Platform != PlatformID.Unix)
            {
                Console.Error.WriteLine("The MonoGame content tools only work on a 64bit OS.");
                return(-1);
            }

            var options = new Options();
            var parser  = new CommandLineParser(options);

            parser.Title = "mgfxc - The MonoGame Effect compiler.";

            if (!parser.ParseCommandLine(args))
            {
                return(1);
            }

            // We don't support running MGFXC on Unix platforms
            // however Wine can be used to make it work so lets try that.
            if (Environment.OSVersion.Platform == PlatformID.Unix)
            {
                return(WineHelper.Run(options));
            }

            // Validate the input file exits.
            if (!File.Exists(options.SourceFile))
            {
                Console.Error.WriteLine("The input file '{0}' was not found!", options.SourceFile);
                return(1);
            }

            // TODO: This would be where we would decide the user
            // is trying to convert an FX file to a MGFX glsl file.
            //
            // For now we assume we're going right to a compiled MGFXO file.

            // Parse the MGFX file expanding includes, macros, and returning the techniques.
            ShaderResult shaderResult;

            try
            {
                shaderResult = ShaderResult.FromFile(options.SourceFile, options, new ConsoleEffectCompilerOutput());

                foreach (var dependency in shaderResult.Dependencies)
                {
                    Console.WriteLine("Dependency: " + dependency);
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
                Console.Error.WriteLine("Failed to parse '{0}'!", options.SourceFile);
                return(1);
            }

            // Create the effect object.
            EffectObject effect;
            var          shaderErrorsAndWarnings = string.Empty;

            try
            {
                effect = EffectObject.CompileEffect(shaderResult, out shaderErrorsAndWarnings);

                if (!string.IsNullOrEmpty(shaderErrorsAndWarnings))
                {
                    Console.Error.WriteLine(shaderErrorsAndWarnings);
                }
            }
            catch (ShaderCompilerException)
            {
                // Write the compiler errors and warnings and let the user know what happened.
                Console.Error.WriteLine(shaderErrorsAndWarnings);
                Console.Error.WriteLine("Failed to compile '{0}'!", options.SourceFile);
                return(1);
            }
            catch (Exception ex)
            {
                // First write all the compiler errors and warnings.
                if (!string.IsNullOrEmpty(shaderErrorsAndWarnings))
                {
                    Console.Error.WriteLine(shaderErrorsAndWarnings);
                }

                // If we have an exception message then write that.
                if (!string.IsNullOrEmpty(ex.Message))
                {
                    Console.Error.WriteLine(ex.Message);
                }

                // Let the user know what happened.
                Console.Error.WriteLine("Unexpected error compiling '{0}'!", options.SourceFile);
                return(1);
            }

            // Get the output file path.
            if (string.IsNullOrEmpty(options.OutputFile))
            {
                options.OutputFile = Path.GetFileNameWithoutExtension(options.SourceFile) + ".mgfxo";
            }

            // Write out the effect to a runtime format.
            try
            {
                using (var stream = new FileStream(options.OutputFile, FileMode.Create, FileAccess.Write))
                    using (var writer = new BinaryWriter(stream))
                        effect.Write(writer, options);
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
                Console.Error.WriteLine("Failed to write '{0}'!", options.OutputFile);
                return(1);
            }

            // We finished succesfully.
            Console.WriteLine("Compiled '{0}' to '{1}'.", options.SourceFile, options.OutputFile);
            return(0);
        }