volray
diff src/volray.c @ 4:3e53a16d4667
foo
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 02 Apr 2012 17:59:46 +0300 |
parents | 6f275934717b |
children | 0c3874aa717a |
line diff
1.1 --- a/src/volray.c Mon Apr 02 14:42:03 2012 +0300 1.2 +++ b/src/volray.c Mon Apr 02 17:59:46 2012 +0300 1.3 @@ -22,8 +22,11 @@ 1.4 1.5 int init(void); 1.6 void disp(void); 1.7 +void render_volume(void); 1.8 +void draw_xfer_func(void); 1.9 void reshape(int x, int y); 1.10 void keyb(unsigned char key, int x, int y); 1.11 +void keyb_up(unsigned char key, int x, int y); 1.12 void mouse(int bn, int state, int x, int y); 1.13 void motion(int x, int y); 1.14 int parse_args(int argc, char **argv); 1.15 @@ -47,6 +50,8 @@ 1.16 float xfer_mean = 0.5, xfer_sdev = 1.0; 1.17 int xfertex_needs_recalc = 1; 1.18 1.19 +static int uimode_xfer; 1.20 + 1.21 int main(int argc, char **argv) 1.22 { 1.23 glutInit(&argc, argv); 1.24 @@ -62,6 +67,7 @@ 1.25 glutDisplayFunc(disp); 1.26 glutReshapeFunc(reshape); 1.27 glutKeyboardFunc(keyb); 1.28 + glutKeyboardUpFunc(keyb_up); 1.29 glutMouseFunc(mouse); 1.30 glutMotionFunc(motion); 1.31 1.32 @@ -90,9 +96,9 @@ 1.33 glBindTexture(GL_TEXTURE_3D, vol_tex); 1.34 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1.35 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.36 - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP); 1.37 - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP); 1.38 - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP); 1.39 + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1.40 + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1.41 + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 1.42 1.43 for(i=0; i<nslices; i++) { 1.44 int xsz, ysz; 1.45 @@ -130,14 +136,27 @@ 1.46 1.47 void disp(void) 1.48 { 1.49 + /* recalculate primary ray texture if needed */ 1.50 if(raytex_needs_recalc) { 1.51 create_ray_texture(win_xsz, win_ysz, 50.0, &tex_scale); 1.52 } 1.53 + /* recalculate transfer function texture if needed */ 1.54 if(xfertex_needs_recalc) { 1.55 create_transfer_map(xfer_mean, xfer_sdev); 1.56 } 1.57 1.58 + render_volume(); 1.59 + draw_xfer_func(); 1.60 + 1.61 + glutSwapBuffers(); 1.62 + assert(glGetError() == GL_NO_ERROR); 1.63 +} 1.64 + 1.65 +void render_volume(void) 1.66 +{ 1.67 + /* set the camera transformation */ 1.68 glMatrixMode(GL_MODELVIEW); 1.69 + glPushMatrix(); 1.70 glLoadIdentity(); 1.71 glRotatef(-90, 1, 0, 0); 1.72 glTranslatef(cam_x, cam_y, -cam_z); 1.73 @@ -145,18 +164,23 @@ 1.74 glRotatef(cam_phi, 1, 0, 0); 1.75 glTranslatef(0, 0, -cam_dist); 1.76 1.77 + /* setup the texture matrix to map the useful part of the ray texture to [0,1] */ 1.78 glMatrixMode(GL_TEXTURE); 1.79 + glPushMatrix(); 1.80 glLoadIdentity(); 1.81 glScalef(tex_scale.x, tex_scale.y, 1.0); 1.82 1.83 + /* tex unit0: volume data 3D texture */ 1.84 glActiveTexture(GL_TEXTURE0); 1.85 glBindTexture(GL_TEXTURE_3D, vol_tex); 1.86 glEnable(GL_TEXTURE_3D); 1.87 1.88 + /* tex unit1: primary rays in view space */ 1.89 glActiveTexture(GL_TEXTURE1); 1.90 glBindTexture(GL_TEXTURE_2D, ray_tex); 1.91 glEnable(GL_TEXTURE_2D); 1.92 1.93 + /* tex unit2: transfer function (1d) */ 1.94 glActiveTexture(GL_TEXTURE2); 1.95 glBindTexture(GL_TEXTURE_1D, xfer_tex); 1.96 glEnable(GL_TEXTURE_1D); 1.97 @@ -179,15 +203,47 @@ 1.98 glDisable(GL_TEXTURE_3D); 1.99 1.100 glMatrixMode(GL_TEXTURE); 1.101 - glLoadIdentity(); 1.102 + glPopMatrix(); 1.103 + glMatrixMode(GL_MODELVIEW); 1.104 + glPopMatrix(); 1.105 +} 1.106 1.107 - glutSwapBuffers(); 1.108 - assert(glGetError() == GL_NO_ERROR); 1.109 +void draw_xfer_func(void) 1.110 +{ 1.111 + glMatrixMode(GL_MODELVIEW); 1.112 + glPushMatrix(); 1.113 + glTranslatef(-0.9, -0.9, 0); 1.114 + glScalef(0.5, 0.1, 1); 1.115 + 1.116 + glBindTexture(GL_TEXTURE_1D, xfer_tex); 1.117 + glEnable(GL_TEXTURE_1D); 1.118 + 1.119 + glBegin(GL_QUADS); 1.120 + glColor3f(1, 1, 1); 1.121 + glTexCoord1f(1); 1.122 + glVertex2f(1, 0); 1.123 + glVertex2f(1, 1); 1.124 + glTexCoord1f(0); 1.125 + glVertex2f(0, 1); 1.126 + glVertex2f(0, 0); 1.127 + glEnd(); 1.128 + 1.129 + glDisable(GL_TEXTURE_1D); 1.130 + 1.131 + glLineWidth(2.0); 1.132 + glBegin(GL_LINE_LOOP); 1.133 + glColor3f(uimode_xfer ? 1 : 0, 0, uimode_xfer ? 0 : 1); 1.134 + glVertex2f(0, 0); 1.135 + glVertex2f(1, 0); 1.136 + glVertex2f(1, 1); 1.137 + glVertex2f(0, 1); 1.138 + glEnd(); 1.139 + 1.140 + glPopMatrix(); 1.141 } 1.142 1.143 void reshape(int x, int y) 1.144 { 1.145 - printf("reshape: %dx%d\n", x, y); 1.146 glViewport(0, 0, x, y); 1.147 1.148 if(x != win_xsz || y != win_ysz) { 1.149 @@ -202,6 +258,21 @@ 1.150 switch(key) { 1.151 case 27: 1.152 exit(0); 1.153 + 1.154 + case 'x': 1.155 + uimode_xfer = 1; 1.156 + glutPostRedisplay(); 1.157 + break; 1.158 + } 1.159 +} 1.160 + 1.161 +void keyb_up(unsigned char key, int x, int y) 1.162 +{ 1.163 + switch(key) { 1.164 + case 'x': 1.165 + uimode_xfer = 0; 1.166 + glutPostRedisplay(); 1.167 + break; 1.168 } 1.169 } 1.170 1.171 @@ -219,30 +290,43 @@ 1.172 { 1.173 int dx = x - prev_x; 1.174 int dy = y - prev_y; 1.175 - 1.176 prev_x = x; 1.177 prev_y = y; 1.178 1.179 - if(bnstate[0]) { 1.180 - cam_theta += dx * 0.5; 1.181 - cam_phi += dy * 0.5; 1.182 + if(uimode_xfer) { 1.183 + if(dx || dy) { 1.184 + xfer_mean += dx / (float)win_xsz; 1.185 + xfer_sdev += 0.5 * dy / (float)win_ysz; 1.186 1.187 - if(cam_phi <= -90) cam_phi = -89; 1.188 - if(cam_phi >= 90) cam_phi = 89; 1.189 + xfer_mean = xfer_mean < 0.0 ? 0.0 : (xfer_mean > 1.0 ? 1.0 : xfer_mean); 1.190 + xfer_sdev = xfer_sdev < 0.0 ? 0.0 : (xfer_sdev > 1.0 ? 1.0 : xfer_sdev); 1.191 1.192 - glutPostRedisplay(); 1.193 - } 1.194 + xfertex_needs_recalc = 1; 1.195 + glutPostRedisplay(); 1.196 + } 1.197 + } else { 1.198 1.199 - if(bnstate[1]) { 1.200 - cam_x += dx * 0.025; 1.201 - cam_y += dy * 0.025; 1.202 - glutPostRedisplay(); 1.203 - } 1.204 + if(bnstate[0]) { 1.205 + cam_theta += dx * 0.5; 1.206 + cam_phi += dy * 0.5; 1.207 1.208 - if(bnstate[2]) { 1.209 - cam_dist += dy * 0.025; 1.210 - if(cam_dist < 0.0) cam_dist = 0.0; 1.211 - glutPostRedisplay(); 1.212 + if(cam_phi <= -90) cam_phi = -89; 1.213 + if(cam_phi >= 90) cam_phi = 89; 1.214 + 1.215 + glutPostRedisplay(); 1.216 + } 1.217 + 1.218 + if(bnstate[1]) { 1.219 + cam_x += dx * 0.025; 1.220 + cam_y += dy * 0.025; 1.221 + glutPostRedisplay(); 1.222 + } 1.223 + 1.224 + if(bnstate[2]) { 1.225 + cam_dist += dy * 0.025; 1.226 + if(cam_dist < 0.0) cam_dist = 0.0; 1.227 + glutPostRedisplay(); 1.228 + } 1.229 } 1.230 } 1.231 1.232 @@ -264,10 +348,10 @@ 1.233 } 1.234 break; 1.235 1.236 - case 'v': 1.237 + case 'd': 1.238 xfer_sdev = strtod(argv[++i], &endp); 1.239 if(endp == argv[i]) { 1.240 - fprintf(stderr, "-v must be followed by the transfer function sdeviance\n"); 1.241 + fprintf(stderr, "-d must be followed by the transfer function std.deviation\n"); 1.242 return -1; 1.243 } 1.244 break; 1.245 @@ -396,10 +480,11 @@ 1.246 } 1.247 1.248 for(i=0; i<XFER_MAP_SZ; i++) { 1.249 - float x = (float)i / (float)XFER_MAP_SZ; 1.250 - map[i] = gaussian(x, mean, sdev); 1.251 + float x = (float)i / (float)(XFER_MAP_SZ - 1); 1.252 + map[i] = gaussian(x, mean, sdev) - 1.0; 1.253 } 1.254 + putchar('\n'); 1.255 1.256 - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XFER_MAP_SZ, 1, GL_LUMINANCE, GL_FLOAT, map); 1.257 + glTexSubImage1D(GL_TEXTURE_1D, 0, 0, XFER_MAP_SZ, GL_LUMINANCE, GL_FLOAT, map); 1.258 xfertex_needs_recalc = 0; 1.259 }