00001 #ifndef OPENTISSUE_UTILITY_VOLUME_RENDERING_VOLUME_RENDERING_TILE_RENDER_H
00002 #define OPENTISSUE_UTILITY_VOLUME_RENDERING_VOLUME_RENDERING_TILE_RENDER_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/utility/gl/gl_matrix_util.h>
00013 #include <OpenTissue/utility/gl/gl_frustum.h>
00014 #include <OpenTissue/gpu/texture/texture_create_texture3D.h>
00015 #include <OpenTissue/utility/volume_rendering/volume_rendering_texture3d_tile.h>
00016
00017 #include <list>
00018 #include <cassert>
00019
00020 namespace OpenTissue
00021 {
00022 namespace volume_rendering
00023 {
00024
00030 template<
00031 typename math_types
00032 , template <typename> class volume_shader_class_
00033 >
00034 class TileRender
00035 {
00036 public:
00037
00038 typedef typename math_types::real_type real_type;
00039 typedef typename math_types::vector3_type vector3_type;
00040 typedef Texture3DTile<math_types> tile_type;
00041 typedef std::list<tile_type> tile_container;
00042 typedef typename tile_container::iterator tile_iterator;
00043 typedef volume_shader_class_<math_types> volume_shader_type;
00044
00045 protected:
00046
00047 real_type m_image_min_x;
00048 real_type m_image_min_y;
00049 real_type m_image_min_z;
00050 real_type m_image_width;
00051 real_type m_image_height;
00052 real_type m_image_depth;
00053 volume_shader_type m_shader;
00054 tile_container m_tiles;
00055 gl::Frustum<math_types> m_frustum;
00056 vector3_type m_vertices[8];
00057
00058 public:
00059
00060 TileRender()
00061 : m_image_min_x()
00062 , m_image_min_y()
00063 , m_image_min_z()
00064 , m_image_width()
00065 , m_image_height()
00066 , m_image_depth()
00067 , m_shader()
00068 , m_tiles()
00069 , m_frustum()
00070 { }
00071
00072 public:
00073
00082 template< typename grid_type >
00083 void init( grid_type & volume )
00084 {
00085 typedef typename grid_type::value_type T;
00086
00087 m_tiles.clear();
00088
00089 real_type dx = volume.dx();
00090 real_type dy = volume.dy();
00091 real_type dz = volume.dz();
00092 unsigned int I = volume.I();
00093 unsigned int J = volume.J();
00094 unsigned int K = volume.K();
00095
00096 m_image_min_x = volume.min_coord(0) - dx*.5;
00097 m_image_min_y = volume.min_coord(1) - dy*.5;
00098 m_image_min_z = volume.min_coord(2) - dz*.5;
00099 real_type image_max_x = volume.max_coord(0) + dx*.5;
00100 real_type image_max_y = volume.max_coord(1) + dy*.5;
00101 real_type image_max_z = volume.max_coord(2) + dz*.5;
00102 m_image_width = image_max_x - m_image_min_x;
00103 m_image_height = image_max_y - m_image_min_y;
00104 m_image_depth = image_max_z - m_image_min_z;
00105
00106 m_vertices[ 0 ] = vector3_type( m_image_min_x , m_image_min_y, m_image_min_z );
00107 m_vertices[ 1 ] = vector3_type( image_max_x , m_image_min_y, m_image_min_z );
00108 m_vertices[ 2 ] = vector3_type( image_max_x , image_max_y, m_image_min_z );
00109 m_vertices[ 3 ] = vector3_type( m_image_min_x , image_max_y, m_image_min_z );
00110 m_vertices[ 4 ] = vector3_type( m_image_min_x , m_image_min_y, image_max_z );
00111 m_vertices[ 5 ] = vector3_type( image_max_x , m_image_min_y, image_max_z );
00112 m_vertices[ 6 ] = vector3_type( image_max_x , image_max_y, image_max_z );
00113 m_vertices[ 7 ] = vector3_type( m_image_min_x , image_max_y, image_max_z );
00114
00115
00116
00117 unsigned int di = 30;
00118 unsigned int dj = 30;
00119 unsigned int dk = 30;
00120 unsigned int i_width = di+2;
00121 unsigned int j_width = dj+2;
00122 unsigned int k_width = dk+2;
00123
00124
00125
00126 for(unsigned int i_first = 1; i_first<(I-1); i_first += di)
00127 for(unsigned int j_first = 1; j_first<(J-1); j_first += dj)
00128 for(unsigned int k_first = 1; k_first < (K-1); k_first += dk)
00129 {
00130
00131 unsigned int i_rest = (I - 1) - i_first;
00132 unsigned int j_rest = (J - 1) - j_first;
00133 unsigned int k_rest = (K - 1) - k_first;
00134
00135 tile_type tile;
00136
00137
00138 tile.m_image_skip_i = (i_first-1);
00139 tile.m_image_skip_j = (j_first-1);
00140 tile.m_image_skip_k = (k_first-1);
00141 tile.m_image_size_i = I;
00142 tile.m_image_size_j = J;
00143 tile.m_image_size_k = K;
00144 tile.m_texture_size_i = i_width;
00145 tile.m_texture_size_j = j_width;
00146 tile.m_texture_size_k = k_width;
00147 tile.m_texture_fill_i = (i_rest > i_width)?di:i_rest;
00148 tile.m_texture_fill_j = (j_rest > j_width)?dj:j_rest;
00149 tile.m_texture_fill_k = (k_rest > k_width)?dk:k_rest;
00150
00151
00152 T max_val = *(std::max_element(volume.begin(),volume.end()));
00153 T threshold = static_cast<T>(0.2*max_val);
00154 bool empty = true;
00155 for( int i=0;i<tile.m_texture_fill_i;++i)
00156 {
00157 for( int j=0;j<tile.m_texture_fill_j;++j)
00158 {
00159 for( int k=0;k<tile.m_texture_fill_k;++k)
00160 {
00161 if( volume(i+i_first,j+j_first,k+k_first) > threshold)
00162 {
00163 empty = false;
00164 break;
00165 }
00166 }
00167 }
00168 }
00169 if(empty)
00170 continue;
00171
00172
00173 real_type width = tile.m_texture_fill_i*dx;
00174 real_type height = tile.m_texture_fill_j*dy;
00175 real_type depth = tile.m_texture_fill_k*dz;
00176 real_type min_x = m_image_min_x + i_first*dx;
00177 real_type min_y = m_image_min_y + j_first*dy;
00178 real_type min_z = m_image_min_z + k_first*dz;
00179 real_type max_x = min_x + width;
00180 real_type max_y = min_y + height;
00181 real_type max_z = min_z + depth;
00182 tile.m_aabb_width = width;
00183 tile.m_aabb_height = height;
00184 tile.m_aabb_depth = depth;
00185 tile.m_aabb_min_x = min_x;
00186 tile.m_aabb_min_y = min_y;
00187 tile.m_aabb_min_z = min_z;
00188 tile.m_vertices[ 0 ] = vector3_type( min_x , min_y, min_z );
00189 tile.m_vertices[ 1 ] = vector3_type( max_x , min_y, min_z );
00190 tile.m_vertices[ 2 ] = vector3_type( max_x , max_y, min_z );
00191 tile.m_vertices[ 3 ] = vector3_type( min_x , max_y, min_z );
00192 tile.m_vertices[ 4 ] = vector3_type( min_x , min_y, max_z );
00193 tile.m_vertices[ 5 ] = vector3_type( max_x , min_y, max_z );
00194 tile.m_vertices[ 6 ] = vector3_type( max_x , max_y, max_z );
00195 tile.m_vertices[ 7 ] = vector3_type( min_x , max_y, max_z );
00196 tile.m_aabb.set( min_x, min_y, min_z, max_x, max_y, max_z);
00197
00198 tile.m_volume_texture = OpenTissue::texture::create_texture3D<T>(
00199 tile.m_texture_size_i
00200 , tile.m_texture_size_j
00201 , tile.m_texture_size_k
00202 );
00203
00204 tile.m_volume_texture->load_sub_image_into_texture(
00205 tile.m_image_skip_i
00206 , tile.m_image_skip_j
00207 , tile.m_image_skip_k
00208 , tile.m_image_size_i
00209 , tile.m_image_size_j
00210 , tile.m_image_size_k
00211 , 0, 0 ,0
00212 , tile.m_texture_fill_i + 2
00213 , tile.m_texture_fill_j + 2
00214 , tile.m_texture_fill_k + 2
00215 , volume.data()
00216 );
00217 tile.m_volume_texture->set_repeating(false);
00218
00219
00220 tile.m_tile_width = i_width* dx;
00221 tile.m_tile_height = j_width* dy;
00222 tile.m_tile_depth = k_width* dz;
00223 tile.m_tile_min_x = m_image_min_x + (i_first-1)*dx;
00224 tile.m_tile_min_y = m_image_min_y + (j_first-1)*dy;
00225 tile.m_tile_min_z = m_image_min_z + (k_first-1)*dz;
00226
00227 m_tiles.push_back(tile);
00228 }
00229
00230 std::cout << "|tiles| = " << m_tiles.size() << std::endl;
00231
00232 m_shader.init();
00233 }
00234
00240 template<typename texture2d_pointer>
00241 void display( texture2d_pointer color_table_texture)
00242 {
00243 using std::fabs;
00244 using std::min;
00245 using std::max;
00246
00247 if(m_tiles.empty() || !color_table_texture)
00248 return;
00249
00250 GLfloat model2eye_matrix[16];
00251 GLfloat eye2model_matrix[16];
00252 glGetFloatv( GL_MODELVIEW_MATRIX, model2eye_matrix );
00253 gl::invert( model2eye_matrix, eye2model_matrix );
00254
00255 real_type min_depth = math::detail::highest<real_type>();
00256 real_type max_depth = math::detail::lowest<real_type>();
00257 {
00258 tile_iterator begin = m_tiles.begin();
00259 tile_iterator end = m_tiles.end();
00260 for(tile_iterator tile=begin;tile!=end;++tile)
00261 {
00262 tile->m_min_depth = math::detail::highest<real_type>();
00263 tile->m_max_depth = math::detail::lowest<real_type>();
00264 for(unsigned int i=0;i<8;++i)
00265 {
00266 tile->m_eye_vertices[i] = gl::xform( model2eye_matrix, tile->m_vertices[i]);
00267 tile->m_min_depth = min(tile->m_eye_vertices[i](2), tile->m_min_depth);
00268 tile->m_max_depth = max(tile->m_eye_vertices[i](2), tile->m_max_depth);
00269 min_depth = min(min_depth, tile->m_min_depth);
00270 max_depth = max(max_depth, tile->m_max_depth);
00271 vector3_type eye_center = gl::xform( model2eye_matrix, (tile->m_vertices[0]+tile->m_vertices[6])*.5 );
00272
00273 tile->m_z_depth = eye_center*eye_center;
00274 }
00275 }
00276 }
00277
00278
00279 if(m_shader.front2back())
00280 m_tiles.sort(std::less<tile_type>( ));
00281 else
00282 m_tiles.sort(std::greater<tile_type>( ));
00283
00284 m_frustum.update();
00285
00286 m_shader.pre_render( color_table_texture );
00287
00288 tile_iterator begin = m_tiles.begin();
00289 tile_iterator end = m_tiles.end();
00290 for(tile_iterator tile=begin;tile!=end;++tile)
00291 {
00292
00293 if(tile->m_max_depth>0)
00294 continue;
00295
00296 if(!m_frustum.contains( tile->m_aabb ) )
00297 continue;
00298 m_shader.render(*tile);
00299 }
00300 m_shader.post_render();
00301 }
00302
00303 };
00304
00305 }
00306 }
00307
00308
00309 #endif