MatrixChainEffect.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. using System.Collections.Specialized;
  2. using Microsoft.Xna.Framework;
  3. using Microsoft.Xna.Framework.Graphics;
  4. namespace MonoGame.Extended.Graphics.Effects
  5. {
  6. /// <summary>
  7. /// An <see cref="Effect" /> that uses the standard chain of matrix transformations to represent a 3D object on a 2D
  8. /// monitor.
  9. /// </summary>
  10. /// <seealso cref="Effect" />
  11. /// <seealso cref="IEffectMatrices" />
  12. public abstract class MatrixChainEffect : Effect, IMatrixChainEffect
  13. {
  14. /// <summary>
  15. /// The bitmask for use with <see cref="Flags"/> indicating wether <see cref="World"/>, <see cref="View"/>, or <see cref="Projection"/> has changed in the last frame.
  16. /// </summary>
  17. protected static int DirtyWorldViewProjectionBitMask = BitVector32.CreateMask();
  18. /// <summary>
  19. /// The bitmask for use with <see cref="Flags"/> indicating wether to use a default projection matrix or a custom projection matrix.
  20. /// </summary>
  21. protected static int UseDefaultProjectionBitMask = BitVector32.CreateMask(DirtyWorldViewProjectionBitMask);
  22. /// <summary>
  23. /// The dirty flags associated with this <see cref="MatrixChainEffect"/>.
  24. /// </summary>
  25. protected BitVector32 Flags;
  26. private Matrix _projection = Matrix.Identity;
  27. private Matrix _view = Matrix.Identity;
  28. private Matrix _world = Matrix.Identity;
  29. private EffectParameter _matrixParameter;
  30. /// <summary>
  31. /// Gets or sets the model-to-world <see cref="Matrix" />.
  32. /// </summary>
  33. /// <value>
  34. /// The model-to-world <see cref="Matrix" />.
  35. /// </value>
  36. public Matrix World
  37. {
  38. get { return _world; }
  39. set { SetWorld(ref value); }
  40. }
  41. /// <summary>
  42. /// Gets or sets the world-to-view <see cref="Matrix" />.
  43. /// </summary>
  44. /// <value>
  45. /// The world-to-view <see cref="Matrix" />.
  46. /// </value>
  47. public Matrix View
  48. {
  49. get { return _view; }
  50. set { SetView(ref value); }
  51. }
  52. /// <summary>
  53. /// Gets or sets the view-to-projection <see cref="Matrix" />.
  54. /// </summary>
  55. /// <value>
  56. /// The view-to-projection <see cref="Matrix" />.
  57. /// </value>
  58. public Matrix Projection
  59. {
  60. get { return _projection; }
  61. set { SetProjection(ref value); }
  62. }
  63. /// <summary>
  64. /// Initializes a new instance of the <see cref="MatrixChainEffect" /> class.
  65. /// </summary>
  66. /// <param name="graphicsDevice">The graphics device.</param>
  67. /// <param name="byteCode">The effect code.</param>
  68. protected MatrixChainEffect(GraphicsDevice graphicsDevice, byte[] byteCode)
  69. : base(graphicsDevice, byteCode)
  70. {
  71. Initialize();
  72. }
  73. /// <summary>
  74. /// Initializes a new instance of the <see cref="MatrixChainEffect" /> class.
  75. /// </summary>
  76. /// <param name="cloneSource">The clone source.</param>
  77. protected MatrixChainEffect(Effect cloneSource)
  78. : base(cloneSource)
  79. {
  80. Initialize();
  81. }
  82. private void Initialize()
  83. {
  84. Flags[UseDefaultProjectionBitMask] = true;
  85. _matrixParameter = Parameters["WorldViewProjection"];
  86. }
  87. /// <summary>
  88. /// Sets the model-to-world <see cref="Matrix" />.
  89. /// </summary>
  90. /// <param name="world">The model-to-world <see cref="Matrix" />.</param>
  91. public void SetWorld(ref Matrix world)
  92. {
  93. _world = world;
  94. Flags[DirtyWorldViewProjectionBitMask] = true;
  95. }
  96. /// <summary>
  97. /// Sets the world-to-view <see cref="Matrix" />.
  98. /// </summary>
  99. /// <param name="view">The world-to-view <see cref="Matrix" />.</param>
  100. public void SetView(ref Matrix view)
  101. {
  102. _view = view;
  103. Flags[DirtyWorldViewProjectionBitMask] = true;
  104. }
  105. /// <summary>
  106. /// Sets the view-to-projection <see cref="Matrix" />.
  107. /// </summary>
  108. /// <param name="projection">The view-to-projection <see cref="Matrix" />.</param>
  109. public void SetProjection(ref Matrix projection)
  110. {
  111. _projection = projection;
  112. Flags[DirtyWorldViewProjectionBitMask] = true;
  113. Flags[UseDefaultProjectionBitMask] = false;
  114. }
  115. /// <summary>
  116. /// Computes derived parameter values immediately before applying the effect.
  117. /// </summary>
  118. protected override void OnApply()
  119. {
  120. base.OnApply();
  121. // ReSharper disable once InvertIf
  122. if (Flags[DirtyWorldViewProjectionBitMask] || Flags[UseDefaultProjectionBitMask])
  123. {
  124. if (Flags[UseDefaultProjectionBitMask])
  125. {
  126. var viewport = GraphicsDevice.Viewport;
  127. _projection = Matrix.CreateOrthographicOffCenter(0, viewport.Width, viewport.Height, 0, 0, -1);
  128. }
  129. Matrix worldViewProjection;
  130. Matrix.Multiply(ref _world, ref _view, out worldViewProjection);
  131. Matrix.Multiply(ref worldViewProjection, ref _projection, out worldViewProjection);
  132. _matrixParameter.SetValue(worldViewProjection);
  133. Flags[DirtyWorldViewProjectionBitMask] = false;
  134. }
  135. }
  136. }
  137. }