textures_particles_blending.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*******************************************************************************************
  2. *
  3. * raylib example - particles blending
  4. *
  5. * This example has been created using raylib 1.7 (www.raylib.com)
  6. * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
  7. *
  8. * Copyright (c) 2017 Ramon Santamaria (@raysan5)
  9. *
  10. ********************************************************************************************/
  11. #include "raylib.h"
  12. #if defined(PLATFORM_WEB)
  13. #include <emscripten/emscripten.h>
  14. #endif
  15. #define MAX_PARTICLES 200
  16. //----------------------------------------------------------------------------------
  17. // Global Variables Definition
  18. //----------------------------------------------------------------------------------
  19. int screenWidth = 800;
  20. int screenHeight = 450;
  21. // Particle structure with basic data
  22. typedef struct {
  23. Vector2 position;
  24. Color color;
  25. float alpha;
  26. float size;
  27. float rotation;
  28. bool active; // NOTE: Use it to activate/deactive particle
  29. } Particle;
  30. Particle mouseTail[MAX_PARTICLES];
  31. float gravity = 3.0f;
  32. Texture2D smoke;
  33. int blending = BLEND_ALPHA;
  34. //----------------------------------------------------------------------------------
  35. // Module Functions Declaration
  36. //----------------------------------------------------------------------------------
  37. void UpdateDrawFrame(void); // Update and Draw one frame
  38. //----------------------------------------------------------------------------------
  39. // Main Enry Point
  40. //----------------------------------------------------------------------------------
  41. int main()
  42. {
  43. // Initialization
  44. //--------------------------------------------------------------------------------------
  45. InitWindow(screenWidth, screenHeight, "raylib [textures] example - particles blending");
  46. // Initialize particles
  47. for (int i = 0; i < MAX_PARTICLES; i++)
  48. {
  49. mouseTail[i].position = (Vector2){ 0, 0 };
  50. mouseTail[i].color = (Color){ GetRandomValue(0, 255), GetRandomValue(0, 255), GetRandomValue(0, 255), 255 };
  51. mouseTail[i].alpha = 1.0f;
  52. mouseTail[i].size = (float)GetRandomValue(1, 30)/20.0f;
  53. mouseTail[i].rotation = GetRandomValue(0, 360);
  54. mouseTail[i].active = false;
  55. }
  56. smoke = LoadTexture("resources/smoke.png");
  57. #if defined(PLATFORM_WEB)
  58. emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
  59. #else
  60. SetTargetFPS(60); // Set our game to run at 60 frames-per-second
  61. //--------------------------------------------------------------------------------------
  62. // Main game loop
  63. while (!WindowShouldClose()) // Detect window close button or ESC key
  64. {
  65. UpdateDrawFrame();
  66. }
  67. #endif
  68. // De-Initialization
  69. //--------------------------------------------------------------------------------------
  70. UnloadTexture(smoke); // Texture unloading
  71. CloseWindow(); // Close window and OpenGL context
  72. //--------------------------------------------------------------------------------------
  73. return 0;
  74. }
  75. //----------------------------------------------------------------------------------
  76. // Module Functions Definition
  77. //----------------------------------------------------------------------------------
  78. void UpdateDrawFrame(void)
  79. {
  80. // Update
  81. //----------------------------------------------------------------------------------
  82. // Activate one particle every frame and Update active particles
  83. // NOTE: Particles initial position should be mouse position when activated
  84. // NOTE: Particles fall down with gravity and rotation... and disappear after 2 seconds (alpha = 0)
  85. // NOTE: When a particle disappears, active = false and it can be reused.
  86. for (int i = 0; i < MAX_PARTICLES; i++)
  87. {
  88. if (!mouseTail[i].active)
  89. {
  90. mouseTail[i].active = true;
  91. mouseTail[i].alpha = 1.0f;
  92. mouseTail[i].position = GetMousePosition();
  93. i = MAX_PARTICLES;
  94. }
  95. }
  96. for (int i = 0; i < MAX_PARTICLES; i++)
  97. {
  98. if (mouseTail[i].active)
  99. {
  100. mouseTail[i].position.y += gravity;
  101. mouseTail[i].alpha -= 0.01f;
  102. if (mouseTail[i].alpha <= 0.0f) mouseTail[i].active = false;
  103. mouseTail[i].rotation += 5.0f;
  104. }
  105. }
  106. if (IsKeyPressed(KEY_SPACE))
  107. {
  108. if (blending == BLEND_ALPHA) blending = BLEND_ADDITIVE;
  109. else blending = BLEND_ALPHA;
  110. }
  111. //----------------------------------------------------------------------------------
  112. // Draw
  113. //----------------------------------------------------------------------------------
  114. BeginDrawing();
  115. ClearBackground(DARKGRAY);
  116. BeginBlendMode(blending);
  117. // Draw active particles
  118. for (int i = 0; i < MAX_PARTICLES; i++)
  119. {
  120. if (mouseTail[i].active) DrawTexturePro(smoke, (Rectangle){ 0, 0, smoke.width, smoke.height },
  121. (Rectangle){ mouseTail[i].position.x, mouseTail[i].position.y, smoke.width*mouseTail[i].size, smoke.height*mouseTail[i].size },
  122. (Vector2){ smoke.width*mouseTail[i].size/2, smoke.height*mouseTail[i].size/2 }, mouseTail[i].rotation,
  123. Fade(mouseTail[i].color, mouseTail[i].alpha));
  124. }
  125. EndBlendMode();
  126. DrawText("PRESS SPACE to CHANGE BLENDING MODE", 180, 20, 20, BLACK);
  127. if (blending == BLEND_ALPHA) DrawText("ALPHA BLENDING", 290, screenHeight - 40, 20, BLACK);
  128. else DrawText("ADDITIVE BLENDING", 280, screenHeight - 40, 20, RAYWHITE);
  129. EndDrawing();
  130. //----------------------------------------------------------------------------------
  131. }