glviewvol
view src/rend_fast.cc @ 9:931a6b35f1cd
added lighting and openmp normal calculation
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 30 Dec 2014 21:20:57 +0200 |
parents | fb6d93471352 |
children | 89efc666105c |
line source
1 #include <stdio.h>
2 #include "opengl.h"
3 #include "rend_fast.h"
4 #include "sdr.h"
6 #define XFER_MAP_SZ 512
8 static unsigned int sdr;
9 static bool have_tex_float;
11 RendererFast::RendererFast()
12 {
13 vol_tex = xfer_tex = 0;
14 vol_tex_valid = xfer_tex_valid = false;
15 proxy_count = 256;
16 vbo_proxy_count = 0;
17 }
19 bool RendererFast::init()
20 {
21 if(!sdr) {
22 if(!(sdr = create_program_load("sdr/fast.v.glsl", "sdr/fast.p.glsl"))) {
23 return false;
24 }
25 have_tex_float = GLEW_ARB_texture_float;
26 }
28 glGenTextures(1, &vol_tex);
29 glBindTexture(GL_TEXTURE_3D, vol_tex);
30 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
31 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
32 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
33 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
34 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
36 glGenTextures(1, &xfer_tex);
37 glBindTexture(GL_TEXTURE_1D, xfer_tex);
38 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
39 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
40 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
41 glTexImage1D(GL_TEXTURE_1D, 0, have_tex_float ? GL_RGBA16F : GL_RGBA, XFER_MAP_SZ, 0, GL_RGB, GL_FLOAT, 0);
43 glGenBuffers(1, &vbo);
44 return true;
45 }
47 void RendererFast::destroy()
48 {
49 glDeleteTextures(1, &vol_tex);
50 glDeleteTextures(1, &xfer_tex);
51 glDeleteBuffers(1, &vbo);
52 }
54 void RendererFast::set_volume(Volume *vol)
55 {
56 vol_tex_valid = false;
57 Renderer::set_volume(vol);
58 }
60 void RendererFast::set_proxy_count(int n)
61 {
62 proxy_count = n;
63 }
65 int RendererFast::get_proxy_count() const
66 {
67 return proxy_count;
68 }
70 void RendererFast::update(unsigned int msec)
71 {
72 if(!vol) return;
74 // make sure the 3D volume texture is up to date
75 if(!vol_tex_valid) {
76 int xsz, ysz, zsz;
78 if((xsz = vol->num_samples(0)) > 0) {
79 ysz = vol->num_samples(1);
80 zsz = vol->num_samples(2);
81 } else {
82 xsz = ysz = zsz = 256;
83 }
85 printf("updating 3D texture data (%dx%dx%d) ... ", xsz, ysz, zsz);
86 fflush(stdout);
88 int int_fmt = GLEW_ARB_texture_float ? GL_RGBA16F_ARB : GL_RGBA;
90 glBindTexture(GL_TEXTURE_3D, vol_tex);
91 glTexImage3D(GL_TEXTURE_3D, 0, int_fmt, xsz, ysz, zsz, 0, GL_RGBA, GL_FLOAT, 0);
93 float *slice = new float[xsz * ysz * 4];
95 for(int i=0; i<zsz; i++) {
96 float z = (float)i;
98 #pragma omp parallel for schedule(dynamic)
99 for(int j=0; j<ysz; j++) {
100 float y = (float)j;
102 float *pptr = slice + (j * xsz) * 4;
103 for(int k=0; k<xsz; k++) {
104 float x = (float)k;
106 // value in alpha channel
107 pptr[3] = vol->valuef(x, y, z);
108 // normal in rgb
109 vol->normalf(pptr, x, y, z);
110 // shift normal to the [0,1] range in case we don't have tex_float
111 pptr[0] = pptr[0] * 0.5 + 0.5;
112 pptr[1] = pptr[1] * 0.5 + 0.5;
113 pptr[2] = pptr[2] * 0.5 + 0.5;
115 pptr += 4;
116 }
117 }
119 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, i, xsz, ysz, 1, GL_RGBA, GL_FLOAT, slice);
120 }
122 printf("done\n");
124 delete [] slice;
126 vol_tex_valid = true;
127 }
129 if(1) {//if(!xfer_tex_valid) {
130 float pixels[XFER_MAP_SZ * 4];
131 float *pptr = pixels;
133 for(int i=0; i<XFER_MAP_SZ; i++) {
134 float x = (float)i / (float)(XFER_MAP_SZ - 1);
136 if(xfer) {
137 xfer->map(x, pptr);
138 pptr[3] = std::max(pptr[0], std::max(pptr[1], pptr[2]));
139 } else {
140 pptr[0] = pptr[1] = pptr[2] = pptr[3] = x;
141 }
142 pptr += 4;
143 }
145 glBindTexture(GL_TEXTURE_1D, xfer_tex);
146 glTexSubImage1D(GL_TEXTURE_1D, 0, 0, XFER_MAP_SZ, GL_RGBA, GL_FLOAT, pixels);
148 xfer_tex_valid = true;
149 }
151 // make sure the proxy object is up to date
152 if(proxy_count != vbo_proxy_count) {
153 static const float pat[][3] = {{-1, -1}, {1, -1}, {1, 1}, {-1, 1}};
155 int nverts = proxy_count * 4;
156 float *verts = new float[nverts * 3];
157 float *vptr = verts;
159 for(int i=0; i<proxy_count; i++) {
160 float z = 2.0 * (float)i / (float)(proxy_count - 1) - 1.0;
162 for(int j=0; j<4; j++) {
163 *vptr++ = pat[j][0];
164 *vptr++ = pat[j][1];
165 *vptr++ = z;
166 }
167 }
169 glBindBuffer(GL_ARRAY_BUFFER, vbo);
170 glBufferData(GL_ARRAY_BUFFER, nverts * 3 * sizeof(float), verts, GL_STATIC_DRAW);
171 glBindBuffer(GL_ARRAY_BUFFER, 0);
173 delete [] verts;
174 vbo_proxy_count = proxy_count;
175 }
176 }
178 void RendererFast::render() const
179 {
180 if(!vol) return;
182 glClear(GL_COLOR_BUFFER_BIT);
184 glUseProgram(sdr);
186 glActiveTexture(GL_TEXTURE0);
187 glBindTexture(GL_TEXTURE_3D, vol_tex);
188 glActiveTexture(GL_TEXTURE1);
189 glBindTexture(GL_TEXTURE_1D, xfer_tex);
191 set_uniform_int(sdr, "vol_tex", 0);
192 set_uniform_int(sdr, "xfer_tex", 1);
194 glEnable(GL_BLEND);
195 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
197 glBindBuffer(GL_ARRAY_BUFFER, vbo);
198 glVertexPointer(3, GL_FLOAT, 0, 0);
199 glBindBuffer(GL_ARRAY_BUFFER, 0);
201 glEnableClientState(GL_VERTEX_ARRAY);
202 glDrawArrays(GL_QUADS, 0, vbo_proxy_count * 4);
203 glDisableClientState(GL_VERTEX_ARRAY);
205 glDisable(GL_BLEND);
207 glUseProgram(0);
208 }