#region File Description //----------------------------------------------------------------------------- // DualTextureEffect.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #endregion namespace Microsoft.Xna.Framework.Graphics { /// /// Built-in effect that supports two-layer multitexturing. /// public class DualTextureEffect : Effect, IEffectMatrices, IEffectFog { #region Effect Parameters EffectParameter textureParam; EffectParameter texture2Param; EffectParameter diffuseColorParam; 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; EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All; #endregion #region Public Properties /// /// Gets or sets the world matrix. /// public Matrix World { get { return world; } set { world = value; dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.Fog; } } /// /// Gets or sets the view matrix. /// public Matrix View { get { return view; } set { view = value; dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.Fog; } } /// /// Gets or sets the projection matrix. /// public Matrix Projection { get { return projection; } set { projection = value; dirtyFlags |= EffectDirtyFlags.WorldViewProj; } } /// /// Gets or sets the material diffuse color (range 0 to 1). /// public Vector3 DiffuseColor { get { return diffuseColor; } set { diffuseColor = value; dirtyFlags |= EffectDirtyFlags.MaterialColor; } } /// /// Gets or sets the material alpha. /// public float Alpha { get { return alpha; } set { alpha = value; dirtyFlags |= EffectDirtyFlags.MaterialColor; } } /// /// Gets or sets the fog enable flag. /// public bool FogEnabled { get { return fogEnabled; } set { if (fogEnabled != value) { fogEnabled = value; dirtyFlags |= EffectDirtyFlags.ShaderIndex | EffectDirtyFlags.FogEnable; } } } /// /// Gets or sets the fog start distance. /// public float FogStart { get { return fogStart; } set { fogStart = value; dirtyFlags |= EffectDirtyFlags.Fog; } } /// /// Gets or sets the fog end distance. /// public float FogEnd { get { return fogEnd; } set { fogEnd = value; dirtyFlags |= EffectDirtyFlags.Fog; } } /// /// Gets or sets the fog color. /// public Vector3 FogColor { get { return fogColorParam.GetValueVector3(); } set { fogColorParam.SetValue(value); } } /// /// Gets or sets the current base texture. /// public Texture2D Texture { get { return textureParam.GetValueTexture2D(); } set { textureParam.SetValue(value); } } /// /// Gets or sets the current overlay texture. /// public Texture2D Texture2 { get { return texture2Param.GetValueTexture2D(); } set { texture2Param.SetValue(value); } } /// /// Gets or sets whether vertex color is enabled. /// public bool VertexColorEnabled { get { return vertexColorEnabled; } set { if (vertexColorEnabled != value) { vertexColorEnabled = value; dirtyFlags |= EffectDirtyFlags.ShaderIndex; } } } #endregion #region Methods /// /// Creates a new DualTextureEffect with default parameter settings. /// public DualTextureEffect(GraphicsDevice device) : base(device, Resources.DualTextureEffect) { CacheEffectParameters(); } /// /// Creates a new DualTextureEffect by cloning parameter settings from an existing instance. /// protected DualTextureEffect(DualTextureEffect 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; } /// /// Creates a clone of the current DualTextureEffect instance. /// public override Effect Clone() { return new DualTextureEffect(this); } /// /// Looks up shortcut references to our effect parameters. /// void CacheEffectParameters() { textureParam = Parameters["Texture"]; texture2Param = Parameters["Texture2"]; diffuseColorParam = Parameters["DiffuseColor"]; fogColorParam = Parameters["FogColor"]; fogVectorParam = Parameters["FogVector"]; worldViewProjParam = Parameters["WorldViewProj"]; shaderIndexParam = Parameters["ShaderIndex"]; } /// /// Lazily computes derived parameter values immediately before applying the effect. /// 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 shader index? if ((dirtyFlags & EffectDirtyFlags.ShaderIndex) != 0) { int shaderIndex = 0; if (!fogEnabled) shaderIndex += 1; if (vertexColorEnabled) shaderIndex += 2; shaderIndexParam.SetValue(shaderIndex); dirtyFlags &= ~EffectDirtyFlags.ShaderIndex; } } #endregion } }