4 #include <cgmath/cgmath.h>
16 #define BBOX_HXSZ (BBOX_XSZ / 2.0f)
17 #define BBOX_HYSZ (BBOX_YSZ / 2.0f)
18 #define BBOX_HZSZ (BBOX_ZSZ / 2.0f)
20 #define VBUF_MAX_TRIS 512
21 #define VBUF_COUNT (VBUF_MAX_TRIS * 3)
24 static void set_voxel_res(int sz);
25 static void draw_metaballs(void);
26 static void gen_default_textures(void);
28 static unsigned int sdr_foo;
29 static unsigned int tex_logo;
30 static int prev_mx, prev_my;
32 static int vox_res, vox_xres, vox_yres, vox_zres;
33 static float vox_xstep, vox_ystep, vox_zstep;
35 static struct metasurface *msurf;
36 static struct mobject *mobj;
38 static int mousebn[3];
39 static int mousex, mousey;
40 static float cam_theta, cam_phi;
42 static unsigned int metavbo[2];
43 static int cur_metavbo;
50 if(init_opengl() == -1) {
53 if(init_assman() == -1) {
57 if(init_music() == -1) {
61 /* global "debug" shader which just visualizes normals */
62 if(!(sdr_dbg = get_sdrprog("sdr/dbg.v.glsl", "sdr/dbg.p.glsl"))) {
65 cmesh_bind_sdrloc(sdr_dbg);
67 gen_default_textures();
69 if(!(sdr_foo = get_sdrprog("sdr/foo.v.glsl", "sdr/foo.p.glsl"))) {
72 if(!(tex_logo = get_tex2d("data/ml_logo_old.png"))) {
75 glBindTexture(GL_TEXTURE_2D, tex_logo);
76 glUseProgram(sdr_foo);
90 glEnable(GL_CULL_FACE);
91 glEnable(GL_DEPTH_TEST);
94 vox_res = DEF_VOX_RES;
95 if(!(msurf = msurf_create())) {
98 msurf_set_threshold(msurf, 8);
99 msurf_set_inside(msurf, MSURF_GREATER);
100 msurf_set_bounds(msurf, -BBOX_HXSZ, -BBOX_HYSZ, -BBOX_HZSZ, BBOX_HXSZ, BBOX_HYSZ, BBOX_HZSZ);
101 set_voxel_res(vox_res);
102 msurf_enable(msurf, MSURF_NORMALIZE);
104 glGenBuffers(2, metavbo);
106 glBindBuffer(GL_ARRAY_BUFFER, metavbo[i]);
107 glBufferData(GL_ARRAY_BUFFER, VBUF_COUNT * 6 * sizeof(float), 0, GL_STREAM_DRAW);
110 mobj = malloc(sizeof *mobj);
111 mobj = metaobj_sflake();
116 void demo_cleanup(void)
118 glDeleteBuffers(2, metavbo);
123 glDeleteTextures(1, &deftex_white);
124 glDeleteTextures(1, &deftex_black);
125 glDeleteTextures(1, &deftex_normal);
128 static void set_voxel_res(int sz)
131 vox_xres = vox_res * BBOX_XSZ / BBOX_ZSZ;
132 vox_yres = vox_res * BBOX_YSZ / BBOX_ZSZ;
134 vox_xstep = (float)BBOX_XSZ / (float)vox_xres;
135 vox_ystep = (float)BBOX_YSZ / (float)vox_yres;
136 vox_zstep = (float)BBOX_ZSZ / (float)vox_zres;
139 msurf_set_resolution(msurf, vox_xres, vox_yres, vox_zres);
143 static void update(float tsec)
148 float *vox = msurf_voxels(msurf);
150 mobj->update(mobj, tsec);
152 for(i=0; i<vox_zres; i++) {
153 pos.z = -BBOX_HZSZ + i * vox_zstep;
154 for(j=0; j<vox_yres; j++) {
155 pos.y = -BBOX_HYSZ + j * vox_ystep;
156 for(k=0; k<vox_xres; k++) {
157 pos.x = -BBOX_HXSZ + k * vox_xstep;
159 /* initialize with the vertical distance for the pool */
160 energy = 5.0 / (pos.y + BBOX_HYSZ);
161 /*energy += 5.0 / (pos.x + BBOX_HXSZ);
162 energy += 5.0 / (BBOX_HXSZ - pos.x);*/
164 energy += mobj->eval(mobj, &pos);
171 msurf_polygonize(msurf);
174 void demo_display(void)
178 time_msec = sys_time - start_time;
179 tsec = (float)time_msec / 1000.0f;
183 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
185 gl_matrix_mode(GL_MODELVIEW);
187 gl_translatef(0, 1, -18);
188 gl_rotatef(cam_phi, 1, 0, 0);
189 gl_rotatef(cam_theta, 0, 1, 0);
192 gl_translatef(0.5f * BBOX_XSZ / vox_xres, 0, 0.5f * BBOX_ZSZ / vox_zres);
198 static void draw_metaballs(void)
200 int nverts, vcount, szbytes;
202 static int vloc = -1, nloc;
204 bind_program(sdr_dbg);
205 gl_apply_xform(sdr_dbg);
208 if((vloc = glGetAttribLocation(sdr_dbg, "attr_vertex")) == -1) {
211 nloc = glGetAttribLocation(sdr_dbg, "attr_normal");
214 nverts = msurf_vertex_count(msurf);
215 varr = msurf_vertices(msurf);
216 narr = msurf_normals(msurf);
218 glEnableVertexAttribArray(vloc);
219 glEnableVertexAttribArray(nloc);
222 vcount = nverts > VBUF_COUNT ? VBUF_COUNT : nverts;
224 szbytes = vcount * 3 * sizeof(float);
226 glBindBuffer(GL_ARRAY_BUFFER, metavbo[cur_metavbo]);
227 cur_metavbo = (cur_metavbo + 1) & 1;
228 glBufferSubData(GL_ARRAY_BUFFER, 0, szbytes, varr);
229 glBufferSubData(GL_ARRAY_BUFFER, szbytes, szbytes, narr);
233 glVertexAttribPointer(vloc, 3, GL_FLOAT, 0, 0, 0);
234 glVertexAttribPointer(nloc, 3, GL_FLOAT, 0, 0, (void*)(intptr_t)szbytes);
236 glDrawArrays(GL_TRIANGLES, 0, vcount);
239 glDisableVertexAttribArray(vloc);
240 glDisableVertexAttribArray(nloc);
243 void demo_reshape(int x, int y)
245 glViewport(0, 0, x, y);
248 win_aspect = (float)x / (float)y;
250 gl_matrix_mode(GL_PROJECTION);
252 glu_perspective(50.0, win_aspect, 0.5, 500.0);
255 void demo_keyboard(int key, int pressed)
260 void demo_mouse(int bn, int pressed, int x, int y)
262 mousebn[bn] = pressed;
268 if(y > 3 * win_height / 4) {
269 mobj->swstate(mobj, MOBJ_GRABING);
272 mobj->swstate(mobj, MOBJ_DROPPING);
277 void demo_motion(int x, int y)
292 mobj->pos.x += dx * 0.03;
293 mobj->pos.y -= dy * 0.03;
296 u = (float)x / (float)win_width;
297 v = (float)y / (float)win_height;
298 cam_theta = cgm_lerp(-15, 15, u);
299 cam_phi = cgm_lerp(-10, 25, v);
302 static void gen_default_textures(void)
304 static const uint32_t col[] = {0xff000000, 0xffffffff, 0xffff7f7f};
308 glGenTextures(3, tex);
310 glBindTexture(GL_TEXTURE_2D, tex[i]);
311 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
312 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
313 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, col + i);
316 deftex_black = tex[0];
317 deftex_white = tex[1];
318 deftex_normal = tex[2];