rev |
line source |
nuclear@4
|
1 #include <stdio.h>
|
nuclear@0
|
2 #include "opengl.h"
|
nuclear@0
|
3 #include "rend_fast.h"
|
nuclear@4
|
4 #include "sdr.h"
|
nuclear@4
|
5
|
nuclear@4
|
6 #define XFER_MAP_SZ 1024
|
nuclear@4
|
7
|
nuclear@4
|
8 static unsigned int sdr;
|
nuclear@4
|
9 static bool have_tex_float;
|
nuclear@0
|
10
|
nuclear@0
|
11 RendererFast::RendererFast()
|
nuclear@0
|
12 {
|
nuclear@4
|
13 vol_tex = xfer_tex = 0;
|
nuclear@4
|
14 vol_tex_valid = xfer_tex_valid = false;
|
nuclear@0
|
15 }
|
nuclear@0
|
16
|
nuclear@0
|
17 bool RendererFast::init()
|
nuclear@0
|
18 {
|
nuclear@4
|
19 if(!sdr) {
|
nuclear@4
|
20 if(!(sdr = create_program_load("sdr/fast.v.glsl", "sdr/fast.p.glsl"))) {
|
nuclear@4
|
21 return false;
|
nuclear@4
|
22 }
|
nuclear@4
|
23 have_tex_float = GLEW_ARB_texture_float;
|
nuclear@4
|
24 }
|
nuclear@4
|
25
|
nuclear@0
|
26 glGenTextures(1, &vol_tex);
|
nuclear@0
|
27 glBindTexture(GL_TEXTURE_3D, vol_tex);
|
nuclear@0
|
28 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@0
|
29 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@0
|
30
|
nuclear@4
|
31 glGenTextures(1, &xfer_tex);
|
nuclear@4
|
32 glBindTexture(GL_TEXTURE_1D, xfer_tex);
|
nuclear@4
|
33 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@4
|
34 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@6
|
35 glTexImage1D(GL_TEXTURE_1D, 0, have_tex_float ? GL_RGBA16F : GL_RGBA, XFER_MAP_SZ, 0, GL_RGB, GL_FLOAT, 0);
|
nuclear@4
|
36
|
nuclear@0
|
37 return true;
|
nuclear@0
|
38 }
|
nuclear@0
|
39
|
nuclear@0
|
40 void RendererFast::destroy()
|
nuclear@0
|
41 {
|
nuclear@0
|
42 glDeleteTextures(1, &vol_tex);
|
nuclear@4
|
43 glDeleteTextures(1, &xfer_tex);
|
nuclear@4
|
44 }
|
nuclear@4
|
45
|
nuclear@4
|
46 void RendererFast::set_volume(Volume *vol)
|
nuclear@4
|
47 {
|
nuclear@4
|
48 vol_tex_valid = false;
|
nuclear@4
|
49 Renderer::set_volume(vol);
|
nuclear@4
|
50 }
|
nuclear@4
|
51
|
nuclear@0
|
52 void RendererFast::update(unsigned int msec)
|
nuclear@0
|
53 {
|
nuclear@0
|
54 if(!vol) return;
|
nuclear@0
|
55
|
nuclear@0
|
56 // make sure the 3D volume texture is up to date
|
nuclear@0
|
57 if(!vol_tex_valid) {
|
nuclear@0
|
58 int xsz, ysz, zsz;
|
nuclear@0
|
59
|
nuclear@0
|
60 if((xsz = vol->num_samples(0)) > 0) {
|
nuclear@0
|
61 ysz = vol->num_samples(1);
|
nuclear@0
|
62 zsz = vol->num_samples(2);
|
nuclear@0
|
63 } else {
|
nuclear@0
|
64 xsz = ysz = zsz = 256;
|
nuclear@0
|
65 }
|
nuclear@0
|
66
|
nuclear@4
|
67 printf("updating 3D texture data (%dx%dx%d) ... ", xsz, ysz, zsz);
|
nuclear@4
|
68 fflush(stdout);
|
nuclear@4
|
69
|
nuclear@0
|
70 int int_fmt = GLEW_ARB_texture_float ? GL_RGBA16F_ARB : GL_RGBA;
|
nuclear@0
|
71
|
nuclear@0
|
72 glBindTexture(GL_TEXTURE_3D, vol_tex);
|
nuclear@0
|
73 glTexImage3D(GL_TEXTURE_3D, 0, int_fmt, xsz, ysz, zsz, 0, GL_RGBA, GL_FLOAT, 0);
|
nuclear@0
|
74
|
nuclear@0
|
75 float *slice = new float[xsz * ysz * 4];
|
nuclear@0
|
76
|
nuclear@0
|
77 for(int i=0; i<zsz; i++) {
|
nuclear@4
|
78 float z = (float)i;
|
nuclear@0
|
79 float *pptr = slice;
|
nuclear@0
|
80
|
nuclear@0
|
81 for(int j=0; j<ysz; j++) {
|
nuclear@4
|
82 float y = (float)j;
|
nuclear@0
|
83 for(int k=0; k<xsz; k++) {
|
nuclear@4
|
84 float x = (float)k;
|
nuclear@0
|
85
|
nuclear@0
|
86 // value in alpha channel
|
nuclear@0
|
87 pptr[3] = vol->valuef(x, y, z);
|
nuclear@0
|
88 // normal in rgb
|
nuclear@0
|
89 vol->normalf(pptr, x, y, z);
|
nuclear@0
|
90 // shift normal to the [0,1] range in case we don't have tex_float
|
nuclear@0
|
91 pptr[0] = pptr[0] * 0.5 + 0.5;
|
nuclear@0
|
92 pptr[1] = pptr[1] * 0.5 + 0.5;
|
nuclear@0
|
93 pptr[2] = pptr[2] * 0.5 + 0.5;
|
nuclear@4
|
94
|
nuclear@4
|
95 pptr += 4;
|
nuclear@0
|
96 }
|
nuclear@0
|
97 }
|
nuclear@0
|
98
|
nuclear@0
|
99 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, i, xsz, ysz, 1, GL_RGBA, GL_FLOAT, slice);
|
nuclear@0
|
100 }
|
nuclear@0
|
101
|
nuclear@4
|
102 printf("done\n");
|
nuclear@4
|
103
|
nuclear@0
|
104 delete [] slice;
|
nuclear@0
|
105
|
nuclear@0
|
106 vol_tex_valid = true;
|
nuclear@0
|
107 }
|
nuclear@4
|
108
|
nuclear@6
|
109 if(1) {//if(!xfer_tex_valid) {
|
nuclear@6
|
110 float pixels[XFER_MAP_SZ * 4];
|
nuclear@4
|
111 float *pptr = pixels;
|
nuclear@4
|
112
|
nuclear@4
|
113 for(int i=0; i<XFER_MAP_SZ; i++) {
|
nuclear@4
|
114 float x = (float)i / (float)(XFER_MAP_SZ - 1);
|
nuclear@5
|
115
|
nuclear@6
|
116 if(xfer) {
|
nuclear@6
|
117 xfer->map(x, pptr);
|
nuclear@7
|
118 pptr[3] = std::max(pptr[0], std::max(pptr[1], pptr[2]));
|
nuclear@6
|
119 } else {
|
nuclear@6
|
120 pptr[0] = pptr[1] = pptr[2] = pptr[3] = x;
|
nuclear@6
|
121 }
|
nuclear@6
|
122 pptr += 4;
|
nuclear@4
|
123 }
|
nuclear@4
|
124
|
nuclear@4
|
125 glBindTexture(GL_TEXTURE_1D, xfer_tex);
|
nuclear@6
|
126 glTexSubImage1D(GL_TEXTURE_1D, 0, 0, XFER_MAP_SZ, GL_RGBA, GL_FLOAT, pixels);
|
nuclear@4
|
127
|
nuclear@4
|
128 xfer_tex_valid = true;
|
nuclear@4
|
129 }
|
nuclear@0
|
130 }
|
nuclear@0
|
131
|
nuclear@0
|
132 void RendererFast::render() const
|
nuclear@0
|
133 {
|
nuclear@0
|
134 if(!vol) return;
|
nuclear@0
|
135
|
nuclear@0
|
136 glClear(GL_COLOR_BUFFER_BIT);
|
nuclear@0
|
137
|
nuclear@0
|
138 glMatrixMode(GL_PROJECTION);
|
nuclear@0
|
139 glPushMatrix();
|
nuclear@0
|
140 glLoadIdentity();
|
nuclear@0
|
141
|
nuclear@0
|
142 glMatrixMode(GL_MODELVIEW);
|
nuclear@0
|
143 glPushMatrix();
|
nuclear@0
|
144 glLoadIdentity();
|
nuclear@0
|
145
|
nuclear@4
|
146 glUseProgram(sdr);
|
nuclear@4
|
147
|
nuclear@4
|
148 glActiveTexture(GL_TEXTURE0);
|
nuclear@0
|
149 glBindTexture(GL_TEXTURE_3D, vol_tex);
|
nuclear@4
|
150 glActiveTexture(GL_TEXTURE1);
|
nuclear@4
|
151 glBindTexture(GL_TEXTURE_1D, xfer_tex);
|
nuclear@4
|
152
|
nuclear@4
|
153 set_uniform_int(sdr, "vol_tex", 0);
|
nuclear@4
|
154 set_uniform_int(sdr, "xfer_tex", 1);
|
nuclear@4
|
155
|
nuclear@0
|
156 glBegin(GL_QUADS);
|
nuclear@4
|
157 glTexCoord3f(0, 0, 0.5); glVertex2f(-1, -1);
|
nuclear@4
|
158 glTexCoord3f(1, 0, 0.5); glVertex2f(1, -1);
|
nuclear@4
|
159 glTexCoord3f(1, 1, 0.5); glVertex2f(1, 1);
|
nuclear@4
|
160 glTexCoord3f(0, 1, 0.5); glVertex2f(-1, 1);
|
nuclear@0
|
161 glEnd();
|
nuclear@0
|
162
|
nuclear@4
|
163 glUseProgram(0);
|
nuclear@4
|
164
|
nuclear@0
|
165 glMatrixMode(GL_PROJECTION);
|
nuclear@0
|
166 glPopMatrix();
|
nuclear@0
|
167 glMatrixMode(GL_MODELVIEW);
|
nuclear@0
|
168 glPopMatrix();
|
nuclear@0
|
169 }
|