particle.c 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #include "particle.h"
  2. #include <stdlib.h>
  3. #include <SDL2/SDL_opengl.h>
  4. #include <SDL2/SDL.h>
  5. #include "dpi.h"
  6. particle_system particle_init(int count, int depth) {
  7. particle_set *sets = malloc(sizeof(particle_set) * depth);
  8. for (size_t i = 0; i < depth; ++i) {
  9. sets[i].current_lifetime = 1.f;
  10. sets[i].particles = malloc(sizeof(particle) * count);
  11. sets[i].particle_count = count;
  12. }
  13. return (particle_system) { sets, depth, 0 };
  14. }
  15. static void random_vector(float magnitude, float *x, float *y) {
  16. float angle = (rand() / (float)RAND_MAX) * 6.28;
  17. *x = cos(angle) * magnitude;
  18. *y = sin(angle) * magnitude;
  19. }
  20. void particle_push(particle_system *system, curve_function cf, float t_start, float t_end) {
  21. //OutputDebugString("Pushing onto particle system...\n");
  22. particle_set *set = system->particle_sets + system->current_set;
  23. set->current_lifetime = 0.f;
  24. for (size_t i = 0; i < set->particle_count; ++i) {
  25. float t_0_1 = i / (set->particle_count - 1.f);
  26. float t = t_start + t_0_1 * (t_end - t_start);
  27. cf(t, &set->particles[i].x, &set->particles[i].y);
  28. random_vector(2, &set->particles[i].dx, &set->particles[i].dy);
  29. set->particles[i].radius = (rand() / (float)RAND_MAX) * 0.4f + 0.8f;
  30. }
  31. system->current_set = (system->current_set + 1) % system->set_count;
  32. }
  33. void particle_update(particle_system *system) {
  34. for (size_t i = 0; i < system->set_count; ++i) {
  35. particle_set *ps = system->particle_sets + i;
  36. ps->current_lifetime += 1 / 24.f;
  37. for (size_t j = 0; j < ps->particle_count; ++j) {
  38. particle *p = ps->particles + j;
  39. p->x += dpi_x(p->dx);
  40. p->y += dpi_y(p->dy);
  41. }
  42. }
  43. }
  44. void particle_destroy(particle_system *system) {
  45. for (size_t i = 0; i < system->set_count; ++i) {
  46. free(system->particle_sets[i].particles);
  47. }
  48. free(system->particle_sets);
  49. }
  50. void particle_render(particle_system *system, float r, float g, float b, float alpha_multiplier) {
  51. //OutputDebugString("Rendering particles...\n");
  52. //char help[128];
  53. //SDL_snprintf(help, 128, "250: %f %f\n", system->particle_sets[0].particles[250].x, system->particle_sets[0].particles[250].y);
  54. //OutputDebugString(help);
  55. for (size_t i = 0; i < system->set_count; ++i) {
  56. particle_set *ps = system->particle_sets + i;
  57. float alpha = 1.f - ps->current_lifetime;
  58. alpha *= alpha_multiplier;
  59. float radius = dpi_x(1.2f - 0.6f * ps->current_lifetime);
  60. float rn = (1 - r) * ps->current_lifetime + r;
  61. float bn = (1 - b) * ps->current_lifetime + b;
  62. float gn = (1 - g) * ps->current_lifetime + g;
  63. glColor4f(rn, gn, bn, alpha);
  64. for (size_t j = 0; j < ps->particle_count; ++j) {
  65. particle *p = ps->particles + j;
  66. float r = p->radius * radius;
  67. /*glBegin(GL_TRIANGLE_FAN);
  68. glVertex2f(p->x, p->y);
  69. for (size_t step = 0; step <= 8; ++step) {
  70. glVertex2f(p->x + cos(step * 6.28 / 8) * radius, p->y + sin(step * 6.28 / 8) * radius);
  71. }
  72. glEnd();*/
  73. glBegin(GL_QUADS);
  74. glVertex2f(p->x - r, p->y);
  75. glVertex2f(p->x, p->y + r);
  76. glVertex2f(p->x + r, p->y);
  77. glVertex2f(p->x, p->y - r);
  78. glEnd();
  79. }
  80. }
  81. }