I'm working on a managed OpenGL game engine for C#, here's how I'm managing shader parameters (uniforms). Is it "alright"? Could it be better? I'm a bit unsure about using generics in this case.
public abstract class ShaderParameter
{
public readonly string Name;
internal readonly int Location;
internal readonly Shader Parent;
internal ShaderParameter(string name, int location, Shader parent)
{
Name = name;
Location = location;
Parent = parent;
}
//Ensures that the value is set on the shader,
//this should be called before using the parent shader
internal abstract void EnsureSet();
//Gives a value to this shader paramerter
public abstract void SetValue<T>(T value);
}
//A shader paramater of type float
public sealed class ShaderParamFloat : ShaderParameter
{
float value = 0;
bool valueChanged = false; //If the value has changed since the last time it was set on the shader
internal ShaderParamFloat(string name, int location, Shader parent)
: base(name, location, parent)
{ }
internal override void EnsureSet()
{
if (valueChanged)
{
//Hands over a single value to OpenGL.
GL.Uniform1(Location, value);
valueChanged = false;
}
}
//Gives a value to this shader parameter
public override void SetValue<T>(T value)
{
if (typeof(T) != typeof(float))
throw new ArgumentException("Value is of type: " + typeof(T).ToString() + ", expected: float", "value");
this.value = (float)(object)value;
valueChanged = true;
}
}
Thanks for taking the time to read my code.
EDIT: The reason for using inheritance is because other ShaderParameter classes behave differently in EnsureSet(). For example ShaderParamVector3 uses GL.Uniform3(...), and ShaderParamTexture needs to ensure that the texture is valid and set on the graphics card.