OpenWalnut 1.3.1
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #ifndef WGETEXTURE_H 00026 #define WGETEXTURE_H 00027 00028 #include <string> 00029 00030 #include <boost/shared_ptr.hpp> 00031 00032 #include <osg/Node> 00033 #include <osg/StateSet> 00034 #include <osg/Texture> 00035 #include <osg/Texture1D> 00036 #include <osg/Texture2D> 00037 #include <osg/Texture3D> 00038 00039 #include "callbacks/WGEFunctorCallback.h" 00040 #include "../common/WBoundingBox.h" 00041 #include "../common/WProperties.h" 00042 #include "../common/WPropertyHelper.h" 00043 #include "../common/math/linearAlgebra/WLinearAlgebra.h" 00044 00045 #include "WGETextureUtils.h" 00046 00047 /** 00048 * This calls serves a simple purpose: have a texture and its scaling information together which allows very easy binding of textures to nodes 00049 * with associated shaders. When this texture gets bind using the bindTo methods, uniforms get added containing needed scaling information. 00050 */ 00051 template < typename TextureType = osg::Texture > 00052 class WGETexture: public TextureType 00053 { 00054 public: 00055 //! We support only 8 textures because some known hardware does not support more texture coordinates. 00056 static std::size_t const MAX_NUMBER_OF_TEXTURES = 8; 00057 00058 //! The maximum texture dimension. 00059 static std::size_t const MAX_TEXTURE_DIMENSION = 2048; 00060 00061 /** 00062 * Default constructor. Creates an empty instance of the texture. 00063 * 00064 * \param scale the scaling factor needed for de-scaling the texture values 00065 * \param min the minimum value allowing negative values too. 00066 */ 00067 WGETexture( double scale = 1.0, double min = 0.0 ); 00068 00069 /** 00070 * Creates texture from given image. Scaling is set to identity. 00071 * 00072 * \param image the image to use as texture 00073 * \param scale the scaling factor needed for de-scaling the texture values 00074 * \param min the minimum value allowing negative values too. 00075 */ 00076 WGETexture( osg::Image* image, double scale = 1.0, double min = 0.0 ); 00077 00078 /** 00079 * Copy the texture. 00080 * 00081 * \param texture the texture to copy 00082 * \param copyop 00083 */ 00084 WGETexture( const WGETexture< TextureType >& texture, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY ); 00085 00086 /** 00087 * Destructor. 00088 */ 00089 virtual ~WGETexture(); 00090 00091 /** 00092 * Returns the name property of the texture. You should set it if you create a texture. 00093 * 00094 * \return texture name property 00095 */ 00096 WPropString name() const; 00097 00098 /** 00099 * Get the minimum in the de-scaled value space. The property can be changed. A change affects all colormaps using this texture. But be 00100 * careful as the texture creating depends on these values. 00101 * 00102 * \return the minimum 00103 */ 00104 WPropDouble minimum() const; 00105 00106 /** 00107 * Get the scaling factor for de-scaling the texture. The property can be changed. A change affects all colormaps using this texture. But be 00108 * careful as the texture creating depends on these values. 00109 * 00110 * \return the scale 00111 */ 00112 WPropDouble scale() const; 00113 00114 /** 00115 * Returns the alpha property. The property can be changed. A change affects all colormaps using this texture. 00116 * 00117 * \return alpha property 00118 */ 00119 WPropDouble alpha() const; 00120 00121 /** 00122 * Returns the threshold property. The property can be changed. A change affects all colormaps using this texture. 00123 * 00124 * \return threshold property 00125 */ 00126 WPropDouble threshold() const; 00127 00128 /** 00129 * Returns the property responsible for enabling threshold based clipping. If this is false, the threshold is ignored. 00130 * 00131 * \return threshold-enable property. 00132 */ 00133 WPropBool thresholdEnabled() const; 00134 00135 /** 00136 * Returns the interpolation property. The property can be changed. A change affects all colormaps using this texture. 00137 * 00138 * \return interpolation property 00139 */ 00140 WPropBool interpolation() const; 00141 00142 /** 00143 * Returns the colormap property. The property can be changed. A change affects all colormaps using this texture. 00144 * 00145 * \return colormap property 00146 */ 00147 WPropSelection colormap() const; 00148 00149 /** 00150 * Returns the active property. The property can be changed. A change affects all colormaps using this texture. 00151 * 00152 * \return active property 00153 */ 00154 WPropBool active() const; 00155 00156 /** 00157 * Returns the texture transformation matrix. The property can be changed. A change affects all colormaps using this texture. This matrix 00158 * converts an world-space coordinate to an texture coordinate! This can be seen as a scaled inverse matrix of the grid's transformation. 00159 * 00160 * \return the matrix 00161 */ 00162 WPropMatrix4X4 transformation() const; 00163 00164 /** 00165 * Binds the texture to the specified node and texture unit. It also adds two uniforms: u_textureXMin and u_textureXScale, where X 00166 * is the unit number. This can be used in shaders to unscale it. 00167 * 00168 * \param node the node where to bind the texture to 00169 * \param unit the unit, by default 0 00170 */ 00171 void bind( osg::ref_ptr< osg::Node > node, size_t unit = 0 ); 00172 00173 /** 00174 * Return a pointer to the properties object of the dataset. Add all the modifiable settings here. This allows the user to modify several 00175 * properties of a dataset. 00176 * 00177 * \return the properties. 00178 */ 00179 boost::shared_ptr< WProperties > getProperties() const; 00180 00181 /** 00182 * Return a pointer to the information properties object of the dataset. The dataset intends these properties to not be modified. 00183 * 00184 * \return the properties. 00185 */ 00186 boost::shared_ptr< WProperties > getInformationProperties() const; 00187 00188 /** 00189 * Applies some custom uniforms to the specified state-set which directly relate to this texture 00190 * 00191 * \param prefix the prefix used for the uniforms 00192 * \param states the state where to add the uniforms 00193 */ 00194 virtual void applyUniforms( std::string prefix, osg::StateSet* states ) const; 00195 00196 /** 00197 * For all the lazy guys to set the filter MIN and MAG at once. 00198 * 00199 * \param mode the new mode for MIN_FILTER and MAG_FILTER. 00200 */ 00201 void setFilterMinMag( osg::Texture::FilterMode mode ); 00202 00203 /** 00204 * For all the lazy guys to set the wrapping for s,t and r directions at once. 00205 * 00206 * \param mode the new mode for WRAP_S, WRAP_T and WRAP_R. 00207 */ 00208 void setWrapSTR( osg::Texture::WrapMode mode ); 00209 00210 /** 00211 * Returns the texture's bounding box. This is const. Although there exists the transformation() property, it is an information property and 00212 * can't be changed. 00213 * 00214 * \return the bounding box. 00215 */ 00216 virtual WBoundingBox getBoundingBox() const; 00217 00218 protected: 00219 /** 00220 * Handles all property updates. Called by m_propCondition. 00221 */ 00222 virtual void handleUpdate(); 00223 00224 /** 00225 * Creates the texture data. Overwrite this method if you want to provide a custom texture creation procedure. 00226 */ 00227 virtual void create(); 00228 00229 /** 00230 * This method implements an update callback which updates the texture image if needed and several other properties like texture matrix. 00231 * 00232 * \param state the state to update 00233 */ 00234 virtual void updateCallback( osg::StateAttribute* state ); 00235 00236 /** 00237 * Initialize the size of the texture properly according to real texture type (1D,2D,3D). 00238 * \note This is needed because osg::Texture::setImage is not virtual and does not set the size from the image. 00239 * 00240 * \param texture the texture where to set the size 00241 * \param width the new width 00242 * \param height the new height 00243 * \param depth the new depth 00244 */ 00245 static void initTextureSize( osg::Texture1D* texture, int width, int height, int depth ); 00246 00247 /** 00248 * Initialize the size of the texture properly according to real texture type (1D,2D,3D). 00249 * \note This is needed because osg::Texture::setImage is not virtual and does not set the size from the image. 00250 * 00251 * \param texture the texture where to set the size 00252 * \param width the new width 00253 * \param height the new height 00254 * \param depth the new depth 00255 */ 00256 static void initTextureSize( osg::Texture2D* texture, int width, int height, int depth ); 00257 00258 /** 00259 * Initialize the size of the texture properly according to real texture type (1D,2D,3D). 00260 * \note This is needed because osg::Texture::setImage is not virtual and does not set the size from the image. 00261 * 00262 * \param texture the texture where to set the size 00263 * \param width the new width 00264 * \param height the new height 00265 * \param depth the new depth 00266 */ 00267 static void initTextureSize( osg::Texture3D* texture, int width, int height, int depth ); 00268 00269 private: 00270 /** 00271 * Creates and assigns all properties. 00272 * 00273 * \param min the min value of the texture 00274 * \param scale the scale value of the texture 00275 */ 00276 void setupProperties( double scale, double min ); 00277 00278 /** 00279 * A condition used to notify about changes in several properties. 00280 */ 00281 boost::shared_ptr< WCondition > m_propCondition; 00282 00283 /** 00284 * The property object for the dataset. 00285 */ 00286 boost::shared_ptr< WProperties > m_properties; 00287 00288 /** 00289 * The property object for the dataset containing only props whose purpose is "PV_PURPOSE_INFORMNATION". It is useful to define some property 00290 * to only be of informational nature. The GUI does not modify them. As it is a WProperties instance, you can use it the same way as 00291 * m_properties. 00292 */ 00293 boost::shared_ptr< WProperties > m_infoProperties; 00294 00295 /** 00296 * If true, the texture gets created. This is used to create texture on demand. 00297 */ 00298 bool m_needCreate; 00299 00300 /** 00301 * The texture name. This might be useful to identify textures. 00302 */ 00303 WPropString m_name; 00304 00305 /** 00306 * The minimum of each value in the texture in unscaled space. 00307 */ 00308 WPropDouble m_min; 00309 00310 /** 00311 * The scaling factor to de-scale a [0-1] texture to original space. 00312 */ 00313 WPropDouble m_scale; 00314 00315 /** 00316 * A list of color map selection types 00317 */ 00318 boost::shared_ptr< WItemSelection > m_colorMapSelectionsList; 00319 00320 /** 00321 * Selection property for color map 00322 */ 00323 WPropSelection m_colorMap; 00324 00325 /** 00326 * Alpha blending value. 00327 */ 00328 WPropDouble m_alpha; 00329 00330 /** 00331 * Threshold for clipping areas. 00332 */ 00333 WPropDouble m_threshold; 00334 00335 /** 00336 * Threshold-enable flag. 00337 */ 00338 WPropBool m_thresholdEnabled; 00339 00340 /** 00341 * True if interpolation should be used. 00342 */ 00343 WPropBool m_interpolation; 00344 00345 /** 00346 * True if the texture is active. 00347 */ 00348 WPropBool m_active; 00349 00350 /** 00351 * The texture transformation matrix. 00352 */ 00353 WPropMatrix4X4 m_texMatrix; 00354 }; 00355 00356 // Some convenience typedefs 00357 00358 /** 00359 * OSG's Texture1D with scaling features 00360 */ 00361 typedef WGETexture< osg::Texture1D > WGETexture1D; 00362 00363 /** 00364 * OSG's Texture2D with scaling features 00365 */ 00366 typedef WGETexture< osg::Texture2D > WGETexture2D; 00367 00368 /** 00369 * OSG's Texture3D with scaling features 00370 */ 00371 typedef WGETexture< osg::Texture3D > WGETexture3D; 00372 00373 00374 template < typename TextureType > 00375 WGETexture< TextureType >::WGETexture( double scale, double min ): 00376 TextureType(), 00377 m_propCondition( boost::shared_ptr< WCondition >( new WCondition() ) ), 00378 m_properties( boost::shared_ptr< WProperties >( new WProperties( "Texture Properties", "Properties of a texture." ) ) ), 00379 m_infoProperties( boost::shared_ptr< WProperties >( new WProperties( "Texture Info Properties", "Texture's information properties." ) ) ), 00380 m_needCreate( true ) 00381 { 00382 setupProperties( scale, min ); 00383 } 00384 00385 template < typename TextureType > 00386 WGETexture< TextureType >::WGETexture( osg::Image* image, double scale, double min ): 00387 TextureType( image ), 00388 m_propCondition( boost::shared_ptr< WCondition >( new WCondition() ) ), 00389 m_properties( boost::shared_ptr< WProperties >( new WProperties( "Texture Properties", "Properties of a texture." ) ) ), 00390 m_infoProperties( boost::shared_ptr< WProperties >( new WProperties( "Texture Info Properties", "Texture's information properties." ) ) ), 00391 m_needCreate( true ) 00392 { 00393 setupProperties( scale, min ); 00394 WGETexture< TextureType >::initTextureSize( this, image->s(), image->t(), image->r() ); 00395 } 00396 00397 template < typename TextureType > 00398 WGETexture< TextureType >::WGETexture( const WGETexture< TextureType >& texture, const osg::CopyOp& copyop ): 00399 TextureType( texture, copyop ), 00400 m_min( texture.m_min ), 00401 m_scale( texture.m_scale ) 00402 { 00403 // initialize members 00404 } 00405 00406 template < typename TextureType > 00407 void WGETexture< TextureType >::setupProperties( double scale, double min ) 00408 { 00409 m_propCondition->subscribeSignal( boost::bind( &WGETexture< TextureType >::handleUpdate, this ) ); 00410 00411 m_name = m_properties->addProperty( "Name", "The name of the texture.", std::string( "Unnamed" ) ); 00412 00413 // initialize members 00414 m_min = m_properties->addProperty( "Minimum", "The minimum value in the original space.", min, true ); 00415 m_min->removeConstraint( m_min->getMin() ); 00416 m_min->removeConstraint( m_min->getMax() ); 00417 00418 m_scale = m_properties->addProperty( "Scale", "The scaling factor to un-scale the texture values to the original space.", scale, true ); 00419 m_scale->removeConstraint( m_scale->getMin() ); 00420 m_scale->removeConstraint( m_scale->getMax() ); 00421 00422 m_alpha = m_properties->addProperty( "Alpha", "The alpha blending value.", 1.0 ); 00423 m_alpha->setMin( 0.0 ); 00424 m_alpha->setMax( 1.0 ); 00425 00426 m_thresholdEnabled = m_properties->addProperty( "Enable Threshold", 00427 "If enabled, threshold based clipping is used. If not, threshold is ignored.", false ); 00428 00429 m_threshold = m_properties->addProperty( "Threshold", "The threshold used to clip areas.", 0.0 ); 00430 m_threshold->setMin( min ); 00431 m_threshold->setMax( min + scale ); 00432 00433 m_interpolation = m_properties->addProperty( "Interpolate", "Interpolation of the volume data.", true, m_propCondition ); 00434 00435 m_colorMapSelectionsList = boost::shared_ptr< WItemSelection >( new WItemSelection() ); 00436 m_colorMapSelectionsList->addItem( "Grayscale", "" ); 00437 m_colorMapSelectionsList->addItem( "Rainbow", "" ); 00438 m_colorMapSelectionsList->addItem( "Hot iron", "" ); 00439 m_colorMapSelectionsList->addItem( "Negative to positive", "" ); 00440 m_colorMapSelectionsList->addItem( "Atlas", "" ); 00441 m_colorMapSelectionsList->addItem( "Blue-Green-Purple", "" ); 00442 m_colorMapSelectionsList->addItem( "Vector", "" ); 00443 00444 m_colorMap = m_properties->addProperty( "Colormap", "The colormap of this texture.", m_colorMapSelectionsList->getSelectorFirst() ); 00445 WPropertyHelper::PC_SELECTONLYONE::addTo( m_colorMap ); 00446 00447 m_active = m_properties->addProperty( "Active", "Can dis-enable a texture.", true ); 00448 00449 WMatrix4d m = WMatrix4d::identity(); 00450 m_texMatrix = m_properties->addProperty( "Texture Transformation", "Usable to transform the texture.", m ); 00451 m_texMatrix->setPurpose( PV_PURPOSE_INFORMATION ); 00452 00453 TextureType::setResizeNonPowerOfTwoHint( false ); 00454 TextureType::setUpdateCallback( new WGEFunctorCallback< osg::StateAttribute >( 00455 boost::bind( &WGETexture< TextureType >::updateCallback, this, _1 ) ) 00456 ); 00457 00458 // init filters 00459 TextureType::setFilter( osg::Texture::MIN_FILTER, m_interpolation->get( true ) ? osg::Texture::LINEAR : osg::Texture::NEAREST ); 00460 TextureType::setFilter( osg::Texture::MAG_FILTER, m_interpolation->get( true ) ? osg::Texture::LINEAR : osg::Texture::NEAREST ); 00461 } 00462 00463 template < typename TextureType > 00464 WGETexture< TextureType >::~WGETexture() 00465 { 00466 // cleanup. 00467 } 00468 00469 template < typename TextureType > 00470 boost::shared_ptr< WProperties > WGETexture< TextureType >::getProperties() const 00471 { 00472 return m_properties; 00473 } 00474 00475 template < typename TextureType > 00476 boost::shared_ptr< WProperties > WGETexture< TextureType >::getInformationProperties() const 00477 { 00478 return m_infoProperties; 00479 } 00480 00481 template < typename TextureType > 00482 inline WPropString WGETexture< TextureType >::name() const 00483 { 00484 return m_name; 00485 } 00486 00487 template < typename TextureType > 00488 inline WPropDouble WGETexture< TextureType >::minimum() const 00489 { 00490 return m_min; 00491 } 00492 00493 template < typename TextureType > 00494 inline WPropDouble WGETexture< TextureType >::scale() const 00495 { 00496 return m_scale; 00497 } 00498 00499 template < typename TextureType > 00500 inline WPropDouble WGETexture< TextureType >::alpha() const 00501 { 00502 return m_alpha; 00503 } 00504 00505 template < typename TextureType > 00506 inline WPropDouble WGETexture< TextureType >::threshold() const 00507 { 00508 return m_threshold; 00509 } 00510 00511 template < typename TextureType > 00512 inline WPropBool WGETexture< TextureType >::thresholdEnabled() const 00513 { 00514 return m_thresholdEnabled; 00515 } 00516 00517 template < typename TextureType > 00518 inline WPropBool WGETexture< TextureType >::interpolation() const 00519 { 00520 return m_interpolation; 00521 } 00522 00523 template < typename TextureType > 00524 inline WPropSelection WGETexture< TextureType >::colormap() const 00525 { 00526 return m_colorMap; 00527 } 00528 00529 template < typename TextureType > 00530 inline WPropBool WGETexture< TextureType >::active() const 00531 { 00532 return m_active; 00533 } 00534 00535 template < typename TextureType > 00536 inline WPropMatrix4X4 WGETexture< TextureType >::transformation() const 00537 { 00538 return m_texMatrix; 00539 } 00540 00541 template < typename TextureType > 00542 void WGETexture< TextureType >::handleUpdate() 00543 { 00544 if( m_interpolation->changed() ) 00545 { 00546 TextureType::setFilter( osg::Texture::MIN_FILTER, m_interpolation->get( true ) ? osg::Texture::LINEAR : osg::Texture::NEAREST ); 00547 TextureType::setFilter( osg::Texture::MAG_FILTER, m_interpolation->get( true ) ? osg::Texture::LINEAR : osg::Texture::NEAREST ); 00548 } 00549 } 00550 00551 template < typename TextureType > 00552 void WGETexture< TextureType >::applyUniforms( std::string prefix, osg::StateSet* states ) const 00553 { 00554 states->addUniform( new WGEPropertyUniform< WPropDouble >( prefix + "Min", minimum() ) ); 00555 states->addUniform( new WGEPropertyUniform< WPropDouble >( prefix + "Scale", scale() ) ); 00556 states->addUniform( new WGEPropertyUniform< WPropDouble >( prefix + "Alpha", alpha() ) ); 00557 states->addUniform( new WGEPropertyUniform< WPropBool >( prefix + "ThresholdEnabled", thresholdEnabled() ) ); 00558 states->addUniform( new WGEPropertyUniform< WPropDouble >( prefix + "Threshold", threshold() ) ); 00559 states->addUniform( new WGEPropertyUniform< WPropSelection >( prefix + "Colormap", colormap() ) ); 00560 states->addUniform( new WGEPropertyUniform< WPropBool >( prefix + "Active", active() ) ); 00561 } 00562 00563 template < typename TextureType > 00564 void WGETexture< TextureType >::bind( osg::ref_ptr< osg::Node > node, size_t unit ) 00565 { 00566 // let our utilities do the work 00567 wge::bindTexture( node, osg::ref_ptr< WGETexture< TextureType > >( this ), unit ); // to avoid recursive stuff -> explicitly specify the type 00568 } 00569 00570 template < typename TextureType > 00571 void WGETexture< TextureType >::create() 00572 { 00573 // do nothing. Derived classes may implement this. 00574 } 00575 00576 template < typename TextureType > 00577 void WGETexture< TextureType >::updateCallback( osg::StateAttribute* /*state*/ ) 00578 { 00579 // create if not done yet 00580 if( m_needCreate ) 00581 { 00582 m_needCreate = false; 00583 create(); 00584 TextureType::dirtyTextureObject(); 00585 } 00586 } 00587 00588 template < typename TextureType > 00589 void WGETexture< TextureType >::setFilterMinMag( osg::Texture::FilterMode mode ) 00590 { 00591 this->setFilter( osg::Texture2D::MIN_FILTER, mode ); 00592 this->setFilter( osg::Texture2D::MAG_FILTER, mode ); 00593 } 00594 00595 template < typename TextureType > 00596 void WGETexture< TextureType >::setWrapSTR( osg::Texture::WrapMode mode ) 00597 { 00598 this->setWrap( osg::Texture2D::WRAP_S, mode ); 00599 this->setWrap( osg::Texture2D::WRAP_T, mode ); 00600 this->setWrap( osg::Texture2D::WRAP_R, mode ); 00601 } 00602 00603 template < typename TextureType > 00604 void WGETexture< TextureType >::initTextureSize( osg::Texture1D* texture, int width, int /*height*/, int /*depth*/ ) 00605 { 00606 texture->setTextureWidth( width ); 00607 } 00608 00609 template < typename TextureType > 00610 void WGETexture< TextureType >::initTextureSize( osg::Texture2D* texture, int width, int height, int /*depth*/ ) 00611 { 00612 texture->setTextureSize( width, height ); 00613 } 00614 00615 template < typename TextureType > 00616 void WGETexture< TextureType >::initTextureSize( osg::Texture3D* texture, int width, int height, int depth ) 00617 { 00618 texture->setTextureSize( width, height, depth ); 00619 } 00620 00621 template < typename TextureType > 00622 WBoundingBox WGETexture< TextureType >::getBoundingBox() const 00623 { 00624 return WBoundingBox( 0.0, 0.0, 0.0, 1.0, 1.0, 1.0 ); 00625 } 00626 00627 #endif // WGETEXTURE_H 00628