OpenWalnut 1.2.5

WGETexture.h

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