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