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; }
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); }