metasurf

view examples/metaballs/src/metaballs.c @ 1:dc0e882ec3f9

renamed example source file test.c -> metaballs.c
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 25 Oct 2011 07:57:07 +0300
parents examples/metaballs/src/test.c@7aa4627e492b
children 9ab057fba0c5
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include <assert.h>
6 #include <GL/glew.h>
7 #ifndef __APPLE__
8 #include <GL/glut.h>
9 #else
10 #include <GLUT/glut.h>
11 #endif
13 #include "cam.h"
14 #include "sdr.h"
15 #include "metasurf.h"
17 #define RES 38
19 struct metaball {
20 float energy;
21 float x, y, z;
22 } mball[] = {
23 {1.0, 0, 0, 0},
24 {0.25, 0.45, 0, 0.25},
25 {0.15, -0.3, 0.2, 0.1}
26 };
28 int num_mballs = sizeof mball / sizeof *mball;
30 float eval(float x, float y, float z);
31 float eval_cached(float x, float y, float z);
32 void vertex(float x, float y, float z);
33 void render(void);
34 void disp(void);
35 void reshape(int x, int y);
36 void keyb(unsigned char key, int x, int y);
37 void mouse(int bn, int state, int x, int y);
38 void motion(int x, int y);
39 void sball_button(int bn, int state);
40 void sball_motion(int x, int y, int z);
41 int parse_args(int argc, char **argv);
43 int stereo;
44 struct metasurface *msurf;
45 float threshold = 12;
46 unsigned int sdr;
47 int bidx = 1;
49 int main(int argc, char **argv)
50 {
51 float amb[] = {0, 0, 0, 0};
52 float lpos[] = {-0.2, 0.2, 1, 0};
54 glutInitWindowSize(1280, 720);
55 glutInit(&argc, argv);
57 if(parse_args(argc, argv) == -1) {
58 return 1;
59 }
60 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | (stereo ? GLUT_STEREO : 0));
61 glutCreateWindow("metasurf");
63 glutDisplayFunc(disp);
64 glutReshapeFunc(reshape);
65 glutKeyboardFunc(keyb);
66 glutMouseFunc(mouse);
67 glutMotionFunc(motion);
68 glutSpaceballButtonFunc(sball_button);
69 glutSpaceballMotionFunc(sball_motion);
71 glewInit();
73 glEnable(GL_CULL_FACE);
74 glEnable(GL_DEPTH_TEST);
76 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
78 glEnable(GL_LIGHTING);
79 glEnable(GL_LIGHT0);
80 glLightfv(GL_LIGHT0, GL_POSITION, lpos);
82 glEnable(GL_NORMALIZE);
84 cam_focus_dist(2.0);
85 cam_clip(0.1, 200.0);
86 cam_rotate(0, 0);
87 cam_dolly(2);
89 msurf = msurf_create();
90 msurf_eval_func(msurf, eval);
91 msurf_vertex_func(msurf, vertex);
92 msurf_threshold(msurf, threshold);
93 msurf_resolution(msurf, RES, RES, RES);
94 msurf_bounds(msurf, -1, -1, -1, 1, 1, 1);
96 glClearColor(0.8, 0.8, 0.8, 1.0);
98 if(!(sdr = create_program_load("sdr/vert.glsl", "sdr/frag.glsl"))) {
99 return 1;
100 }
102 glutMainLoop();
103 return 0;
104 }
106 float eval(float x, float y, float z)
107 {
108 int i;
109 float val = 0.0f;
111 for(i=0; i<num_mballs; i++) {
112 float dx = mball[i].x - x;
113 float dy = mball[i].y - y;
114 float dz = mball[i].z - z;
115 float dist_sq = dx * dx + dy * dy + dz * dz;
117 if(dist_sq < 1e-6) {
118 val += 100.0;
119 } else {
120 val += mball[i].energy / dist_sq;
121 }
122 }
123 return val;
124 }
126 void vertex(float x, float y, float z)
127 {
128 const float dt = 0.001;
129 float dfdx = eval(x - dt, y, z) - eval(x + dt, y, z);
130 float dfdy = eval(x, y - dt, z) - eval(x, y + dt, z);
131 float dfdz = eval(x, y, z - dt) - eval(x, y, z + dt);
133 glNormal3f(dfdx, dfdy, dfdz);
134 glVertex3f(x, y, z);
135 }
137 void render(void)
138 {
139 float kd[] = {0.7, 0.28, 0.2, 1.0};
140 float ks[] = {0.9, 0.9, 0.9, 1.0};
142 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, kd);
143 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, ks);
144 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60.0);
146 bind_program(sdr);
148 glBegin(GL_TRIANGLES);
149 msurf_polygonize(msurf);
150 glEnd();
152 assert(glGetError() == GL_NO_ERROR);
153 }
155 void disp(void)
156 {
157 if(stereo) {
158 glDrawBuffer(GL_BACK_LEFT);
159 }
161 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
163 glMatrixMode(GL_PROJECTION);
164 glLoadIdentity();
165 cam_stereo_proj_matrix(stereo ? CAM_LEFT : CAM_CENTER);
167 glMatrixMode(GL_MODELVIEW);
168 glLoadIdentity();
169 cam_stereo_view_matrix(stereo ? CAM_LEFT : CAM_CENTER);
171 render();
173 if(stereo) {
174 glDrawBuffer(GL_BACK_RIGHT);
175 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
177 glMatrixMode(GL_PROJECTION);
178 glLoadIdentity();
179 cam_stereo_proj_matrix(CAM_RIGHT);
181 glMatrixMode(GL_MODELVIEW);
182 glLoadIdentity();
183 cam_stereo_view_matrix(CAM_RIGHT);
185 render();
186 }
187 glutSwapBuffers();
188 }
190 void reshape(int x, int y)
191 {
192 glViewport(0, 0, x, y);
193 cam_aspect((float)x / (float)y);
194 }
196 void keyb(unsigned char key, int x, int y)
197 {
198 static int wire;
200 switch(key) {
201 case 27:
202 exit(0);
204 case 's':
205 stereo = !stereo;
206 glutPostRedisplay();
207 break;
209 case 'w':
210 wire = !wire;
211 glPolygonMode(GL_FRONT_AND_BACK, wire ? GL_LINE : GL_FILL);
212 glutPostRedisplay();
213 break;
215 case '=':
216 threshold += 0.05;
217 msurf_threshold(msurf, threshold);
218 printf("threshold: %f\n", threshold);
219 glutPostRedisplay();
220 break;
222 case '-':
223 threshold -= 0.05;
224 msurf_threshold(msurf, threshold);
225 printf("threshold: %f\n", threshold);
226 glutPostRedisplay();
227 break;
229 case ' ':
230 bidx = (bidx + 1) % num_mballs;
231 break;
233 default:
234 break;
235 }
236 }
238 int bnstate[32];
239 int prev_x, prev_y;
241 void mouse(int bn, int state, int x, int y)
242 {
243 bnstate[bn] = state == GLUT_DOWN;
244 prev_x = x;
245 prev_y = y;
246 }
248 void motion(int x, int y)
249 {
250 int dx, dy;
252 dx = x - prev_x;
253 dy = y - prev_y;
254 prev_x = x;
255 prev_y = y;
257 if(bnstate[GLUT_LEFT_BUTTON]) {
258 cam_inp_rotate(dx, dy);
259 glutPostRedisplay();
260 }
261 if(bnstate[GLUT_RIGHT_BUTTON]) {
262 cam_inp_zoom(dy);
263 glutPostRedisplay();
264 }
265 }
267 void sball_button(int bn, int state)
268 {
269 if(state) return;
271 if(bn < num_mballs) {
272 bidx = bn;
273 } else {
274 bidx = (bidx + 1) % num_mballs;
275 }
276 }
278 void sball_motion(int x, int y, int z)
279 {
280 mball[bidx].x += (float)x / 32768.0;
281 mball[bidx].y += (float)y / 32768.0;
282 mball[bidx].z -= (float)z / 32768.0;
283 glutPostRedisplay();
284 }
286 int parse_args(int argc, char **argv)
287 {
288 int i;
290 for(i=1; i<argc; i++) {
291 if(argv[i][0] == '-' && argv[i][2] == 0) {
292 switch(argv[i][1]) {
293 case 's':
294 stereo = !stereo;
295 break;
297 default:
298 fprintf(stderr, "unrecognized option: %s\n", argv[i]);
299 return -1;
300 }
301 } else {
302 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
303 return -1;
304 }
305 }
306 return 0;
307 }