glviewvol

annotate 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
rev   line source
nuclear@12 1 /*
nuclear@12 2 glviewvol is an OpenGL 3D volume data viewer
nuclear@12 3 Copyright (C) 2014 John Tsiombikas <nuclear@member.fsf.org>
nuclear@12 4
nuclear@12 5 This program is free software: you can redistribute it and/or modify
nuclear@12 6 it under the terms of the GNU General Public License as published by
nuclear@12 7 the Free Software Foundation, either version 3 of the License, or
nuclear@12 8 (at your option) any later version.
nuclear@12 9
nuclear@12 10 This program is distributed in the hope that it will be useful,
nuclear@12 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
nuclear@12 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
nuclear@12 13 GNU General Public License for more details.
nuclear@12 14
nuclear@12 15 You should have received a copy of the GNU General Public License
nuclear@12 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
nuclear@12 17 */
nuclear@4 18 #include <stdio.h>
nuclear@7 19 #include <math.h>
nuclear@4 20 #include "opengl.h"
nuclear@4 21 #include "xfer_view.h"
nuclear@11 22 #include "viewer.h"
nuclear@4 23
nuclear@6 24 static TransferFunc *xfer;
nuclear@4 25
nuclear@7 26 static int act_color = -1;
nuclear@7 27 static int grabbed_handle = -1;
nuclear@7 28 static int mousex, mousey;
nuclear@4 29
nuclear@6 30 bool xfview_init(TransferFunc *xferarg)
nuclear@4 31 {
nuclear@6 32 xfer = xferarg;
nuclear@4 33 return true;
nuclear@4 34 }
nuclear@4 35
nuclear@4 36 void xfview_destroy()
nuclear@4 37 {
nuclear@4 38 }
nuclear@4 39
nuclear@4 40 void xfview_draw()
nuclear@4 41 {
nuclear@4 42 float line_color[][3] = {
nuclear@4 43 { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { 1, 1, 1 }
nuclear@4 44 };
nuclear@4 45
nuclear@4 46 glMatrixMode(GL_PROJECTION);
nuclear@4 47 glLoadIdentity();
nuclear@7 48 glOrtho(0, 1, 0, 1, -1, 1);
nuclear@7 49
nuclear@4 50 glMatrixMode(GL_MODELVIEW);
nuclear@4 51 glLoadIdentity();
nuclear@4 52
nuclear@4 53 int xsz, ysz;
nuclear@4 54 get_window_size(&xsz, &ysz);
nuclear@4 55 int nsamples = xsz / 4;
nuclear@4 56
nuclear@4 57 // paint the background a faint version of the selected color
nuclear@4 58 glBegin(GL_QUADS);
nuclear@7 59 int cidx = act_color == -1 ? 3 : act_color;
nuclear@7 60 glColor3f(line_color[cidx][0] * 0.1, line_color[cidx][1] * 0.1, line_color[cidx][2] * 0.1);
nuclear@4 61 glVertex2f(-1, -1);
nuclear@4 62 glVertex2f(1, -1);
nuclear@4 63 glVertex2f(1, 1);
nuclear@4 64 glVertex2f(-1, 1);
nuclear@4 65 glEnd();
nuclear@4 66
nuclear@4 67 glEnable(GL_LINE_SMOOTH);
nuclear@4 68
nuclear@4 69 glEnable(GL_BLEND);
nuclear@4 70 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
nuclear@4 71
nuclear@7 72 // draw handles on the selected curve
nuclear@7 73 TransferWindow *xfwin = dynamic_cast<TransferWindow*>(xfer);
nuclear@7 74 if(xfwin) {
nuclear@7 75 float dx = 1.0 / (float)xsz;
nuclear@7 76 float cursor = (float)mousex / (float)xsz;
nuclear@7 77 float low[3], high[3];
nuclear@7 78 xfwin->get_interval_rgba(low, high);
nuclear@7 79
nuclear@7 80 if(act_color == -1) { // all curves
nuclear@7 81 int nearest = xfwin->nearest_handle(-1, cursor);
nuclear@7 82
nuclear@7 83 if(grabbed_handle != -1) {
nuclear@7 84 glBegin(GL_LINES);
nuclear@7 85 glColor3f(0.8, 0.8, 0.8);
nuclear@7 86 for(int i=0; i<3; i++) {
nuclear@7 87 float x = xfwin->get_handle(i, nearest);
nuclear@7 88 float rad = xfwin->get_soft_radius();
nuclear@7 89 glVertex2f(x - rad, 0.5);
nuclear@7 90 glVertex2f(x + rad, 0.5);
nuclear@7 91 glVertex2f(x - rad, 0.4);
nuclear@7 92 glVertex2f(x - rad, 0.6);
nuclear@7 93 glVertex2f(x + rad, 0.4);
nuclear@7 94 glVertex2f(x + rad, 0.6);
nuclear@7 95 }
nuclear@7 96 glEnd();
nuclear@7 97 }
nuclear@7 98
nuclear@7 99 // draw handles on all lines, highlighting the nearest side of all of them
nuclear@7 100 glBegin(GL_QUADS);
nuclear@7 101 glColor3f(1, 1, 1);
nuclear@7 102
nuclear@7 103 for(int i=0; i<3; i++) {
nuclear@7 104 float x = nearest == TransferWindow::HANDLE_LOW ? low[i] : high[i];
nuclear@7 105 glVertex2f(x - 2.0 * dx, -1);
nuclear@7 106 glVertex2f(x + 2.0 * dx, -1);
nuclear@7 107 glVertex2f(x + 2.0 * dx, 1);
nuclear@7 108 glVertex2f(x - 2.0 * dx, 1);
nuclear@7 109 }
nuclear@7 110 for(int i=0; i<3; i++) {
nuclear@7 111 glColor3fv(line_color[i]);
nuclear@7 112 glVertex2f(low[i] - dx, -1);
nuclear@7 113 glVertex2f(low[i] + dx, -1);
nuclear@7 114 glVertex2f(low[i] + dx, 1);
nuclear@7 115 glVertex2f(low[i] - dx, 1);
nuclear@7 116 glVertex2f(high[i] - dx, -1);
nuclear@7 117 glVertex2f(high[i] + dx, -1);
nuclear@7 118 glVertex2f(high[i] + dx, 1);
nuclear@7 119 glVertex2f(high[i] - dx, 1);
nuclear@7 120 }
nuclear@7 121 glEnd();
nuclear@7 122
nuclear@7 123 } else {
nuclear@7 124 int nearest = xfwin->nearest_handle(act_color, cursor);
nuclear@7 125 float x = nearest == TransferWindow::HANDLE_LOW ? low[act_color] : high[act_color];
nuclear@7 126
nuclear@7 127 if(grabbed_handle != -1) {
nuclear@7 128 float x = xfwin->get_handle(act_color, nearest);
nuclear@7 129 float rad = xfwin->get_soft_radius();
nuclear@7 130
nuclear@7 131 glBegin(GL_LINES);
nuclear@7 132 glColor3f(0.8, 0.8, 0.8);
nuclear@7 133 glVertex2f(x - rad, 0.5);
nuclear@7 134 glVertex2f(x + rad, 0.5);
nuclear@7 135 glVertex2f(x - rad, 0.4);
nuclear@7 136 glVertex2f(x - rad, 0.6);
nuclear@7 137 glVertex2f(x + rad, 0.4);
nuclear@7 138 glVertex2f(x + rad, 0.6);
nuclear@7 139 glEnd();
nuclear@7 140 }
nuclear@7 141
nuclear@7 142
nuclear@7 143 glBegin(GL_QUADS);
nuclear@7 144 glColor3f(1, 1, 1);
nuclear@7 145 glVertex2f(x - 2.0 * dx, -1);
nuclear@7 146 glVertex2f(x + 2.0 * dx, -1);
nuclear@7 147 glVertex2f(x + 2.0 * dx, 1);
nuclear@7 148 glVertex2f(x - 2.0 * dx, 1);
nuclear@7 149
nuclear@7 150 glColor3fv(line_color[act_color]);
nuclear@7 151 for(int i=0; i<2; i++) {
nuclear@7 152 glVertex2f(x - dx, -1);
nuclear@7 153 glVertex2f(x + dx, -1);
nuclear@7 154 glVertex2f(x + dx, 1);
nuclear@7 155 glVertex2f(x - dx, 1);
nuclear@7 156 x = nearest == TransferWindow::HANDLE_LOW ? high[act_color] : low[act_color];
nuclear@7 157 }
nuclear@7 158 glEnd();
nuclear@7 159 }
nuclear@7 160 }
nuclear@7 161
nuclear@6 162 // draw curve
nuclear@4 163 glLineWidth(2.0);
nuclear@4 164
nuclear@7 165 for(int i=0; i<4; i++) {
nuclear@4 166 int idx;
nuclear@7 167 if(act_color == -1) {
nuclear@7 168 idx = i;
nuclear@4 169 } else {
nuclear@7 170 idx = (i + act_color + 1) % 4;
nuclear@4 171 }
nuclear@4 172
nuclear@4 173 glColor3fv(line_color[idx]);
nuclear@4 174
nuclear@4 175 glBegin(GL_LINE_STRIP);
nuclear@4 176 for(int j=0; j<nsamples; j++) {
nuclear@4 177 float t = (float)j / (float)(nsamples - 1);
nuclear@6 178 float vval[4];
nuclear@4 179
nuclear@7 180 if(idx < 3) {
nuclear@7 181 xfer->map(t, vval);
nuclear@7 182 } else {
nuclear@7 183 vval[3] = xfer->map(t);
nuclear@7 184 }
nuclear@7 185
nuclear@7 186 glVertex2f(t, vval[idx]);
nuclear@4 187 }
nuclear@4 188 glEnd();
nuclear@4 189 }
nuclear@4 190
nuclear@4 191 glDisable(GL_BLEND);
nuclear@4 192 }
nuclear@4 193
nuclear@7 194 static int prev_x, prev_y;
nuclear@7 195
nuclear@4 196 void xfview_button(int bn, int press, int x, int y)
nuclear@4 197 {
nuclear@7 198 prev_x = x;
nuclear@7 199 prev_y = y;
nuclear@7 200
nuclear@7 201 if(bn == 2 && press && grabbed_handle == -1) {
nuclear@7 202 act_color = (act_color + 2) % 4 - 1;
nuclear@4 203 redisplay();
nuclear@4 204 return;
nuclear@4 205 }
nuclear@4 206
nuclear@7 207 if(bn == 0) {
nuclear@7 208 int xsz, ysz;
nuclear@7 209 get_window_size(&xsz, &ysz);
nuclear@7 210
nuclear@7 211 TransferWindow *xfwin = dynamic_cast<TransferWindow*>(xfer);
nuclear@7 212 if(xfwin && press) {
nuclear@7 213 float cursor = (float)x / (float)xsz;
nuclear@7 214 float low[3], high[3];
nuclear@7 215 xfwin->get_interval_rgba(low, high);
nuclear@7 216
nuclear@7 217 // grab the nearest handle
nuclear@7 218 grabbed_handle = xfwin->nearest_handle(act_color, cursor);
nuclear@5 219 } else {
nuclear@7 220 grabbed_handle = -1;
nuclear@5 221 }
nuclear@7 222 redisplay();
nuclear@4 223 }
nuclear@4 224 }
nuclear@4 225
nuclear@4 226 void xfview_motion(int x, int y)
nuclear@4 227 {
nuclear@7 228 mousex = x;
nuclear@7 229 mousey = y;
nuclear@7 230
nuclear@7 231 int dx = x - prev_x;
nuclear@7 232 int dy = y - prev_y;
nuclear@7 233 prev_x = x;
nuclear@7 234 prev_y = y;
nuclear@7 235
nuclear@7 236 if(grabbed_handle != -1) {
nuclear@7 237 TransferWindow *xfwin = dynamic_cast<TransferWindow*>(xfer);
nuclear@7 238 if(!xfwin) return;
nuclear@7 239
nuclear@7 240 int xsz, ysz;
nuclear@7 241 get_window_size(&xsz, &ysz);
nuclear@7 242
nuclear@7 243 if(get_modifiers()) {
nuclear@7 244 float soft = xfwin->get_soft_radius() + dy * 0.01;
nuclear@7 245 if(soft < 0.0) soft = 0.0;
nuclear@7 246 xfwin->set_soft_radius(soft);
nuclear@7 247 } else {
nuclear@7 248 float pos = (float)x / (float)xsz;
nuclear@7 249 xfwin->set_handle(act_color, grabbed_handle, pos);
nuclear@7 250 }
nuclear@7 251 }
nuclear@7 252
nuclear@7 253 redisplay();
nuclear@4 254 }