metasurf
diff examples/metaballs/src/test.c @ 0:7aa4627e492b
first commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 25 Oct 2011 07:34:31 +0300 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/examples/metaballs/src/test.c Tue Oct 25 07:34:31 2011 +0300 1.3 @@ -0,0 +1,307 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <math.h> 1.7 +#include <assert.h> 1.8 + 1.9 +#include <GL/glew.h> 1.10 +#ifndef __APPLE__ 1.11 +#include <GL/glut.h> 1.12 +#else 1.13 +#include <GLUT/glut.h> 1.14 +#endif 1.15 + 1.16 +#include "cam.h" 1.17 +#include "sdr.h" 1.18 +#include "metasurf.h" 1.19 + 1.20 +#define RES 38 1.21 + 1.22 +struct metaball { 1.23 + float energy; 1.24 + float x, y, z; 1.25 +} mball[] = { 1.26 + {1.0, 0, 0, 0}, 1.27 + {0.25, 0.45, 0, 0.25}, 1.28 + {0.15, -0.3, 0.2, 0.1} 1.29 +}; 1.30 + 1.31 +int num_mballs = sizeof mball / sizeof *mball; 1.32 + 1.33 +float eval(float x, float y, float z); 1.34 +float eval_cached(float x, float y, float z); 1.35 +void vertex(float x, float y, float z); 1.36 +void render(void); 1.37 +void disp(void); 1.38 +void reshape(int x, int y); 1.39 +void keyb(unsigned char key, int x, int y); 1.40 +void mouse(int bn, int state, int x, int y); 1.41 +void motion(int x, int y); 1.42 +void sball_button(int bn, int state); 1.43 +void sball_motion(int x, int y, int z); 1.44 +int parse_args(int argc, char **argv); 1.45 + 1.46 +int stereo; 1.47 +struct metasurface *msurf; 1.48 +float threshold = 12; 1.49 +unsigned int sdr; 1.50 +int bidx = 1; 1.51 + 1.52 +int main(int argc, char **argv) 1.53 +{ 1.54 + float amb[] = {0, 0, 0, 0}; 1.55 + float lpos[] = {-0.2, 0.2, 1, 0}; 1.56 + 1.57 + glutInitWindowSize(1280, 720); 1.58 + glutInit(&argc, argv); 1.59 + 1.60 + if(parse_args(argc, argv) == -1) { 1.61 + return 1; 1.62 + } 1.63 + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | (stereo ? GLUT_STEREO : 0)); 1.64 + glutCreateWindow("metasurf"); 1.65 + 1.66 + glutDisplayFunc(disp); 1.67 + glutReshapeFunc(reshape); 1.68 + glutKeyboardFunc(keyb); 1.69 + glutMouseFunc(mouse); 1.70 + glutMotionFunc(motion); 1.71 + glutSpaceballButtonFunc(sball_button); 1.72 + glutSpaceballMotionFunc(sball_motion); 1.73 + 1.74 + glewInit(); 1.75 + 1.76 + glEnable(GL_CULL_FACE); 1.77 + glEnable(GL_DEPTH_TEST); 1.78 + 1.79 + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb); 1.80 + 1.81 + glEnable(GL_LIGHTING); 1.82 + glEnable(GL_LIGHT0); 1.83 + glLightfv(GL_LIGHT0, GL_POSITION, lpos); 1.84 + 1.85 + glEnable(GL_NORMALIZE); 1.86 + 1.87 + cam_focus_dist(2.0); 1.88 + cam_clip(0.1, 200.0); 1.89 + cam_rotate(0, 0); 1.90 + cam_dolly(2); 1.91 + 1.92 + msurf = msurf_create(); 1.93 + msurf_eval_func(msurf, eval); 1.94 + msurf_vertex_func(msurf, vertex); 1.95 + msurf_threshold(msurf, threshold); 1.96 + msurf_resolution(msurf, RES, RES, RES); 1.97 + msurf_bounds(msurf, -1, -1, -1, 1, 1, 1); 1.98 + 1.99 + glClearColor(0.8, 0.8, 0.8, 1.0); 1.100 + 1.101 + if(!(sdr = create_program_load("sdr/vert.glsl", "sdr/frag.glsl"))) { 1.102 + return 1; 1.103 + } 1.104 + 1.105 + glutMainLoop(); 1.106 + return 0; 1.107 +} 1.108 + 1.109 +float eval(float x, float y, float z) 1.110 +{ 1.111 + int i; 1.112 + float val = 0.0f; 1.113 + 1.114 + for(i=0; i<num_mballs; i++) { 1.115 + float dx = mball[i].x - x; 1.116 + float dy = mball[i].y - y; 1.117 + float dz = mball[i].z - z; 1.118 + float dist_sq = dx * dx + dy * dy + dz * dz; 1.119 + 1.120 + if(dist_sq < 1e-6) { 1.121 + val += 100.0; 1.122 + } else { 1.123 + val += mball[i].energy / dist_sq; 1.124 + } 1.125 + } 1.126 + return val; 1.127 +} 1.128 + 1.129 +void vertex(float x, float y, float z) 1.130 +{ 1.131 + const float dt = 0.001; 1.132 + float dfdx = eval(x - dt, y, z) - eval(x + dt, y, z); 1.133 + float dfdy = eval(x, y - dt, z) - eval(x, y + dt, z); 1.134 + float dfdz = eval(x, y, z - dt) - eval(x, y, z + dt); 1.135 + 1.136 + glNormal3f(dfdx, dfdy, dfdz); 1.137 + glVertex3f(x, y, z); 1.138 +} 1.139 + 1.140 +void render(void) 1.141 +{ 1.142 + float kd[] = {0.7, 0.28, 0.2, 1.0}; 1.143 + float ks[] = {0.9, 0.9, 0.9, 1.0}; 1.144 + 1.145 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, kd); 1.146 + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, ks); 1.147 + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60.0); 1.148 + 1.149 + bind_program(sdr); 1.150 + 1.151 + glBegin(GL_TRIANGLES); 1.152 + msurf_polygonize(msurf); 1.153 + glEnd(); 1.154 + 1.155 + assert(glGetError() == GL_NO_ERROR); 1.156 +} 1.157 + 1.158 +void disp(void) 1.159 +{ 1.160 + if(stereo) { 1.161 + glDrawBuffer(GL_BACK_LEFT); 1.162 + } 1.163 + 1.164 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.165 + 1.166 + glMatrixMode(GL_PROJECTION); 1.167 + glLoadIdentity(); 1.168 + cam_stereo_proj_matrix(stereo ? CAM_LEFT : CAM_CENTER); 1.169 + 1.170 + glMatrixMode(GL_MODELVIEW); 1.171 + glLoadIdentity(); 1.172 + cam_stereo_view_matrix(stereo ? CAM_LEFT : CAM_CENTER); 1.173 + 1.174 + render(); 1.175 + 1.176 + if(stereo) { 1.177 + glDrawBuffer(GL_BACK_RIGHT); 1.178 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.179 + 1.180 + glMatrixMode(GL_PROJECTION); 1.181 + glLoadIdentity(); 1.182 + cam_stereo_proj_matrix(CAM_RIGHT); 1.183 + 1.184 + glMatrixMode(GL_MODELVIEW); 1.185 + glLoadIdentity(); 1.186 + cam_stereo_view_matrix(CAM_RIGHT); 1.187 + 1.188 + render(); 1.189 + } 1.190 + glutSwapBuffers(); 1.191 +} 1.192 + 1.193 +void reshape(int x, int y) 1.194 +{ 1.195 + glViewport(0, 0, x, y); 1.196 + cam_aspect((float)x / (float)y); 1.197 +} 1.198 + 1.199 +void keyb(unsigned char key, int x, int y) 1.200 +{ 1.201 + static int wire; 1.202 + 1.203 + switch(key) { 1.204 + case 27: 1.205 + exit(0); 1.206 + 1.207 + case 's': 1.208 + stereo = !stereo; 1.209 + glutPostRedisplay(); 1.210 + break; 1.211 + 1.212 + case 'w': 1.213 + wire = !wire; 1.214 + glPolygonMode(GL_FRONT_AND_BACK, wire ? GL_LINE : GL_FILL); 1.215 + glutPostRedisplay(); 1.216 + break; 1.217 + 1.218 + case '=': 1.219 + threshold += 0.05; 1.220 + msurf_threshold(msurf, threshold); 1.221 + printf("threshold: %f\n", threshold); 1.222 + glutPostRedisplay(); 1.223 + break; 1.224 + 1.225 + case '-': 1.226 + threshold -= 0.05; 1.227 + msurf_threshold(msurf, threshold); 1.228 + printf("threshold: %f\n", threshold); 1.229 + glutPostRedisplay(); 1.230 + break; 1.231 + 1.232 + case ' ': 1.233 + bidx = (bidx + 1) % num_mballs; 1.234 + break; 1.235 + 1.236 + default: 1.237 + break; 1.238 + } 1.239 +} 1.240 + 1.241 +int bnstate[32]; 1.242 +int prev_x, prev_y; 1.243 + 1.244 +void mouse(int bn, int state, int x, int y) 1.245 +{ 1.246 + bnstate[bn] = state == GLUT_DOWN; 1.247 + prev_x = x; 1.248 + prev_y = y; 1.249 +} 1.250 + 1.251 +void motion(int x, int y) 1.252 +{ 1.253 + int dx, dy; 1.254 + 1.255 + dx = x - prev_x; 1.256 + dy = y - prev_y; 1.257 + prev_x = x; 1.258 + prev_y = y; 1.259 + 1.260 + if(bnstate[GLUT_LEFT_BUTTON]) { 1.261 + cam_inp_rotate(dx, dy); 1.262 + glutPostRedisplay(); 1.263 + } 1.264 + if(bnstate[GLUT_RIGHT_BUTTON]) { 1.265 + cam_inp_zoom(dy); 1.266 + glutPostRedisplay(); 1.267 + } 1.268 +} 1.269 + 1.270 +void sball_button(int bn, int state) 1.271 +{ 1.272 + if(state) return; 1.273 + 1.274 + if(bn < num_mballs) { 1.275 + bidx = bn; 1.276 + } else { 1.277 + bidx = (bidx + 1) % num_mballs; 1.278 + } 1.279 +} 1.280 + 1.281 +void sball_motion(int x, int y, int z) 1.282 +{ 1.283 + mball[bidx].x += (float)x / 32768.0; 1.284 + mball[bidx].y += (float)y / 32768.0; 1.285 + mball[bidx].z -= (float)z / 32768.0; 1.286 + glutPostRedisplay(); 1.287 +} 1.288 + 1.289 +int parse_args(int argc, char **argv) 1.290 +{ 1.291 + int i; 1.292 + 1.293 + for(i=1; i<argc; i++) { 1.294 + if(argv[i][0] == '-' && argv[i][2] == 0) { 1.295 + switch(argv[i][1]) { 1.296 + case 's': 1.297 + stereo = !stereo; 1.298 + break; 1.299 + 1.300 + default: 1.301 + fprintf(stderr, "unrecognized option: %s\n", argv[i]); 1.302 + return -1; 1.303 + } 1.304 + } else { 1.305 + fprintf(stderr, "unexpected argument: %s\n", argv[i]); 1.306 + return -1; 1.307 + } 1.308 + } 1.309 + return 0; 1.310 +}