Ejemplo n.º 1
0
        private GLShader Attach(Compiler.Block block, string shadername, Dict classes,
                                CompileException err)
        {
            GLShader obj = null;

            // get shader from class list
            if (shadername != null && classes.TryGetValue(shadername, out obj, block, err))
            {
                GL.UseProgramStages(glname, ShaderType2ShaderBit(obj.ShaderType), obj.glname);
            }

            return(obj);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Create OpenGL object. Standard object constructor for ProtoFX.
        /// </summary>
        /// <param name="block"></param>
        /// <param name="scene"></param>
        /// <param name="genDebugInfo"></param>
        public GLPass(Compiler.Block block, Dict scene, bool genDebugInfo)
            : base(block.Name, block.Anno, 309, genDebugInfo)
        {
            var err = new CompileException($"pass '{Name}'");

            GenDebugInfo = genDebugInfo;

            /// PARSE COMMANDS AND CONVERT THEM TO CLASS FIELDS

            Cmds2Fields(block, err);

            /// PARSE COMMANDS

            foreach (var cmd in block)
            {
                // ignore class fields
                var field = GetType().GetField(cmd.Name, Instance | Public | NonPublic);
                var attr  = field?.GetCustomAttributes(typeof(FxField), false);
                if (attr?.Length > 0)
                {
                    continue;
                }

                using (var e = err | $"command '{cmd.Name}' line {cmd.LineInFile}")
                {
                    switch (cmd.Name)
                    {
                    case "draw": ParseDrawCall(cmd, scene, e); break;

                    case "compute": ParseComputeCall(cmd, scene, e); break;

                    case "tex": ParseTexCmd(cmd, scene, e); break;

                    case "img": ParseImgCmd(cmd, scene, e); break;

                    case "samp": ParseSampCmd(cmd, scene, e); break;

                    case "exec": ParseCsharpExec(cmd, scene, e); break;

                    case "vertout": vertoutput = new Vertoutput(cmd, scene, e);  break;

                    case "fragout": scene.TryGetValue(cmd[0].Text, out fragoutput, cmd, e); break;

                    default: ParseOpenGLCall(cmd, e); break;
                    }
                }
            }

            if (err.HasErrors)
            {
                throw err;
            }

            /// CREATE OPENGL OBJECT

            if (Vert != null || Comp != null)
            {
                GL.CreateProgramPipelines(1, out glname);

                // Attach shader objects.
                // First try attaching a compute shader. If that
                // fails, try attaching the default shader pipeline.
                if ((glcomp = Attach(block, Comp, scene, err)) == null)
                {
                    glvert = Attach(block, Vert, scene, err);
                    gltess = Attach(block, Tess, scene, err);
                    gleval = Attach(block, Eval, scene, err);
                    glgeom = Attach(block, Geom, scene, err);
                    glfrag = Attach(block, Frag, scene, err);
                }

                // get debug shaders
                if (GenDebugInfo)
                {
                    if (glcomp != null)
                    {
                        dbgcomp = (CompShader)glcomp.DebugShader;
                    }
                    else
                    {
                        Shader prev =
                            dbgvert = (VertShader)glvert.DebugShader;
                        dbgtess     = (TessShader)gltess?.DebugShader;
                        dbgeval     = (EvalShader)gleval?.DebugShader;
                        dbggeom     = (GeomShader)glgeom?.DebugShader;
                        dbgfrag     = (FragShader)glfrag?.DebugShader;
                        if (dbgtess != null)
                        {
                            dbgtess.Prev = prev;
                            prev         = dbgtess;
                        }
                        if (dbgeval != null)
                        {
                            dbgeval.Prev = prev;
                            prev         = dbgeval;
                        }
                        if (dbggeom != null)
                        {
                            dbggeom.Prev = prev;
                            prev         = dbggeom;
                        }
                    }
                }
            }

            /// CHECK FOR ERRORS

            if (GL.GetError() != ErrorCode.NoError)
            {
                err.Add($"OpenGL error '{GL.GetError()}' occurred " +
                        "during shader program creation.", block);
            }
            if (err.HasErrors)
            {
                throw err;
            }
        }