372 lines
10 KiB
C#
Raw Normal View History

2011-11-16 00:00:17 +00:00
using System;
using ANX.Framework.NonXNA;
using ANX.Framework.NonXNA.Development;
2011-11-16 00:00:17 +00:00
// This file is part of the ANX.Framework created by the
// "ANX.Framework developer group" and released under the Ms-PL license.
// For details see: http://anxframework.codeplex.com/license
2011-11-16 00:00:17 +00:00
namespace ANX.Framework.Graphics
{
[PercentageComplete(100)]
[TestState(TestStateAttribute.TestState.InProgress)]
[Developer("AstrorEnales")]
2011-11-16 00:00:17 +00:00
public class BasicEffect : Effect, IEffectMatrices, IEffectLights, IEffectFog
{
#region Private
private Matrix world;
private Matrix view;
private Matrix projection;
private bool preferPerPixelLighting;
private bool isFogEnabled;
private bool isLightingEnabled;
private bool isVertexColorEnabled;
private bool isTextureEnabled;
private Vector3 diffuseColor;
private Vector3 specularColor;
private Vector3 fogColor;
private Vector3 emissiveColor;
private Vector3 ambientLightColor;
#endregion
#region Public
public float FogEnd { get; set; }
public float FogStart { get; set; }
public Texture2D Texture { get; set; }
public float SpecularPower { get; set; }
public float Alpha { get; set; }
public DirectionalLight DirectionalLight0 { get; private set; }
public DirectionalLight DirectionalLight1 { get; private set; }
public DirectionalLight DirectionalLight2 { get; private set; }
public bool PreferPerPixelLighting
{
get { return preferPerPixelLighting; }
set
{
preferPerPixelLighting = value;
SelectTechnique();
}
}
public Matrix Projection
{
get { return projection; }
set { projection = value; }
}
public Matrix View
{
get { return view; }
set { view = value; }
}
public Matrix World
{
get { return world; }
set { world = value; }
}
public Vector3 AmbientLightColor
{
get { return ambientLightColor; }
set { ambientLightColor = value; }
}
public bool LightingEnabled
{
get { return isLightingEnabled; }
set
{
isLightingEnabled = value;
SelectTechnique();
}
}
public Vector3 FogColor
{
get { return fogColor; }
set { fogColor = value; }
}
public bool FogEnabled
{
get { return isFogEnabled; }
set
{
isFogEnabled = value;
SelectTechnique();
}
}
public bool TextureEnabled
{
get { return isTextureEnabled; }
set
{
isTextureEnabled = value;
SelectTechnique();
}
}
public Vector3 DiffuseColor
{
get { return diffuseColor; }
set { diffuseColor = value; }
}
public Vector3 EmissiveColor
{
get { return emissiveColor; }
set { emissiveColor = value; }
}
public Vector3 SpecularColor
{
get { return specularColor; }
set { specularColor = value; }
}
public bool VertexColorEnabled
{
get { return isVertexColorEnabled; }
set
{
isVertexColorEnabled = value;
SelectTechnique();
}
}
#endregion
#region Constructor
public BasicEffect(GraphicsDevice graphics)
: base(graphics, GetByteCode(), GetSourceLanguage())
{
world = Matrix.Identity;
view = Matrix.Identity;
projection = Matrix.Identity;
FogStart = 0f;
FogEnd = 1f;
Alpha = 1f;
diffuseColor = Vector3.One;
ambientLightColor = Vector3.One;
emissiveColor = Vector3.One;
specularColor = Vector3.One;
SpecularPower = 16f;
CreateLights(null);
DirectionalLight0.Enabled = true;
SelectTechnique();
2011-11-16 00:00:17 +00:00
}
protected BasicEffect(BasicEffect cloneSource)
: base(cloneSource)
{
world = cloneSource.world;
view = cloneSource.view;
projection = cloneSource.projection;
preferPerPixelLighting = cloneSource.preferPerPixelLighting;
isFogEnabled = cloneSource.isFogEnabled;
isLightingEnabled = cloneSource.isLightingEnabled;
isVertexColorEnabled = cloneSource.isVertexColorEnabled;
isTextureEnabled = cloneSource.isTextureEnabled;
diffuseColor = cloneSource.diffuseColor;
specularColor = cloneSource.specularColor;
fogColor = cloneSource.fogColor;
emissiveColor = cloneSource.emissiveColor;
ambientLightColor = cloneSource.ambientLightColor;
FogEnd = cloneSource.FogEnd;
FogStart = cloneSource.FogStart;
Texture = cloneSource.Texture;
SpecularPower = cloneSource.SpecularPower;
Alpha = cloneSource.Alpha;
CreateLights(cloneSource);
SelectTechnique();
}
#endregion
#region GetByteCode
private static byte[] GetByteCode()
{
var creator = AddInSystemFactory.Instance.GetDefaultCreator<IRenderSystemCreator>();
return creator.GetShaderByteCode(PreDefinedShader.BasicEffect);
}
#endregion
#region GetSourceLanguage
private static EffectSourceLanguage GetSourceLanguage()
{
var creator = AddInSystemFactory.Instance.GetDefaultCreator<IRenderSystemCreator>();
return creator.GetStockShaderSourceLanguage;
}
#endregion
2011-11-16 00:00:17 +00:00
#region EnableDefaultLighting
public void EnableDefaultLighting()
{
LightingEnabled = true;
ambientLightColor = new Vector3(0.05333332f, 0.09882354f, 0.1819608f);
DirectionalLight0.Direction = new Vector3(-0.5265408f, -0.5735765f, -0.6275069f);
DirectionalLight0.DiffuseColor = new Vector3(1f, 0.9607844f, 0.8078432f);
DirectionalLight0.SpecularColor = DirectionalLight0.DiffuseColor;
DirectionalLight0.Enabled = true;
DirectionalLight1.Direction = new Vector3(0.7198464f, 0.3420201f, 0.6040227f);
DirectionalLight1.DiffuseColor = new Vector3(0.9647059f, 0.7607844f, 0.4078432f);
DirectionalLight1.SpecularColor = Vector3.Zero;
DirectionalLight1.Enabled = true;
DirectionalLight2.Direction = new Vector3(0.4545195f, -0.7660444f, 0.4545195f);
DirectionalLight2.DiffuseColor = new Vector3(0.3231373f, 0.3607844f, 0.3937255f);
DirectionalLight2.SpecularColor = DirectionalLight2.DiffuseColor;
DirectionalLight2.Enabled = true;
}
#endregion
2011-11-16 00:00:17 +00:00
#region Clone
public override Effect Clone()
2011-11-16 00:00:17 +00:00
{
return new BasicEffect(this);
}
#endregion
2011-11-16 00:00:17 +00:00
#region CreateLights
private void CreateLights(BasicEffect cloneSource)
{
DirectionalLight0 = new DirectionalLight(Parameters["DirLight0Direction"], Parameters["DirLight0DiffuseColor"],
null, (cloneSource != null) ? cloneSource.DirectionalLight0 : null);
DirectionalLight1 = new DirectionalLight(Parameters["DirLight1Direction"], Parameters["DirLight1DiffuseColor"],
null, (cloneSource != null) ? cloneSource.DirectionalLight1 : null);
DirectionalLight2 = new DirectionalLight(Parameters["DirLight2Direction"], Parameters["DirLight2DiffuseColor"],
null, (cloneSource != null) ? cloneSource.DirectionalLight2 : null);
}
#endregion
2011-11-16 00:00:17 +00:00
#region PreBindSetParameters
internal override void PreBindSetParameters()
{
Matrix worldView;
Matrix.Multiply(ref world, ref view, out worldView);
Matrix wvp;
Matrix.Multiply(ref worldView, ref projection, out wvp);
Parameters["WorldViewProj"].SetValue(wvp);
2011-11-16 00:00:17 +00:00
SetLightingMatrices();
SetMaterialColor();
2011-11-16 00:00:17 +00:00
Parameters["FogColor"].SetValue(fogColor);
Parameters["SpecularPower"].SetValue(SpecularPower);
Parameters["SpecularColor"].SetValue(specularColor);
2011-11-16 00:00:17 +00:00
if (Texture != null)
Parameters["Texture"].SetValue(Texture);
2011-11-16 00:00:17 +00:00
if (isFogEnabled)
SetFogVector(ref worldView);
else
Parameters["FogVector"].SetValue(Vector4.Zero);
2011-11-16 00:00:17 +00:00
SelectTechnique();
}
#endregion
2011-11-16 00:00:17 +00:00
#region SelectTechnique
private void SelectTechnique()
2011-11-16 00:00:17 +00:00
{
string techniqueName = "BasicEffect";
if (isLightingEnabled)
{
if (preferPerPixelLighting)
techniqueName += "PixelLighting";
else
{
bool isLight1Disabled = DirectionalLight1 == null || DirectionalLight1.Enabled == false;
bool isLight2Disabled = DirectionalLight2 == null || DirectionalLight2.Enabled == false;
if (isLight1Disabled && isLight2Disabled)
techniqueName += "OneLight";
else
techniqueName += "VertexLighting";
}
}
if (isTextureEnabled)
techniqueName += "Texture";
if (isVertexColorEnabled)
techniqueName += "VertexColor";
if (isFogEnabled == false)
techniqueName += "NoFog";
CurrentTechnique = Techniques[techniqueName];
2011-11-16 00:00:17 +00:00
}
#endregion
2011-11-16 00:00:17 +00:00
#region SetLightingMatrices
private void SetLightingMatrices()
{
Matrix worldInverse;
Matrix.Invert(ref world, out worldInverse);
Matrix worldInverseTranspose;
Matrix.Transpose(ref worldInverse, out worldInverseTranspose);
2011-11-16 00:00:17 +00:00
Parameters["World"].SetValue(world);
Parameters["WorldInverseTranspose"].SetValue(worldInverseTranspose);
Matrix viewInverse;
Matrix.Invert(ref view, out viewInverse);
Parameters["EyePosition"].SetValue(viewInverse.Translation);
}
#endregion
#region SetMaterialColor
private void SetMaterialColor()
{
Vector4 diffuse;
if (isLightingEnabled)
{
diffuse.X = diffuseColor.X * Alpha;
diffuse.Y = diffuseColor.Y * Alpha;
diffuse.Z = diffuseColor.Z * Alpha;
diffuse.W = Alpha;
Vector3 emissive;
emissive.X = (emissiveColor.X + ambientLightColor.X * diffuseColor.X) * Alpha;
emissive.Y = (emissiveColor.Y + ambientLightColor.Y * diffuseColor.Y) * Alpha;
emissive.Z = (emissiveColor.Z + ambientLightColor.Z * diffuseColor.Z) * Alpha;
Parameters["DiffuseColor"].SetValue(diffuse);
Parameters["EmissiveColor"].SetValue(emissive);
return;
}
diffuse.X = (diffuseColor.X + emissiveColor.X) * Alpha;
diffuse.Y = (diffuseColor.Y + emissiveColor.Y) * Alpha;
diffuse.Z = (diffuseColor.Z + emissiveColor.Z) * Alpha;
diffuse.W = Alpha;
Parameters["DiffuseColor"].SetValue(diffuse);
}
#endregion
#region SetFogVector
private void SetFogVector(ref Matrix worldView)
{
if (FogStart == FogEnd)
{
Parameters["FogVector"].SetValue(new Vector4(0f, 0f, 0f, 1f));
return;
}
float fogFactor = 1f / (FogStart - FogEnd);
Vector4 value;
value.X = worldView.M13 * fogFactor;
value.Y = worldView.M23 * fogFactor;
value.Z = worldView.M33 * fogFactor;
value.W = (worldView.M43 + FogStart) * fogFactor;
Parameters["FogVector"].SetValue(value);
}
#endregion
2011-11-16 00:00:17 +00:00
}
}