glviewvol
diff src/xfer_view.cc @ 7:71b479ffb9f7
curve manipulation works
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 30 Dec 2014 17:28:38 +0200 |
parents | f22be47a3572 |
children | 73edd1b7c2da |
line diff
1.1 --- a/src/xfer_view.cc Tue Dec 30 06:22:54 2014 +0200 1.2 +++ b/src/xfer_view.cc Tue Dec 30 17:28:38 2014 +0200 1.3 @@ -1,11 +1,14 @@ 1.4 #include <stdio.h> 1.5 +#include <math.h> 1.6 #include "opengl.h" 1.7 #include "xfer_view.h" 1.8 #include "dicomview.h" 1.9 1.10 static TransferFunc *xfer; 1.11 1.12 -static int act_color = 3; 1.13 +static int act_color = -1; 1.14 +static int grabbed_handle = -1; 1.15 +static int mousex, mousey; 1.16 1.17 bool xfview_init(TransferFunc *xferarg) 1.18 { 1.19 @@ -25,6 +28,8 @@ 1.20 1.21 glMatrixMode(GL_PROJECTION); 1.22 glLoadIdentity(); 1.23 + glOrtho(0, 1, 0, 1, -1, 1); 1.24 + 1.25 glMatrixMode(GL_MODELVIEW); 1.26 glLoadIdentity(); 1.27 1.28 @@ -34,7 +39,8 @@ 1.29 1.30 // paint the background a faint version of the selected color 1.31 glBegin(GL_QUADS); 1.32 - glColor3f(line_color[act_color][0] * 0.1, line_color[act_color][1] * 0.1, line_color[act_color][2] * 0.1); 1.33 + int cidx = act_color == -1 ? 3 : act_color; 1.34 + glColor3f(line_color[cidx][0] * 0.1, line_color[cidx][1] * 0.1, line_color[cidx][2] * 0.1); 1.35 glVertex2f(-1, -1); 1.36 glVertex2f(1, -1); 1.37 glVertex2f(1, 1); 1.38 @@ -46,15 +52,105 @@ 1.39 glEnable(GL_BLEND); 1.40 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1.41 1.42 + // draw handles on the selected curve 1.43 + TransferWindow *xfwin = dynamic_cast<TransferWindow*>(xfer); 1.44 + if(xfwin) { 1.45 + float dx = 1.0 / (float)xsz; 1.46 + float cursor = (float)mousex / (float)xsz; 1.47 + float low[3], high[3]; 1.48 + xfwin->get_interval_rgba(low, high); 1.49 + 1.50 + if(act_color == -1) { // all curves 1.51 + int nearest = xfwin->nearest_handle(-1, cursor); 1.52 + 1.53 + if(grabbed_handle != -1) { 1.54 + glBegin(GL_LINES); 1.55 + glColor3f(0.8, 0.8, 0.8); 1.56 + for(int i=0; i<3; i++) { 1.57 + float x = xfwin->get_handle(i, nearest); 1.58 + float rad = xfwin->get_soft_radius(); 1.59 + glVertex2f(x - rad, 0.5); 1.60 + glVertex2f(x + rad, 0.5); 1.61 + glVertex2f(x - rad, 0.4); 1.62 + glVertex2f(x - rad, 0.6); 1.63 + glVertex2f(x + rad, 0.4); 1.64 + glVertex2f(x + rad, 0.6); 1.65 + } 1.66 + glEnd(); 1.67 + } 1.68 + 1.69 + // draw handles on all lines, highlighting the nearest side of all of them 1.70 + glBegin(GL_QUADS); 1.71 + glColor3f(1, 1, 1); 1.72 + 1.73 + for(int i=0; i<3; i++) { 1.74 + float x = nearest == TransferWindow::HANDLE_LOW ? low[i] : high[i]; 1.75 + glVertex2f(x - 2.0 * dx, -1); 1.76 + glVertex2f(x + 2.0 * dx, -1); 1.77 + glVertex2f(x + 2.0 * dx, 1); 1.78 + glVertex2f(x - 2.0 * dx, 1); 1.79 + } 1.80 + for(int i=0; i<3; i++) { 1.81 + glColor3fv(line_color[i]); 1.82 + glVertex2f(low[i] - dx, -1); 1.83 + glVertex2f(low[i] + dx, -1); 1.84 + glVertex2f(low[i] + dx, 1); 1.85 + glVertex2f(low[i] - dx, 1); 1.86 + glVertex2f(high[i] - dx, -1); 1.87 + glVertex2f(high[i] + dx, -1); 1.88 + glVertex2f(high[i] + dx, 1); 1.89 + glVertex2f(high[i] - dx, 1); 1.90 + } 1.91 + glEnd(); 1.92 + 1.93 + } else { 1.94 + int nearest = xfwin->nearest_handle(act_color, cursor); 1.95 + float x = nearest == TransferWindow::HANDLE_LOW ? low[act_color] : high[act_color]; 1.96 + 1.97 + if(grabbed_handle != -1) { 1.98 + float x = xfwin->get_handle(act_color, nearest); 1.99 + float rad = xfwin->get_soft_radius(); 1.100 + 1.101 + glBegin(GL_LINES); 1.102 + glColor3f(0.8, 0.8, 0.8); 1.103 + glVertex2f(x - rad, 0.5); 1.104 + glVertex2f(x + rad, 0.5); 1.105 + glVertex2f(x - rad, 0.4); 1.106 + glVertex2f(x - rad, 0.6); 1.107 + glVertex2f(x + rad, 0.4); 1.108 + glVertex2f(x + rad, 0.6); 1.109 + glEnd(); 1.110 + } 1.111 + 1.112 + 1.113 + glBegin(GL_QUADS); 1.114 + glColor3f(1, 1, 1); 1.115 + glVertex2f(x - 2.0 * dx, -1); 1.116 + glVertex2f(x + 2.0 * dx, -1); 1.117 + glVertex2f(x + 2.0 * dx, 1); 1.118 + glVertex2f(x - 2.0 * dx, 1); 1.119 + 1.120 + glColor3fv(line_color[act_color]); 1.121 + for(int i=0; i<2; i++) { 1.122 + glVertex2f(x - dx, -1); 1.123 + glVertex2f(x + dx, -1); 1.124 + glVertex2f(x + dx, 1); 1.125 + glVertex2f(x - dx, 1); 1.126 + x = nearest == TransferWindow::HANDLE_LOW ? high[act_color] : low[act_color]; 1.127 + } 1.128 + glEnd(); 1.129 + } 1.130 + } 1.131 + 1.132 // draw curve 1.133 glLineWidth(2.0); 1.134 1.135 - for(int i=0; i<3; i++) { 1.136 + for(int i=0; i<4; i++) { 1.137 int idx; 1.138 - if(act_color < 3) { 1.139 - idx = (i + act_color + 1) % 3; 1.140 + if(act_color == -1) { 1.141 + idx = i; 1.142 } else { 1.143 - idx = i; 1.144 + idx = (i + act_color + 1) % 4; 1.145 } 1.146 1.147 glColor3fv(line_color[idx]); 1.148 @@ -63,9 +159,14 @@ 1.149 for(int j=0; j<nsamples; j++) { 1.150 float t = (float)j / (float)(nsamples - 1); 1.151 float vval[4]; 1.152 - xfer->map(t, vval); 1.153 1.154 - glVertex2f(t * 2.0 - 1.0, vval[i] * 2.0 - 1.0); 1.155 + if(idx < 3) { 1.156 + xfer->map(t, vval); 1.157 + } else { 1.158 + vval[3] = xfer->map(t); 1.159 + } 1.160 + 1.161 + glVertex2f(t, vval[idx]); 1.162 } 1.163 glEnd(); 1.164 } 1.165 @@ -73,21 +174,64 @@ 1.166 glDisable(GL_BLEND); 1.167 } 1.168 1.169 +static int prev_x, prev_y; 1.170 + 1.171 void xfview_button(int bn, int press, int x, int y) 1.172 { 1.173 - if(bn == 2 && press) { 1.174 - act_color = (act_color + 1) % 4; 1.175 + prev_x = x; 1.176 + prev_y = y; 1.177 + 1.178 + if(bn == 2 && press && grabbed_handle == -1) { 1.179 + act_color = (act_color + 2) % 4 - 1; 1.180 redisplay(); 1.181 return; 1.182 } 1.183 1.184 - if(bn == 1) { 1.185 - if(press) { 1.186 + if(bn == 0) { 1.187 + int xsz, ysz; 1.188 + get_window_size(&xsz, &ysz); 1.189 + 1.190 + TransferWindow *xfwin = dynamic_cast<TransferWindow*>(xfer); 1.191 + if(xfwin && press) { 1.192 + float cursor = (float)x / (float)xsz; 1.193 + float low[3], high[3]; 1.194 + xfwin->get_interval_rgba(low, high); 1.195 + 1.196 + // grab the nearest handle 1.197 + grabbed_handle = xfwin->nearest_handle(act_color, cursor); 1.198 } else { 1.199 + grabbed_handle = -1; 1.200 } 1.201 + redisplay(); 1.202 } 1.203 } 1.204 1.205 void xfview_motion(int x, int y) 1.206 { 1.207 + mousex = x; 1.208 + mousey = y; 1.209 + 1.210 + int dx = x - prev_x; 1.211 + int dy = y - prev_y; 1.212 + prev_x = x; 1.213 + prev_y = y; 1.214 + 1.215 + if(grabbed_handle != -1) { 1.216 + TransferWindow *xfwin = dynamic_cast<TransferWindow*>(xfer); 1.217 + if(!xfwin) return; 1.218 + 1.219 + int xsz, ysz; 1.220 + get_window_size(&xsz, &ysz); 1.221 + 1.222 + if(get_modifiers()) { 1.223 + float soft = xfwin->get_soft_radius() + dy * 0.01; 1.224 + if(soft < 0.0) soft = 0.0; 1.225 + xfwin->set_soft_radius(soft); 1.226 + } else { 1.227 + float pos = (float)x / (float)xsz; 1.228 + xfwin->set_handle(act_color, grabbed_handle, pos); 1.229 + } 1.230 + } 1.231 + 1.232 + redisplay(); 1.233 }