glviewvol

view src/xfer_view.cc @ 14:0d2447b9c512

did the histogram... doesn't seem to work right
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 01 Jan 2015 06:36:45 +0200
parents 773f89037a35
children
line source
1 /*
2 glviewvol is an OpenGL 3D volume data viewer
3 Copyright (C) 2014 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include <stdio.h>
19 #include <math.h>
20 #include "opengl.h"
21 #include "xfer_view.h"
22 #include "viewer.h"
23 #include "volume.h"
25 static void draw_histogram();
27 static TransferFunc *xfer;
28 static Volume *vol;
30 static int act_color = -1;
31 static int grabbed_handle = -1;
32 static int mousex, mousey;
34 bool xfview_init(TransferFunc *xferarg)
35 {
36 xfer = xferarg;
37 return true;
38 }
40 void xfview_destroy()
41 {
42 }
44 void xfview_set_volume(Volume *volarg)
45 {
46 vol = volarg;
47 }
49 void xfview_draw()
50 {
51 float line_color[][3] = {
52 { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { 1, 1, 1 }
53 };
55 glMatrixMode(GL_PROJECTION);
56 glLoadIdentity();
57 glOrtho(0, 1, 0, 1, -1, 1);
59 glMatrixMode(GL_MODELVIEW);
60 glLoadIdentity();
62 int xsz, ysz;
63 get_window_size(&xsz, &ysz);
64 int nsamples = xsz / 4;
66 // paint the background a faint version of the selected color
67 glBegin(GL_QUADS);
68 int cidx = act_color == -1 ? 3 : act_color;
69 glColor3f(line_color[cidx][0] * 0.1, line_color[cidx][1] * 0.1, line_color[cidx][2] * 0.1);
70 glVertex2f(-1, -1);
71 glVertex2f(1, -1);
72 glVertex2f(1, 1);
73 glVertex2f(-1, 1);
74 glEnd();
76 draw_histogram();
78 glEnable(GL_LINE_SMOOTH);
80 glEnable(GL_BLEND);
81 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
83 // draw handles on the selected curve
84 TransferWindow *xfwin = dynamic_cast<TransferWindow*>(xfer);
85 if(xfwin) {
86 float dx = 1.0 / (float)xsz;
87 float cursor = (float)mousex / (float)xsz;
88 float low[3], high[3];
89 xfwin->get_interval_rgba(low, high);
91 if(act_color == -1) { // all curves
92 int nearest = xfwin->nearest_handle(-1, cursor);
94 if(grabbed_handle != -1) {
95 glBegin(GL_LINES);
96 glColor3f(0.8, 0.8, 0.8);
97 for(int i=0; i<3; i++) {
98 float x = xfwin->get_handle(i, nearest);
99 float rad = xfwin->get_soft_radius();
100 glVertex2f(x - rad, 0.5);
101 glVertex2f(x + rad, 0.5);
102 glVertex2f(x - rad, 0.4);
103 glVertex2f(x - rad, 0.6);
104 glVertex2f(x + rad, 0.4);
105 glVertex2f(x + rad, 0.6);
106 }
107 glEnd();
108 }
110 // draw handles on all lines, highlighting the nearest side of all of them
111 glBegin(GL_QUADS);
112 glColor3f(1, 1, 1);
114 for(int i=0; i<3; i++) {
115 float x = nearest == TransferWindow::HANDLE_LOW ? low[i] : high[i];
116 glVertex2f(x - 2.0 * dx, -1);
117 glVertex2f(x + 2.0 * dx, -1);
118 glVertex2f(x + 2.0 * dx, 1);
119 glVertex2f(x - 2.0 * dx, 1);
120 }
121 for(int i=0; i<3; i++) {
122 glColor3fv(line_color[i]);
123 glVertex2f(low[i] - dx, -1);
124 glVertex2f(low[i] + dx, -1);
125 glVertex2f(low[i] + dx, 1);
126 glVertex2f(low[i] - dx, 1);
127 glVertex2f(high[i] - dx, -1);
128 glVertex2f(high[i] + dx, -1);
129 glVertex2f(high[i] + dx, 1);
130 glVertex2f(high[i] - dx, 1);
131 }
132 glEnd();
134 } else {
135 int nearest = xfwin->nearest_handle(act_color, cursor);
136 float x = nearest == TransferWindow::HANDLE_LOW ? low[act_color] : high[act_color];
138 if(grabbed_handle != -1) {
139 float x = xfwin->get_handle(act_color, nearest);
140 float rad = xfwin->get_soft_radius();
142 glBegin(GL_LINES);
143 glColor3f(0.8, 0.8, 0.8);
144 glVertex2f(x - rad, 0.5);
145 glVertex2f(x + rad, 0.5);
146 glVertex2f(x - rad, 0.4);
147 glVertex2f(x - rad, 0.6);
148 glVertex2f(x + rad, 0.4);
149 glVertex2f(x + rad, 0.6);
150 glEnd();
151 }
154 glBegin(GL_QUADS);
155 glColor3f(1, 1, 1);
156 glVertex2f(x - 2.0 * dx, -1);
157 glVertex2f(x + 2.0 * dx, -1);
158 glVertex2f(x + 2.0 * dx, 1);
159 glVertex2f(x - 2.0 * dx, 1);
161 glColor3fv(line_color[act_color]);
162 for(int i=0; i<2; i++) {
163 glVertex2f(x - dx, -1);
164 glVertex2f(x + dx, -1);
165 glVertex2f(x + dx, 1);
166 glVertex2f(x - dx, 1);
167 x = nearest == TransferWindow::HANDLE_LOW ? high[act_color] : low[act_color];
168 }
169 glEnd();
170 }
171 }
173 // draw curve
174 glLineWidth(2.0);
176 for(int i=0; i<4; i++) {
177 int idx;
178 if(act_color == -1) {
179 idx = i;
180 } else {
181 idx = (i + act_color + 1) % 4;
182 }
184 glColor3fv(line_color[idx]);
186 glBegin(GL_LINE_STRIP);
187 for(int j=0; j<nsamples; j++) {
188 float t = (float)j / (float)(nsamples - 1);
189 float vval[4];
191 if(idx < 3) {
192 xfer->map(t, vval);
193 } else {
194 vval[3] = xfer->map(t);
195 }
197 glVertex2f(t, vval[idx]);
198 }
199 glEnd();
200 }
202 glDisable(GL_BLEND);
203 }
205 #define HIST_SAMPLES 256
207 static void draw_histogram()
208 {
209 VoxelVolume *voxvol = dynamic_cast<VoxelVolume*>(vol);
210 if(!voxvol) return;
212 float *hist = voxvol->calc_histogram(HIST_SAMPLES);
213 if(!hist) return;
215 float max_y = 0.0f;
216 for(int i=0; i<HIST_SAMPLES; i++) {
217 if(hist[i] > max_y) {
218 max_y = hist[i];
219 }
220 }
222 float dx = 1.0 / (float)HIST_SAMPLES;
223 glBegin(GL_QUADS);
224 glColor3f(0.6, 0.6, 0.6);
225 for(int i=0; i<HIST_SAMPLES; i++) {
226 float x0 = (float)i / (float)HIST_SAMPLES;
227 float x1 = x0 + dx;
229 float y = hist[i] / max_y;
231 glVertex2f(x0, 0);
232 glVertex2f(x1, 0);
233 glVertex2f(x1, y);
234 glVertex2f(x0, y);
235 }
236 glEnd();
237 }
239 static int prev_x, prev_y;
241 void xfview_button(int bn, int press, int x, int y)
242 {
243 prev_x = x;
244 prev_y = y;
246 if(bn == 2 && press && grabbed_handle == -1) {
247 act_color = (act_color + 2) % 4 - 1;
248 redisplay();
249 return;
250 }
252 if(bn == 0) {
253 int xsz, ysz;
254 get_window_size(&xsz, &ysz);
256 TransferWindow *xfwin = dynamic_cast<TransferWindow*>(xfer);
257 if(xfwin && press) {
258 float cursor = (float)x / (float)xsz;
259 float low[3], high[3];
260 xfwin->get_interval_rgba(low, high);
262 // grab the nearest handle
263 grabbed_handle = xfwin->nearest_handle(act_color, cursor);
264 } else {
265 grabbed_handle = -1;
266 }
267 redisplay();
268 }
269 }
271 void xfview_motion(int x, int y)
272 {
273 mousex = x;
274 mousey = y;
276 int dx = x - prev_x;
277 int dy = y - prev_y;
278 prev_x = x;
279 prev_y = y;
281 if(grabbed_handle != -1) {
282 TransferWindow *xfwin = dynamic_cast<TransferWindow*>(xfer);
283 if(!xfwin) return;
285 int xsz, ysz;
286 get_window_size(&xsz, &ysz);
288 if(get_modifiers()) {
289 float soft = xfwin->get_soft_radius() + dy * 0.01;
290 if(soft < 0.0) soft = 0.0;
291 xfwin->set_soft_radius(soft);
292 } else {
293 float pos = (float)x / (float)xsz;
294 xfwin->set_handle(act_color, grabbed_handle, pos);
295 }
296 }
298 redisplay();
299 }