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