glviewvol

annotate src/xfer_view.cc @ 7:71b479ffb9f7

curve manipulation works
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 30 Dec 2014 17:28:38 +0200
parents f22be47a3572
children 73edd1b7c2da
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@4 5 #include "dicomview.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 }