using System.Collections.Specialized; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace MonoGame.Extended.Graphics.Effects { /// /// An that allows objects, within a 3D context, to be represented on a 2D monitor. /// /// /// public class DefaultEffect : MatrixChainEffect, ITextureEffect { /// /// The bitmask for use with indicating wether has /// changed in the last frame. /// protected static int DirtyTextureBitMask = BitVector32.CreateMask(UseDefaultProjectionBitMask); /// /// The bitmask for use with indicating wether the underlying vertex shader and /// fragment (pixel) shaders have changed to one of the pre-defined shaders in the last frame. /// protected static int DirtyShaderIndexBitMask = BitVector32.CreateMask(DirtyTextureBitMask); /// /// The bitmask for use with indicating wether the material color has changed in /// the last frame. /// public static int DirtyMaterialColorBitMask = BitVector32.CreateMask(DirtyShaderIndexBitMask); private Texture2D _texture; private EffectParameter _textureParameter; private float _alpha = 1; private Color _diffuseColor = Color.White; private EffectParameter _diffuseColorParameter; private bool _textureEnabled; private bool _vertexColorEnabled; /// /// Gets or sets the material . /// /// /// The material . /// public Texture2D Texture { get { return _texture; } set { _texture = value; Flags[DirtyTextureBitMask] = true; } } /// /// Gets or sets the material color alpha. /// /// /// /// The alpha channel uses the premultiplied (associated) representation. This means that the RGB components of a /// color represent /// the color of the object of pixel, adjusted for its opacity by multiplication of . /// /// public float Alpha { get { return _alpha; } set { _alpha = value; Flags[DirtyMaterialColorBitMask] = true; } } /// /// Gets or sets whether texturing is enabled. /// public bool TextureEnabled { get { return _textureEnabled; } set { if (_textureEnabled == value) return; _textureEnabled = value; Flags[DirtyShaderIndexBitMask] = true; } } /// /// Gets or sets whether vertex color is enabled. /// public bool VertexColorEnabled { get { return _vertexColorEnabled; } set { if (_vertexColorEnabled == value) return; _vertexColorEnabled = value; Flags[DirtyShaderIndexBitMask] = true; } } /// /// Initializes a new instance of the class. /// /// The graphics device. public DefaultEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, EffectResource.DefaultEffect.Bytecode) { Initialize(); } /// /// Initializes a new instance of the class. /// /// The graphics device. /// The byte code of the shader program. public DefaultEffect(GraphicsDevice graphicsDevice, byte[] byteCode) : base(graphicsDevice, byteCode) { Initialize(); } /// /// Initializes a new instance of the class. /// /// The clone source. public DefaultEffect(Effect cloneSource) : base(cloneSource) { Initialize(); } private void Initialize() { Flags[DirtyMaterialColorBitMask] = true; _textureParameter = Parameters["Texture"]; _diffuseColorParameter = Parameters["DiffuseColor"]; } /// /// Computes derived parameter values immediately before applying the effect. /// protected override void OnApply() { base.OnApply(); if (Flags[DirtyTextureBitMask]) { _textureParameter.SetValue(_texture); Flags[DirtyTextureBitMask] = false; } // ReSharper disable once InvertIf if (Flags[DirtyMaterialColorBitMask]) { UpdateMaterialColor(); Flags[DirtyMaterialColorBitMask] = false; } // ReSharper disable once InvertIf if (Flags[DirtyShaderIndexBitMask]) { var shaderIndex = 0; if (_textureEnabled) shaderIndex += 1; if (_vertexColorEnabled) shaderIndex += 2; Flags[DirtyShaderIndexBitMask] = false; CurrentTechnique = Techniques[shaderIndex]; } } /// /// Updates the material color parameters associated with this . /// protected virtual void UpdateMaterialColor() { var diffuseColorVector3 = _diffuseColor.ToVector3(); var diffuseColorVector4 = new Vector4() { X = diffuseColorVector3.X * Alpha, Y = diffuseColorVector3.Y * Alpha, Z = diffuseColorVector3.Z * Alpha, W = Alpha, }; _diffuseColorParameter.SetValue(diffuseColorVector4); } } }