Exemplo n.º 1
0
 public DrawCall(DrawFunc drawfunc, PrimType mode, ElementType indextype, List <int> arg)
 {
     this.mode      = mode;
     this.indextype = indextype;
     // iBaseVertex, vBaseVertex, voStream, indirectPtr
     arg0 = arg.Count > 0 ? arg[0] : 0;
     // iBaseIndex, vVertexCount, indirectCount
     arg1 = arg.Count > 1 ? arg[1] :
            drawfunc == DrawFunc.TransformFeedback ||
            drawfunc == DrawFunc.ArraysIndirect ||
            drawfunc == DrawFunc.ElementsIndirect
         ? 1
         : 0;
     // iIndexCount, vBaseInstance, indirectStride
     arg2 = arg.Count > 2 ? arg[2] :
            drawfunc == DrawFunc.TransformFeedback
         ? 1
         : drawfunc == DrawFunc.ArraysIndirect
             ? 16
             : drawfunc == DrawFunc.ElementsIndirect
                 ? 32
                 : 0;
     // iBaseInstance, vInstanceCount
     arg3 = arg.Count > 3 ? arg[3] :
            drawfunc == DrawFunc.ArraysInstanced ? 1 : 0;
     // iInstanceCount
     arg4 = arg.Count > 4 ? arg[4] :
            drawfunc == DrawFunc.ElementsInstanced ? 1 : 0;
 }
Exemplo n.º 2
0
        private void ParseDrawCall(Compiler.Command cmd, Dict classes, CompileException err)
        {
            var          args      = new List <int>();
            GLVertinput  vertexin  = null;
            GLVertoutput vertout   = null;
            GLBuffer     indexbuf  = null;
            GLBuffer     indirect  = null;
            bool         modeIsSet = false;
            bool         typeIsSet = false;
            PrimType     primitive = 0;
            ElementType  indextype = 0;

            // parse draw call arguments
            foreach (var arg in cmd)
            {
                if (classes.TryGetValue(arg.Text, ref vertexin))
                {
                    continue;
                }
                if (classes.TryGetValue(arg.Text, ref vertout))
                {
                    continue;
                }
                if (classes.TryGetValue(arg.Text, ref indexbuf))
                {
                    continue;
                }
                if (classes.TryGetValue(arg.Text, ref indirect))
                {
                    continue;
                }
                if (int.TryParse(arg.Text, out int val))
                {
                    args.Add(val);
                }
                else if (typeIsSet == false && Enum.TryParse(arg.Text, true, out indextype))
                {
                    typeIsSet = true;
                }
                else if (modeIsSet == false && Enum.TryParse(arg.Text, true, out primitive))
                {
                    modeIsSet = true;
                }
                else
                {
                    err.Add($"Unable to process argument '{arg.Text}'.", cmd);
                }
            }

            if (err.HasErrors)
            {
                return;
            }

            // a draw call must specify a primitive type
            if (modeIsSet == false)
            {
                err.Add("Draw call must specify a primitive type (e.g. triangles, "
                        + "trianglefan, lines, points, ...).", cmd);
                return;
            }

            // determine the right draw call function
            int bits = (vertout != null ? 1 : 0)
                       | (indexbuf != null ? 2 : 0)
                       | (indirect != null ? 4 : 0)
                       | (typeIsSet ? 8 : 0);

            if (!Enum.IsDefined(typeof(DrawFunc), bits))
            {
                err.Add("Draw call function not recognized or ambiguous.", cmd);
                return;
            }

            var drawfunc = (DrawFunc)bits;

            // get index buffer object (if present) and find existing MultiDraw class
            var multidrawcall = drawcalls.Find(
                x => x.vertexin == (vertexin != null ? vertexin.glname : 0) &&
                x.indexbuf == (indexbuf != null ? indexbuf.glname : 0) &&
                x.vertout == (vertout != null ? vertout.glname : 0) &&
                x.indirect == (indirect != null ? indirect.glname : 0))
                                ?? new MultiDrawCall(drawfunc, vertexin, vertout, indexbuf, indirect);

            // add new draw command to the MultiDraw class
            multidrawcall.cmd.Add(new DrawCall(drawfunc, primitive, indextype, args));

            drawcalls.Add(multidrawcall);
        }