//TODO: More types


        // TODO: Do we need this?

        /*
         * protected void BindFragDataLocation(int colourSlot, string outputName)
         * {
         *  GL.BindFragDataLocation(Handle, colourSlot, outputName);
         * }
         */

        public void BindVariable(string variableName, Action <int> bindAction)
        {
            int location;

            if (!VariableLocations.TryGetValue(variableName, out location))
            {
                throw new Exception($"ShaderProgram.BindVariable ({Name}): Variable {variableName} not defined.");
            }

            bindAction?.Invoke(location);
        }
 public ShaderProgram AddVariable(int index, string name)
 {
     if (!string.IsNullOrWhiteSpace(name))
     {
         if (VariableLocations.ContainsKey(name))
         {
             VariableLocations[name] = index;
         }
         else
         {
             VariableLocations.Add(name, index);
         }
     }
     return(this);
 }
        public ShaderProgram(ShaderProgram cloneFrom)
        {
            if (cloneFrom == null)
            {
                throw new ArgumentNullException(nameof(cloneFrom));
            }

            if (cloneFrom.ShaderSourceOrFilenames.Count == 0)
            {
                throw new InvalidOperationException($"ShaderProgram: cannot clone from {cloneFrom.Name} due to insufficient shader information");
            }

            Name = cloneFrom.Name;

            foreach (var v in cloneFrom.VariableLocations)
            {
                VariableLocations.Add(v.Key, v.Value);
            }

            foreach (var f in cloneFrom.FragDataLocation)
            {
                FragDataLocation.Add(f.Key, f.Value);
            }

            UsingFilenames = cloneFrom.UsingFilenames;
            foreach (var s in cloneFrom.ShaderSourceOrFilenames)
            {
                ShaderSourceOrFilenames.Add(s);
            }

            if (UsingFilenames)
            {
                InitFromFiles();
            }
            else
            {
                InitFromSource();
            }
        }
        public ShaderProgram SetVariables(params string[] variables)
        {
            VariableLocations.Clear();

            if (variables == null || variables.Length == 0)
            {
                return(this);
            }


            // if we've only been passed a single string and it contains commas, then split it.
            if (variables.Length == 1 && variables[0].Contains(","))
            {
                return(SetVariables(variables[0].Split(',')));
            }

            for (int i = 0; i < variables.Length; i++)
            {
                AddVariable(i, variables[i]);
            }

            return(this);
        }