예제 #1
0
        /// <summary>
        /// Actually create this ShaderObject resource.
        /// </summary>
        /// <param name="ctx">
        /// A <see cref="GraphicsContext"/> used for allocating resources.
        /// </param>
        protected override void CreateObject(GraphicsContext ctx)
        {
            if (ctx == null)
            {
                throw new ArgumentNullException("ctx");
            }
            if (_CompilationParams == null)
            {
                throw new InvalidOperationException("no compiler parameters");
            }

            // Using a deep copy of the shader compiler context, since it will be modified by this ShaderProgram
            // instance and the attached ShaderObject instances
            ShaderCompilerContext cctx = new ShaderCompilerContext(_CompilationParams);

            sLog.Debug("Compilation of shader object '{0}'.", _SourcePath);

            List <string> source = GenerateSource(ctx, cctx);                   // Source generation!

            // Set shader source
            Gl.ShaderSource(ObjectName, source.ToArray());

            if (ctx.Caps.GlExtensions.ShadingLanguageInclude_ARB)
            {
                string[] includePaths = new string[cctx.Includes.Count];

                cctx.Includes.CopyTo(includePaths, 0);

                // Compile shader object (specifying include paths)
                Gl.CompileShaderIncludeARB(ObjectName, includePaths, null);
            }
            else
            {
                // Compile shader object (includes are already preprocessed)
                Gl.CompileShader(ObjectName);
            }

            // Check for compilation errors
            int cStatus;

            Gl.GetObjectParameterARB(ObjectName, Gl.COMPILE_STATUS, out cStatus);

            if (cStatus != Gl.TRUE)
            {
                StringBuilder sb = GetInfoLog();

                // Stop compilation process
                sLog.Error("Shader object \"{0}\" compilation failed:\n{1}", _SourcePath ?? "<Hardcoded>", sb.ToString());

                // Log the source code referred to the shader log
                sLog.Error("Source code for shader '{0}' that has generated the compiler error.", _SourcePath);
                sLog.Error("--------------------------------------------------------------------------------");
                uint sourcelineNo = 0;
                foreach (string sourceline in source)
                {
                    sLog.Error("{0,4} | {1}", ++sourcelineNo, sourceline.Length > 0 ? sourceline.Remove(sourceline.Length - 1, 1) : String.Empty);
                }
                sLog.Error("--------------------------------------------------------------------------------");

                throw new ShaderException("shader object is not valid. Compiler output for {0}: {1}\n", _SourcePath, sb.ToString());
            }
            else
            {
                StringBuilder sb = GetInfoLog();

                if (sb.Length > 0)
                {
                    sLog.Warn("Shader object \"{0}\" compilation warning: {1}", _SourcePath ?? "<Hardcoded>", sb.ToString());
                }
            }

            _Compiled = true;
        }