particles.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #include <r3d/r3d.h>
  2. #include <math.h>
  3. #define MAX_PARTICLES 4096
  4. typedef struct {
  5. Vector3 pos;
  6. Vector3 vel;
  7. float life;
  8. } Particle;
  9. int main(void)
  10. {
  11. // Initialize window
  12. InitWindow(800, 450, "[r3d] - Particles example");
  13. SetTargetFPS(60);
  14. // Initialize R3D
  15. R3D_Init(GetScreenWidth(), GetScreenHeight());
  16. // Set environment
  17. R3D_ENVIRONMENT_SET(background.color, (Color){4, 4, 4});
  18. R3D_ENVIRONMENT_SET(bloom.mode, R3D_BLOOM_ADDITIVE);
  19. // Generate a gradient as emission texture for our particles
  20. Image image = GenImageGradientRadial(64, 64, 0.0f, WHITE, BLACK);
  21. Texture texture = LoadTextureFromImage(image);
  22. UnloadImage(image);
  23. // Generate a quad mesh for our particles
  24. R3D_Mesh mesh = R3D_GenMeshQuad(0.25f, 0.25f, 1, 1, (Vector3){0, 0, 1});
  25. // Setup particle material
  26. R3D_Material material = R3D_GetDefaultMaterial();
  27. material.billboardMode = R3D_BILLBOARD_FRONT;
  28. material.blendMode = R3D_BLEND_ADDITIVE;
  29. material.albedo.texture = R3D_GetBlackTexture();
  30. material.emission.color = (Color){255, 0, 0, 255};
  31. material.emission.texture = texture;
  32. material.emission.energy = 1.0f;
  33. // Create particle instance buffer
  34. R3D_InstanceBuffer instances = R3D_LoadInstanceBuffer(MAX_PARTICLES, R3D_INSTANCE_POSITION);
  35. // Setup camera
  36. Camera3D camera = {
  37. .position = {-7, 7, -7},
  38. .target = {0, 1, 0},
  39. .up = {0, 1, 0},
  40. .fovy = 60.0f,
  41. .projection = CAMERA_PERSPECTIVE
  42. };
  43. // CPU buffer for storing particles
  44. Particle particles[MAX_PARTICLES] = {0};
  45. Vector3 positions[MAX_PARTICLES];
  46. int particleCount = 0;
  47. while (!WindowShouldClose())
  48. {
  49. float dt = GetFrameTime();
  50. UpdateCamera(&camera, CAMERA_ORBITAL);
  51. // Spawn particles
  52. for (int i = 0; i < 10; i++) {
  53. if (particleCount < MAX_PARTICLES) {
  54. float angle = GetRandomValue(0, 360) * DEG2RAD;
  55. particles[particleCount].pos = (Vector3){0, 0, 0};
  56. particles[particleCount].vel = (Vector3){
  57. cosf(angle) * GetRandomValue(20, 40) / 10.0f,
  58. GetRandomValue(60, 80) / 10.0f,
  59. sinf(angle) * GetRandomValue(20, 40) / 10.0f
  60. };
  61. particles[particleCount].life = 1.0f;
  62. particleCount++;
  63. }
  64. }
  65. // Update particles
  66. int alive = 0;
  67. for (int i = 0; i < particleCount; i++) {
  68. particles[i].vel.y -= 9.81f * dt;
  69. particles[i].pos.x += particles[i].vel.x * dt;
  70. particles[i].pos.y += particles[i].vel.y * dt;
  71. particles[i].pos.z += particles[i].vel.z * dt;
  72. particles[i].life -= dt * 0.5f;
  73. if (particles[i].life > 0) {
  74. positions[alive] = particles[i].pos;
  75. particles[alive] = particles[i];
  76. alive++;
  77. }
  78. }
  79. particleCount = alive;
  80. R3D_UploadInstances(instances, R3D_INSTANCE_POSITION, 0, particleCount, positions);
  81. BeginDrawing();
  82. R3D_Begin(camera);
  83. R3D_DrawMeshInstanced(mesh, material, instances, particleCount);
  84. R3D_End();
  85. DrawFPS(10, 10);
  86. EndDrawing();
  87. }
  88. R3D_UnloadInstanceBuffer(instances);
  89. R3D_UnloadMaterial(material);
  90. R3D_UnloadMesh(mesh);
  91. R3D_Close();
  92. CloseWindow();
  93. return 0;
  94. }