PageRenderTime 64ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/Rendering/EffectTests/Effect2DTests.cs

#
C# | 494 lines | 365 code | 27 blank | 102 comment | 13 complexity | bd58ecfd1a3b583bef4c438571291c68 MD5 | raw file
Possible License(s): Apache-2.0
  1. using Delta.ContentSystem.Rendering;
  2. using Delta.ContentSystem.Rendering.Helpers;
  3. using Delta.Engine;
  4. using Delta.InputSystem;
  5. using Delta.Rendering.Basics.Fonts;
  6. using Delta.Rendering.Basics.Materials;
  7. using Delta.Rendering.Effects;
  8. using Delta.Rendering.Effects.Modifiers;
  9. using Delta.Rendering.Enums;
  10. using Delta.Utilities.Datatypes;
  11. using Delta.Utilities.Helpers;
  12. using Delta.Utilities.Math;
  13. using NUnit.Framework;
  14. namespace Delta.Rendering.EffectTests
  15. {
  16. /// <summary>
  17. /// Effect test in 2D space.
  18. /// </summary>
  19. [Category("Visual")]
  20. internal class Effect2DTests
  21. {
  22. #region Helpers
  23. /// <summary>
  24. /// The default 2d material modifier, so we don't have to write the code
  25. /// in every test again.
  26. /// </summary>
  27. public static readonly MaterialModifier Default2DMaterialModifier =
  28. new MaterialModifier
  29. {
  30. Material = new Material2DColored(
  31. //"SmokeSmallAdditive")
  32. //"DeltaEngineLogo")
  33. "BreakoutEffect")
  34. {
  35. DrawLayer = RenderLayer.Normal,
  36. BlendColor = Color.White,
  37. }
  38. };
  39. #endregion
  40. #region SimpleEffect (Static)
  41. /// <summary>
  42. /// Spawn simple effect
  43. /// </summary>
  44. [Test]
  45. public static void SimpleEffect()
  46. {
  47. // Create a new template.
  48. EffectData data = EffectData.Get("<SimpleEffect>");
  49. // With one emitter.
  50. EmitterData emitter = new EmitterData();
  51. // Add some modifiers for the emitter and particles.
  52. emitter.Modifiers.Add(Default2DMaterialModifier);
  53. emitter.Modifiers.Add(new AlwaysSpawnModifier());
  54. emitter.Modifiers.Add(new FadeModifier
  55. {
  56. AlphaFade = new Range(1f, 0f),
  57. });
  58. emitter.Modifiers.Add(new SizeModifier
  59. {
  60. WidthRange = new Range(2, 0),
  61. HeightRange = new Range(2, 0),
  62. });
  63. emitter.Modifiers.Add(new RotationModifier
  64. {
  65. Rotation = new Range(0, 360),
  66. });
  67. emitter.Modifiers.Add(new VelocityModifier
  68. {
  69. Velocity = new Vector(0f, 0.1f, 0f)
  70. });
  71. data.Emitters.Add(emitter);
  72. // We want to start and stop the effect by hand, so save the invalid id.
  73. int effectId = MathHelper.InvalidIndex;
  74. // Start the application.
  75. Application.Start(delegate
  76. {
  77. // On enter or touch we start/stop the effect.
  78. if (Input.Keyboard.EnterReleased ||
  79. Input.Touch.TouchReleased)
  80. {
  81. if (effectId == MathHelper.InvalidIndex)
  82. {
  83. effectId = Effect.Spawn(data, ScreenSpace.DrawArea.Center);
  84. }
  85. else
  86. {
  87. Effect.Stop(effectId);
  88. effectId = MathHelper.InvalidIndex;
  89. }
  90. }
  91. // Write some debug info.
  92. Font.DrawTopLeftInformation(
  93. "Press Enter or Touch to activate spawning." +
  94. "\nEffect.IsActive=" + (effectId != MathHelper.InvalidIndex) +
  95. "\nEffect.ActiveParticles=" +
  96. Effect.NumberOfActiveParticles(effectId));
  97. });
  98. }
  99. #endregion
  100. #region MultiEmitterEffect (Static)
  101. /// <summary>
  102. /// Spawn a simple effect with multiple emitters.
  103. /// </summary>
  104. [Test]
  105. public static void MultiEmitterEffect()
  106. {
  107. // Create a new template.
  108. EffectData data = EffectData.Get("<MultiEmitterEffect>");
  109. // With one emitter that spawns always.
  110. EmitterData constantEmitter = new EmitterData();
  111. // Add some modifiers for the emitter and particles.
  112. constantEmitter.Modifiers.Add(new AlwaysSpawnModifier());
  113. constantEmitter.Modifiers.Add(Default2DMaterialModifier);
  114. constantEmitter.Modifiers.Add(new VelocityModifier
  115. {
  116. Velocity = new Vector(0f, 0.1f, 0f)
  117. });
  118. data.Emitters.Add(constantEmitter);
  119. // And one emitter that starts at 3s and spawns all the time after that.
  120. EmitterData timeRangeEmitter = new EmitterData();
  121. // Add some modifiers for the emitter and particles.
  122. timeRangeEmitter.Modifiers.Add(new AlwaysSpawnModifier());
  123. timeRangeEmitter.Modifiers.Add(new TimeRangeModifier
  124. {
  125. TimeRange = new Range(3, float.PositiveInfinity)
  126. });
  127. timeRangeEmitter.Modifiers.Add(Default2DMaterialModifier);
  128. timeRangeEmitter.Modifiers.Add(new VelocityModifier
  129. {
  130. Velocity = new Vector(0.1f, 0f, 0f)
  131. });
  132. data.Emitters.Add(timeRangeEmitter);
  133. // Start the effect.
  134. int effectId = Effect.Spawn(data, ScreenSpace.DrawArea.Center);
  135. // Start the application.
  136. Application.Start();
  137. }
  138. #endregion
  139. #region CollisionEffect (Static)
  140. [Test]
  141. public static void CollisionEffect()
  142. {
  143. // Setup the visual collision effect for the ball
  144. var collision = new Material2DColored("BreakoutEffect");
  145. EffectData effectTemplate = EffectData.Get("<BrickDestroyEffect>");
  146. EmitterData emitter = new EmitterData();
  147. emitter.Modifiers.Add(new SpawnOnceModifier());
  148. emitter.Modifiers.Add(new SizeModifier
  149. {
  150. WidthRange = new Range(1.0f, 4.0f),
  151. HeightRange = new Range(1.0f, 4.0f),
  152. });
  153. emitter.Modifiers.Add(new FadeModifier
  154. {
  155. AlphaFade = new Range(1.0f, 0.0f),
  156. });
  157. emitter.Modifiers.Add(new MaterialModifier
  158. {
  159. BillboardMode = BillboardMode.Only2D,
  160. Material = collision,
  161. });
  162. effectTemplate.Emitters.Add(emitter);
  163. Application.Start(delegate
  164. {
  165. Font.DrawTopLeftInformation("Click to spawn effect");
  166. if (Input.Mouse.LeftButtonReleased)
  167. {
  168. Effect.Spawn(effectTemplate, Input.Mouse.Position);
  169. }
  170. });
  171. }
  172. #endregion
  173. #region SimpleEffectWithAnimatedMaterial (Static)
  174. /// <summary>
  175. /// Spawn simple effect.
  176. /// </summary>
  177. [Test]
  178. public static void SimpleEffectWithAnimatedMaterial()
  179. {
  180. // Create a new template.
  181. EffectData data = EffectData.Get("<SimpleEffectWithAnimatedMaterial>");
  182. // With one emitter.
  183. EmitterData emitter = new EmitterData();
  184. // Add some modifiers for the emitter and particles.
  185. emitter.Modifiers.Add(new MaterialModifier
  186. {
  187. Material = new Material2DColored("BigExplosion")
  188. });
  189. emitter.Modifiers.Add(new AlwaysSpawnModifier());
  190. data.Emitters.Add(emitter);
  191. // Start the effect.
  192. int effectId = Effect.Spawn(data, ScreenSpace.DrawArea.Center);
  193. // Start the application.
  194. Application.Start();
  195. }
  196. #endregion
  197. #region OnceEffect (Static)
  198. /// <summary>
  199. /// Spawn once effect
  200. /// </summary>
  201. [Test]
  202. public static void OnceEffect()
  203. {
  204. // Create a new template.
  205. EffectData data = EffectData.Get("<OnceEffect>");
  206. // With one emitter.
  207. EmitterData emitter = new EmitterData();
  208. // Add some modifiers for the emitter and particles.
  209. emitter.Modifiers.Add(Default2DMaterialModifier);
  210. emitter.Modifiers.Add(new SpawnOnceModifier());
  211. data.Emitters.Add(emitter);
  212. // Start the application.
  213. Application.Start(delegate
  214. {
  215. // This effect will only spawn a particle once, so we can activate
  216. // the effect whenever we hit enter or touch or press the screen.
  217. if (Input.Keyboard.EnterReleased)
  218. {
  219. Effect.Spawn(data, ScreenSpace.DrawArea.Center);
  220. }
  221. if (Input.Touch.TouchReleased)
  222. {
  223. Effect.Spawn(data, Input.Touch.Position);
  224. }
  225. else if (Input.Mouse.LeftButtonReleased)
  226. {
  227. Effect.Spawn(data, Input.Mouse.Position);
  228. }
  229. });
  230. }
  231. #endregion
  232. #region SimpleElapsingEffect (Static)
  233. /// <summary>
  234. /// Spawn simple elapsing effect.
  235. /// This effect is exceeding after 5s and then stopping itself.
  236. /// </summary>
  237. [Test]
  238. public static void SimpleElapsingEffect()
  239. {
  240. // Create a new template.
  241. EffectData data = EffectData.Get("<SimpleElapsingEffect>");
  242. // With one emitter.
  243. EmitterData emitter = new EmitterData();
  244. // Add some modifiers for the emitter and particles.
  245. emitter.Modifiers.Add(Default2DMaterialModifier);
  246. emitter.Modifiers.Add(new TimeRangeModifier
  247. {
  248. TimeRange = new Range(0f, 5f)
  249. });
  250. emitter.Modifiers.Add(new VelocityModifier
  251. {
  252. Velocity = new Vector(0f, 0.01f, 0f)
  253. });
  254. data.Emitters.Add(emitter);
  255. // Start the effect.
  256. int effectId = Effect.Spawn(data, ScreenSpace.DrawArea.Center);
  257. // Start the application.
  258. Application.Start();
  259. }
  260. #endregion
  261. #region AdvancedElapsingEffect (Static)
  262. /// <summary>
  263. /// Spawn advanced elapsing effect.
  264. ///
  265. /// First an emitter is spawning until 3s and then an other emitter is
  266. /// spawning particles until 6s. Then the effect stops automatically.
  267. /// </summary>
  268. [Test]
  269. public static void AdvancedElapsingEffect()
  270. {
  271. // Create a new template.
  272. EffectData data = EffectData.Get("<MultiEmitterEffect>");
  273. // With one emitter that spawns the first 3 seconds
  274. EmitterData timeRangeEmitter = new EmitterData();
  275. // Add some modifiers for the emitter and particles.
  276. timeRangeEmitter.Modifiers.Add(new AlwaysSpawnModifier());
  277. timeRangeEmitter.Modifiers.Add(Default2DMaterialModifier);
  278. timeRangeEmitter.Modifiers.Add(new VelocityModifier
  279. {
  280. Velocity = new Vector(0f, 0.1f, 0f)
  281. });
  282. timeRangeEmitter.Modifiers.Add(new TimeRangeModifier
  283. {
  284. TimeRange = new Range(0f, 3f)
  285. });
  286. timeRangeEmitter.Modifiers.Add(new FadeModifier
  287. {
  288. AlphaFade = new Range(1.0f, 0.0f),
  289. });
  290. data.Emitters.Add(timeRangeEmitter);
  291. // And another emitter that starts at 3s and ends at 6s.
  292. EmitterData delayedEmitter = new EmitterData();
  293. // Add some modifiers for the emitter and particles.
  294. delayedEmitter.Modifiers.Add(new AlwaysSpawnModifier());
  295. delayedEmitter.Modifiers.Add(new TimeRangeModifier
  296. {
  297. TimeRange = new Range(3f, 6f)
  298. });
  299. delayedEmitter.Modifiers.Add(Default2DMaterialModifier);
  300. delayedEmitter.Modifiers.Add(new VelocityModifier
  301. {
  302. Velocity = new Vector(0.1f, 0f, 0f)
  303. });
  304. data.Emitters.Add(delayedEmitter);
  305. // Start the effect.
  306. int effectId = Effect.Spawn(data, ScreenSpace.DrawArea.Center);
  307. // Start the application.
  308. Application.Start();
  309. }
  310. #endregion
  311. #region SimpleEffectPerformance (Static)
  312. /// <summary>
  313. /// Simple Effect performance.
  314. ///
  315. /// Marcel: ~2100 FPS with Debugger attached
  316. /// - Win Vista, Dual Core 3.00 GHZ, 4 GB Ram, NVIDIA GeForce GTS 250
  317. /// </summary>
  318. [Test]
  319. public static void SimpleEffectPerformance()
  320. {
  321. // Create a new template.
  322. EffectData data = EffectData.Get("<SimpleEffectPerformance>");
  323. // With one emitter.
  324. EmitterData emitter = new EmitterData();
  325. // Add some modifiers for the emitter and particles.
  326. emitter.Modifiers.Add(Default2DMaterialModifier);
  327. emitter.Modifiers.Add(new TimeRangeModifier
  328. {
  329. TimeRange = new Range(0f, float.PositiveInfinity),
  330. });
  331. emitter.Modifiers.Add(new SpawnIntervalModifier
  332. {
  333. SpawnInterval = 0.01f,
  334. });
  335. emitter.Modifiers.Add(new SizeModifier
  336. {
  337. WidthRange = new Range(2, 0),
  338. HeightRange = new Range(2, 0),
  339. });
  340. emitter.Modifiers.Add(new VelocityModifier
  341. {
  342. Velocity = new Vector(0f, 0.1f, 0f)
  343. });
  344. data.Emitters.Add(emitter);
  345. // Start the effect.
  346. int effectId = Effect.Spawn(data, ScreenSpace.DrawArea.Center);
  347. // Start the application.
  348. Application.Start(delegate
  349. {
  350. Font.DrawTopLeftInformation(
  351. "Fps=" + Time.Fps + "\n" +
  352. "Current active particles=" +
  353. Effect.NumberOfActiveParticles(effectId));
  354. });
  355. }
  356. #endregion
  357. #region TestMultiEffectPerformance (Static)
  358. /// <summary>
  359. /// Spawn multiple effects
  360. /// Marcel: ~1400 FPS with Debugger attached
  361. /// - Win Vista, Dual Core 3.00 GHZ, 4 GB Ram, NVIDIA GeForce GTS 250
  362. /// </summary>
  363. [Test]
  364. public static void TestMultiEffectPerformance()
  365. {
  366. // We use numberX * numberY particles here in a grid for performance test
  367. int numberX = 15;
  368. int numberY = 15;
  369. float offsetX = (numberX / 2f) * 0.05f;
  370. float offsetY = (numberY / 2f) * 0.05f;
  371. Point startPos = new Point(0.5f - offsetX, 0.5f - offsetY);
  372. int index = 0;
  373. for (int iy = 0; iy < numberY; iy++)
  374. {
  375. for (int ix = 0; ix < numberX; ix++)
  376. {
  377. // Create a new template.
  378. EffectData data = EffectData.Get("<Effect" + index + ">");
  379. // With one emitter.
  380. EmitterData emitter = new EmitterData();
  381. // Add some modifiers for the emitter and particles.
  382. emitter.Modifiers.Add(new MaterialModifier
  383. {
  384. Material = new Material2DColored("SmokeSmallAdditive")
  385. {
  386. BlendColor = Color.NextSolidColor,
  387. },
  388. BillboardMode = BillboardMode.Only2D,
  389. });
  390. if (index % 2 == 0)
  391. {
  392. emitter.Modifiers.Add(new RotationModifier
  393. {
  394. Rotation = new Range(0f, 360f),
  395. });
  396. emitter.Modifiers.Add(new SizeModifier
  397. {
  398. WidthRange = new Range(1, 0),
  399. HeightRange = new Range(1, 0),
  400. });
  401. }
  402. else
  403. {
  404. emitter.Modifiers.Add(new FadeModifier
  405. {
  406. AlphaFade = new Range(1f, 0f),
  407. });
  408. }
  409. emitter.Modifiers.Add(new AlwaysSpawnModifier());
  410. data.Emitters.Add(emitter);
  411. // Start the effect.
  412. Effect.Spawn(data, startPos + new Point(ix * 0.05f, iy * 0.05f));
  413. index++;
  414. }
  415. }
  416. // Start the application.
  417. Application.Start(delegate
  418. {
  419. Font.DrawTopLeftInformation("Fps: " + Time.Fps);
  420. });
  421. }
  422. #endregion
  423. #region MassiveEffectPerformance (Static)
  424. /// <summary>
  425. /// Massive Effect performance.
  426. ///
  427. /// Marcel: ~560 FPS with Debugger attached
  428. /// - Win Vista, Dual Core 3.00 GHZ, 4 GB Ram, NVIDIA GeForce GTS 250
  429. /// </summary>
  430. [Test]
  431. public static void MassiveEffectPerformance()
  432. {
  433. // Create a new template.
  434. EffectData data = EffectData.Get("<MassiveEffectPerformance>");
  435. // With one emitter.
  436. EmitterData emitter = new EmitterData();
  437. // Add some modifiers for the emitter and particles.
  438. emitter.Modifiers.Add(Default2DMaterialModifier);
  439. emitter.Modifiers.Add(new AlwaysSpawnModifier());
  440. emitter.Modifiers.Add(new SpawnIntervalModifier
  441. {
  442. SpawnInterval = 0.0001f,
  443. });
  444. emitter.Modifiers.Add(new SizeModifier
  445. {
  446. WidthRange = new Range(0.1f),
  447. HeightRange = new Range(4, 1),
  448. });
  449. emitter.Modifiers.Add(new VelocityModifier
  450. {
  451. Velocity = Vector.UnitX
  452. });
  453. data.Emitters.Add(emitter);
  454. // Start the effect.
  455. int effectId = Effect.Spawn(data, new Point(0f, 0.5f));
  456. // Start the application.
  457. Application.Start(delegate
  458. {
  459. Font.DrawTopLeftInformation(
  460. "Fps: " + Time.Fps + "\n" +
  461. "Currently active particles: " +
  462. Effect.NumberOfActiveParticles(effectId));
  463. });
  464. }
  465. #endregion
  466. }
  467. }