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 -}