glviewvol
diff src/viewer.cc @ 11:73edd1b7c2da
changed the name to glviewvol
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 31 Dec 2014 07:53:53 +0200 |
parents | src/dicomview.cc@89efc666105c |
children | 773f89037a35 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/viewer.cc Wed Dec 31 07:53:53 2014 +0200 1.3 @@ -0,0 +1,248 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include "opengl.h" 1.7 +#include "viewer.h" 1.8 +#include "rend_fast.h" 1.9 +#include "opt.h" 1.10 +#include "volume.h" 1.11 +#include "xfer_view.h" 1.12 + 1.13 +static int win_width, win_height; 1.14 +static float cam_theta, cam_phi, cam_dist = 4; 1.15 +static float pre_rot = -90; 1.16 +static int splitter_y = -1; 1.17 + 1.18 +#define SPLITTER_WIDTH 5 1.19 + 1.20 +static Renderer *rend; 1.21 +static Volume *vol; 1.22 +static TransferFunc *xfer; 1.23 + 1.24 +extern "C" { 1.25 + 1.26 +int init() 1.27 +{ 1.28 + if(!opt.fname) { 1.29 + fprintf(stderr, "you must specify the volume data filename\n"); 1.30 + return -1; 1.31 + } 1.32 + 1.33 + switch(opt.rend_type) { 1.34 + case REND_FAST: 1.35 + rend = new RendererFast; 1.36 + break; 1.37 + default: 1.38 + return -1; 1.39 + } 1.40 + 1.41 + if(!rend->init()) { 1.42 + fprintf(stderr, "renderer initialization failed\n"); 1.43 + return -1; 1.44 + } 1.45 + 1.46 + VoxelVolume *voxvol = new VoxelVolume; 1.47 + if(!voxvol->load(opt.fname)) { 1.48 + fprintf(stderr, "failed to load volume data from: %s\n", opt.fname); 1.49 + return -1; 1.50 + } 1.51 + vol = voxvol; 1.52 + rend->set_volume(vol); 1.53 + 1.54 + xfer = new TransferWindow; 1.55 + rend->set_transfer_function(xfer); 1.56 + 1.57 + if(!xfview_init(xfer)) { 1.58 + return -1; 1.59 + } 1.60 + 1.61 + return 0; 1.62 +} 1.63 + 1.64 +void cleanup() 1.65 +{ 1.66 + xfview_destroy(); 1.67 + 1.68 + rend->destroy(); 1.69 + delete rend; 1.70 + delete vol; 1.71 + delete xfer; 1.72 +} 1.73 + 1.74 +void ev_display() 1.75 +{ 1.76 + glClear(GL_COLOR_BUFFER_BIT); 1.77 + 1.78 + // render the main view 1.79 + glViewport(0, win_height - splitter_y, win_width, splitter_y); 1.80 + 1.81 + glMatrixMode(GL_PROJECTION); 1.82 + glLoadIdentity(); 1.83 + gluPerspective(50.0, (float)win_width / (float)splitter_y, 0.1, 100.0); 1.84 + 1.85 + glMatrixMode(GL_MODELVIEW); 1.86 + glLoadIdentity(); 1.87 + glTranslatef(0, 0, -cam_dist); 1.88 + glRotatef(cam_phi + pre_rot, 1, 0, 0); 1.89 + glRotatef(cam_theta, 0, 1, 0); 1.90 + 1.91 + rend->update(0); 1.92 + rend->render(); 1.93 + 1.94 + // draw the transfer function view 1.95 + glViewport(0, 0, win_width, win_height - splitter_y); 1.96 + 1.97 + xfview_draw(); 1.98 + 1.99 + // draw the GUI 1.100 + glViewport(0, 0, win_width, win_height); 1.101 + 1.102 + glMatrixMode(GL_PROJECTION); 1.103 + glLoadIdentity(); 1.104 + glOrtho(0, win_width, win_height, 0, -1, 1); 1.105 + 1.106 + glMatrixMode(GL_MODELVIEW); 1.107 + glLoadIdentity(); 1.108 + 1.109 + glBegin(GL_QUADS); 1.110 + glColor3f(1, 1, 1); 1.111 + glVertex2f(0, splitter_y + SPLITTER_WIDTH / 2); 1.112 + glVertex2f(win_width, splitter_y + SPLITTER_WIDTH / 2); 1.113 + glVertex2f(win_width, splitter_y - SPLITTER_WIDTH / 2); 1.114 + glVertex2f(0, splitter_y - SPLITTER_WIDTH / 2); 1.115 + glEnd(); 1.116 + 1.117 + swap_buffers(); 1.118 +} 1.119 + 1.120 +void ev_reshape(int x, int y) 1.121 +{ 1.122 + if(splitter_y < 0) { // not initialized yet 1.123 + splitter_y = (int)(y * 0.85); 1.124 + } else { 1.125 + // calculate where the splitter was relative to the window height 1.126 + // and based on that, it's new position 1.127 + float split = (float)splitter_y / (float)win_height; 1.128 + splitter_y = (int)(y * split); 1.129 + } 1.130 + 1.131 + win_width = x; 1.132 + win_height = y; 1.133 + 1.134 + glViewport(0, 0, x, y); 1.135 + if(rend) { 1.136 + rend->reshape(x, y); 1.137 + } 1.138 +} 1.139 + 1.140 +static bool zscaling; 1.141 + 1.142 +void ev_keyboard(int key, int press, int x, int y) 1.143 +{ 1.144 + RendererFast *fr; 1.145 + 1.146 + switch(key) { 1.147 + case 27: 1.148 + if(press) { 1.149 + quit(); 1.150 + } 1.151 + break; 1.152 + 1.153 + case 'z': 1.154 + case 'Z': 1.155 + zscaling = press; 1.156 + break; 1.157 + 1.158 + case '=': 1.159 + if(press && (fr = dynamic_cast<RendererFast*>(rend))) { 1.160 + int n = fr->get_proxy_count(); 1.161 + int add = n / 4; 1.162 + n += add < 1 ? 1 : add; 1.163 + printf("proxy count: %d\n", n); 1.164 + fr->set_proxy_count(n); 1.165 + redisplay(); 1.166 + } 1.167 + break; 1.168 + 1.169 + case '-': 1.170 + if(press && (fr = dynamic_cast<RendererFast*>(rend))) { 1.171 + int n = fr->get_proxy_count(); 1.172 + int sub = n / 4; 1.173 + n -= sub < 1 ? 1 : sub; 1.174 + 1.175 + if(n < 1) n = 1; 1.176 + 1.177 + printf("proxy count: %d\n", n); 1.178 + fr->set_proxy_count(n); 1.179 + redisplay(); 1.180 + } 1.181 + break; 1.182 + 1.183 + default: 1.184 + break; 1.185 + } 1.186 +} 1.187 + 1.188 +static bool bnstate[8]; 1.189 +static int prev_x, prev_y; 1.190 + 1.191 +#define ON_SPLITTER(y) (abs(y - splitter_y) <= SPLITTER_WIDTH / 2) 1.192 +static bool splitter_dragging; 1.193 + 1.194 +void ev_mouse_button(int bn, int press, int x, int y) 1.195 +{ 1.196 + bnstate[bn] = press != 0; 1.197 + prev_x = x; 1.198 + prev_y = y; 1.199 + 1.200 + splitter_dragging = bn == 0 && press && ON_SPLITTER(y); 1.201 + 1.202 + if(!splitter_dragging && y > splitter_y) { 1.203 + xfview_button(bn, press, x, y); 1.204 + } 1.205 +} 1.206 + 1.207 +void ev_mouse_motion(int x, int y) 1.208 +{ 1.209 + int dx = x - prev_x; 1.210 + int dy = y - prev_y; 1.211 + prev_x = x; 1.212 + prev_y = y; 1.213 + 1.214 + if((dx | dy) == 0) return; 1.215 + 1.216 + if(bnstate[0] && zscaling) { 1.217 + float s = rend->get_zscale() + (float)dy / (float)win_height; 1.218 + rend->set_zscale(s < 0.0 ? 0.0 : s); 1.219 + redisplay(); 1.220 + return; 1.221 + } 1.222 + 1.223 + if(splitter_dragging) { 1.224 + splitter_y += dy; 1.225 + redisplay(); 1.226 + return; 1.227 + } 1.228 + 1.229 + if(y > splitter_y) { 1.230 + xfview_motion(x, y); 1.231 + return; 1.232 + } 1.233 + 1.234 + // main view motion handling 1.235 + if(bnstate[0]) { 1.236 + cam_theta += dx * 0.5; 1.237 + cam_phi += dy * 0.5; 1.238 + 1.239 + if(cam_phi < -90) cam_phi = -90; 1.240 + if(cam_phi > 90) cam_phi = 90; 1.241 + redisplay(); 1.242 + } 1.243 + if(bnstate[2]) { 1.244 + cam_dist += dy * 0.1; 1.245 + 1.246 + if(cam_dist < 0.0) cam_dist = 0.0; 1.247 + redisplay(); 1.248 + } 1.249 +} 1.250 + 1.251 +} // extern "C"