PageRenderTime 43ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/branches/1.x/Ionian/Examples/Framework/ParticleAcceleration/MainForm.cs

http://gorgonlib.googlecode.com/
C# | 336 lines | 231 code | 39 blank | 66 comment | 21 complexity | ef0fd9049b33b7214fdf3a782fd9be26 MD5 | raw file
Possible License(s): LGPL-2.0
  1. #region MIT.
  2. //
  3. // Examples.
  4. // Copyright (C) 2008 Michael Winsor
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. // Created: Thursday, October 02, 2008 10:46:02 PM
  24. //
  25. #endregion
  26. using System;
  27. using System.Collections.Generic;
  28. using System.ComponentModel;
  29. using Drawing = System.Drawing;
  30. using System.Text;
  31. using System.Windows.Forms;
  32. using Dialogs;
  33. using GorgonLibrary;
  34. using GorgonLibrary.Framework;
  35. using GorgonLibrary.Graphics;
  36. using GorgonLibrary.Graphics.Utilities;
  37. using GorgonLibrary.InputDevices;
  38. namespace GorgonLibrary.Example
  39. {
  40. /// <summary>
  41. /// Main application form.
  42. /// </summary>
  43. public partial class MainForm
  44. : GorgonApplicationWindow
  45. {
  46. #region Variables.
  47. private Random _rnd = new Random(); // Random number generator.
  48. private List<ParticleEmitter> _emitters = null; // List of particle emitters.
  49. private RenderImage _particleImage = null; // Particle image.
  50. private RenderImage _screen = null; // Primary target.
  51. private Sprite _particleSprite = null; // Particle sprite.
  52. private bool _clearScreen = false; // Flag to indicate that we should clear each frame.
  53. private PreciseTimer _timer = new PreciseTimer(); // Timer object.
  54. private PreciseTimer _splatTimer = new PreciseTimer(); // Particle splat timer.
  55. private TextSprite _text = null; // Help text.
  56. private bool _inverted = false; // Flag to invert the screen.
  57. private bool _showHelp = true; // Flag to show help text.
  58. #endregion
  59. #region Methods.
  60. /// <summary>
  61. /// Function to perform logic updates.
  62. /// </summary>
  63. /// <param name="e">Frame event parameters.</param>
  64. protected override void OnLogicUpdate(FrameEventArgs e)
  65. {
  66. base.OnLogicUpdate(e);
  67. int i = 0;
  68. if (_inverted)
  69. {
  70. _text.Color = Drawing.Color.White;
  71. _particleSprite.BlendingMode = BlendingModes.Additive;
  72. _screen.BackgroundColor = Drawing.Color.Black;
  73. }
  74. else
  75. {
  76. _text.Color = Drawing.Color.Black;
  77. _particleSprite.BlendingMode = BlendingModes.Modulated;
  78. _screen.BackgroundColor = Drawing.Color.White;
  79. }
  80. while (i < _emitters.Count)
  81. {
  82. if (_emitters[i].Age < _emitters[i].ParticleLifetimeRange.End)
  83. {
  84. _emitters[i].Update(e.FrameDeltaTime);
  85. i++;
  86. }
  87. else
  88. _emitters.Remove(_emitters[i]);
  89. }
  90. }
  91. /// <summary>
  92. /// Function to perform rendering updates.
  93. /// </summary>
  94. /// <param name="e">Frame event parameters.</param>
  95. protected override void OnFrameUpdate(FrameEventArgs e)
  96. {
  97. base.OnFrameUpdate(e);
  98. int i = 0;
  99. Gorgon.CurrentRenderTarget = _screen;
  100. if (_clearScreen)
  101. _screen.Clear();
  102. else
  103. {
  104. if (_timer.Milliseconds > 12.5)
  105. {
  106. if (!_inverted)
  107. {
  108. _screen.BlendingMode = BlendingModes.Additive;
  109. _screen.FilledRectangle(0, 0, _screen.Width, _screen.Height, Drawing.Color.FromArgb(1, _rnd.Next(0, 255), _rnd.Next(0, 255), _rnd.Next(0, 255)));
  110. _screen.BlendingMode = BlendingModes.None;
  111. }
  112. else
  113. {
  114. _screen.BlendingMode = BlendingModes.Modulated;
  115. _screen.FilledRectangle(0, 0, _screen.Width, _screen.Height, Drawing.Color.FromArgb(1, _rnd.Next(0, 255), _rnd.Next(0, 255), _rnd.Next(0, 255)));
  116. _screen.BlendingMode = BlendingModes.None;
  117. }
  118. _timer.Reset();
  119. }
  120. }
  121. for (i = 0; i < _emitters.Count; i++)
  122. _emitters[i].Draw();
  123. Gorgon.CurrentRenderTarget = null;
  124. _screen.Blit();
  125. if (_showHelp)
  126. {
  127. _text.Text = "H - Show/hide this help text.\nI - Invert and use additive blending.\nLeft mouse button - Splat some particles.\nRight mouse button - Splat multicolored particles.\nMiddle mouse button - Toggle clear each frame.\nCTRL + F - Show frame statistics.\nESC - Exit.\n\nParticle emitter count: " + _emitters.Count.ToString();
  128. _text.Draw();
  129. }
  130. }
  131. /// <summary>
  132. /// Function called when the video device is set to a lost state.
  133. /// </summary>
  134. protected override void OnDeviceLost()
  135. {
  136. base.OnDeviceLost();
  137. }
  138. /// <summary>
  139. /// Function called when a keyboard key is pushed down.
  140. /// </summary>
  141. /// <param name="e">Keyboard event parameters.</param>
  142. protected override void OnKeyboardKeyDown(KeyboardInputEventArgs e)
  143. {
  144. base.OnKeyboardKeyDown(e);
  145. if (e.Key == KeyboardKeys.I)
  146. _inverted = !_inverted;
  147. if (e.Key == KeyboardKeys.H)
  148. _showHelp = !_showHelp;
  149. }
  150. /// <summary>
  151. /// Function called when the video device has recovered from a lost state.
  152. /// </summary>
  153. protected override void OnDeviceReset()
  154. {
  155. base.OnDeviceReset();
  156. _screen.Width = Gorgon.Screen.Width;
  157. _screen.Height = Gorgon.Screen.Height;
  158. _screen.Clear();
  159. }
  160. /// <summary>
  161. /// Function to create a particle.
  162. /// </summary>
  163. private void CreateParticle()
  164. {
  165. Drawing.Color particleColor;
  166. _particleImage.Clear(Drawing.Color.Transparent);
  167. _particleImage.BeginDrawing();
  168. for (int x = 64; x > 0; x--)
  169. {
  170. particleColor = Drawing.Color.FromArgb(255 - ((x * 4) - 1), 255, 255, 255);
  171. _particleImage.FilledCircle(32.0f, 32.0f, x / 2, particleColor);
  172. }
  173. _particleImage.EndDrawing();
  174. }
  175. /// <summary>
  176. /// Function to create a particle emitter.
  177. /// </summary>
  178. /// <param name="position">The position of the emitter.</param>
  179. /// <returns>A new emitter.</returns>
  180. private ParticleEmitter CreateEmitter(Vector2D position)
  181. {
  182. ParticleEmitter emitter = null;
  183. emitter = new ParticleEmitter("Emitter" + _emitters.Count.ToString(), _particleSprite, position);
  184. emitter.ColorRange = new Range<Drawing.Color>(Drawing.Color.Black, Drawing.Color.FromArgb(0, Drawing.Color.Black));
  185. emitter.ContinuousParticles = false;
  186. emitter.EmitterLifetime = 1.5f;
  187. emitter.ParticleLifetimeRange = new Range<float>(0.0f, (float)(_rnd.NextDouble() * 10.0) + 5.0f);
  188. emitter.ParticleSizeRange = new Range<float>((float)(_rnd.NextDouble() * 1.5) + 0.25f, 0.0f);
  189. emitter.ParticleSpeedRange = new Range<float>(0.0f, (float)(_rnd.NextDouble() * 10.0) + 4.0f);
  190. emitter.TangentialAccelerationRange = new Range<float>(0.0f, 0.0f);
  191. emitter.RadialAccelerationRange = new Range<float>(0.0f, (float)(_rnd.NextDouble() * 10.0) + 4.0f);
  192. emitter.ParticleRotationRange = new Range<float>(-10.0f, 10.0f);
  193. emitter.Spread = (float)(_rnd.NextDouble() * 360.0);
  194. emitter.EmitterScale = 1.0f;
  195. _splatTimer.Reset();
  196. _emitters.Add(emitter);
  197. return emitter;
  198. }
  199. /// <summary>
  200. /// Function called when the mouse is moved.
  201. /// </summary>
  202. /// <param name="e">Mouse event parameters.</param>
  203. protected override void OnMouseMovement(MouseInputEventArgs e)
  204. {
  205. base.OnMouseMovement(e);
  206. ParticleEmitter emitter = null;
  207. Drawing.Color startColor;
  208. Drawing.Color endColor;
  209. int alpha = 255;
  210. if (_clearScreen)
  211. alpha = _rnd.Next(64, 192);
  212. if (_splatTimer.Milliseconds >= 10)
  213. {
  214. switch (e.Buttons)
  215. {
  216. case GorgonLibrary.InputDevices.MouseButtons.Button1:
  217. startColor = Drawing.Color.FromArgb(alpha, _rnd.Next(0, 255), _rnd.Next(0, 255), _rnd.Next(0, 255));
  218. endColor = Drawing.Color.FromArgb(0, startColor);
  219. emitter = CreateEmitter(e.Position);
  220. emitter.ColorRange = new Range<System.Drawing.Color>(startColor, endColor);
  221. break;
  222. case GorgonLibrary.InputDevices.MouseButtons.Button2:
  223. startColor = Drawing.Color.FromArgb(alpha, Drawing.Color.Black);
  224. endColor = Drawing.Color.FromArgb(0, Drawing.Color.White);
  225. emitter = CreateEmitter(e.Position);
  226. emitter.ColorRange = new Range<System.Drawing.Color>(startColor, endColor);
  227. break;
  228. }
  229. _splatTimer.Reset();
  230. }
  231. }
  232. /// <summary>
  233. /// Function called when a mouse button is pushed down.
  234. /// </summary>
  235. /// <param name="e">Mouse event parameters.</param>
  236. protected override void OnMouseButtonDown(MouseInputEventArgs e)
  237. {
  238. base.OnMouseButtonDown(e);
  239. ParticleEmitter emitter = null;
  240. Drawing.Color startColor;
  241. Drawing.Color endColor;
  242. int alpha = 255;
  243. if (e.Buttons == GorgonLibrary.InputDevices.MouseButtons.Button3)
  244. _clearScreen = !_clearScreen;
  245. else
  246. {
  247. if (_clearScreen)
  248. alpha = _rnd.Next(64, 192);
  249. if (e.Buttons == GorgonLibrary.InputDevices.MouseButtons.Button1)
  250. {
  251. startColor = Drawing.Color.FromArgb(alpha, _rnd.Next(0, 255), _rnd.Next(0, 255), _rnd.Next(0, 255));
  252. endColor = Drawing.Color.FromArgb(0, startColor);
  253. }
  254. else
  255. {
  256. startColor = Drawing.Color.FromArgb(alpha, Drawing.Color.Black);
  257. endColor = Drawing.Color.FromArgb(0, Drawing.Color.White);
  258. }
  259. emitter = CreateEmitter(e.Position);
  260. emitter.ColorRange = new Range<System.Drawing.Color>(startColor, endColor);
  261. }
  262. }
  263. /// <summary>
  264. /// Function to provide initialization for our example.
  265. /// </summary>
  266. protected override void Initialize()
  267. {
  268. try
  269. {
  270. _text = new TextSprite("Help Text", string.Empty, FrameworkFont, Drawing.Color.Black);
  271. _particleImage = new RenderImage("ParticleImage", 64, 64, ImageBufferFormats.BufferRGB888A8);
  272. _screen = new RenderImage("Screen", Gorgon.Screen.Width, Gorgon.Screen.Height, ImageBufferFormats.BufferRGB888X8);
  273. CreateParticle();
  274. _particleSprite = new Sprite("ParticleSprite", _particleImage);
  275. _particleSprite.Axis = new Vector2D(32, 32);
  276. CreateEmitter(new Vector2D(Gorgon.Screen.Width / 2.0f, Gorgon.Screen.Height / 2.0f));
  277. _screen.Clear();
  278. }
  279. catch (Exception ex)
  280. {
  281. UI.ErrorBox(this, "Unable to initialize the application.", ex);
  282. }
  283. }
  284. #endregion
  285. #region Constructor.
  286. /// <summary>
  287. /// Constructor.
  288. /// </summary>
  289. public MainForm()
  290. : base(@".\ParticleAcceleration.xml")
  291. {
  292. InitializeComponent();
  293. _emitters = new List<ParticleEmitter>();
  294. }
  295. #endregion
  296. }
  297. }