/// <summary>
/// Sets up the appropriate OpenGL rendering state for this DrawTechnique.
/// </summary>
/// <param name="lastTechnique">The last DrawTechnique that has been set up. This parameter is optional, but
/// specifying it will increase performance by reducing redundant state changes.</param>
/// <param name="textures">A set of <see cref="Duality.Resources.Texture">Textures</see> to use.</param>
/// <param name="uniforms">A set of <see cref="Duality.Resources.ShaderVarInfo">uniform values</see> to apply.</param>
public void SetupForRendering(IDrawDevice device, BatchInfo material, DrawTechnique lastTechnique)
{
// Prepare Rendering
if (this.NeedsPreparation)
{
// Clone the material, if not done yet due to vertex preprocessing
if (!this.NeedsPreprocess)
{
material = new BatchInfo(material);
}
this.PrepareRendering(device, material);
}
// Setup BlendType
if (lastTechnique == null || this.blendType != lastTechnique.blendType)
{
this.SetupBlendType(this.blendType, device.DepthWrite);
}
// Bind Shader
ContentRef <ShaderProgram> selShader = this.SelectShader();
if (lastTechnique == null || selShader.Res != lastTechnique.shader.Res)
{
ShaderProgram.Bind(selShader);
}
// Setup shader data
if (selShader.IsAvailable)
{
ShaderVarInfo[] varInfo = selShader.Res.VarInfo;
// Setup sampler bindings automatically
int curSamplerIndex = 0;
if (material.Textures != null)
{
for (int i = 0; i < varInfo.Length; i++)
{
if (varInfo[i].glVarLoc == -1)
{
continue;
}
if (varInfo[i].type != ShaderVarType.Sampler2D)
{
continue;
}
// Bind Texture
ContentRef <Texture> texRef = material.GetTexture(varInfo[i].name);
Texture.Bind(texRef, curSamplerIndex);
GL.Uniform1(varInfo[i].glVarLoc, curSamplerIndex);
curSamplerIndex++;
}
}
Texture.ResetBinding(curSamplerIndex);
// Transfer uniform data from material to actual shader
if (material.Uniforms != null)
{
for (int i = 0; i < varInfo.Length; i++)
{
if (varInfo[i].glVarLoc == -1)
{
continue;
}
float[] data = material.GetUniform(varInfo[i].name);
if (data == null)
{
continue;
}
varInfo[i].SetupUniform(data);
}
}
}
// Setup fixed function data
else
{
// Fixed function texture binding
if (material.Textures != null)
{
int samplerIndex = 0;
foreach (var pair in material.Textures)
{
Texture.Bind(pair.Value, samplerIndex);
samplerIndex++;
}
Texture.ResetBinding(samplerIndex);
}
else
{
Texture.ResetBinding();
}
}
}