Show More
Commit Description:
Tweak selected text color.
Commit Description:
Tweak selected text color.
References:
File last commit:
Show/Diff file:
Action:
FNA/src/Graphics/Effect/StockEffects/AlphaTestEffect.cs
441 lines | 13.1 KiB | text/x-csharp | CSharpLexer
441 lines | 13.1 KiB | text/x-csharp | CSharpLexer
r0 | #region File Description | |||
//----------------------------------------------------------------------------- | ||||
// AlphaTestEffect.cs | ||||
// | ||||
// Microsoft XNA Community Game Platform | ||||
// Copyright (C) Microsoft Corporation. All rights reserved. | ||||
//----------------------------------------------------------------------------- | ||||
#endregion | ||||
namespace Microsoft.Xna.Framework.Graphics | ||||
{ | ||||
/// <summary> | ||||
/// Built-in effect that supports alpha testing. | ||||
/// </summary> | ||||
public class AlphaTestEffect : Effect, IEffectMatrices, IEffectFog | ||||
{ | ||||
#region Effect Parameters | ||||
EffectParameter textureParam; | ||||
EffectParameter diffuseColorParam; | ||||
EffectParameter alphaTestParam; | ||||
EffectParameter fogColorParam; | ||||
EffectParameter fogVectorParam; | ||||
EffectParameter worldViewProjParam; | ||||
EffectParameter shaderIndexParam; | ||||
#endregion | ||||
#region Fields | ||||
bool fogEnabled; | ||||
bool vertexColorEnabled; | ||||
Matrix world = Matrix.Identity; | ||||
Matrix view = Matrix.Identity; | ||||
Matrix projection = Matrix.Identity; | ||||
Matrix worldView; | ||||
Vector3 diffuseColor = Vector3.One; | ||||
float alpha = 1; | ||||
float fogStart = 0; | ||||
float fogEnd = 1; | ||||
CompareFunction alphaFunction = CompareFunction.Greater; | ||||
int referenceAlpha; | ||||
bool isEqNe; | ||||
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All; | ||||
#endregion | ||||
#region Public Properties | ||||
/// <summary> | ||||
/// Gets or sets the world matrix. | ||||
/// </summary> | ||||
public Matrix World | ||||
{ | ||||
get { return world; } | ||||
set | ||||
{ | ||||
world = value; | ||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.Fog; | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// Gets or sets the view matrix. | ||||
/// </summary> | ||||
public Matrix View | ||||
{ | ||||
get { return view; } | ||||
set | ||||
{ | ||||
view = value; | ||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.Fog; | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// Gets or sets the projection matrix. | ||||
/// </summary> | ||||
public Matrix Projection | ||||
{ | ||||
get { return projection; } | ||||
set | ||||
{ | ||||
projection = value; | ||||
dirtyFlags |= EffectDirtyFlags.WorldViewProj; | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// Gets or sets the material diffuse color (range 0 to 1). | ||||
/// </summary> | ||||
public Vector3 DiffuseColor | ||||
{ | ||||
get { return diffuseColor; } | ||||
set | ||||
{ | ||||
diffuseColor = value; | ||||
dirtyFlags |= EffectDirtyFlags.MaterialColor; | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// Gets or sets the material alpha. | ||||
/// </summary> | ||||
public float Alpha | ||||
{ | ||||
get { return alpha; } | ||||
set | ||||
{ | ||||
alpha = value; | ||||
dirtyFlags |= EffectDirtyFlags.MaterialColor; | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// Gets or sets the fog enable flag. | ||||
/// </summary> | ||||
public bool FogEnabled | ||||
{ | ||||
get { return fogEnabled; } | ||||
set | ||||
{ | ||||
if (fogEnabled != value) | ||||
{ | ||||
fogEnabled = value; | ||||
dirtyFlags |= EffectDirtyFlags.ShaderIndex | EffectDirtyFlags.FogEnable; | ||||
} | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// Gets or sets the fog start distance. | ||||
/// </summary> | ||||
public float FogStart | ||||
{ | ||||
get { return fogStart; } | ||||
set | ||||
{ | ||||
fogStart = value; | ||||
dirtyFlags |= EffectDirtyFlags.Fog; | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// Gets or sets the fog end distance. | ||||
/// </summary> | ||||
public float FogEnd | ||||
{ | ||||
get { return fogEnd; } | ||||
set | ||||
{ | ||||
fogEnd = value; | ||||
dirtyFlags |= EffectDirtyFlags.Fog; | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// Gets or sets the fog color. | ||||
/// </summary> | ||||
public Vector3 FogColor | ||||
{ | ||||
get { return fogColorParam.GetValueVector3(); } | ||||
set { fogColorParam.SetValue(value); } | ||||
} | ||||
/// <summary> | ||||
/// Gets or sets the current texture. | ||||
/// </summary> | ||||
public Texture2D Texture | ||||
{ | ||||
get { return textureParam.GetValueTexture2D(); } | ||||
set { textureParam.SetValue(value); } | ||||
} | ||||
/// <summary> | ||||
/// Gets or sets whether vertex color is enabled. | ||||
/// </summary> | ||||
public bool VertexColorEnabled | ||||
{ | ||||
get { return vertexColorEnabled; } | ||||
set | ||||
{ | ||||
if (vertexColorEnabled != value) | ||||
{ | ||||
vertexColorEnabled = value; | ||||
dirtyFlags |= EffectDirtyFlags.ShaderIndex; | ||||
} | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// Gets or sets the alpha compare function (default Greater). | ||||
/// </summary> | ||||
public CompareFunction AlphaFunction | ||||
{ | ||||
get { return alphaFunction; } | ||||
set | ||||
{ | ||||
alphaFunction = value; | ||||
dirtyFlags |= EffectDirtyFlags.AlphaTest; | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// Gets or sets the reference alpha value (default 0). | ||||
/// </summary> | ||||
public int ReferenceAlpha | ||||
{ | ||||
get { return referenceAlpha; } | ||||
set | ||||
{ | ||||
referenceAlpha = value; | ||||
dirtyFlags |= EffectDirtyFlags.AlphaTest; | ||||
} | ||||
} | ||||
#endregion | ||||
#region Methods | ||||
/// <summary> | ||||
/// Creates a new AlphaTestEffect with default parameter settings. | ||||
/// </summary> | ||||
public AlphaTestEffect(GraphicsDevice device) | ||||
: base(device, Resources.AlphaTestEffect) | ||||
{ | ||||
CacheEffectParameters(); | ||||
} | ||||
/// <summary> | ||||
/// Creates a new AlphaTestEffect by cloning parameter settings from an existing instance. | ||||
/// </summary> | ||||
protected AlphaTestEffect(AlphaTestEffect cloneSource) | ||||
: base(cloneSource) | ||||
{ | ||||
CacheEffectParameters(); | ||||
fogEnabled = cloneSource.fogEnabled; | ||||
vertexColorEnabled = cloneSource.vertexColorEnabled; | ||||
world = cloneSource.world; | ||||
view = cloneSource.view; | ||||
projection = cloneSource.projection; | ||||
diffuseColor = cloneSource.diffuseColor; | ||||
alpha = cloneSource.alpha; | ||||
fogStart = cloneSource.fogStart; | ||||
fogEnd = cloneSource.fogEnd; | ||||
alphaFunction = cloneSource.alphaFunction; | ||||
referenceAlpha = cloneSource.referenceAlpha; | ||||
} | ||||
/// <summary> | ||||
/// Creates a clone of the current AlphaTestEffect instance. | ||||
/// </summary> | ||||
public override Effect Clone() | ||||
{ | ||||
return new AlphaTestEffect(this); | ||||
} | ||||
/// <summary> | ||||
/// Looks up shortcut references to our effect parameters. | ||||
/// </summary> | ||||
void CacheEffectParameters() | ||||
{ | ||||
textureParam = Parameters["Texture"]; | ||||
diffuseColorParam = Parameters["DiffuseColor"]; | ||||
alphaTestParam = Parameters["AlphaTest"]; | ||||
fogColorParam = Parameters["FogColor"]; | ||||
fogVectorParam = Parameters["FogVector"]; | ||||
worldViewProjParam = Parameters["WorldViewProj"]; | ||||
shaderIndexParam = Parameters["ShaderIndex"]; | ||||
} | ||||
/// <summary> | ||||
/// Lazily computes derived parameter values immediately before applying the effect. | ||||
/// </summary> | ||||
protected internal override void OnApply() | ||||
{ | ||||
// Recompute the world+view+projection matrix or fog vector? | ||||
dirtyFlags = EffectHelpers.SetWorldViewProjAndFog(dirtyFlags, ref world, ref view, ref projection, ref worldView, fogEnabled, fogStart, fogEnd, worldViewProjParam, fogVectorParam); | ||||
// Recompute the diffuse/alpha material color parameter? | ||||
if ((dirtyFlags & EffectDirtyFlags.MaterialColor) != 0) | ||||
{ | ||||
diffuseColorParam.SetValue(new Vector4(diffuseColor * alpha, alpha)); | ||||
dirtyFlags &= ~EffectDirtyFlags.MaterialColor; | ||||
} | ||||
// Recompute the alpha test settings? | ||||
if ((dirtyFlags & EffectDirtyFlags.AlphaTest) != 0) | ||||
{ | ||||
Vector4 alphaTest = new Vector4(); | ||||
bool eqNe = false; | ||||
// Convert reference alpha from 8 bit integer to 0-1 float format. | ||||
float reference = (float)referenceAlpha / 255f; | ||||
// Comparison tolerance of half the 8 bit integer precision. | ||||
const float threshold = 0.5f / 255f; | ||||
switch (alphaFunction) | ||||
{ | ||||
case CompareFunction.Less: | ||||
// Shader will evaluate: clip((a < x) ? z : w) | ||||
alphaTest.X = reference - threshold; | ||||
alphaTest.Z = 1; | ||||
alphaTest.W = -1; | ||||
break; | ||||
case CompareFunction.LessEqual: | ||||
// Shader will evaluate: clip((a < x) ? z : w) | ||||
alphaTest.X = reference + threshold; | ||||
alphaTest.Z = 1; | ||||
alphaTest.W = -1; | ||||
break; | ||||
case CompareFunction.GreaterEqual: | ||||
// Shader will evaluate: clip((a < x) ? z : w) | ||||
alphaTest.X = reference - threshold; | ||||
alphaTest.Z = -1; | ||||
alphaTest.W = 1; | ||||
break; | ||||
case CompareFunction.Greater: | ||||
// Shader will evaluate: clip((a < x) ? z : w) | ||||
alphaTest.X = reference + threshold; | ||||
alphaTest.Z = -1; | ||||
alphaTest.W = 1; | ||||
break; | ||||
case CompareFunction.Equal: | ||||
// Shader will evaluate: clip((abs(a - x) < Y) ? z : w) | ||||
alphaTest.X = reference; | ||||
alphaTest.Y = threshold; | ||||
alphaTest.Z = 1; | ||||
alphaTest.W = -1; | ||||
eqNe = true; | ||||
break; | ||||
case CompareFunction.NotEqual: | ||||
// Shader will evaluate: clip((abs(a - x) < Y) ? z : w) | ||||
alphaTest.X = reference; | ||||
alphaTest.Y = threshold; | ||||
alphaTest.Z = -1; | ||||
alphaTest.W = 1; | ||||
eqNe = true; | ||||
break; | ||||
case CompareFunction.Never: | ||||
// Shader will evaluate: clip((a < x) ? z : w) | ||||
alphaTest.Z = -1; | ||||
alphaTest.W = -1; | ||||
break; | ||||
case CompareFunction.Always: | ||||
default: | ||||
// Shader will evaluate: clip((a < x) ? z : w) | ||||
alphaTest.Z = 1; | ||||
alphaTest.W = 1; | ||||
break; | ||||
} | ||||
alphaTestParam.SetValue(alphaTest); | ||||
dirtyFlags &= ~EffectDirtyFlags.AlphaTest; | ||||
// If we changed between less/greater vs. equal/notequal | ||||
// compare modes, we must also update the shader index. | ||||
if (isEqNe != eqNe) | ||||
{ | ||||
isEqNe = eqNe; | ||||
dirtyFlags |= EffectDirtyFlags.ShaderIndex; | ||||
} | ||||
} | ||||
// Recompute the shader index? | ||||
if ((dirtyFlags & EffectDirtyFlags.ShaderIndex) != 0) | ||||
{ | ||||
int shaderIndex = 0; | ||||
if (!fogEnabled) | ||||
shaderIndex += 1; | ||||
if (vertexColorEnabled) | ||||
shaderIndex += 2; | ||||
if (isEqNe) | ||||
shaderIndex += 4; | ||||
shaderIndexParam.SetValue(shaderIndex); | ||||
dirtyFlags &= ~EffectDirtyFlags.ShaderIndex; | ||||
} | ||||
} | ||||
#endregion | ||||
} | ||||
} | ||||