/Prog/Solution/Ale/Graphics/AleRenderTarget.cs

http://conquera.codeplex.com · C# · 297 lines · 210 code · 52 blank · 35 comment · 19 complexity · ce89fe06eb2ae842fb56c874c5f262af MD5 · raw file

  1. //////////////////////////////////////////////////////////////////////
  2. // Copyright (C) 2010 by Conquera Team
  3. // Part of the Conquera Project
  4. //
  5. // This program is free software: you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation, either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. ////////////////////////////////////////////////////////////////////////
  18. using System;
  19. using System.Collections.Generic;
  20. using System.Text;
  21. using Microsoft.Xna.Framework.Graphics;
  22. using Ale.Tools;
  23. using Microsoft.Xna.Framework;
  24. namespace Ale.Graphics
  25. {
  26. public sealed class AleRenderTarget : IDisposable
  27. {
  28. private static DepthStencilBuffer mDefaultDepthStencilBuffer = null;
  29. private GraphicsDeviceManager mGraphicsDeviceManager;
  30. private RenderTarget2D mRenderTarget2D;
  31. private DepthStencilBuffer mDepthStencilBuffer;
  32. private bool mInBeginEnd = false;
  33. private NameId mName;
  34. private int mWidth;
  35. private int mHeight;
  36. private int mNumberLevels;
  37. private SurfaceFormat mFormat;
  38. private MultiSampleType mMultiSampleType;
  39. private int mMultiSampleQuality;
  40. private RenderTargetUsage mUsage;
  41. /// <summary>
  42. /// If == DepthFormat.Unknown then no DepthStencilBuffer is used
  43. /// </summary>
  44. private DepthFormat mDepthFormat;
  45. private bool mIsDisposed = false;
  46. public Color Color { get; set; }
  47. public bool ClearOnBegin { get; set; }
  48. public GraphicsDevice GraphicsDevice
  49. {
  50. get { return mGraphicsDeviceManager.GraphicsDevice; }
  51. }
  52. public NameId Name
  53. {
  54. get { return mName; }
  55. }
  56. public int Width
  57. {
  58. get { return mWidth; }
  59. }
  60. public int Height
  61. {
  62. get { return mHeight; }
  63. }
  64. public int NumberLevels
  65. {
  66. get { return mNumberLevels; }
  67. }
  68. public SurfaceFormat Format
  69. {
  70. get { return mFormat; }
  71. }
  72. public MultiSampleType MultiSampleType
  73. {
  74. get { return mMultiSampleType; }
  75. }
  76. public int MultiSampleQuality
  77. {
  78. get { return mMultiSampleQuality; }
  79. }
  80. public RenderTargetUsage Usage
  81. {
  82. get { return mUsage; }
  83. }
  84. public DepthFormat DepthFormat
  85. {
  86. get { return mDepthFormat; }
  87. }
  88. public Texture2D Texture
  89. {
  90. get
  91. {
  92. if (null == mRenderTarget2D || mRenderTarget2D.IsContentLost)
  93. {
  94. Clear();
  95. }
  96. return mRenderTarget2D.GetTexture();
  97. }
  98. }
  99. public AleRenderTarget(GraphicsDeviceManager graphicsDeviceManager, NameId name, int width, int height, int numberLevels, SurfaceFormat format)
  100. : this(graphicsDeviceManager, name, width, height, numberLevels, format, DepthFormat.Unknown, MultiSampleType.None, 0, RenderTargetUsage.DiscardContents)
  101. {
  102. }
  103. public AleRenderTarget(GraphicsDeviceManager graphicsDeviceManager, NameId name, int width, int height, int numberLevels, SurfaceFormat format, DepthFormat depthFormat,
  104. MultiSampleType multiSampleType, int multiSampleQuality, RenderTargetUsage usage)
  105. {
  106. Tracer.WriteInfo("Creating render target '{0}' width={1} height={2} levels={3} format={4} depthFormat={5} multiSampleType={6} multiSampleQuality={7} usage={8}",
  107. name, width, height, numberLevels, format, depthFormat, multiSampleType, multiSampleQuality, usage);
  108. mGraphicsDeviceManager = graphicsDeviceManager ;
  109. mName = name;
  110. mWidth = width;
  111. mHeight = height;
  112. mNumberLevels = numberLevels;
  113. mFormat = format;
  114. mMultiSampleType = multiSampleType;
  115. mMultiSampleQuality = multiSampleQuality;
  116. mUsage = usage;
  117. mDepthFormat = depthFormat;
  118. Color = Color.White;
  119. ClearOnBegin = true;
  120. }
  121. /// <summary>
  122. /// Clears the render target. This method calls Begin and End.
  123. /// </summary>
  124. /// <param name="color"></param>
  125. public void Clear()
  126. {
  127. Begin();
  128. if (!ClearOnBegin)
  129. {
  130. ClearInter();
  131. }
  132. End(true);
  133. }
  134. /// <summary>
  135. /// Clears the render target with a given color. This method calls Begin and End.
  136. /// </summary>
  137. /// <param name="color"></param>
  138. /// <param name="clearOptions"></param>
  139. /// <param name="depth"></param>
  140. /// <param name="stencil"></param>
  141. public void Clear(ClearOptions clearOptions, Color color, float depth, int stencil)
  142. {
  143. Begin();
  144. GraphicsDevice.Clear(clearOptions, color, depth, stencil);
  145. End();
  146. }
  147. public void Begin()
  148. {
  149. Begin(0);
  150. }
  151. int mIndex;
  152. public void Begin(int index)
  153. {
  154. if (mInBeginEnd)
  155. {
  156. throw new InvalidOperationException("Multiple calls of Begin method detected withou calling End");
  157. }
  158. mInBeginEnd = true;
  159. if (null == mRenderTarget2D) //not loaded
  160. {
  161. Load();
  162. }
  163. if (null == mDefaultDepthStencilBuffer)
  164. {
  165. mDefaultDepthStencilBuffer = GraphicsDevice.DepthStencilBuffer;
  166. mDefaultDepthStencilBuffer.Disposing += new EventHandler(mDefaultDepthStencilBuffer_Disposing);
  167. }
  168. mIndex = index;
  169. GraphicsDevice.SetRenderTarget(mIndex, mRenderTarget2D);
  170. GraphicsDevice.DepthStencilBuffer = mDepthStencilBuffer;
  171. if (ClearOnBegin)
  172. {
  173. ClearInter();
  174. }
  175. }
  176. public void End()
  177. {
  178. End(true);
  179. }
  180. public void End(bool setDefaultRenderTarget)
  181. {
  182. if (!mInBeginEnd)
  183. {
  184. throw new InvalidOperationException("End method can't be called without calling Begin method first");
  185. }
  186. mInBeginEnd = false;
  187. if (setDefaultRenderTarget)
  188. {
  189. GraphicsDevice.SetRenderTarget(mIndex, null);
  190. GraphicsDevice.DepthStencilBuffer = mDefaultDepthStencilBuffer;
  191. }
  192. }
  193. public override string ToString()
  194. {
  195. return mName.ToString();
  196. }
  197. #region IDisposable
  198. public void Dispose()
  199. {
  200. if (!mIsDisposed)
  201. {
  202. Tracer.WriteInfo("Disposing AleRenderTarget '{0}'", mName);
  203. if (null != mRenderTarget2D)
  204. {
  205. mRenderTarget2D.Dispose();
  206. mRenderTarget2D = null;
  207. }
  208. if (null != mDepthStencilBuffer)
  209. {
  210. mDepthStencilBuffer.Dispose();
  211. mDepthStencilBuffer = null;
  212. }
  213. GC.SuppressFinalize(this);
  214. mIsDisposed = true;
  215. }
  216. }
  217. #endregion IDisposable
  218. private void mDefaultDepthStencilBuffer_Disposing(object sender, EventArgs e)
  219. {
  220. mDefaultDepthStencilBuffer.Disposing -= mDefaultDepthStencilBuffer_Disposing;
  221. mDefaultDepthStencilBuffer = null;
  222. }
  223. private void Load()
  224. {
  225. Tracer.WriteInfo("Loading AleRenderTarget '{0}'", mName);
  226. mRenderTarget2D = new RenderTarget2D(GraphicsDevice, mWidth, mHeight, mNumberLevels, mFormat, mMultiSampleType, mMultiSampleQuality, mUsage);
  227. if (DepthFormat.Unknown != mDepthFormat)
  228. {
  229. mDepthStencilBuffer = new DepthStencilBuffer(GraphicsDevice, mWidth, mHeight, mDepthFormat, mMultiSampleType, mMultiSampleQuality);
  230. }
  231. else
  232. {
  233. mDepthStencilBuffer = null;
  234. }
  235. }
  236. /// <summary>
  237. /// Clears the render target. This method calls Begin and End.
  238. /// </summary>
  239. /// <param name="color"></param>
  240. private void ClearInter()
  241. {
  242. GraphicsDevice.Clear(Color);
  243. }
  244. }
  245. }