rev |
line source |
nuclear@0
|
1 #include "opengl.h"
|
nuclear@0
|
2 #include "rend_fast.h"
|
nuclear@0
|
3
|
nuclear@0
|
4 RendererFast::RendererFast()
|
nuclear@0
|
5 {
|
nuclear@0
|
6 vol_tex = 0;
|
nuclear@0
|
7 vol_tex_valid = false;
|
nuclear@0
|
8 }
|
nuclear@0
|
9
|
nuclear@0
|
10 bool RendererFast::init()
|
nuclear@0
|
11 {
|
nuclear@0
|
12 glGenTextures(1, &vol_tex);
|
nuclear@0
|
13 glBindTexture(GL_TEXTURE_3D, vol_tex);
|
nuclear@0
|
14 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@0
|
15 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@0
|
16
|
nuclear@0
|
17 return true;
|
nuclear@0
|
18 }
|
nuclear@0
|
19
|
nuclear@0
|
20 void RendererFast::destroy()
|
nuclear@0
|
21 {
|
nuclear@0
|
22 glDeleteTextures(1, &vol_tex);
|
nuclear@0
|
23 }
|
nuclear@0
|
24
|
nuclear@0
|
25 void RendererFast::update(unsigned int msec)
|
nuclear@0
|
26 {
|
nuclear@0
|
27 if(!vol) return;
|
nuclear@0
|
28
|
nuclear@0
|
29 // make sure the 3D volume texture is up to date
|
nuclear@0
|
30 if(!vol_tex_valid) {
|
nuclear@0
|
31 int xsz, ysz, zsz;
|
nuclear@0
|
32
|
nuclear@0
|
33 if((xsz = vol->num_samples(0)) > 0) {
|
nuclear@0
|
34 ysz = vol->num_samples(1);
|
nuclear@0
|
35 zsz = vol->num_samples(2);
|
nuclear@0
|
36 } else {
|
nuclear@0
|
37 xsz = ysz = zsz = 256;
|
nuclear@0
|
38 }
|
nuclear@0
|
39
|
nuclear@0
|
40 int int_fmt = GLEW_ARB_texture_float ? GL_RGBA16F_ARB : GL_RGBA;
|
nuclear@0
|
41
|
nuclear@0
|
42 glBindTexture(GL_TEXTURE_3D, vol_tex);
|
nuclear@0
|
43 glTexImage3D(GL_TEXTURE_3D, 0, int_fmt, xsz, ysz, zsz, 0, GL_RGBA, GL_FLOAT, 0);
|
nuclear@0
|
44
|
nuclear@0
|
45 float *slice = new float[xsz * ysz * 4];
|
nuclear@0
|
46
|
nuclear@0
|
47 for(int i=0; i<zsz; i++) {
|
nuclear@0
|
48 float z = (float)i / (float)(zsz - 1);
|
nuclear@0
|
49 float *pptr = slice;
|
nuclear@0
|
50
|
nuclear@0
|
51 for(int j=0; j<ysz; j++) {
|
nuclear@0
|
52 float y = (float)j / (float)(ysz - 1);
|
nuclear@0
|
53 for(int k=0; k<xsz; k++) {
|
nuclear@0
|
54 float x = (float)k / (float)(xsz - 1);
|
nuclear@0
|
55
|
nuclear@0
|
56 // value in alpha channel
|
nuclear@0
|
57 pptr[3] = vol->valuef(x, y, z);
|
nuclear@0
|
58 // normal in rgb
|
nuclear@0
|
59 vol->normalf(pptr, x, y, z);
|
nuclear@0
|
60 // shift normal to the [0,1] range in case we don't have tex_float
|
nuclear@0
|
61 pptr[0] = pptr[0] * 0.5 + 0.5;
|
nuclear@0
|
62 pptr[1] = pptr[1] * 0.5 + 0.5;
|
nuclear@0
|
63 pptr[2] = pptr[2] * 0.5 + 0.5;
|
nuclear@0
|
64 }
|
nuclear@0
|
65 }
|
nuclear@0
|
66
|
nuclear@0
|
67 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, i, xsz, ysz, 1, GL_RGBA, GL_FLOAT, slice);
|
nuclear@0
|
68 }
|
nuclear@0
|
69
|
nuclear@0
|
70 delete [] slice;
|
nuclear@0
|
71
|
nuclear@0
|
72 vol_tex_valid = true;
|
nuclear@0
|
73 }
|
nuclear@0
|
74 }
|
nuclear@0
|
75
|
nuclear@0
|
76 void RendererFast::render() const
|
nuclear@0
|
77 {
|
nuclear@0
|
78 if(!vol) return;
|
nuclear@0
|
79
|
nuclear@0
|
80 glClear(GL_COLOR_BUFFER_BIT);
|
nuclear@0
|
81
|
nuclear@0
|
82 glMatrixMode(GL_PROJECTION);
|
nuclear@0
|
83 glPushMatrix();
|
nuclear@0
|
84 glLoadIdentity();
|
nuclear@0
|
85
|
nuclear@0
|
86 glMatrixMode(GL_MODELVIEW);
|
nuclear@0
|
87 glPushMatrix();
|
nuclear@0
|
88 glLoadIdentity();
|
nuclear@0
|
89
|
nuclear@0
|
90 glBindTexture(GL_TEXTURE_3D, vol_tex);
|
nuclear@0
|
91 glBegin(GL_QUADS);
|
nuclear@0
|
92 glTexCoord3f(0, 0, 0); glVertex2f(-1, -1);
|
nuclear@0
|
93 glTexCoord3f(1, 0, 0); glVertex2f(1, -1);
|
nuclear@0
|
94 glTexCoord3f(1, 1, 0); glVertex2f(1, 1);
|
nuclear@0
|
95 glTexCoord3f(0, 1, 0); glVertex2f(-1, 1);
|
nuclear@0
|
96 glEnd();
|
nuclear@0
|
97
|
nuclear@0
|
98 glMatrixMode(GL_PROJECTION);
|
nuclear@0
|
99 glPopMatrix();
|
nuclear@0
|
100 glMatrixMode(GL_MODELVIEW);
|
nuclear@0
|
101 glPopMatrix();
|
nuclear@0
|
102 }
|