00001 #ifndef OPENTISSUE_UTILITY_VOLUME_RENDERING_VOLUME_RENDERING_RENDER_H
00002 #define OPENTISSUE_UTILITY_VOLUME_RENDERING_VOLUME_RENDERING_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/gpu/texture/texture_create_texture3D.h>
00014 #include <OpenTissue/utility/volume_rendering/volume_rendering_texture3d_tile.h>
00015
00016 #include <list>
00017 #include <cassert>
00018
00019 namespace OpenTissue
00020 {
00021 namespace volume_rendering
00022 {
00023
00031 template<
00032 typename math_types
00033 , template <typename> class volume_shader_class_
00034 >
00035 class Render
00036 {
00037 public:
00038
00039 typedef typename math_types::real_type real_type;
00040 typedef typename math_types::vector3_type vector3_type;
00041 typedef Texture3DTile<math_types> tile_type;
00042 typedef volume_shader_class_<math_types> volume_shader_type;
00043
00044 protected:
00045
00046 real_type m_image_min_x;
00047 real_type m_image_min_y;
00048 real_type m_image_min_z;
00049 real_type m_image_width;
00050 real_type m_image_height;
00051 real_type m_image_depth;
00052 tile_type m_tile;
00053 volume_shader_type m_shader;
00054 vector3_type m_vertices[8];
00055
00056 public:
00057
00058 Render()
00059 : m_image_min_x()
00060 , m_image_min_y()
00061 , m_image_min_z()
00062 , m_image_width()
00063 , m_image_height()
00064 , m_image_depth()
00065 , m_tile()
00066 , m_shader()
00067 { }
00068
00069 public:
00070
00079 template< typename grid_type >
00080 void init( grid_type & volume )
00081 {
00082 using std::max;
00083
00084 typedef typename grid_type::value_type T;
00085
00086 real_type dx = volume.dx();
00087 real_type dy = volume.dy();
00088 real_type dz = volume.dz();
00089 unsigned int I = volume.I();
00090 unsigned int J = volume.J();
00091 unsigned int K = volume.K();
00092
00093 m_image_min_x = volume.min_coord(0) - dx*.5;
00094 m_image_min_y = volume.min_coord(1) - dy*.5;
00095 m_image_min_z = volume.min_coord(2) - dz*.5;
00096 real_type image_max_x = volume.max_coord(0) + dx*.5;
00097 real_type image_max_y = volume.max_coord(1) + dy*.5;
00098 real_type image_max_z = volume.max_coord(2) + dz*.5;
00099 m_image_width = image_max_x - m_image_min_x;
00100 m_image_height = image_max_y - m_image_min_y;
00101 m_image_depth = image_max_z - m_image_min_z;
00102
00103 m_vertices[ 0 ] = vector3_type( m_image_min_x , m_image_min_y, m_image_min_z );
00104 m_vertices[ 1 ] = vector3_type( image_max_x , m_image_min_y, m_image_min_z );
00105 m_vertices[ 2 ] = vector3_type( image_max_x , image_max_y, m_image_min_z );
00106 m_vertices[ 3 ] = vector3_type( m_image_min_x , image_max_y, m_image_min_z );
00107 m_vertices[ 4 ] = vector3_type( m_image_min_x , m_image_min_y, image_max_z );
00108 m_vertices[ 5 ] = vector3_type( image_max_x , m_image_min_y, image_max_z );
00109 m_vertices[ 6 ] = vector3_type( image_max_x , image_max_y, image_max_z );
00110 m_vertices[ 7 ] = vector3_type( m_image_min_x , image_max_y, image_max_z );
00111
00112
00113
00114 unsigned int dim = math::upper_power2( max( I, max( J, K ) ) );
00115 std::cout << "enclosing power 2 texture : " << dim << std::endl;
00116
00117 unsigned int di = dim-2;
00118 unsigned int dj = dim-2;
00119 unsigned int dk = dim-2;
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 unsigned int i_first = 1;
00127 unsigned int j_first = 1;
00128 unsigned int k_first = 1;
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
00136 m_tile.m_image_skip_i = (i_first-1);
00137 m_tile.m_image_skip_j = (j_first-1);
00138 m_tile.m_image_skip_k = (k_first-1);
00139 m_tile.m_image_size_i = I;
00140 m_tile.m_image_size_j = J;
00141 m_tile.m_image_size_k = K;
00142 m_tile.m_texture_size_i = i_width;
00143 m_tile.m_texture_size_j = j_width;
00144 m_tile.m_texture_size_k = k_width;
00145 m_tile.m_texture_fill_i = (i_rest > i_width)?di:i_rest;
00146 m_tile.m_texture_fill_j = (j_rest > j_width)?dj:j_rest;
00147 m_tile.m_texture_fill_k = (k_rest > k_width)?dk:k_rest;
00148
00149
00150 real_type width = m_tile.m_texture_fill_i*dx;
00151 real_type height = m_tile.m_texture_fill_j*dy;
00152 real_type depth = m_tile.m_texture_fill_k*dz;
00153 real_type min_x = m_image_min_x + i_first*dx;
00154 real_type min_y = m_image_min_y + j_first*dy;
00155 real_type min_z = m_image_min_z + k_first*dz;
00156 real_type max_x = min_x + width;
00157 real_type max_y = min_y + height;
00158 real_type max_z = min_z + depth;
00159 m_tile.m_aabb_width = width;
00160 m_tile.m_aabb_height = height;
00161 m_tile.m_aabb_depth = depth;
00162 m_tile.m_aabb_min_x = min_x;
00163 m_tile.m_aabb_min_y = min_y;
00164 m_tile.m_aabb_min_z = min_z;
00165 m_tile.m_vertices[ 0 ] = vector3_type( min_x , min_y, min_z );
00166 m_tile.m_vertices[ 1 ] = vector3_type( max_x , min_y, min_z );
00167 m_tile.m_vertices[ 2 ] = vector3_type( max_x , max_y, min_z );
00168 m_tile.m_vertices[ 3 ] = vector3_type( min_x , max_y, min_z );
00169 m_tile.m_vertices[ 4 ] = vector3_type( min_x , min_y, max_z );
00170 m_tile.m_vertices[ 5 ] = vector3_type( max_x , min_y, max_z );
00171 m_tile.m_vertices[ 6 ] = vector3_type( max_x , max_y, max_z );
00172 m_tile.m_vertices[ 7 ] = vector3_type( min_x , max_y, max_z );
00173 m_tile.m_aabb.set( min_x, min_y, min_z, max_x, max_y, max_z);
00174
00175 m_tile.m_volume_texture = OpenTissue::texture::create_texture3D<T>(
00176 m_tile.m_texture_size_i
00177 , m_tile.m_texture_size_j
00178 , m_tile.m_texture_size_k
00179 );
00180
00181 m_tile.m_volume_texture->load_sub_image_into_texture(
00182 m_tile.m_image_skip_i
00183 , m_tile.m_image_skip_j
00184 , m_tile.m_image_skip_k
00185 , m_tile.m_image_size_i
00186 , m_tile.m_image_size_j
00187 , m_tile.m_image_size_k
00188 , 0, 0 ,0
00189 , m_tile.m_texture_fill_i + 2
00190 , m_tile.m_texture_fill_j + 2
00191 , m_tile.m_texture_fill_k + 2
00192 , volume.data()
00193 );
00194 m_tile.m_volume_texture->set_repeating(false);
00195
00196
00197 m_tile.m_tile_width = i_width* dx;
00198 m_tile.m_tile_height = j_width* dy;
00199 m_tile.m_tile_depth = k_width* dz;
00200 m_tile.m_tile_min_x = m_image_min_x + (i_first-1)*dx;
00201 m_tile.m_tile_min_y = m_image_min_y + (j_first-1)*dy;
00202 m_tile.m_tile_min_z = m_image_min_z + (k_first-1)*dz;
00203
00204 m_shader.init();
00205 }
00206
00212 template<typename texture2d_pointer>
00213 void display( texture2d_pointer color_table_texture)
00214 {
00215 using std::fabs;
00216 using std::min;
00217 using std::max;
00218
00219 if(!color_table_texture)
00220 return;
00221
00222 GLfloat model2eye_matrix[16];
00223 GLfloat eye2model_matrix[16];
00224 glGetFloatv( GL_MODELVIEW_MATRIX, model2eye_matrix );
00225 gl::invert( model2eye_matrix, eye2model_matrix );
00226
00227 m_tile.m_min_depth = math::detail::highest<real_type>();
00228 m_tile.m_max_depth = math::detail::lowest<real_type>();
00229 for(unsigned int i=0;i<8;++i)
00230 {
00231 m_tile.m_eye_vertices[i] = gl::xform( model2eye_matrix, m_tile.m_vertices[i]);
00232 m_tile.m_min_depth = min(m_tile.m_eye_vertices[i](2), m_tile.m_min_depth);
00233 m_tile.m_max_depth = max(m_tile.m_eye_vertices[i](2), m_tile.m_max_depth);
00234 }
00235 m_shader.pre_render( color_table_texture );
00236 m_shader.render(m_tile);
00237 m_shader.post_render();
00238 }
00239
00240 };
00241
00242 }
00243 }
00244
00245
00246 #endif