glviewvol
changeset 6:f22be47a3572
moved to TransferFuncs completely
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 30 Dec 2014 06:22:54 +0200 |
parents | 5417c25cb238 |
children | 71b479ffb9f7 |
files | src/dicomview.cc src/main.cc src/opt.cc src/opt.h src/rend_fast.cc src/rend_fast.h src/renderer.cc src/renderer.h src/xfer_view.cc src/xfer_view.h src/xfermap.cc src/xfermap.h |
diffstat | 12 files changed, 157 insertions(+), 108 deletions(-) [+] |
line diff
1.1 --- a/src/dicomview.cc Mon Dec 29 15:59:55 2014 +0200 1.2 +++ b/src/dicomview.cc Tue Dec 30 06:22:54 2014 +0200 1.3 @@ -15,6 +15,7 @@ 1.4 1.5 static Renderer *rend; 1.6 static Volume *vol; 1.7 +static TransferFunc *xfer; 1.8 1.9 extern "C" { 1.10 1.11 @@ -46,7 +47,10 @@ 1.12 vol = voxvol; 1.13 rend->set_volume(vol); 1.14 1.15 - if(!xfview_init(rend)) { 1.16 + xfer = new TransferWindow; 1.17 + rend->set_transfer_function(xfer); 1.18 + 1.19 + if(!xfview_init(xfer)) { 1.20 return -1; 1.21 } 1.22 1.23 @@ -60,6 +64,7 @@ 1.24 rend->destroy(); 1.25 delete rend; 1.26 delete vol; 1.27 + delete xfer; 1.28 } 1.29 1.30 void ev_display()
2.1 --- a/src/main.cc Mon Dec 29 15:59:55 2014 +0200 2.2 +++ b/src/main.cc Tue Dec 30 06:22:54 2014 +0200 2.3 @@ -30,7 +30,7 @@ 2.4 return 1; 2.5 } 2.6 2.7 - glutInitWindowSize(1280, 800); 2.8 + glutInitWindowSize(opt.xsz, opt.ysz); 2.9 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); 2.10 glutCreateWindow("dicom viewer"); 2.11
3.1 --- a/src/opt.cc Mon Dec 29 15:59:55 2014 +0200 3.2 +++ b/src/opt.cc Tue Dec 30 06:22:54 2014 +0200 3.3 @@ -16,6 +16,8 @@ 3.4 { 3.5 opt.fname = 0; 3.6 opt.rend_type = REND_FAST; 3.7 + opt.xsz = 800; 3.8 + opt.ysz = 800; 3.9 } 3.10 3.11 static RendererType renderer_type(const char *name) 3.12 @@ -36,6 +38,13 @@ 3.13 if(argv[i][0] == '-') { 3.14 if(argv[i][2] == 0) { 3.15 switch(argv[i][1]) { 3.16 + case 's': 3.17 + if(sscanf(argv[++i], "%dx%d", &opt.xsz, &opt.ysz) != 2) { 3.18 + fprintf(stderr, "-s must be followed by the window size (WxH)\n"); 3.19 + return -1; 3.20 + } 3.21 + break; 3.22 + 3.23 case 'r': 3.24 if((opt.rend_type = renderer_type(argv[++i])) == REND_NONE) { 3.25 if(strcmp(argv[i], "help") == 0) {
4.1 --- a/src/opt.h Mon Dec 29 15:59:55 2014 +0200 4.2 +++ b/src/opt.h Tue Dec 30 06:22:54 2014 +0200 4.3 @@ -9,6 +9,7 @@ 4.4 struct Options { 4.5 char *fname; 4.6 RendererType rend_type; 4.7 + int xsz, ysz; 4.8 }; 4.9 4.10 extern Options opt;
5.1 --- a/src/rend_fast.cc Mon Dec 29 15:59:55 2014 +0200 5.2 +++ b/src/rend_fast.cc Tue Dec 30 06:22:54 2014 +0200 5.3 @@ -34,7 +34,7 @@ 5.4 glBindTexture(GL_TEXTURE_1D, xfer_tex); 5.5 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 5.6 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 5.7 - glTexImage1D(GL_TEXTURE_1D, 0, have_tex_float ? GL_RGB16F : GL_RGB, XFER_MAP_SZ, 0, GL_RGB, GL_FLOAT, 0); 5.8 + glTexImage1D(GL_TEXTURE_1D, 0, have_tex_float ? GL_RGBA16F : GL_RGBA, XFER_MAP_SZ, 0, GL_RGB, GL_FLOAT, 0); 5.9 5.10 return true; 5.11 } 5.12 @@ -51,18 +51,6 @@ 5.13 Renderer::set_volume(vol); 5.14 } 5.15 5.16 -Curve &RendererFast::transfer_curve(int color) 5.17 -{ 5.18 - xfer_tex_valid = false; 5.19 - return Renderer::transfer_curve(color); 5.20 -} 5.21 - 5.22 -void RendererFast::set_simple_transfer(float low, float high) 5.23 -{ 5.24 - xfer_tex_valid = false; 5.25 - Renderer::set_simple_transfer(low, high); 5.26 -} 5.27 - 5.28 void RendererFast::update(unsigned int msec) 5.29 { 5.30 if(!vol) return; 5.31 @@ -120,28 +108,23 @@ 5.32 vol_tex_valid = true; 5.33 } 5.34 5.35 - if(!xfer_tex_valid) { 5.36 - float pixels[XFER_MAP_SZ * 3]; 5.37 + if(1) {//if(!xfer_tex_valid) { 5.38 + float pixels[XFER_MAP_SZ * 4]; 5.39 float *pptr = pixels; 5.40 5.41 for(int i=0; i<XFER_MAP_SZ; i++) { 5.42 float x = (float)i / (float)(XFER_MAP_SZ - 1); 5.43 5.44 - // TODO make 0.1 a tweakable parameter 5.45 - float val = smoothstep(xfer_low - 0.1, xfer_low + 0.1, x); 5.46 - val *= 1.0 - smoothstep(xfer_high - 0.1, xfer_high + 0.1, x); 5.47 - *pptr++ = val; 5.48 - *pptr++ = val; 5.49 - *pptr++ = val; 5.50 - /* 5.51 - *pptr++ = xfer[0].value(x); 5.52 - *pptr++ = xfer[1].value(x); 5.53 - *pptr++ = xfer[2].value(x); 5.54 - */ 5.55 + if(xfer) { 5.56 + xfer->map(x, pptr); 5.57 + } else { 5.58 + pptr[0] = pptr[1] = pptr[2] = pptr[3] = x; 5.59 + } 5.60 + pptr += 4; 5.61 } 5.62 5.63 glBindTexture(GL_TEXTURE_1D, xfer_tex); 5.64 - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, XFER_MAP_SZ, GL_RGB, GL_FLOAT, pixels); 5.65 + glTexSubImage1D(GL_TEXTURE_1D, 0, 0, XFER_MAP_SZ, GL_RGBA, GL_FLOAT, pixels); 5.66 5.67 xfer_tex_valid = true; 5.68 }
6.1 --- a/src/rend_fast.h Mon Dec 29 15:59:55 2014 +0200 6.2 +++ b/src/rend_fast.h Tue Dec 30 06:22:54 2014 +0200 6.3 @@ -15,8 +15,6 @@ 6.4 void destroy(); 6.5 6.6 void set_volume(Volume *vol); 6.7 - Curve &transfer_curve(int color); 6.8 - void set_simple_transfer(float low, float high); 6.9 6.10 void update(unsigned int msec); 6.11 void render() const;
7.1 --- a/src/renderer.cc Mon Dec 29 15:59:55 2014 +0200 7.2 +++ b/src/renderer.cc Tue Dec 30 06:22:54 2014 +0200 7.3 @@ -7,14 +7,6 @@ 7.4 view_width = 512; 7.5 view_height = 512; 7.6 7.7 - for(int i=0; i<3; i++) { 7.8 - xfer[i].set_point(0, 0); 7.9 - xfer[i].set_point(1, 1); 7.10 - } 7.11 - 7.12 - xfer_low = 0.0; 7.13 - xfer_high = 1.0; 7.14 - 7.15 for(int i=0; i<MAX_CLIP_PLANES; i++) { 7.16 disable_clipping_plane(i); 7.17 } 7.18 @@ -44,26 +36,14 @@ 7.19 return vol; 7.20 } 7.21 7.22 -Curve &Renderer::transfer_curve(int color) 7.23 +void Renderer::set_transfer_function(TransferFunc *xfer) 7.24 { 7.25 - return xfer[color]; 7.26 + this->xfer = xfer; 7.27 } 7.28 7.29 -const Curve &Renderer::transfer_curve(int color) const 7.30 +TransferFunc *Renderer::get_transfer_function() const 7.31 { 7.32 - return xfer[color]; 7.33 -} 7.34 - 7.35 -void Renderer::set_simple_transfer(float low, float high) 7.36 -{ 7.37 - xfer_low = std::min(low, high); 7.38 - xfer_high = std::max(low, high); 7.39 -} 7.40 - 7.41 -void Renderer::get_simple_transfer(float *low, float *high) const 7.42 -{ 7.43 - *low = xfer_low; 7.44 - *high = xfer_high; 7.45 + return xfer; 7.46 } 7.47 7.48 void Renderer::set_clipping_plane(int idx, float nx, float ny, float nz, float dist)
8.1 --- a/src/renderer.h Mon Dec 29 15:59:55 2014 +0200 8.2 +++ b/src/renderer.h Tue Dec 30 06:22:54 2014 +0200 8.3 @@ -2,7 +2,7 @@ 8.4 #define RENDERER_H_ 8.5 8.6 #include "volume.h" 8.7 -#include "curve.h" 8.8 +#include "xfermap.h" 8.9 8.10 #define MAX_CLIP_PLANES 4 8.11 8.12 @@ -13,8 +13,7 @@ 8.13 8.14 float clip_plane[MAX_CLIP_PLANES][4]; // nx,ny,nz,dist 8.15 8.16 - Curve xfer[3]; // rgb transfer function 8.17 - float xfer_low, xfer_high; // simple transfer function bounds 8.18 + TransferFunc *xfer; 8.19 8.20 public: 8.21 Renderer(); 8.22 @@ -26,11 +25,8 @@ 8.23 virtual void set_volume(Volume *vol); 8.24 virtual Volume *get_volume() const; 8.25 8.26 - virtual Curve &transfer_curve(int color); 8.27 - virtual const Curve &transfer_curve(int color) const; 8.28 - 8.29 - virtual void set_simple_transfer(float low, float high); 8.30 - virtual void get_simple_transfer(float *low, float *high) const; 8.31 + virtual void set_transfer_function(TransferFunc *xfer); 8.32 + virtual TransferFunc *get_transfer_function() const; 8.33 8.34 virtual void set_clipping_plane(int idx, float nx, float ny, float nz, float dist); 8.35 virtual void disable_clipping_plane(int idx);
9.1 --- a/src/xfer_view.cc Mon Dec 29 15:59:55 2014 +0200 9.2 +++ b/src/xfer_view.cc Tue Dec 30 06:22:54 2014 +0200 9.3 @@ -3,14 +3,13 @@ 9.4 #include "xfer_view.h" 9.5 #include "dicomview.h" 9.6 9.7 -static Renderer *rend; 9.8 +static TransferFunc *xfer; 9.9 9.10 static int act_color = 3; 9.11 -static CurvePoint *cpsel; 9.12 9.13 -bool xfview_init(Renderer *rendarg) 9.14 +bool xfview_init(TransferFunc *xferarg) 9.15 { 9.16 - rend = rendarg; 9.17 + xfer = xferarg; 9.18 return true; 9.19 } 9.20 9.21 @@ -42,38 +41,12 @@ 9.22 glVertex2f(-1, 1); 9.23 glEnd(); 9.24 9.25 - glEnable(GL_POINT_SMOOTH); 9.26 glEnable(GL_LINE_SMOOTH); 9.27 9.28 glEnable(GL_BLEND); 9.29 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 9.30 9.31 - // draw selection outline 9.32 - if(act_color < 3) { 9.33 - glPointSize(13.0); 9.34 - glLineWidth(5.0); 9.35 - 9.36 - const Curve &sel_curve = rend->transfer_curve(act_color); 9.37 - glColor3f(0.7, 0.7, 0.7); 9.38 - glBegin(GL_LINE_STRIP); 9.39 - for(int i=0; i<nsamples; i++) { 9.40 - float t = (float)i / (float)(nsamples - 1); 9.41 - float val = sel_curve.value(t); 9.42 - glVertex2f(t * 2.0 - 1.0, val * 2.0 - 1.0); 9.43 - } 9.44 - glEnd(); 9.45 - glBegin(GL_POINTS); 9.46 - for(int i=0; i<sel_curve.get_num_points(); i++) { 9.47 - const CurvePoint *p = sel_curve.get_point(i); 9.48 - float x = 2.0 * (float)p->t_int / 65535.0 - 1.0; 9.49 - glVertex2f(x, p->value * 2.0 - 1.0); 9.50 - } 9.51 - glEnd(); 9.52 - } 9.53 - 9.54 - 9.55 - // draw curves and points 9.56 - glPointSize(9.0); 9.57 + // draw curve 9.58 glLineWidth(2.0); 9.59 9.60 for(int i=0; i<3; i++) { 9.61 @@ -84,22 +57,15 @@ 9.62 idx = i; 9.63 } 9.64 9.65 - const Curve &xfer = rend->transfer_curve(idx); 9.66 glColor3fv(line_color[idx]); 9.67 9.68 glBegin(GL_LINE_STRIP); 9.69 for(int j=0; j<nsamples; j++) { 9.70 float t = (float)j / (float)(nsamples - 1); 9.71 - float val = xfer.value(t); 9.72 - glVertex2f(t * 2.0 - 1.0, val * 2.0 - 1.0); 9.73 - } 9.74 - glEnd(); 9.75 + float vval[4]; 9.76 + xfer->map(t, vval); 9.77 9.78 - glBegin(GL_POINTS); 9.79 - for(int j=0; j<xfer.get_num_points(); j++) { 9.80 - const CurvePoint *p = xfer.get_point(j); 9.81 - float x = 2.0 * (float)p->t_int / 65535.0 - 1.0; 9.82 - glVertex2f(x, p->value * 2.0 - 1.0); 9.83 + glVertex2f(t * 2.0 - 1.0, vval[i] * 2.0 - 1.0); 9.84 } 9.85 glEnd(); 9.86 } 9.87 @@ -109,7 +75,7 @@ 9.88 9.89 void xfview_button(int bn, int press, int x, int y) 9.90 { 9.91 - if(bn == 2 && press && !cpsel) { 9.92 + if(bn == 2 && press) { 9.93 act_color = (act_color + 1) % 4; 9.94 redisplay(); 9.95 return; 9.96 @@ -118,7 +84,6 @@ 9.97 if(bn == 1) { 9.98 if(press) { 9.99 } else { 9.100 - cpsel = 0; 9.101 } 9.102 } 9.103 }
10.1 --- a/src/xfer_view.h Mon Dec 29 15:59:55 2014 +0200 10.2 +++ b/src/xfer_view.h Tue Dec 30 06:22:54 2014 +0200 10.3 @@ -1,9 +1,9 @@ 10.4 #ifndef XFER_VIEW_H_ 10.5 #define XFER_VIEW_H_ 10.6 10.7 -#include "renderer.h" 10.8 +#include "xfermap.h" 10.9 10.10 -bool xfview_init(Renderer *rend); 10.11 +bool xfview_init(TransferFunc *xfer); 10.12 void xfview_destroy(); 10.13 10.14 void xfview_draw();
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/src/xfermap.cc Tue Dec 30 06:22:54 2014 +0200 11.3 @@ -0,0 +1,77 @@ 11.4 +#include <algorithm> 11.5 +#include "xfermap.h" 11.6 + 11.7 +TransferFunc::~TransferFunc() 11.8 +{ 11.9 +} 11.10 + 11.11 + 11.12 +// ---- TransferWindow ---- 11.13 + 11.14 +TransferWindow::TransferWindow() 11.15 +{ 11.16 + soft_rad = 0.5; 11.17 + for(int i=0; i<4; i++) { 11.18 + low[i] = 0.5; 11.19 + high[i] = 2.0; 11.20 + } 11.21 +} 11.22 + 11.23 +void TransferWindow::set_interval(float a, float b) 11.24 +{ 11.25 + float v0 = std::min(a, b); 11.26 + float v1 = std::max(a, b); 11.27 + 11.28 + for(int i=0; i<4; i++) { 11.29 + low[i] = v0; 11.30 + high[i] = v1; 11.31 + } 11.32 +} 11.33 + 11.34 +void TransferWindow::set_interval(float *rgba_low, float *rgba_high) 11.35 +{ 11.36 + for(int i=0; i<4; i++) { 11.37 + low[i] = std::min(rgba_low[i], rgba_high[i]); 11.38 + high[i] = std::max(rgba_low[i], rgba_high[i]); 11.39 + } 11.40 +} 11.41 + 11.42 +void TransferWindow::set_interval_rgba(int channel, float a, float b) 11.43 +{ 11.44 + low[channel] = std::min(a, b); 11.45 + high[channel] = std::max(a, b); 11.46 +} 11.47 + 11.48 +void TransferWindow::set_soft_radius(float s) 11.49 +{ 11.50 + soft_rad = s; 11.51 +} 11.52 + 11.53 +float TransferWindow::get_soft_radius() const 11.54 +{ 11.55 + return soft_rad; 11.56 +} 11.57 + 11.58 +static inline float smoothstep(float a, float b, float x) 11.59 +{ 11.60 + if(x < a) return 0.0f; 11.61 + if(x >= b) return 1.0f; 11.62 + 11.63 + float t = (x - a) / (b - a); 11.64 + return t * t * (3.0f - 2.0f * t); 11.65 +} 11.66 + 11.67 +float TransferWindow::map(float x) const 11.68 +{ 11.69 + return smoothstep(low[3] - soft_rad, high[3] - soft_rad, x) * 11.70 + (1.0 - smoothstep(low[3] + soft_rad, high[3] + soft_rad, x)); 11.71 +} 11.72 + 11.73 +void TransferWindow::map(float x, float *rgba_value) const 11.74 +{ 11.75 + for(int i=0; i<4; i++) { 11.76 + float val = smoothstep(low[i] - soft_rad, high[i] - soft_rad, x); 11.77 + val *= 1.0 - smoothstep(low[i] + soft_rad, high[i] + soft_rad, x); 11.78 + rgba_value[i] = val; 11.79 + } 11.80 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/src/xfermap.h Tue Dec 30 06:22:54 2014 +0200 12.3 @@ -0,0 +1,35 @@ 12.4 +#ifndef XFERMAP_H_ 12.5 +#define XFERMAP_H_ 12.6 + 12.7 +class TransferFunc { 12.8 +public: 12.9 + virtual ~TransferFunc(); 12.10 + 12.11 + virtual float map(float x) const = 0; 12.12 + virtual void map(float x, float *rgba_value) const = 0; 12.13 +}; 12.14 + 12.15 +class TransferWindow : public TransferFunc { 12.16 +private: 12.17 + float soft_rad; 12.18 + float low[4], high[4]; // rgb 12.19 + 12.20 +public: 12.21 + TransferWindow(); 12.22 + 12.23 + void set_interval(float a, float b); 12.24 + void set_interval(float *rgba_low, float *rgba_high); 12.25 + void set_interval_rgba(int channel, float a, float b); 12.26 + 12.27 + void get_interval(float *aptr, float *bptr) const; 12.28 + void get_interval_rgba(float *rgba_low, float *rgba_high) const; 12.29 + void get_interval_rgba(int channel, float *aptr, float *bptr) const; 12.30 + 12.31 + void set_soft_radius(float s); 12.32 + float get_soft_radius() const; 12.33 + 12.34 + float map(float x) const; 12.35 + void map(float x, float *rgba_value) const; 12.36 +}; 12.37 + 12.38 +#endif // XFERMAP_H_