nuclear@1: #include nuclear@1: #include nuclear@2: #include nuclear@1: nuclear@1: #ifndef __APPLE__ nuclear@1: #include nuclear@1: #else nuclear@1: #include nuclear@1: #endif nuclear@1: nuclear@1: #include nuclear@2: #include nuclear@1: #include "psys.h" nuclear@1: nuclear@8: void cleanup(void); nuclear@1: void disp(void); nuclear@1: void idle(void); nuclear@1: void reshape(int x, int y); nuclear@1: void keyb(unsigned char key, int x, int y); nuclear@1: void mouse(int bn, int state, int x, int y); nuclear@1: void motion(int x, int y); nuclear@1: vec3_t get_mouse_hit(float x, float y); nuclear@2: unsigned int load_texture(const char *fname); nuclear@1: nuclear@1: struct psys_emitter *ps; nuclear@2: unsigned int tex; nuclear@1: nuclear@9: #define RATE 300.0 nuclear@9: nuclear@1: int main(int argc, char **argv) nuclear@1: { nuclear@1: glutInitWindowSize(800, 600); nuclear@1: glutInit(&argc, argv); nuclear@1: glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); nuclear@1: glutCreateWindow("libpsys example: simple"); nuclear@1: nuclear@1: glutDisplayFunc(disp); nuclear@1: glutReshapeFunc(reshape); nuclear@1: glutKeyboardFunc(keyb); nuclear@1: glutMouseFunc(mouse); nuclear@1: glutMotionFunc(motion); nuclear@1: glutIdleFunc(idle); nuclear@1: nuclear@2: glClearColor(0.05, 0.05, 0.05, 1); nuclear@2: nuclear@2: if(!(tex = load_texture("pimg.png"))) { nuclear@8: fprintf(stderr, "failed to load the texture\n"); nuclear@2: return 1; nuclear@2: } nuclear@1: nuclear@1: if(!(ps = psys_create())) { nuclear@1: return 1; nuclear@1: } nuclear@9: ps->attr.tex = tex; nuclear@9: ps->attr.drag = 2; nuclear@9: psys_set_value3(&ps->attr.grav, 0, v3_cons(0, -4, 0)); nuclear@8: psys_set_anm_rnd(&ps->attr.life, 0, 2, 0); nuclear@9: psys_set_value3(&ps->attr.spawn_range, 0, v3_cons(0.3, 0.3, 0.3)); nuclear@9: psys_set_anm_rnd3(&ps->attr.dir, 0, v3_cons(0, 0, 0), v3_cons(4, 4, 4)); nuclear@9: nuclear@9: psys_set_value3(&ps->attr.part_attr.color, 0, v3_cons(1.0, 0.6, 0.4)); nuclear@9: psys_set_value3(&ps->attr.part_attr.color, 1000, v3_cons(0.6, 0.3, 1.0)); nuclear@9: psys_set_value(&ps->attr.part_attr.alpha, 0, 1); nuclear@9: psys_set_value(&ps->attr.part_attr.alpha, 700, 1); nuclear@9: psys_set_value(&ps->attr.part_attr.alpha, 1000, 0); nuclear@8: nuclear@8: atexit(cleanup); nuclear@1: nuclear@1: glutMainLoop(); nuclear@1: return 0; nuclear@1: } nuclear@1: nuclear@8: void cleanup(void) nuclear@8: { nuclear@8: psys_free(ps); nuclear@8: } nuclear@8: nuclear@1: void disp(void) nuclear@1: { nuclear@1: static unsigned int prev_msec; nuclear@1: unsigned int msec = glutGet(GLUT_ELAPSED_TIME); nuclear@1: nuclear@1: glMatrixMode(GL_MODELVIEW); nuclear@1: glLoadIdentity(); nuclear@1: glTranslatef(0, 0, -10); nuclear@1: nuclear@1: glClear(GL_COLOR_BUFFER_BIT); nuclear@1: nuclear@1: psys_update(ps, (msec - prev_msec) / 1000.0); nuclear@1: psys_draw(ps); nuclear@1: nuclear@1: glutSwapBuffers(); nuclear@2: assert(glGetError() == GL_NO_ERROR); nuclear@1: } nuclear@1: nuclear@1: void idle(void) nuclear@1: { nuclear@1: glutPostRedisplay(); nuclear@1: } nuclear@1: nuclear@1: void reshape(int x, int y) nuclear@1: { nuclear@1: glViewport(0, 0, x, y); nuclear@1: nuclear@1: glMatrixMode(GL_PROJECTION); nuclear@1: glLoadIdentity(); nuclear@1: gluPerspective(45.0, (float)x / (float)y, 1.0, 1000.0); nuclear@1: } nuclear@1: nuclear@1: void keyb(unsigned char key, int x, int y) nuclear@1: { nuclear@1: switch(key) { nuclear@1: case 27: nuclear@1: exit(0); nuclear@1: } nuclear@1: } nuclear@1: nuclear@1: static int bnstate[32]; nuclear@1: void mouse(int bn, int state, int x, int y) nuclear@1: { nuclear@1: bnstate[bn - GLUT_LEFT_BUTTON] = state == GLUT_DOWN; nuclear@1: if(bn == GLUT_LEFT_BUTTON) { nuclear@9: psys_set_value(&ps->attr.rate, 0, state == GLUT_DOWN ? RATE : 0.0); nuclear@1: psys_set_pos(ps, get_mouse_hit(x, y), 0); nuclear@1: } nuclear@1: } nuclear@1: nuclear@1: void motion(int x, int y) nuclear@1: { nuclear@1: if(bnstate[0]) { nuclear@1: psys_set_pos(ps, get_mouse_hit(x, y), 0); nuclear@1: } nuclear@1: } nuclear@1: nuclear@1: vec3_t get_mouse_hit(float x, float y) nuclear@1: { nuclear@1: double mv[16], proj[16]; nuclear@1: int vp[4]; nuclear@1: double res_x, res_y, res_z; nuclear@1: float t; nuclear@1: vec3_t res, pnear, pfar; nuclear@1: nuclear@1: glGetDoublev(GL_MODELVIEW_MATRIX, mv); nuclear@1: glGetDoublev(GL_PROJECTION_MATRIX, proj); nuclear@1: glGetIntegerv(GL_VIEWPORT, vp); nuclear@1: nuclear@1: y = vp[3] - y; nuclear@1: nuclear@1: gluUnProject(x, y, 0, mv, proj, vp, &res_x, &res_y, &res_z); nuclear@1: pnear.x = res_x; nuclear@1: pnear.y = res_y; nuclear@1: pnear.z = res_z; nuclear@1: nuclear@1: gluUnProject(x, y, 1, mv, proj, vp, &res_x, &res_y, &res_z); nuclear@1: pfar.x = res_x; nuclear@1: pfar.y = res_y; nuclear@1: pfar.z = res_z; nuclear@1: nuclear@1: t = fabs(pnear.z) / fabs(pfar.z - pnear.z); nuclear@1: res = v3_add(pnear, v3_scale(v3_sub(pfar, pnear), t)); nuclear@1: nuclear@1: return res; nuclear@1: } nuclear@2: nuclear@2: unsigned int load_texture(const char *fname) nuclear@2: { nuclear@2: void *pixels; nuclear@2: int xsz, ysz; nuclear@2: unsigned int tex; nuclear@2: nuclear@2: if(!(pixels = img_load_pixels(fname, &xsz, &ysz, IMG_FMT_RGBA32))) { nuclear@2: return 0; nuclear@2: } nuclear@2: nuclear@2: glGenTextures(1, &tex); nuclear@2: glBindTexture(GL_TEXTURE_2D, tex); nuclear@2: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); nuclear@2: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); nuclear@2: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); nuclear@2: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); nuclear@2: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); nuclear@2: img_free_pixels(pixels); nuclear@2: nuclear@2: return tex; nuclear@2: }