glviewvol

view src/xfer_view.cc @ 12:773f89037a35

added copyright headers
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 31 Dec 2014 07:57:04 +0200
parents 73edd1b7c2da
children 0d2447b9c512
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"
24 static TransferFunc *xfer;
26 static int act_color = -1;
27 static int grabbed_handle = -1;
28 static int mousex, mousey;
30 bool xfview_init(TransferFunc *xferarg)
31 {
32 xfer = xferarg;
33 return true;
34 }
36 void xfview_destroy()
37 {
38 }
40 void xfview_draw()
41 {
42 float line_color[][3] = {
43 { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { 1, 1, 1 }
44 };
46 glMatrixMode(GL_PROJECTION);
47 glLoadIdentity();
48 glOrtho(0, 1, 0, 1, -1, 1);
50 glMatrixMode(GL_MODELVIEW);
51 glLoadIdentity();
53 int xsz, ysz;
54 get_window_size(&xsz, &ysz);
55 int nsamples = xsz / 4;
57 // paint the background a faint version of the selected color
58 glBegin(GL_QUADS);
59 int cidx = act_color == -1 ? 3 : act_color;
60 glColor3f(line_color[cidx][0] * 0.1, line_color[cidx][1] * 0.1, line_color[cidx][2] * 0.1);
61 glVertex2f(-1, -1);
62 glVertex2f(1, -1);
63 glVertex2f(1, 1);
64 glVertex2f(-1, 1);
65 glEnd();
67 glEnable(GL_LINE_SMOOTH);
69 glEnable(GL_BLEND);
70 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
72 // draw handles on the selected curve
73 TransferWindow *xfwin = dynamic_cast<TransferWindow*>(xfer);
74 if(xfwin) {
75 float dx = 1.0 / (float)xsz;
76 float cursor = (float)mousex / (float)xsz;
77 float low[3], high[3];
78 xfwin->get_interval_rgba(low, high);
80 if(act_color == -1) { // all curves
81 int nearest = xfwin->nearest_handle(-1, cursor);
83 if(grabbed_handle != -1) {
84 glBegin(GL_LINES);
85 glColor3f(0.8, 0.8, 0.8);
86 for(int i=0; i<3; i++) {
87 float x = xfwin->get_handle(i, nearest);
88 float rad = xfwin->get_soft_radius();
89 glVertex2f(x - rad, 0.5);
90 glVertex2f(x + rad, 0.5);
91 glVertex2f(x - rad, 0.4);
92 glVertex2f(x - rad, 0.6);
93 glVertex2f(x + rad, 0.4);
94 glVertex2f(x + rad, 0.6);
95 }
96 glEnd();
97 }
99 // draw handles on all lines, highlighting the nearest side of all of them
100 glBegin(GL_QUADS);
101 glColor3f(1, 1, 1);
103 for(int i=0; i<3; i++) {
104 float x = nearest == TransferWindow::HANDLE_LOW ? low[i] : high[i];
105 glVertex2f(x - 2.0 * dx, -1);
106 glVertex2f(x + 2.0 * dx, -1);
107 glVertex2f(x + 2.0 * dx, 1);
108 glVertex2f(x - 2.0 * dx, 1);
109 }
110 for(int i=0; i<3; i++) {
111 glColor3fv(line_color[i]);
112 glVertex2f(low[i] - dx, -1);
113 glVertex2f(low[i] + dx, -1);
114 glVertex2f(low[i] + dx, 1);
115 glVertex2f(low[i] - dx, 1);
116 glVertex2f(high[i] - dx, -1);
117 glVertex2f(high[i] + dx, -1);
118 glVertex2f(high[i] + dx, 1);
119 glVertex2f(high[i] - dx, 1);
120 }
121 glEnd();
123 } else {
124 int nearest = xfwin->nearest_handle(act_color, cursor);
125 float x = nearest == TransferWindow::HANDLE_LOW ? low[act_color] : high[act_color];
127 if(grabbed_handle != -1) {
128 float x = xfwin->get_handle(act_color, nearest);
129 float rad = xfwin->get_soft_radius();
131 glBegin(GL_LINES);
132 glColor3f(0.8, 0.8, 0.8);
133 glVertex2f(x - rad, 0.5);
134 glVertex2f(x + rad, 0.5);
135 glVertex2f(x - rad, 0.4);
136 glVertex2f(x - rad, 0.6);
137 glVertex2f(x + rad, 0.4);
138 glVertex2f(x + rad, 0.6);
139 glEnd();
140 }
143 glBegin(GL_QUADS);
144 glColor3f(1, 1, 1);
145 glVertex2f(x - 2.0 * dx, -1);
146 glVertex2f(x + 2.0 * dx, -1);
147 glVertex2f(x + 2.0 * dx, 1);
148 glVertex2f(x - 2.0 * dx, 1);
150 glColor3fv(line_color[act_color]);
151 for(int i=0; i<2; i++) {
152 glVertex2f(x - dx, -1);
153 glVertex2f(x + dx, -1);
154 glVertex2f(x + dx, 1);
155 glVertex2f(x - dx, 1);
156 x = nearest == TransferWindow::HANDLE_LOW ? high[act_color] : low[act_color];
157 }
158 glEnd();
159 }
160 }
162 // draw curve
163 glLineWidth(2.0);
165 for(int i=0; i<4; i++) {
166 int idx;
167 if(act_color == -1) {
168 idx = i;
169 } else {
170 idx = (i + act_color + 1) % 4;
171 }
173 glColor3fv(line_color[idx]);
175 glBegin(GL_LINE_STRIP);
176 for(int j=0; j<nsamples; j++) {
177 float t = (float)j / (float)(nsamples - 1);
178 float vval[4];
180 if(idx < 3) {
181 xfer->map(t, vval);
182 } else {
183 vval[3] = xfer->map(t);
184 }
186 glVertex2f(t, vval[idx]);
187 }
188 glEnd();
189 }
191 glDisable(GL_BLEND);
192 }
194 static int prev_x, prev_y;
196 void xfview_button(int bn, int press, int x, int y)
197 {
198 prev_x = x;
199 prev_y = y;
201 if(bn == 2 && press && grabbed_handle == -1) {
202 act_color = (act_color + 2) % 4 - 1;
203 redisplay();
204 return;
205 }
207 if(bn == 0) {
208 int xsz, ysz;
209 get_window_size(&xsz, &ysz);
211 TransferWindow *xfwin = dynamic_cast<TransferWindow*>(xfer);
212 if(xfwin && press) {
213 float cursor = (float)x / (float)xsz;
214 float low[3], high[3];
215 xfwin->get_interval_rgba(low, high);
217 // grab the nearest handle
218 grabbed_handle = xfwin->nearest_handle(act_color, cursor);
219 } else {
220 grabbed_handle = -1;
221 }
222 redisplay();
223 }
224 }
226 void xfview_motion(int x, int y)
227 {
228 mousex = x;
229 mousey = y;
231 int dx = x - prev_x;
232 int dy = y - prev_y;
233 prev_x = x;
234 prev_y = y;
236 if(grabbed_handle != -1) {
237 TransferWindow *xfwin = dynamic_cast<TransferWindow*>(xfer);
238 if(!xfwin) return;
240 int xsz, ysz;
241 get_window_size(&xsz, &ysz);
243 if(get_modifiers()) {
244 float soft = xfwin->get_soft_radius() + dy * 0.01;
245 if(soft < 0.0) soft = 0.0;
246 xfwin->set_soft_radius(soft);
247 } else {
248 float pos = (float)x / (float)xsz;
249 xfwin->set_handle(act_color, grabbed_handle, pos);
250 }
251 }
253 redisplay();
254 }