using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace MonoGame.Extended.Graphics.Effects { /// /// An that uses the standard chain of matrix transformations to represent a 3D object on a 2D /// monitor. /// /// /// public abstract class MatrixChainEffect : Effect, IMatrixChainEffect { private Matrix _projection = Matrix.Identity; private Matrix _view = Matrix.Identity; private Matrix _world = Matrix.Identity; private bool _worldViewProjectionIsDirty; private EffectParameter _worldViewProjectionParameter; /// /// Initializes a new instance of the class. /// /// The graphics device. /// The effect code. protected MatrixChainEffect(GraphicsDevice graphicsDevice, byte[] effectCode) : base(graphicsDevice, effectCode) { CacheEffectParameters(); } /// /// Initializes a new instance of the class. /// /// The clone source. protected MatrixChainEffect(Effect cloneSource) : base(cloneSource) { CacheEffectParameters(); } /// /// Gets or sets the model-to-world . /// /// /// The model-to-world . /// public Matrix World { get { return _world; } set { SetWorld(ref value); } } /// /// Gets or sets the world-to-view . /// /// /// The world-to-view . /// public Matrix View { get { return _view; } set { SetView(ref value); } } /// /// Gets or sets the view-to-projection . /// /// /// The view-to-projection . /// public Matrix Projection { get { return _projection; } set { SetProjection(ref value); } } /// /// Sets the model-to-world . /// /// The model-to-world . public void SetWorld(ref Matrix world) { _world = world; _worldViewProjectionIsDirty = true; } /// /// Sets the world-to-view . /// /// The world-to-view . public void SetView(ref Matrix view) { _view = view; _worldViewProjectionIsDirty = true; } /// /// Sets the view-to-projection . /// /// The view-to-projection . public void SetProjection(ref Matrix projection) { _projection = projection; _worldViewProjectionIsDirty = true; } private void CacheEffectParameters() { _worldViewProjectionParameter = Parameters["WorldViewProjection"]; } /// /// Computes derived parameter values immediately before applying the effect. /// protected override bool OnApply() { base.OnApply(); // ReSharper disable once InvertIf if (_worldViewProjectionIsDirty) { _worldViewProjectionIsDirty = false; Matrix worldViewProjection; Matrix.Multiply(ref _world, ref _view, out worldViewProjection); Matrix.Multiply(ref worldViewProjection, ref _projection, out worldViewProjection); _worldViewProjectionParameter.SetValue(worldViewProjection); } // in MonoGame 3.6 this method won't return anything; see https://github.com/MonoGame/MonoGame/pull/5090 return false; } } }