nuclear@4: #include nuclear@7: #include nuclear@4: #include "opengl.h" nuclear@4: #include "xfer_view.h" nuclear@4: #include "dicomview.h" nuclear@4: nuclear@6: static TransferFunc *xfer; nuclear@4: nuclear@7: static int act_color = -1; nuclear@7: static int grabbed_handle = -1; nuclear@7: static int mousex, mousey; nuclear@4: nuclear@6: bool xfview_init(TransferFunc *xferarg) nuclear@4: { nuclear@6: xfer = xferarg; nuclear@4: return true; nuclear@4: } nuclear@4: nuclear@4: void xfview_destroy() nuclear@4: { nuclear@4: } nuclear@4: nuclear@4: void xfview_draw() nuclear@4: { nuclear@4: float line_color[][3] = { nuclear@4: { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { 1, 1, 1 } nuclear@4: }; nuclear@4: nuclear@4: glMatrixMode(GL_PROJECTION); nuclear@4: glLoadIdentity(); nuclear@7: glOrtho(0, 1, 0, 1, -1, 1); nuclear@7: nuclear@4: glMatrixMode(GL_MODELVIEW); nuclear@4: glLoadIdentity(); nuclear@4: nuclear@4: int xsz, ysz; nuclear@4: get_window_size(&xsz, &ysz); nuclear@4: int nsamples = xsz / 4; nuclear@4: nuclear@4: // paint the background a faint version of the selected color nuclear@4: glBegin(GL_QUADS); nuclear@7: int cidx = act_color == -1 ? 3 : act_color; nuclear@7: glColor3f(line_color[cidx][0] * 0.1, line_color[cidx][1] * 0.1, line_color[cidx][2] * 0.1); nuclear@4: glVertex2f(-1, -1); nuclear@4: glVertex2f(1, -1); nuclear@4: glVertex2f(1, 1); nuclear@4: glVertex2f(-1, 1); nuclear@4: glEnd(); nuclear@4: nuclear@4: glEnable(GL_LINE_SMOOTH); nuclear@4: nuclear@4: glEnable(GL_BLEND); nuclear@4: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); nuclear@4: nuclear@7: // draw handles on the selected curve nuclear@7: TransferWindow *xfwin = dynamic_cast(xfer); nuclear@7: if(xfwin) { nuclear@7: float dx = 1.0 / (float)xsz; nuclear@7: float cursor = (float)mousex / (float)xsz; nuclear@7: float low[3], high[3]; nuclear@7: xfwin->get_interval_rgba(low, high); nuclear@7: nuclear@7: if(act_color == -1) { // all curves nuclear@7: int nearest = xfwin->nearest_handle(-1, cursor); nuclear@7: nuclear@7: if(grabbed_handle != -1) { nuclear@7: glBegin(GL_LINES); nuclear@7: glColor3f(0.8, 0.8, 0.8); nuclear@7: for(int i=0; i<3; i++) { nuclear@7: float x = xfwin->get_handle(i, nearest); nuclear@7: float rad = xfwin->get_soft_radius(); nuclear@7: glVertex2f(x - rad, 0.5); nuclear@7: glVertex2f(x + rad, 0.5); nuclear@7: glVertex2f(x - rad, 0.4); nuclear@7: glVertex2f(x - rad, 0.6); nuclear@7: glVertex2f(x + rad, 0.4); nuclear@7: glVertex2f(x + rad, 0.6); nuclear@7: } nuclear@7: glEnd(); nuclear@7: } nuclear@7: nuclear@7: // draw handles on all lines, highlighting the nearest side of all of them nuclear@7: glBegin(GL_QUADS); nuclear@7: glColor3f(1, 1, 1); nuclear@7: nuclear@7: for(int i=0; i<3; i++) { nuclear@7: float x = nearest == TransferWindow::HANDLE_LOW ? low[i] : high[i]; nuclear@7: glVertex2f(x - 2.0 * dx, -1); nuclear@7: glVertex2f(x + 2.0 * dx, -1); nuclear@7: glVertex2f(x + 2.0 * dx, 1); nuclear@7: glVertex2f(x - 2.0 * dx, 1); nuclear@7: } nuclear@7: for(int i=0; i<3; i++) { nuclear@7: glColor3fv(line_color[i]); nuclear@7: glVertex2f(low[i] - dx, -1); nuclear@7: glVertex2f(low[i] + dx, -1); nuclear@7: glVertex2f(low[i] + dx, 1); nuclear@7: glVertex2f(low[i] - dx, 1); nuclear@7: glVertex2f(high[i] - dx, -1); nuclear@7: glVertex2f(high[i] + dx, -1); nuclear@7: glVertex2f(high[i] + dx, 1); nuclear@7: glVertex2f(high[i] - dx, 1); nuclear@7: } nuclear@7: glEnd(); nuclear@7: nuclear@7: } else { nuclear@7: int nearest = xfwin->nearest_handle(act_color, cursor); nuclear@7: float x = nearest == TransferWindow::HANDLE_LOW ? low[act_color] : high[act_color]; nuclear@7: nuclear@7: if(grabbed_handle != -1) { nuclear@7: float x = xfwin->get_handle(act_color, nearest); nuclear@7: float rad = xfwin->get_soft_radius(); nuclear@7: nuclear@7: glBegin(GL_LINES); nuclear@7: glColor3f(0.8, 0.8, 0.8); nuclear@7: glVertex2f(x - rad, 0.5); nuclear@7: glVertex2f(x + rad, 0.5); nuclear@7: glVertex2f(x - rad, 0.4); nuclear@7: glVertex2f(x - rad, 0.6); nuclear@7: glVertex2f(x + rad, 0.4); nuclear@7: glVertex2f(x + rad, 0.6); nuclear@7: glEnd(); nuclear@7: } nuclear@7: nuclear@7: nuclear@7: glBegin(GL_QUADS); nuclear@7: glColor3f(1, 1, 1); nuclear@7: glVertex2f(x - 2.0 * dx, -1); nuclear@7: glVertex2f(x + 2.0 * dx, -1); nuclear@7: glVertex2f(x + 2.0 * dx, 1); nuclear@7: glVertex2f(x - 2.0 * dx, 1); nuclear@7: nuclear@7: glColor3fv(line_color[act_color]); nuclear@7: for(int i=0; i<2; i++) { nuclear@7: glVertex2f(x - dx, -1); nuclear@7: glVertex2f(x + dx, -1); nuclear@7: glVertex2f(x + dx, 1); nuclear@7: glVertex2f(x - dx, 1); nuclear@7: x = nearest == TransferWindow::HANDLE_LOW ? high[act_color] : low[act_color]; nuclear@7: } nuclear@7: glEnd(); nuclear@7: } nuclear@7: } nuclear@7: nuclear@6: // draw curve nuclear@4: glLineWidth(2.0); nuclear@4: nuclear@7: for(int i=0; i<4; i++) { nuclear@4: int idx; nuclear@7: if(act_color == -1) { nuclear@7: idx = i; nuclear@4: } else { nuclear@7: idx = (i + act_color + 1) % 4; nuclear@4: } nuclear@4: nuclear@4: glColor3fv(line_color[idx]); nuclear@4: nuclear@4: glBegin(GL_LINE_STRIP); nuclear@4: for(int j=0; jmap(t, vval); nuclear@7: } else { nuclear@7: vval[3] = xfer->map(t); nuclear@7: } nuclear@7: nuclear@7: glVertex2f(t, vval[idx]); nuclear@4: } nuclear@4: glEnd(); nuclear@4: } nuclear@4: nuclear@4: glDisable(GL_BLEND); nuclear@4: } nuclear@4: nuclear@7: static int prev_x, prev_y; nuclear@7: nuclear@4: void xfview_button(int bn, int press, int x, int y) nuclear@4: { nuclear@7: prev_x = x; nuclear@7: prev_y = y; nuclear@7: nuclear@7: if(bn == 2 && press && grabbed_handle == -1) { nuclear@7: act_color = (act_color + 2) % 4 - 1; nuclear@4: redisplay(); nuclear@4: return; nuclear@4: } nuclear@4: nuclear@7: if(bn == 0) { nuclear@7: int xsz, ysz; nuclear@7: get_window_size(&xsz, &ysz); nuclear@7: nuclear@7: TransferWindow *xfwin = dynamic_cast(xfer); nuclear@7: if(xfwin && press) { nuclear@7: float cursor = (float)x / (float)xsz; nuclear@7: float low[3], high[3]; nuclear@7: xfwin->get_interval_rgba(low, high); nuclear@7: nuclear@7: // grab the nearest handle nuclear@7: grabbed_handle = xfwin->nearest_handle(act_color, cursor); nuclear@5: } else { nuclear@7: grabbed_handle = -1; nuclear@5: } nuclear@7: redisplay(); nuclear@4: } nuclear@4: } nuclear@4: nuclear@4: void xfview_motion(int x, int y) nuclear@4: { nuclear@7: mousex = x; nuclear@7: mousey = y; nuclear@7: nuclear@7: int dx = x - prev_x; nuclear@7: int dy = y - prev_y; nuclear@7: prev_x = x; nuclear@7: prev_y = y; nuclear@7: nuclear@7: if(grabbed_handle != -1) { nuclear@7: TransferWindow *xfwin = dynamic_cast(xfer); nuclear@7: if(!xfwin) return; nuclear@7: nuclear@7: int xsz, ysz; nuclear@7: get_window_size(&xsz, &ysz); nuclear@7: nuclear@7: if(get_modifiers()) { nuclear@7: float soft = xfwin->get_soft_radius() + dy * 0.01; nuclear@7: if(soft < 0.0) soft = 0.0; nuclear@7: xfwin->set_soft_radius(soft); nuclear@7: } else { nuclear@7: float pos = (float)x / (float)xsz; nuclear@7: xfwin->set_handle(act_color, grabbed_handle, pos); nuclear@7: } nuclear@7: } nuclear@7: nuclear@7: redisplay(); nuclear@4: }