# HG changeset patch # User John Tsiombikas # Date 1317170521 -10800 # Node ID 9c24273f211bd0b44d10aeb4320e7ddbb57860c3 # Parent a10f1967414793a593bda82d071fbe6ee955d6af first test is done diff -r a10f19674147 -r 9c24273f211b Makefile.in --- a/Makefile.in Tue Sep 27 21:47:27 2011 +0300 +++ b/Makefile.in Wed Sep 28 03:42:01 2011 +0300 @@ -18,7 +18,7 @@ CC = gcc AR = ar -CFLAGS = -std=c89 -pedantic -Wall -g -fPIC -Isrc +CFLAGS = -std=c89 -pedantic -Wall $(dbg) $(opt) -fPIC -Isrc LDFLAGS = -lanim -limago -lvmath .PHONY: all diff -r a10f19674147 -r 9c24273f211b configure --- a/configure Tue Sep 27 21:47:27 2011 +0300 +++ b/configure Wed Sep 28 03:42:01 2011 +0300 @@ -63,9 +63,4 @@ fi cat Makefile.in >>Makefile -echo 'creating pkg-config file ...' -echo "prefix=$PREFIX" >psys.pc -echo "ver=$VERSION" >>psys.pc -cat psys.pc.in >>psys.pc - echo 'configuration completed, type make (or gmake) to build.' diff -r a10f19674147 -r 9c24273f211b examples/simple/simple.c --- a/examples/simple/simple.c Tue Sep 27 21:47:27 2011 +0300 +++ b/examples/simple/simple.c Wed Sep 28 03:42:01 2011 +0300 @@ -25,6 +25,8 @@ struct psys_emitter *ps; unsigned int tex; +#define RATE 300.0 + int main(int argc, char **argv) { glutInitWindowSize(800, 600); @@ -49,11 +51,18 @@ if(!(ps = psys_create())) { return 1; } - psys_set_value3(&ps->attr.grav, 0, v3_cons(0, -9, 0)); + ps->attr.tex = tex; + ps->attr.drag = 2; + psys_set_value3(&ps->attr.grav, 0, v3_cons(0, -4, 0)); psys_set_anm_rnd(&ps->attr.life, 0, 2, 0); - psys_set_value3(&ps->attr.spawn_range, 0, v3_cons(0.2, 0.2, 0.2)); - psys_set_anm_rnd3(&ps->attr.dir, 0, v3_cons(0, 0, 0), v3_cons(2, 2, 2)); - ps->attr.tex = tex; + psys_set_value3(&ps->attr.spawn_range, 0, v3_cons(0.3, 0.3, 0.3)); + psys_set_anm_rnd3(&ps->attr.dir, 0, v3_cons(0, 0, 0), v3_cons(4, 4, 4)); + + psys_set_value3(&ps->attr.part_attr.color, 0, v3_cons(1.0, 0.6, 0.4)); + psys_set_value3(&ps->attr.part_attr.color, 1000, v3_cons(0.6, 0.3, 1.0)); + psys_set_value(&ps->attr.part_attr.alpha, 0, 1); + psys_set_value(&ps->attr.part_attr.alpha, 700, 1); + psys_set_value(&ps->attr.part_attr.alpha, 1000, 0); atexit(cleanup); @@ -111,7 +120,7 @@ { bnstate[bn - GLUT_LEFT_BUTTON] = state == GLUT_DOWN; if(bn == GLUT_LEFT_BUTTON) { - psys_set_value(&ps->attr.rate, 0, state == GLUT_DOWN ? 30.0 : 0.0); + psys_set_value(&ps->attr.rate, 0, state == GLUT_DOWN ? RATE : 0.0); psys_set_pos(ps, get_mouse_hit(x, y), 0); } } diff -r a10f19674147 -r 9c24273f211b src/pattr.c --- a/src/pattr.c Tue Sep 27 21:47:27 2011 +0300 +++ b/src/pattr.c Wed Sep 28 03:42:01 2011 +0300 @@ -5,6 +5,9 @@ #include "pattr.h" #include "psys_gl.h" +static int init_particle_attr(struct psys_particle_attributes *pattr); +static void destroy_particle_attr(struct psys_particle_attributes *pattr); + static void *tex_cls; static unsigned int (*load_texture)(const char*, void*) = psys_gl_load_texture; static void (*unload_texture)(unsigned int, void*) = psys_gl_unload_texture; @@ -33,6 +36,9 @@ if(psys_init_track3(&attr->grav) == -1) goto err; + if(init_particle_attr(&attr->part_attr) == -1) + goto err; + attr->max_particles = -1; anm_set_track_default(&attr->size.value.trk, 1.0); @@ -45,6 +51,31 @@ return -1; } + +static int init_particle_attr(struct psys_particle_attributes *pattr) +{ + if(psys_init_track3(&pattr->color) == -1) { + return -1; + } + if(psys_init_track(&pattr->alpha) == -1) { + psys_destroy_track3(&pattr->color); + return -1; + } + if(psys_init_track(&pattr->size) == -1) { + psys_destroy_track3(&pattr->color); + psys_destroy_track(&pattr->alpha); + return -1; + } + + anm_set_track_default(&pattr->color.x, 1.0); + anm_set_track_default(&pattr->color.y, 1.0); + anm_set_track_default(&pattr->color.z, 1.0); + anm_set_track_default(&pattr->alpha.trk, 1.0); + anm_set_track_default(&pattr->size.trk, 1.0); + return 0; +} + + void psys_destroy_attr(struct psys_attributes *attr) { psys_destroy_track3(&attr->spawn_range); @@ -54,11 +85,20 @@ psys_destroy_anm_rnd3(&attr->dir); psys_destroy_track3(&attr->grav); + destroy_particle_attr(&attr->part_attr); + if(attr->tex && unload_texture) { unload_texture(attr->tex, tex_cls); } } +static void destroy_particle_attr(struct psys_particle_attributes *pattr) +{ + psys_destroy_track3(&pattr->color); + psys_destroy_track(&pattr->alpha); + psys_destroy_track(&pattr->size); +} + void psys_eval_attr(struct psys_attributes *attr, anm_time_t tm) { psys_eval_track3(&attr->spawn_range, tm); diff -r a10f19674147 -r 9c24273f211b src/pattr.h --- a/src/pattr.h Tue Sep 27 21:47:27 2011 +0300 +++ b/src/pattr.h Wed Sep 28 03:42:01 2011 +0300 @@ -4,6 +4,13 @@ #include "pstrack.h" #include "rndval.h" +/* the particle attributes vary from 0 to 1 during its lifetime */ +struct psys_particle_attributes { + struct psys_track3 color; + struct psys_track alpha; + struct psys_track size; +}; + struct psys_attributes { unsigned int tex; /* OpenGL texture to use for the billboard */ @@ -14,8 +21,10 @@ struct psys_anm_rnd3 dir; /* particle shoot direction */ struct psys_track3 grav; /* external force (usually gravity) */ + float drag; /* I don't think this needs to animate */ - float drag; /* I don't think this needs to animate */ + /* particle attributes */ + struct psys_particle_attributes part_attr; /* limits */ int max_particles; diff -r a10f19674147 -r 9c24273f211b src/psys.c --- a/src/psys.c Tue Sep 27 21:47:27 2011 +0300 +++ b/src/psys.c Wed Sep 28 03:42:01 2011 +0300 @@ -204,6 +204,7 @@ struct psys_particle *tmp = p->next; p->next = p->next->next; pfree(tmp); + em->pcount--; } else { p = p->next; } @@ -211,6 +212,8 @@ em->plist = pdummy.next; em->last_update = tm; + + printf("particles: %5d\r", em->pcount); } void psys_draw(struct psys_emitter *em) @@ -240,8 +243,10 @@ p->pos = psys_eval_rnd3(&rpos); p->vel = psys_eval_anm_rnd3(&em->attr.dir, PSYS_EVAL_CUR); - p->size = psys_eval_anm_rnd(&em->attr.size, PSYS_EVAL_CUR); - p->life = psys_eval_anm_rnd(&em->attr.life, PSYS_EVAL_CUR); + p->base_size = psys_eval_anm_rnd(&em->attr.size, PSYS_EVAL_CUR); + p->max_life = p->life = psys_eval_anm_rnd(&em->attr.life, PSYS_EVAL_CUR); + + p->pattr = &em->attr.part_attr; psys_add_particle(em, p); return 0; @@ -250,6 +255,7 @@ static void update_particle(struct psys_emitter *em, struct psys_particle *p, float tm, float dt, void *cls) { vec3_t accel, grav; + anm_time_t t; grav = psys_get_cur_value3(&em->attr.grav); @@ -265,6 +271,13 @@ p->pos.y += p->vel.y * dt; p->pos.z += p->vel.z * dt; + /* update particle attributes */ + t = (anm_time_t)(1000.0 * (p->max_life - p->life) / p->max_life); + + p->color = psys_get_value3(&p->pattr->color, t); + p->alpha = psys_get_value(&p->pattr->alpha, t); + p->size = p->base_size * psys_get_value(&p->pattr->size, t); + p->life -= dt; } diff -r a10f19674147 -r 9c24273f211b src/psys.h --- a/src/psys.h Tue Sep 27 21:47:27 2011 +0300 +++ b/src/psys.h Wed Sep 28 03:42:01 2011 +0300 @@ -58,7 +58,14 @@ struct psys_particle { vec3_t pos, vel; - float life, size; + float life, max_life; + float base_size; + + struct psys_particle_attributes *pattr; + + /* current particle attr values calculated during update */ + vec3_t color; + float alpha, size; struct psys_particle *next; }; diff -r a10f19674147 -r 9c24273f211b src/psys_gl.c --- a/src/psys_gl.c Tue Sep 27 21:47:27 2011 +0300 +++ b/src/psys_gl.c Wed Sep 28 03:42:01 2011 +0300 @@ -49,6 +49,8 @@ { float hsz = p->size / 2.0; + glColor4f(p->color.x, p->color.y, p->color.z, p->alpha); + glTexCoord2f(0, 0); glVertex3f(p->pos.x - hsz, p->pos.y - hsz, p->pos.z);