rev |
line source |
nuclear@1
|
1 #include <stdio.h>
|
nuclear@1
|
2 #include <stdlib.h>
|
nuclear@2
|
3 #include <assert.h>
|
nuclear@1
|
4
|
nuclear@1
|
5 #ifndef __APPLE__
|
nuclear@1
|
6 #include <GL/glut.h>
|
nuclear@1
|
7 #else
|
nuclear@1
|
8 #include <GLUT/glut.h>
|
nuclear@1
|
9 #endif
|
nuclear@1
|
10
|
nuclear@1
|
11 #include <vmath.h>
|
nuclear@2
|
12 #include <imago2.h>
|
nuclear@1
|
13 #include "psys.h"
|
nuclear@1
|
14
|
nuclear@8
|
15 void cleanup(void);
|
nuclear@1
|
16 void disp(void);
|
nuclear@1
|
17 void idle(void);
|
nuclear@1
|
18 void reshape(int x, int y);
|
nuclear@1
|
19 void keyb(unsigned char key, int x, int y);
|
nuclear@1
|
20 void mouse(int bn, int state, int x, int y);
|
nuclear@1
|
21 void motion(int x, int y);
|
nuclear@1
|
22 vec3_t get_mouse_hit(float x, float y);
|
nuclear@2
|
23 unsigned int load_texture(const char *fname);
|
nuclear@1
|
24
|
nuclear@1
|
25 struct psys_emitter *ps;
|
nuclear@2
|
26 unsigned int tex;
|
nuclear@1
|
27
|
nuclear@9
|
28 #define RATE 300.0
|
nuclear@9
|
29
|
nuclear@1
|
30 int main(int argc, char **argv)
|
nuclear@1
|
31 {
|
nuclear@1
|
32 glutInitWindowSize(800, 600);
|
nuclear@1
|
33 glutInit(&argc, argv);
|
nuclear@1
|
34 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
|
nuclear@1
|
35 glutCreateWindow("libpsys example: simple");
|
nuclear@1
|
36
|
nuclear@1
|
37 glutDisplayFunc(disp);
|
nuclear@1
|
38 glutReshapeFunc(reshape);
|
nuclear@1
|
39 glutKeyboardFunc(keyb);
|
nuclear@1
|
40 glutMouseFunc(mouse);
|
nuclear@1
|
41 glutMotionFunc(motion);
|
nuclear@1
|
42 glutIdleFunc(idle);
|
nuclear@1
|
43
|
nuclear@2
|
44 glClearColor(0.05, 0.05, 0.05, 1);
|
nuclear@2
|
45
|
nuclear@2
|
46 if(!(tex = load_texture("pimg.png"))) {
|
nuclear@8
|
47 fprintf(stderr, "failed to load the texture\n");
|
nuclear@2
|
48 return 1;
|
nuclear@2
|
49 }
|
nuclear@1
|
50
|
nuclear@1
|
51 if(!(ps = psys_create())) {
|
nuclear@1
|
52 return 1;
|
nuclear@1
|
53 }
|
nuclear@16
|
54 if(psys_load_attr(&ps->attr, "simple.psys") == -1) {
|
nuclear@16
|
55 fprintf(stderr, "failed to load particle system definition\n");
|
nuclear@16
|
56 psys_free(ps);
|
nuclear@16
|
57 return 1;
|
nuclear@16
|
58 }
|
nuclear@16
|
59 /*ps->attr.tex = tex;
|
nuclear@9
|
60 ps->attr.drag = 2;
|
nuclear@9
|
61 psys_set_value3(&ps->attr.grav, 0, v3_cons(0, -4, 0));
|
nuclear@8
|
62 psys_set_anm_rnd(&ps->attr.life, 0, 2, 0);
|
nuclear@9
|
63 psys_set_value3(&ps->attr.spawn_range, 0, v3_cons(0.3, 0.3, 0.3));
|
nuclear@9
|
64 psys_set_anm_rnd3(&ps->attr.dir, 0, v3_cons(0, 0, 0), v3_cons(4, 4, 4));
|
nuclear@9
|
65
|
nuclear@9
|
66 psys_set_value3(&ps->attr.part_attr.color, 0, v3_cons(1.0, 0.6, 0.4));
|
nuclear@9
|
67 psys_set_value3(&ps->attr.part_attr.color, 1000, v3_cons(0.6, 0.3, 1.0));
|
nuclear@9
|
68 psys_set_value(&ps->attr.part_attr.alpha, 0, 1);
|
nuclear@9
|
69 psys_set_value(&ps->attr.part_attr.alpha, 700, 1);
|
nuclear@16
|
70 psys_set_value(&ps->attr.part_attr.alpha, 1000, 0);*/
|
nuclear@8
|
71
|
nuclear@16
|
72 assert(glGetError() == GL_NO_ERROR);
|
nuclear@8
|
73 atexit(cleanup);
|
nuclear@1
|
74
|
nuclear@1
|
75 glutMainLoop();
|
nuclear@1
|
76 return 0;
|
nuclear@1
|
77 }
|
nuclear@1
|
78
|
nuclear@8
|
79 void cleanup(void)
|
nuclear@8
|
80 {
|
nuclear@8
|
81 psys_free(ps);
|
nuclear@8
|
82 }
|
nuclear@8
|
83
|
nuclear@1
|
84 void disp(void)
|
nuclear@1
|
85 {
|
nuclear@1
|
86 static unsigned int prev_msec;
|
nuclear@1
|
87 unsigned int msec = glutGet(GLUT_ELAPSED_TIME);
|
nuclear@1
|
88
|
nuclear@1
|
89 glMatrixMode(GL_MODELVIEW);
|
nuclear@1
|
90 glLoadIdentity();
|
nuclear@1
|
91 glTranslatef(0, 0, -10);
|
nuclear@1
|
92
|
nuclear@1
|
93 glClear(GL_COLOR_BUFFER_BIT);
|
nuclear@1
|
94
|
nuclear@1
|
95 psys_update(ps, (msec - prev_msec) / 1000.0);
|
nuclear@1
|
96 psys_draw(ps);
|
nuclear@1
|
97
|
nuclear@1
|
98 glutSwapBuffers();
|
nuclear@2
|
99 assert(glGetError() == GL_NO_ERROR);
|
nuclear@1
|
100 }
|
nuclear@1
|
101
|
nuclear@1
|
102 void idle(void)
|
nuclear@1
|
103 {
|
nuclear@1
|
104 glutPostRedisplay();
|
nuclear@1
|
105 }
|
nuclear@1
|
106
|
nuclear@1
|
107 void reshape(int x, int y)
|
nuclear@1
|
108 {
|
nuclear@1
|
109 glViewport(0, 0, x, y);
|
nuclear@1
|
110
|
nuclear@1
|
111 glMatrixMode(GL_PROJECTION);
|
nuclear@1
|
112 glLoadIdentity();
|
nuclear@1
|
113 gluPerspective(45.0, (float)x / (float)y, 1.0, 1000.0);
|
nuclear@1
|
114 }
|
nuclear@1
|
115
|
nuclear@1
|
116 void keyb(unsigned char key, int x, int y)
|
nuclear@1
|
117 {
|
nuclear@1
|
118 switch(key) {
|
nuclear@1
|
119 case 27:
|
nuclear@1
|
120 exit(0);
|
nuclear@1
|
121 }
|
nuclear@1
|
122 }
|
nuclear@1
|
123
|
nuclear@1
|
124 static int bnstate[32];
|
nuclear@1
|
125 void mouse(int bn, int state, int x, int y)
|
nuclear@1
|
126 {
|
nuclear@1
|
127 bnstate[bn - GLUT_LEFT_BUTTON] = state == GLUT_DOWN;
|
nuclear@1
|
128 if(bn == GLUT_LEFT_BUTTON) {
|
nuclear@9
|
129 psys_set_value(&ps->attr.rate, 0, state == GLUT_DOWN ? RATE : 0.0);
|
nuclear@1
|
130 psys_set_pos(ps, get_mouse_hit(x, y), 0);
|
nuclear@1
|
131 }
|
nuclear@1
|
132 }
|
nuclear@1
|
133
|
nuclear@1
|
134 void motion(int x, int y)
|
nuclear@1
|
135 {
|
nuclear@1
|
136 if(bnstate[0]) {
|
nuclear@1
|
137 psys_set_pos(ps, get_mouse_hit(x, y), 0);
|
nuclear@1
|
138 }
|
nuclear@1
|
139 }
|
nuclear@1
|
140
|
nuclear@1
|
141 vec3_t get_mouse_hit(float x, float y)
|
nuclear@1
|
142 {
|
nuclear@1
|
143 double mv[16], proj[16];
|
nuclear@1
|
144 int vp[4];
|
nuclear@1
|
145 double res_x, res_y, res_z;
|
nuclear@1
|
146 float t;
|
nuclear@1
|
147 vec3_t res, pnear, pfar;
|
nuclear@1
|
148
|
nuclear@1
|
149 glGetDoublev(GL_MODELVIEW_MATRIX, mv);
|
nuclear@1
|
150 glGetDoublev(GL_PROJECTION_MATRIX, proj);
|
nuclear@1
|
151 glGetIntegerv(GL_VIEWPORT, vp);
|
nuclear@1
|
152
|
nuclear@1
|
153 y = vp[3] - y;
|
nuclear@1
|
154
|
nuclear@1
|
155 gluUnProject(x, y, 0, mv, proj, vp, &res_x, &res_y, &res_z);
|
nuclear@1
|
156 pnear.x = res_x;
|
nuclear@1
|
157 pnear.y = res_y;
|
nuclear@1
|
158 pnear.z = res_z;
|
nuclear@1
|
159
|
nuclear@1
|
160 gluUnProject(x, y, 1, mv, proj, vp, &res_x, &res_y, &res_z);
|
nuclear@1
|
161 pfar.x = res_x;
|
nuclear@1
|
162 pfar.y = res_y;
|
nuclear@1
|
163 pfar.z = res_z;
|
nuclear@1
|
164
|
nuclear@1
|
165 t = fabs(pnear.z) / fabs(pfar.z - pnear.z);
|
nuclear@1
|
166 res = v3_add(pnear, v3_scale(v3_sub(pfar, pnear), t));
|
nuclear@1
|
167
|
nuclear@1
|
168 return res;
|
nuclear@1
|
169 }
|
nuclear@2
|
170
|
nuclear@2
|
171 unsigned int load_texture(const char *fname)
|
nuclear@2
|
172 {
|
nuclear@2
|
173 void *pixels;
|
nuclear@2
|
174 int xsz, ysz;
|
nuclear@2
|
175 unsigned int tex;
|
nuclear@2
|
176
|
nuclear@2
|
177 if(!(pixels = img_load_pixels(fname, &xsz, &ysz, IMG_FMT_RGBA32))) {
|
nuclear@2
|
178 return 0;
|
nuclear@2
|
179 }
|
nuclear@2
|
180
|
nuclear@2
|
181 glGenTextures(1, &tex);
|
nuclear@2
|
182 glBindTexture(GL_TEXTURE_2D, tex);
|
nuclear@2
|
183 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@2
|
184 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@2
|
185 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
nuclear@2
|
186 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
nuclear@2
|
187 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
nuclear@2
|
188 img_free_pixels(pixels);
|
nuclear@2
|
189
|
nuclear@2
|
190 return tex;
|
nuclear@2
|
191 }
|