volmetrics
diff src/main.cc @ 9:40febfed6cff
rendering isosurfaces / added simple gui
author | Eleni Maria Stea <elene.mst@gmail.com> |
---|---|
date | Sun, 26 Jan 2014 23:13:37 +0200 |
parents | 5455c9723d9e |
children | 8ffa6d61eb56 |
line diff
1.1 --- a/src/main.cc Sat Jan 25 19:25:32 2014 +0200 1.2 +++ b/src/main.cc Sun Jan 26 23:13:37 2014 +0200 1.3 @@ -1,27 +1,40 @@ 1.4 #include <GL/glew.h> 1.5 #include <GL/glut.h> 1.6 +#include <GL/glui.h> 1.7 1.8 #include <stdio.h> 1.9 #include <assert.h> 1.10 1.11 +#include <vector> 1.12 + 1.13 +#include "mesh.h" 1.14 #include "volume.h" 1.15 1.16 -//static void init(void); 1.17 -static void display(void); 1.18 -static void reshape(int x, int y); 1.19 -static void keyboard(unsigned char key, int x, int y); 1.20 -static void mouse(int button, int state, int x, int y); 1.21 -static void motion(int x, int y); 1.22 +bool init(void); 1.23 +GLUI *create_ui(void); 1.24 +void display(void); 1.25 +void reshape(int x, int y); 1.26 +void keyboard(unsigned char key, int x, int y); 1.27 +void keyboard_up(unsigned char key, int x, int y); 1.28 +void mouse(int button, int state, int x, int y); 1.29 +void motion(int x, int y); 1.30 1.31 static int win_xsz, win_ysz; 1.32 +static float cam_phi, cam_theta, cam_dist = 6; 1.33 +static std::vector<bool> key_state(256); 1.34 1.35 ///////////////////////////// 1.36 // debug TODO remove 1.37 //////////////////////////// 1.38 -static bool init(); 1.39 1.40 static Volume *vol; 1.41 -static float cur_z; 1.42 +static Mesh *mesh; 1.43 +static float cur_z, thres = 0.5; 1.44 + 1.45 +static int use_orig_vol_res = 1; 1.46 +static int vol_res[3]; // volume sampling resolution x/y/z 1.47 + 1.48 +static GLUI *ui; 1.49 1.50 int main(int argc, char **argv) 1.51 { 1.52 @@ -36,6 +49,7 @@ 1.53 glutDisplayFunc(display); 1.54 glutReshapeFunc(reshape); 1.55 glutKeyboardFunc(keyboard); 1.56 + glutKeyboardUpFunc(keyboard_up); 1.57 glutMouseFunc(mouse); 1.58 glutMotionFunc(motion); 1.59 1.60 @@ -51,9 +65,85 @@ 1.61 return 0; 1.62 } 1.63 1.64 +bool init() 1.65 +{ 1.66 + vol = new Volume; 1.67 + if(!vol->load("data/test1.vol")) { 1.68 + fprintf(stderr, "Failed to load test1.vol"); 1.69 + return false; 1.70 + } 1.71 + mesh = new Mesh; 1.72 + cur_z = 0.5; 1.73 + 1.74 + vol_res[0] = vol->get_slice(0)->get_width(); 1.75 + vol_res[1] = vol->get_slice(0)->get_height(); 1.76 + vol_res[2] = vol->get_slice_count(); 1.77 + 1.78 + if(!(ui = create_ui())) { 1.79 + return false; 1.80 + } 1.81 + 1.82 + return true; 1.83 +} 1.84 + 1.85 +static GLUI_Spinner *res_spin[3]; 1.86 + 1.87 +static void toggle_use_orig(int id) 1.88 +{ 1.89 + for(int i=0; i<3; i++) { 1.90 + if(use_orig_vol_res) { 1.91 + res_spin[i]->disable(); 1.92 + } else { 1.93 + res_spin[i]->enable(); 1.94 + } 1.95 + } 1.96 +} 1.97 + 1.98 +static void thres_change(int id) 1.99 +{ 1.100 + static float prev_thres = thres; 1.101 + 1.102 + if(prev_thres != thres) { 1.103 + prev_thres = thres; 1.104 + mesh->clear(); 1.105 + } 1.106 +} 1.107 + 1.108 +GLUI *create_ui() 1.109 +{ 1.110 + GLUI *ui = GLUI_Master.create_glui("ui"); 1.111 + assert(ui); 1.112 + 1.113 + ui->set_main_gfx_window(glutGetWindow()); 1.114 + 1.115 + GLUI_Spinner *thres_spin = ui->add_spinner("iso threshold", GLUI_SPINNER_FLOAT, &thres, 0, thres_change); 1.116 + thres_spin->set_float_limits(0, 1); 1.117 + 1.118 + GLUI_Panel *res_panel = ui->add_panel("volume resolution"); 1.119 + 1.120 + ui->add_checkbox_to_panel(res_panel, "original resolution", &use_orig_vol_res, 0, toggle_use_orig); 1.121 + 1.122 + static const char *res_spin_name[] = {"x", "y", "z"}; 1.123 + for(int i=0; i<3; i++) { 1.124 + res_spin[i] = ui->add_spinner_to_panel(res_panel, res_spin_name[i], GLUI_SPINNER_INT, vol_res + i); 1.125 + res_spin[i]->set_int_limits(8, 256); // TODO limits as arguments or config 1.126 + res_spin[i]->disable(); 1.127 + } 1.128 + 1.129 + return ui; 1.130 +} 1.131 + 1.132 void display(void) 1.133 { 1.134 - //render 1.135 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.136 + 1.137 + glMatrixMode(GL_MODELVIEW); 1.138 + glLoadIdentity(); 1.139 + glTranslatef(0, 0, -cam_dist); 1.140 + glRotatef(cam_phi, 1, 0, 0); 1.141 + glRotatef(cam_theta, 0, 1, 0); 1.142 + 1.143 +/* 1.144 glBindTexture(GL_TEXTURE_3D, vol->get_texture()); 1.145 glEnable(GL_TEXTURE_3D); 1.146 glBegin(GL_QUADS); 1.147 @@ -63,7 +153,17 @@ 1.148 glTexCoord3f(1, 0, cur_z); glVertex3f(1, -1, 0); 1.149 glEnd(); 1.150 glDisable(GL_TEXTURE_3D); 1.151 +*/ 1.152 1.153 + if(mesh->is_empty()) { 1.154 + printf("recalculating isosurface ... "); 1.155 + fflush(stdout); 1.156 + vol->create_mesh(mesh, thres); 1.157 + printf("done.\n"); 1.158 + } 1.159 + mesh->draw(); 1.160 + 1.161 + //TODO: draw threshold 1.162 glutSwapBuffers(); 1.163 assert(glGetError() == GL_NO_ERROR); 1.164 } 1.165 @@ -71,8 +171,11 @@ 1.166 void reshape(int x, int y) 1.167 { 1.168 glViewport(0, 0, x, y); 1.169 + glMatrixMode(GL_PROJECTION); 1.170 + glLoadIdentity(); 1.171 + gluPerspective(45, (float)x / (float)y, 0.5, 500); 1.172 + 1.173 if(x != win_xsz || y != win_ysz) { 1.174 - //TODO raytex_needs_recalc = 1; 1.175 win_xsz = x; 1.176 win_ysz = y; 1.177 } 1.178 @@ -80,42 +183,91 @@ 1.179 1.180 void keyboard(unsigned char key, int x, int y) 1.181 { 1.182 + key_state[(int)key] = true; 1.183 + 1.184 switch(key) { 1.185 case 27: 1.186 exit(0); 1.187 + case 'w': 1.188 + { 1.189 + static bool wire; 1.190 + 1.191 + wire = !wire; 1.192 + glPolygonMode(GL_FRONT_AND_BACK, wire ? GL_LINE : GL_FILL); 1.193 + } 1.194 + break; 1.195 default: 1.196 break; 1.197 } 1.198 } 1.199 1.200 +void keyboard_up(unsigned char key, int x, int y) 1.201 +{ 1.202 + key_state[(int) key] = false; 1.203 +} 1.204 + 1.205 static int prev_x, prev_y; 1.206 +static bool bn_state[32]; 1.207 +static float prev_thres; 1.208 + 1.209 void mouse(int bn, int state, int x, int y) 1.210 { 1.211 prev_x = x; 1.212 prev_y = y; 1.213 + 1.214 + bn_state[bn - GLUT_LEFT_BUTTON] = (state == GLUT_DOWN); 1.215 + 1.216 + if(state == GLUT_DOWN) { 1.217 + prev_thres = thres; 1.218 + } 1.219 + else { 1.220 + if(thres != prev_thres) { 1.221 + mesh->clear(); 1.222 + } 1.223 + } 1.224 } 1.225 1.226 void motion(int x, int y) 1.227 { 1.228 int dx = x - prev_x; 1.229 int dy = y - prev_y; 1.230 + 1.231 + if(!dx && !dy) 1.232 + return; 1.233 + 1.234 prev_x = x; 1.235 prev_y = y; 1.236 1.237 - if(dx != 0) { 1.238 - cur_z = (float)x / (float)win_xsz; 1.239 + if(key_state[(int)'t']) { 1.240 + thres = (float)x / (float)win_xsz; 1.241 + printf("threshold: %f\n", thres); 1.242 + 1.243 + glutPostRedisplay(); 1.244 + return; 1.245 + } 1.246 + 1.247 + // camera 1.248 + if(bn_state[0]) { 1.249 + if(key_state[(int)'z']) { 1.250 + //zoom the camera 1.251 + 1.252 + cam_dist += dy * 0.1; 1.253 + 1.254 + if(cam_dist < 0) 1.255 + cam_dist = 0; 1.256 + } 1.257 + else { 1.258 + //rotate the camera 1.259 + 1.260 + cam_phi += dy * 0.5; 1.261 + cam_theta += dx * 0.5; 1.262 + 1.263 + if(cam_phi > 90) 1.264 + cam_phi = 90; 1.265 + if(cam_phi < -90) 1.266 + cam_phi = -90; 1.267 + } 1.268 + 1.269 glutPostRedisplay(); 1.270 } 1.271 } 1.272 - 1.273 -bool init() 1.274 -{ 1.275 - vol = new Volume; 1.276 - if(!vol->load("data/test1.vol")) { 1.277 - fprintf(stderr, "Failed to load test1.vol"); 1.278 - return false; 1.279 - } 1.280 - cur_z = 0.5; 1.281 - 1.282 - return true; 1.283 -}