metasurf
changeset 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 | 7aa4627e492b |
children | 9ab057fba0c5 |
files | README examples/metaballs/Makefile examples/metaballs/src/metaballs.c examples/metaballs/src/test.c |
diffstat | 4 files changed, 359 insertions(+), 310 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/README Tue Oct 25 07:57:07 2011 +0300 1.3 @@ -0,0 +1,49 @@ 1.4 +metasurf - a library for implicit surface polygonization 1.5 + 1.6 +1. Overview 1.7 +----------- 1.8 + 1.9 +Metasurf is a library for implict surface polygonization. You only need to 1.10 +set a callback that returns the scalar field value at any given point in 1.11 +3-space, and another callback to accept isosurface vertices. Then at any point 1.12 +just call msurf_polygonize, and the library handles everything else for you. 1.13 + 1.14 +2. Usage 1.15 +-------- 1.16 +The following snippet is sufficient to draw the surface of an implict sphere. 1.17 + 1.18 + struct metasurface *ms; 1.19 + 1.20 + /* initialization */ 1.21 + ms = msurf_create(); 1.22 + msurf_eval_func(ms, eval); 1.23 + msurf_vertex_func(ms, glVertex3f); 1.24 + 1.25 + /* drawing */ 1.26 + glBegin(GL_TRIANGLES); 1.27 + msurf_polygonize(ms); 1.28 + glEnd(); 1.29 + 1.30 + /* evaluator */ 1.31 + float eval(float x, float y, float z) 1.32 + { 1.33 + return x * x + y * y + z * z; 1.34 + } 1.35 + 1.36 +See the examples subdirectory for more examples. 1.37 + 1.38 +3. License 1.39 +---------- 1.40 +Copyright: John Tsiombikas <nuclear@member.fsf.org> 1.41 + 1.42 +Metasurf is free software, you may use, modify, and redistribute it freely under 1.43 +the terms of the GNU Lesser General Public License (LGPL) v3 (or at your option, 1.44 +any later version published by the Free Software Foundation). See COPYING and 1.45 +COPYING.LESSER for more details. 1.46 + 1.47 + 1.48 +4. Contributions 1.49 +---------------- 1.50 +If you'd like to fix the marching tetrahedra implementation or have any other 1.51 +ideas for improving this library drop me an email at: nuclear@member.fsf.org. 1.52 +Also feel free to submit patches for bugfixes.
2.1 --- a/examples/metaballs/Makefile Tue Oct 25 07:34:31 2011 +0300 2.2 +++ b/examples/metaballs/Makefile Tue Oct 25 07:57:07 2011 +0300 2.3 @@ -1,11 +1,11 @@ 2.4 src = $(wildcard src/*.c) 2.5 obj = $(src:.c=.o) 2.6 dep = $(obj:.o=.d) 2.7 -bin = metasurf 2.8 +bin = metaballs 2.9 2.10 CC = gcc 2.11 -CFLAGS = -pedantic -Wall -g -O3 2.12 -LDFLAGS = $(libgl) 2.13 +CFLAGS = -pedantic -Wall -g -I../../src 2.14 +LDFLAGS = -L../.. -lmetasurf $(libgl) 2.15 2.16 ifeq ($(shell uname -s), Darwin) 2.17 libgl = -framework OpenGL -framework GLUT -lGLEW
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/examples/metaballs/src/metaballs.c Tue Oct 25 07:57:07 2011 +0300 3.3 @@ -0,0 +1,307 @@ 3.4 +#include <stdio.h> 3.5 +#include <stdlib.h> 3.6 +#include <math.h> 3.7 +#include <assert.h> 3.8 + 3.9 +#include <GL/glew.h> 3.10 +#ifndef __APPLE__ 3.11 +#include <GL/glut.h> 3.12 +#else 3.13 +#include <GLUT/glut.h> 3.14 +#endif 3.15 + 3.16 +#include "cam.h" 3.17 +#include "sdr.h" 3.18 +#include "metasurf.h" 3.19 + 3.20 +#define RES 38 3.21 + 3.22 +struct metaball { 3.23 + float energy; 3.24 + float x, y, z; 3.25 +} mball[] = { 3.26 + {1.0, 0, 0, 0}, 3.27 + {0.25, 0.45, 0, 0.25}, 3.28 + {0.15, -0.3, 0.2, 0.1} 3.29 +}; 3.30 + 3.31 +int num_mballs = sizeof mball / sizeof *mball; 3.32 + 3.33 +float eval(float x, float y, float z); 3.34 +float eval_cached(float x, float y, float z); 3.35 +void vertex(float x, float y, float z); 3.36 +void render(void); 3.37 +void disp(void); 3.38 +void reshape(int x, int y); 3.39 +void keyb(unsigned char key, int x, int y); 3.40 +void mouse(int bn, int state, int x, int y); 3.41 +void motion(int x, int y); 3.42 +void sball_button(int bn, int state); 3.43 +void sball_motion(int x, int y, int z); 3.44 +int parse_args(int argc, char **argv); 3.45 + 3.46 +int stereo; 3.47 +struct metasurface *msurf; 3.48 +float threshold = 12; 3.49 +unsigned int sdr; 3.50 +int bidx = 1; 3.51 + 3.52 +int main(int argc, char **argv) 3.53 +{ 3.54 + float amb[] = {0, 0, 0, 0}; 3.55 + float lpos[] = {-0.2, 0.2, 1, 0}; 3.56 + 3.57 + glutInitWindowSize(1280, 720); 3.58 + glutInit(&argc, argv); 3.59 + 3.60 + if(parse_args(argc, argv) == -1) { 3.61 + return 1; 3.62 + } 3.63 + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | (stereo ? GLUT_STEREO : 0)); 3.64 + glutCreateWindow("metasurf"); 3.65 + 3.66 + glutDisplayFunc(disp); 3.67 + glutReshapeFunc(reshape); 3.68 + glutKeyboardFunc(keyb); 3.69 + glutMouseFunc(mouse); 3.70 + glutMotionFunc(motion); 3.71 + glutSpaceballButtonFunc(sball_button); 3.72 + glutSpaceballMotionFunc(sball_motion); 3.73 + 3.74 + glewInit(); 3.75 + 3.76 + glEnable(GL_CULL_FACE); 3.77 + glEnable(GL_DEPTH_TEST); 3.78 + 3.79 + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb); 3.80 + 3.81 + glEnable(GL_LIGHTING); 3.82 + glEnable(GL_LIGHT0); 3.83 + glLightfv(GL_LIGHT0, GL_POSITION, lpos); 3.84 + 3.85 + glEnable(GL_NORMALIZE); 3.86 + 3.87 + cam_focus_dist(2.0); 3.88 + cam_clip(0.1, 200.0); 3.89 + cam_rotate(0, 0); 3.90 + cam_dolly(2); 3.91 + 3.92 + msurf = msurf_create(); 3.93 + msurf_eval_func(msurf, eval); 3.94 + msurf_vertex_func(msurf, vertex); 3.95 + msurf_threshold(msurf, threshold); 3.96 + msurf_resolution(msurf, RES, RES, RES); 3.97 + msurf_bounds(msurf, -1, -1, -1, 1, 1, 1); 3.98 + 3.99 + glClearColor(0.8, 0.8, 0.8, 1.0); 3.100 + 3.101 + if(!(sdr = create_program_load("sdr/vert.glsl", "sdr/frag.glsl"))) { 3.102 + return 1; 3.103 + } 3.104 + 3.105 + glutMainLoop(); 3.106 + return 0; 3.107 +} 3.108 + 3.109 +float eval(float x, float y, float z) 3.110 +{ 3.111 + int i; 3.112 + float val = 0.0f; 3.113 + 3.114 + for(i=0; i<num_mballs; i++) { 3.115 + float dx = mball[i].x - x; 3.116 + float dy = mball[i].y - y; 3.117 + float dz = mball[i].z - z; 3.118 + float dist_sq = dx * dx + dy * dy + dz * dz; 3.119 + 3.120 + if(dist_sq < 1e-6) { 3.121 + val += 100.0; 3.122 + } else { 3.123 + val += mball[i].energy / dist_sq; 3.124 + } 3.125 + } 3.126 + return val; 3.127 +} 3.128 + 3.129 +void vertex(float x, float y, float z) 3.130 +{ 3.131 + const float dt = 0.001; 3.132 + float dfdx = eval(x - dt, y, z) - eval(x + dt, y, z); 3.133 + float dfdy = eval(x, y - dt, z) - eval(x, y + dt, z); 3.134 + float dfdz = eval(x, y, z - dt) - eval(x, y, z + dt); 3.135 + 3.136 + glNormal3f(dfdx, dfdy, dfdz); 3.137 + glVertex3f(x, y, z); 3.138 +} 3.139 + 3.140 +void render(void) 3.141 +{ 3.142 + float kd[] = {0.7, 0.28, 0.2, 1.0}; 3.143 + float ks[] = {0.9, 0.9, 0.9, 1.0}; 3.144 + 3.145 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, kd); 3.146 + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, ks); 3.147 + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60.0); 3.148 + 3.149 + bind_program(sdr); 3.150 + 3.151 + glBegin(GL_TRIANGLES); 3.152 + msurf_polygonize(msurf); 3.153 + glEnd(); 3.154 + 3.155 + assert(glGetError() == GL_NO_ERROR); 3.156 +} 3.157 + 3.158 +void disp(void) 3.159 +{ 3.160 + if(stereo) { 3.161 + glDrawBuffer(GL_BACK_LEFT); 3.162 + } 3.163 + 3.164 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 3.165 + 3.166 + glMatrixMode(GL_PROJECTION); 3.167 + glLoadIdentity(); 3.168 + cam_stereo_proj_matrix(stereo ? CAM_LEFT : CAM_CENTER); 3.169 + 3.170 + glMatrixMode(GL_MODELVIEW); 3.171 + glLoadIdentity(); 3.172 + cam_stereo_view_matrix(stereo ? CAM_LEFT : CAM_CENTER); 3.173 + 3.174 + render(); 3.175 + 3.176 + if(stereo) { 3.177 + glDrawBuffer(GL_BACK_RIGHT); 3.178 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 3.179 + 3.180 + glMatrixMode(GL_PROJECTION); 3.181 + glLoadIdentity(); 3.182 + cam_stereo_proj_matrix(CAM_RIGHT); 3.183 + 3.184 + glMatrixMode(GL_MODELVIEW); 3.185 + glLoadIdentity(); 3.186 + cam_stereo_view_matrix(CAM_RIGHT); 3.187 + 3.188 + render(); 3.189 + } 3.190 + glutSwapBuffers(); 3.191 +} 3.192 + 3.193 +void reshape(int x, int y) 3.194 +{ 3.195 + glViewport(0, 0, x, y); 3.196 + cam_aspect((float)x / (float)y); 3.197 +} 3.198 + 3.199 +void keyb(unsigned char key, int x, int y) 3.200 +{ 3.201 + static int wire; 3.202 + 3.203 + switch(key) { 3.204 + case 27: 3.205 + exit(0); 3.206 + 3.207 + case 's': 3.208 + stereo = !stereo; 3.209 + glutPostRedisplay(); 3.210 + break; 3.211 + 3.212 + case 'w': 3.213 + wire = !wire; 3.214 + glPolygonMode(GL_FRONT_AND_BACK, wire ? GL_LINE : GL_FILL); 3.215 + glutPostRedisplay(); 3.216 + break; 3.217 + 3.218 + case '=': 3.219 + threshold += 0.05; 3.220 + msurf_threshold(msurf, threshold); 3.221 + printf("threshold: %f\n", threshold); 3.222 + glutPostRedisplay(); 3.223 + break; 3.224 + 3.225 + case '-': 3.226 + threshold -= 0.05; 3.227 + msurf_threshold(msurf, threshold); 3.228 + printf("threshold: %f\n", threshold); 3.229 + glutPostRedisplay(); 3.230 + break; 3.231 + 3.232 + case ' ': 3.233 + bidx = (bidx + 1) % num_mballs; 3.234 + break; 3.235 + 3.236 + default: 3.237 + break; 3.238 + } 3.239 +} 3.240 + 3.241 +int bnstate[32]; 3.242 +int prev_x, prev_y; 3.243 + 3.244 +void mouse(int bn, int state, int x, int y) 3.245 +{ 3.246 + bnstate[bn] = state == GLUT_DOWN; 3.247 + prev_x = x; 3.248 + prev_y = y; 3.249 +} 3.250 + 3.251 +void motion(int x, int y) 3.252 +{ 3.253 + int dx, dy; 3.254 + 3.255 + dx = x - prev_x; 3.256 + dy = y - prev_y; 3.257 + prev_x = x; 3.258 + prev_y = y; 3.259 + 3.260 + if(bnstate[GLUT_LEFT_BUTTON]) { 3.261 + cam_inp_rotate(dx, dy); 3.262 + glutPostRedisplay(); 3.263 + } 3.264 + if(bnstate[GLUT_RIGHT_BUTTON]) { 3.265 + cam_inp_zoom(dy); 3.266 + glutPostRedisplay(); 3.267 + } 3.268 +} 3.269 + 3.270 +void sball_button(int bn, int state) 3.271 +{ 3.272 + if(state) return; 3.273 + 3.274 + if(bn < num_mballs) { 3.275 + bidx = bn; 3.276 + } else { 3.277 + bidx = (bidx + 1) % num_mballs; 3.278 + } 3.279 +} 3.280 + 3.281 +void sball_motion(int x, int y, int z) 3.282 +{ 3.283 + mball[bidx].x += (float)x / 32768.0; 3.284 + mball[bidx].y += (float)y / 32768.0; 3.285 + mball[bidx].z -= (float)z / 32768.0; 3.286 + glutPostRedisplay(); 3.287 +} 3.288 + 3.289 +int parse_args(int argc, char **argv) 3.290 +{ 3.291 + int i; 3.292 + 3.293 + for(i=1; i<argc; i++) { 3.294 + if(argv[i][0] == '-' && argv[i][2] == 0) { 3.295 + switch(argv[i][1]) { 3.296 + case 's': 3.297 + stereo = !stereo; 3.298 + break; 3.299 + 3.300 + default: 3.301 + fprintf(stderr, "unrecognized option: %s\n", argv[i]); 3.302 + return -1; 3.303 + } 3.304 + } else { 3.305 + fprintf(stderr, "unexpected argument: %s\n", argv[i]); 3.306 + return -1; 3.307 + } 3.308 + } 3.309 + return 0; 3.310 +}
4.1 --- a/examples/metaballs/src/test.c Tue Oct 25 07:34:31 2011 +0300 4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 @@ -1,307 +0,0 @@ 4.4 -#include <stdio.h> 4.5 -#include <stdlib.h> 4.6 -#include <math.h> 4.7 -#include <assert.h> 4.8 - 4.9 -#include <GL/glew.h> 4.10 -#ifndef __APPLE__ 4.11 -#include <GL/glut.h> 4.12 -#else 4.13 -#include <GLUT/glut.h> 4.14 -#endif 4.15 - 4.16 -#include "cam.h" 4.17 -#include "sdr.h" 4.18 -#include "metasurf.h" 4.19 - 4.20 -#define RES 38 4.21 - 4.22 -struct metaball { 4.23 - float energy; 4.24 - float x, y, z; 4.25 -} mball[] = { 4.26 - {1.0, 0, 0, 0}, 4.27 - {0.25, 0.45, 0, 0.25}, 4.28 - {0.15, -0.3, 0.2, 0.1} 4.29 -}; 4.30 - 4.31 -int num_mballs = sizeof mball / sizeof *mball; 4.32 - 4.33 -float eval(float x, float y, float z); 4.34 -float eval_cached(float x, float y, float z); 4.35 -void vertex(float x, float y, float z); 4.36 -void render(void); 4.37 -void disp(void); 4.38 -void reshape(int x, int y); 4.39 -void keyb(unsigned char key, int x, int y); 4.40 -void mouse(int bn, int state, int x, int y); 4.41 -void motion(int x, int y); 4.42 -void sball_button(int bn, int state); 4.43 -void sball_motion(int x, int y, int z); 4.44 -int parse_args(int argc, char **argv); 4.45 - 4.46 -int stereo; 4.47 -struct metasurface *msurf; 4.48 -float threshold = 12; 4.49 -unsigned int sdr; 4.50 -int bidx = 1; 4.51 - 4.52 -int main(int argc, char **argv) 4.53 -{ 4.54 - float amb[] = {0, 0, 0, 0}; 4.55 - float lpos[] = {-0.2, 0.2, 1, 0}; 4.56 - 4.57 - glutInitWindowSize(1280, 720); 4.58 - glutInit(&argc, argv); 4.59 - 4.60 - if(parse_args(argc, argv) == -1) { 4.61 - return 1; 4.62 - } 4.63 - glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | (stereo ? GLUT_STEREO : 0)); 4.64 - glutCreateWindow("metasurf"); 4.65 - 4.66 - glutDisplayFunc(disp); 4.67 - glutReshapeFunc(reshape); 4.68 - glutKeyboardFunc(keyb); 4.69 - glutMouseFunc(mouse); 4.70 - glutMotionFunc(motion); 4.71 - glutSpaceballButtonFunc(sball_button); 4.72 - glutSpaceballMotionFunc(sball_motion); 4.73 - 4.74 - glewInit(); 4.75 - 4.76 - glEnable(GL_CULL_FACE); 4.77 - glEnable(GL_DEPTH_TEST); 4.78 - 4.79 - glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb); 4.80 - 4.81 - glEnable(GL_LIGHTING); 4.82 - glEnable(GL_LIGHT0); 4.83 - glLightfv(GL_LIGHT0, GL_POSITION, lpos); 4.84 - 4.85 - glEnable(GL_NORMALIZE); 4.86 - 4.87 - cam_focus_dist(2.0); 4.88 - cam_clip(0.1, 200.0); 4.89 - cam_rotate(0, 0); 4.90 - cam_dolly(2); 4.91 - 4.92 - msurf = msurf_create(); 4.93 - msurf_eval_func(msurf, eval); 4.94 - msurf_vertex_func(msurf, vertex); 4.95 - msurf_threshold(msurf, threshold); 4.96 - msurf_resolution(msurf, RES, RES, RES); 4.97 - msurf_bounds(msurf, -1, -1, -1, 1, 1, 1); 4.98 - 4.99 - glClearColor(0.8, 0.8, 0.8, 1.0); 4.100 - 4.101 - if(!(sdr = create_program_load("sdr/vert.glsl", "sdr/frag.glsl"))) { 4.102 - return 1; 4.103 - } 4.104 - 4.105 - glutMainLoop(); 4.106 - return 0; 4.107 -} 4.108 - 4.109 -float eval(float x, float y, float z) 4.110 -{ 4.111 - int i; 4.112 - float val = 0.0f; 4.113 - 4.114 - for(i=0; i<num_mballs; i++) { 4.115 - float dx = mball[i].x - x; 4.116 - float dy = mball[i].y - y; 4.117 - float dz = mball[i].z - z; 4.118 - float dist_sq = dx * dx + dy * dy + dz * dz; 4.119 - 4.120 - if(dist_sq < 1e-6) { 4.121 - val += 100.0; 4.122 - } else { 4.123 - val += mball[i].energy / dist_sq; 4.124 - } 4.125 - } 4.126 - return val; 4.127 -} 4.128 - 4.129 -void vertex(float x, float y, float z) 4.130 -{ 4.131 - const float dt = 0.001; 4.132 - float dfdx = eval(x - dt, y, z) - eval(x + dt, y, z); 4.133 - float dfdy = eval(x, y - dt, z) - eval(x, y + dt, z); 4.134 - float dfdz = eval(x, y, z - dt) - eval(x, y, z + dt); 4.135 - 4.136 - glNormal3f(dfdx, dfdy, dfdz); 4.137 - glVertex3f(x, y, z); 4.138 -} 4.139 - 4.140 -void render(void) 4.141 -{ 4.142 - float kd[] = {0.7, 0.28, 0.2, 1.0}; 4.143 - float ks[] = {0.9, 0.9, 0.9, 1.0}; 4.144 - 4.145 - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, kd); 4.146 - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, ks); 4.147 - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60.0); 4.148 - 4.149 - bind_program(sdr); 4.150 - 4.151 - glBegin(GL_TRIANGLES); 4.152 - msurf_polygonize(msurf); 4.153 - glEnd(); 4.154 - 4.155 - assert(glGetError() == GL_NO_ERROR); 4.156 -} 4.157 - 4.158 -void disp(void) 4.159 -{ 4.160 - if(stereo) { 4.161 - glDrawBuffer(GL_BACK_LEFT); 4.162 - } 4.163 - 4.164 - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 4.165 - 4.166 - glMatrixMode(GL_PROJECTION); 4.167 - glLoadIdentity(); 4.168 - cam_stereo_proj_matrix(stereo ? CAM_LEFT : CAM_CENTER); 4.169 - 4.170 - glMatrixMode(GL_MODELVIEW); 4.171 - glLoadIdentity(); 4.172 - cam_stereo_view_matrix(stereo ? CAM_LEFT : CAM_CENTER); 4.173 - 4.174 - render(); 4.175 - 4.176 - if(stereo) { 4.177 - glDrawBuffer(GL_BACK_RIGHT); 4.178 - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 4.179 - 4.180 - glMatrixMode(GL_PROJECTION); 4.181 - glLoadIdentity(); 4.182 - cam_stereo_proj_matrix(CAM_RIGHT); 4.183 - 4.184 - glMatrixMode(GL_MODELVIEW); 4.185 - glLoadIdentity(); 4.186 - cam_stereo_view_matrix(CAM_RIGHT); 4.187 - 4.188 - render(); 4.189 - } 4.190 - glutSwapBuffers(); 4.191 -} 4.192 - 4.193 -void reshape(int x, int y) 4.194 -{ 4.195 - glViewport(0, 0, x, y); 4.196 - cam_aspect((float)x / (float)y); 4.197 -} 4.198 - 4.199 -void keyb(unsigned char key, int x, int y) 4.200 -{ 4.201 - static int wire; 4.202 - 4.203 - switch(key) { 4.204 - case 27: 4.205 - exit(0); 4.206 - 4.207 - case 's': 4.208 - stereo = !stereo; 4.209 - glutPostRedisplay(); 4.210 - break; 4.211 - 4.212 - case 'w': 4.213 - wire = !wire; 4.214 - glPolygonMode(GL_FRONT_AND_BACK, wire ? GL_LINE : GL_FILL); 4.215 - glutPostRedisplay(); 4.216 - break; 4.217 - 4.218 - case '=': 4.219 - threshold += 0.05; 4.220 - msurf_threshold(msurf, threshold); 4.221 - printf("threshold: %f\n", threshold); 4.222 - glutPostRedisplay(); 4.223 - break; 4.224 - 4.225 - case '-': 4.226 - threshold -= 0.05; 4.227 - msurf_threshold(msurf, threshold); 4.228 - printf("threshold: %f\n", threshold); 4.229 - glutPostRedisplay(); 4.230 - break; 4.231 - 4.232 - case ' ': 4.233 - bidx = (bidx + 1) % num_mballs; 4.234 - break; 4.235 - 4.236 - default: 4.237 - break; 4.238 - } 4.239 -} 4.240 - 4.241 -int bnstate[32]; 4.242 -int prev_x, prev_y; 4.243 - 4.244 -void mouse(int bn, int state, int x, int y) 4.245 -{ 4.246 - bnstate[bn] = state == GLUT_DOWN; 4.247 - prev_x = x; 4.248 - prev_y = y; 4.249 -} 4.250 - 4.251 -void motion(int x, int y) 4.252 -{ 4.253 - int dx, dy; 4.254 - 4.255 - dx = x - prev_x; 4.256 - dy = y - prev_y; 4.257 - prev_x = x; 4.258 - prev_y = y; 4.259 - 4.260 - if(bnstate[GLUT_LEFT_BUTTON]) { 4.261 - cam_inp_rotate(dx, dy); 4.262 - glutPostRedisplay(); 4.263 - } 4.264 - if(bnstate[GLUT_RIGHT_BUTTON]) { 4.265 - cam_inp_zoom(dy); 4.266 - glutPostRedisplay(); 4.267 - } 4.268 -} 4.269 - 4.270 -void sball_button(int bn, int state) 4.271 -{ 4.272 - if(state) return; 4.273 - 4.274 - if(bn < num_mballs) { 4.275 - bidx = bn; 4.276 - } else { 4.277 - bidx = (bidx + 1) % num_mballs; 4.278 - } 4.279 -} 4.280 - 4.281 -void sball_motion(int x, int y, int z) 4.282 -{ 4.283 - mball[bidx].x += (float)x / 32768.0; 4.284 - mball[bidx].y += (float)y / 32768.0; 4.285 - mball[bidx].z -= (float)z / 32768.0; 4.286 - glutPostRedisplay(); 4.287 -} 4.288 - 4.289 -int parse_args(int argc, char **argv) 4.290 -{ 4.291 - int i; 4.292 - 4.293 - for(i=1; i<argc; i++) { 4.294 - if(argv[i][0] == '-' && argv[i][2] == 0) { 4.295 - switch(argv[i][1]) { 4.296 - case 's': 4.297 - stereo = !stereo; 4.298 - break; 4.299 - 4.300 - default: 4.301 - fprintf(stderr, "unrecognized option: %s\n", argv[i]); 4.302 - return -1; 4.303 - } 4.304 - } else { 4.305 - fprintf(stderr, "unexpected argument: %s\n", argv[i]); 4.306 - return -1; 4.307 - } 4.308 - } 4.309 - return 0; 4.310 -}