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  }