00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef WDATATEXTURE3D_H
00026 #define WDATATEXTURE3D_H
00027
00028 #include <algorithm>
00029 #include <limits>
00030 #include <string>
00031
00032 #include <boost/shared_ptr.hpp>
00033 #include <boost/signals2.hpp>
00034
00035 #include "../graphicsEngine/WGETexture.h"
00036 #include "../graphicsEngine/WGETypeTraits.h"
00037 #include "../common/WProperties.h"
00038
00039 #include "WValueSetBase.h"
00040 #include "WGridRegular3D.h"
00041
00042 #include "WExportDataHandler.h"
00043
00044
00045
00046
00047 namespace WDataTexture3DScalers
00048 {
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 template < typename T >
00063 inline typename wge::GLType< T >::Type scaleInterval( T value, T minimum, T maximum, double scaler )
00064 {
00065 return static_cast< double >( std::min( std::max( value, minimum ), maximum ) - minimum ) / scaler;
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075 inline int8_t scaleInterval( int8_t value, int8_t , int8_t , double )
00076 {
00077 return value;
00078 }
00079
00080
00081
00082
00083
00084
00085
00086
00087 inline uint8_t scaleInterval( uint8_t value, uint8_t , uint8_t , double )
00088 {
00089 return value;
00090 }
00091 }
00092
00093
00094
00095
00096
00097 class OWDATAHANDLER_EXPORT WDataTexture3D: public WGETexture3D
00098 {
00099 public:
00100
00101
00102
00103
00104
00105
00106
00107 WDataTexture3D( boost::shared_ptr< WValueSetBase > valueSet, boost::shared_ptr< WGridRegular3D > grid );
00108
00109
00110
00111
00112 virtual ~WDataTexture3D();
00113
00114
00115
00116
00117
00118
00119
00120 virtual WBoundingBox getBoundingBox() const;
00121
00122 protected:
00123
00124
00125
00126
00127 virtual void create();
00128
00129 private:
00130
00131
00132
00133
00134 boost::shared_ptr< WValueSetBase > m_valueSet;
00135
00136
00137
00138
00139 WBoundingBox m_boundingBox;
00140
00141
00142
00143
00144 boost::shared_mutex m_creationLock;
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 template < typename T >
00156 osg::ref_ptr< osg::Image > createTexture( T* source, int components = 1 );
00157 };
00158
00159
00160
00161
00162 namespace wge
00163 {
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 void OWDATAHANDLER_EXPORT bindTexture( osg::ref_ptr< osg::Node > node, osg::ref_ptr< WDataTexture3D > texture,
00180 size_t unit = 0, std::string prefix = "" );
00181 }
00182
00183 template < typename T >
00184 osg::ref_ptr< osg::Image > WDataTexture3D::createTexture( T* source, int components )
00185 {
00186
00187 boost::unique_lock< boost::shared_mutex > lock( m_creationLock );
00188
00189
00190 T min = static_cast< T >( minimum()->get() );
00191 double scaler = scale()->get();
00192 T max = min + static_cast< T >( scaler );
00193
00194 typedef typename wge::GLType< T >::Type TexType;
00195 GLenum type = wge::GLType< T >::TypeEnum;
00196
00197 wlog::debug( "WDataTexture3D" ) << "Resolution: " << getTextureWidth() << "x" << getTextureHeight() << "x" << getTextureDepth();
00198 wlog::debug( "WDataTexture3D" ) << "Channels: " << components;
00199
00200 wlog::debug( "WDataTexture3D" ) << "Value Range: [" << static_cast< float >( min ) << "," << static_cast< float >( max ) <<
00201 "] - Scaler: " << scaler;
00202 osg::ref_ptr< osg::Image > ima = new osg::Image;
00203
00204 size_t nbVoxels = getTextureWidth() * getTextureHeight() * getTextureDepth();
00205
00206 if( components == 1)
00207 {
00208
00209 ima->allocateImage( getTextureWidth(), getTextureHeight(), getTextureDepth(), GL_LUMINANCE_ALPHA, type );
00210 TexType* data = reinterpret_cast< TexType* >( ima->data() );
00211
00212
00213 for( unsigned int i = 0; i < nbVoxels; ++i )
00214 {
00215 data[ 2 * i ] = WDataTexture3DScalers::scaleInterval( source[i], min, max, scaler );
00216
00217 data[ ( 2 * i ) + 1] = wge::GLType< T >::FullIntensity() * ( source[i] != min );
00218 }
00219 }
00220 else if( components == 2)
00221 {
00222
00223 ima->allocateImage( getTextureWidth(), getTextureHeight(), getTextureDepth(), GL_RGBA, type );
00224 ima->setInternalTextureFormat( GL_RGBA );
00225 TexType* data = reinterpret_cast< TexType* >( ima->data() );
00226
00227
00228 for( unsigned int i = 0; i < nbVoxels; ++i )
00229 {
00230 data[ ( 4 * i ) ] = WDataTexture3DScalers::scaleInterval( source[ ( 2 * i ) ], min, max, scaler );
00231 data[ ( 4 * i ) + 1 ] = WDataTexture3DScalers::scaleInterval( source[ ( 2 * i ) + 1 ], min, max, scaler );
00232 data[ ( 4 * i ) + 2 ] = 0;
00233 data[ ( 4 * i ) + 3 ] = wge::GLType< T >::FullIntensity();
00234 }
00235 }
00236 else if( components == 3)
00237 {
00238
00239 ima->allocateImage( getTextureWidth(), getTextureHeight(), getTextureDepth(), GL_RGBA, type );
00240 ima->setInternalTextureFormat( GL_RGBA );
00241 TexType* data = reinterpret_cast< TexType* >( ima->data() );
00242
00243
00244 for( unsigned int i = 0; i < nbVoxels; ++i )
00245 {
00246 data[ ( 4 * i ) ] = WDataTexture3DScalers::scaleInterval( source[ ( 3 * i ) ], min, max, scaler );
00247 data[ ( 4 * i ) + 1 ] = WDataTexture3DScalers::scaleInterval( source[ ( 3 * i ) + 1 ], min, max, scaler );
00248 data[ ( 4 * i ) + 2 ] = WDataTexture3DScalers::scaleInterval( source[ ( 3 * i ) + 2 ], min, max, scaler );
00249 data[ ( 4 * i ) + 3 ] = wge::GLType< T >::FullIntensity();
00250 }
00251 }
00252 else if( components == 4)
00253 {
00254
00255 ima->allocateImage( getTextureWidth(), getTextureHeight(), getTextureDepth(), GL_RGBA, type );
00256 ima->setInternalTextureFormat( GL_RGBA );
00257 TexType* data = reinterpret_cast< TexType* >( ima->data() );
00258
00259
00260 for( unsigned int i = 0; i < nbVoxels; ++i )
00261 {
00262 data[ ( 4 * i ) ] = WDataTexture3DScalers::scaleInterval( source[ ( 4 * i ) ], min, max, scaler );
00263 data[ ( 4 * i ) + 1 ] = WDataTexture3DScalers::scaleInterval( source[ ( 4 * i ) + 1 ], min, max, scaler );
00264 data[ ( 4 * i ) + 2 ] = WDataTexture3DScalers::scaleInterval( source[ ( 4 * i ) + 2 ], min, max, scaler );
00265 data[ ( 4 * i ) + 3 ] = WDataTexture3DScalers::scaleInterval( source[ ( 4 * i ) + 3 ], min, max, scaler );
00266 }
00267 }
00268 else
00269 {
00270 wlog::error( "WDataTexture3D" ) << "Did not handle dataset ( components != 1,2,3 or 4 ).";
00271 }
00272
00273
00274 lock.unlock();
00275
00276 return ima;
00277 }
00278
00279 #endif // WDATATEXTURE3D_H
00280