glviewvol
view src/xfer_view.cc @ 8:fb6d93471352
main thing done
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 30 Dec 2014 20:03:32 +0200 |
parents | f22be47a3572 |
children | 73edd1b7c2da |
line source
1 #include <stdio.h>
2 #include <math.h>
3 #include "opengl.h"
4 #include "xfer_view.h"
5 #include "dicomview.h"
7 static TransferFunc *xfer;
9 static int act_color = -1;
10 static int grabbed_handle = -1;
11 static int mousex, mousey;
13 bool xfview_init(TransferFunc *xferarg)
14 {
15 xfer = xferarg;
16 return true;
17 }
19 void xfview_destroy()
20 {
21 }
23 void xfview_draw()
24 {
25 float line_color[][3] = {
26 { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { 1, 1, 1 }
27 };
29 glMatrixMode(GL_PROJECTION);
30 glLoadIdentity();
31 glOrtho(0, 1, 0, 1, -1, 1);
33 glMatrixMode(GL_MODELVIEW);
34 glLoadIdentity();
36 int xsz, ysz;
37 get_window_size(&xsz, &ysz);
38 int nsamples = xsz / 4;
40 // paint the background a faint version of the selected color
41 glBegin(GL_QUADS);
42 int cidx = act_color == -1 ? 3 : act_color;
43 glColor3f(line_color[cidx][0] * 0.1, line_color[cidx][1] * 0.1, line_color[cidx][2] * 0.1);
44 glVertex2f(-1, -1);
45 glVertex2f(1, -1);
46 glVertex2f(1, 1);
47 glVertex2f(-1, 1);
48 glEnd();
50 glEnable(GL_LINE_SMOOTH);
52 glEnable(GL_BLEND);
53 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
55 // draw handles on the selected curve
56 TransferWindow *xfwin = dynamic_cast<TransferWindow*>(xfer);
57 if(xfwin) {
58 float dx = 1.0 / (float)xsz;
59 float cursor = (float)mousex / (float)xsz;
60 float low[3], high[3];
61 xfwin->get_interval_rgba(low, high);
63 if(act_color == -1) { // all curves
64 int nearest = xfwin->nearest_handle(-1, cursor);
66 if(grabbed_handle != -1) {
67 glBegin(GL_LINES);
68 glColor3f(0.8, 0.8, 0.8);
69 for(int i=0; i<3; i++) {
70 float x = xfwin->get_handle(i, nearest);
71 float rad = xfwin->get_soft_radius();
72 glVertex2f(x - rad, 0.5);
73 glVertex2f(x + rad, 0.5);
74 glVertex2f(x - rad, 0.4);
75 glVertex2f(x - rad, 0.6);
76 glVertex2f(x + rad, 0.4);
77 glVertex2f(x + rad, 0.6);
78 }
79 glEnd();
80 }
82 // draw handles on all lines, highlighting the nearest side of all of them
83 glBegin(GL_QUADS);
84 glColor3f(1, 1, 1);
86 for(int i=0; i<3; i++) {
87 float x = nearest == TransferWindow::HANDLE_LOW ? low[i] : high[i];
88 glVertex2f(x - 2.0 * dx, -1);
89 glVertex2f(x + 2.0 * dx, -1);
90 glVertex2f(x + 2.0 * dx, 1);
91 glVertex2f(x - 2.0 * dx, 1);
92 }
93 for(int i=0; i<3; i++) {
94 glColor3fv(line_color[i]);
95 glVertex2f(low[i] - dx, -1);
96 glVertex2f(low[i] + dx, -1);
97 glVertex2f(low[i] + dx, 1);
98 glVertex2f(low[i] - dx, 1);
99 glVertex2f(high[i] - dx, -1);
100 glVertex2f(high[i] + dx, -1);
101 glVertex2f(high[i] + dx, 1);
102 glVertex2f(high[i] - dx, 1);
103 }
104 glEnd();
106 } else {
107 int nearest = xfwin->nearest_handle(act_color, cursor);
108 float x = nearest == TransferWindow::HANDLE_LOW ? low[act_color] : high[act_color];
110 if(grabbed_handle != -1) {
111 float x = xfwin->get_handle(act_color, nearest);
112 float rad = xfwin->get_soft_radius();
114 glBegin(GL_LINES);
115 glColor3f(0.8, 0.8, 0.8);
116 glVertex2f(x - rad, 0.5);
117 glVertex2f(x + rad, 0.5);
118 glVertex2f(x - rad, 0.4);
119 glVertex2f(x - rad, 0.6);
120 glVertex2f(x + rad, 0.4);
121 glVertex2f(x + rad, 0.6);
122 glEnd();
123 }
126 glBegin(GL_QUADS);
127 glColor3f(1, 1, 1);
128 glVertex2f(x - 2.0 * dx, -1);
129 glVertex2f(x + 2.0 * dx, -1);
130 glVertex2f(x + 2.0 * dx, 1);
131 glVertex2f(x - 2.0 * dx, 1);
133 glColor3fv(line_color[act_color]);
134 for(int i=0; i<2; i++) {
135 glVertex2f(x - dx, -1);
136 glVertex2f(x + dx, -1);
137 glVertex2f(x + dx, 1);
138 glVertex2f(x - dx, 1);
139 x = nearest == TransferWindow::HANDLE_LOW ? high[act_color] : low[act_color];
140 }
141 glEnd();
142 }
143 }
145 // draw curve
146 glLineWidth(2.0);
148 for(int i=0; i<4; i++) {
149 int idx;
150 if(act_color == -1) {
151 idx = i;
152 } else {
153 idx = (i + act_color + 1) % 4;
154 }
156 glColor3fv(line_color[idx]);
158 glBegin(GL_LINE_STRIP);
159 for(int j=0; j<nsamples; j++) {
160 float t = (float)j / (float)(nsamples - 1);
161 float vval[4];
163 if(idx < 3) {
164 xfer->map(t, vval);
165 } else {
166 vval[3] = xfer->map(t);
167 }
169 glVertex2f(t, vval[idx]);
170 }
171 glEnd();
172 }
174 glDisable(GL_BLEND);
175 }
177 static int prev_x, prev_y;
179 void xfview_button(int bn, int press, int x, int y)
180 {
181 prev_x = x;
182 prev_y = y;
184 if(bn == 2 && press && grabbed_handle == -1) {
185 act_color = (act_color + 2) % 4 - 1;
186 redisplay();
187 return;
188 }
190 if(bn == 0) {
191 int xsz, ysz;
192 get_window_size(&xsz, &ysz);
194 TransferWindow *xfwin = dynamic_cast<TransferWindow*>(xfer);
195 if(xfwin && press) {
196 float cursor = (float)x / (float)xsz;
197 float low[3], high[3];
198 xfwin->get_interval_rgba(low, high);
200 // grab the nearest handle
201 grabbed_handle = xfwin->nearest_handle(act_color, cursor);
202 } else {
203 grabbed_handle = -1;
204 }
205 redisplay();
206 }
207 }
209 void xfview_motion(int x, int y)
210 {
211 mousex = x;
212 mousey = y;
214 int dx = x - prev_x;
215 int dy = y - prev_y;
216 prev_x = x;
217 prev_y = y;
219 if(grabbed_handle != -1) {
220 TransferWindow *xfwin = dynamic_cast<TransferWindow*>(xfer);
221 if(!xfwin) return;
223 int xsz, ysz;
224 get_window_size(&xsz, &ysz);
226 if(get_modifiers()) {
227 float soft = xfwin->get_soft_radius() + dy * 0.01;
228 if(soft < 0.0) soft = 0.0;
229 xfwin->set_soft_radius(soft);
230 } else {
231 float pos = (float)x / (float)xsz;
232 xfwin->set_handle(act_color, grabbed_handle, pos);
233 }
234 }
236 redisplay();
237 }