/// <summary>
/// Creates this shader as an OGRE material.
/// </summary>
/// <remarks>
/// Creates a new material based on this shaders settings and registers it with the
/// SceneManager passed in.
/// Material name is in the format of: shader#lightmap.
/// </remarks>
/// <param name="sm">SceneManager to register the material with.</param>
/// <param name="lightmapNumber">Lightmap number</param>
public Material CreateAsMaterial(SceneManager sm, int lightmapNumber)
{
string materialName = String.Format("{0}#{1}", name, lightmapNumber);
Material material = sm.CreateMaterial(materialName);
LogManager.Instance.Write("Using Q3 shader {0}", name);
for(int p = 0; p < pass.Count; ++p)
{
TextureUnitState t;
// Create basic texture
t = LoadMaterialTextures(p, lightmapNumber, material);
// Blending
if(p == 0)
{
// scene blend
material.SetSceneBlending(pass[p].blendSrc, pass[p].blendDest);
if(material.IsTransparent && (pass[p].blendSrc != SceneBlendFactor.SourceAlpha))
material.DepthWrite = false;
t.SetColorOperation(LayerBlendOperation.Replace);
}
else
{
if(pass[p].customBlend)
{
// Fallback for now
t.SetColorOperation(LayerBlendOperation.Modulate);
}
else
{
t.SetColorOperation(pass[p].blend);
}
}
// Tex coords
if(pass[p].texGen == ShaderTextureGen.Base)
t.TextureCoordSet = 0;
else if(pass[p].texGen == ShaderTextureGen.Lightmap)
t.TextureCoordSet = 1;
else if(pass[p].texGen == ShaderTextureGen.Environment)
t.SetEnvironmentMap(true, EnvironmentMap.Planar);
// Tex mod
// Scale
t.SetTextureScaleU(pass[p].tcModScale[0]);
t.SetTextureScaleV(pass[p].tcModScale[1]);
CreateProceduralTextureMods(p, t);
// Address mode
t.TextureAddressing = pass[p].addressMode;
// Alpha mode
t.SetAlphaRejectSettings(pass[p].alphaFunc, pass[p].alphaVal);
}
// Do farbox (create new material)
// Do skydome (use this material)
if(skyDome)
{
float halfAngle = 0.5f * (0.5f * (4.0f * (float) Math.Atan(1.0f)));
float sin = (float) Math.Sin(halfAngle);
// Quake3 is always aligned with Z upwards
Quaternion q = new Quaternion(
(float) Math.Cos(halfAngle),
sin * Vector3.UnitX.x,
sin * Vector3.UnitY.y,
sin * Vector3.UnitX.z
);
// Also draw last, and make close to camera (far clip plane is shorter)
sm.SetSkyDome(true, materialName, 20 - (cloudHeight / 256 * 18), 12, 2000, false, q);
}
material.CullingMode = Axiom.Graphics.CullingMode.None;
material.ManualCullMode = cullMode;
material.Lighting = false;
material.Load();
return material;
}