OpenWalnut  1.4.0
WGETextureUtils.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 WGETEXTUREUTILS_H
00026 #define WGETEXTUREUTILS_H
00027 
00028 #include <string>
00029 
00030 #include <osg/Node>
00031 #include <osg/StateSet>
00032 #include <osg/TexMat>
00033 #include <osg/Texture1D>
00034 #include <osg/Texture2D>
00035 #include <osg/Texture3D>
00036 
00037 #include "../common/WStringUtils.h"
00038 
00039 #include "shaders/WGEPropertyUniform.h"
00040 #include "callbacks/WGEPropertyTransformationCallback.h"
00041 
00042 template < typename T > class WGETexture;
00043 class WDataTexture3D;
00044 
00045 namespace wge
00046 {
00047     /**
00048      * Binds the specified texture to the specified unit. It automatically adds several uniforms which then can be utilized in the shader:
00049      * - u_textureXUnit: the unit number (useful for accessing correct gl_TexCoord and so on)
00050      * - u_textureXSampler: the needed sampler
00051      * - u_textureXSizeX: width of the texture in pixels
00052      * - u_textureXSizeY: height of the texture in pixels
00053      * - u_textureXSizeZ: depth of the texture in pixels
00054      *
00055      * \warning this is not OSG-thread-safe. This method binds the texture immediately. So please use this only for nodes which are not yet used
00056      * in the scene graph. For safely binding textures to a node already in the scene, utilize an update callback.
00057      *
00058      * \param node where to bind
00059      * \param unit the unit to use
00060      * \param texture the texture to use.
00061      * \param prefix if specified, defines the uniform name prefix. (Sampler, Unit, Sizes, ...)
00062      * \tparam T the type of texture. Usually osg::Texture3D or osg::Texture2D.
00063      */
00064     template < typename T >
00065     void bindTexture( osg::ref_ptr< osg::Node > node, osg::ref_ptr< T > texture, size_t unit = 0, std::string prefix = "" );
00066 
00067     /**
00068      * Binds the specified texture to the specified unit. It automatically adds several uniforms which then can be utilized in the shader:
00069      * - u_textureXUnit: the unit number (useful for accessing correct gl_TexCoord and so on)
00070      * - u_textureXSampler: the needed sampler
00071      * - u_textureXSizeX: width of the texture in pixels
00072      * - u_textureXSizeY: height of the texture in pixels
00073      * - u_textureXSizeZ: depth of the texture in pixels
00074      * If the specified texture is a WGETexture, it additionally adds u_textureXMin and u_textureXScale for unscaling.
00075      *
00076      * \warning this is not OSG-thread-safe. This method binds the texture immediately. So please use this only for nodes which are not yet used
00077      * in the scene graph. For safely binding textures to a node already in the scene, utilize an update callback.
00078      *
00079      * \param node where to bind
00080      * \param unit the unit to use
00081      * \param texture the texture to use.
00082      * \param prefix if specified, defines the uniform name prefix. (Sampler, Unit, Sizes, ...)
00083      * \tparam T the type of texture. Usually osg::Texture3D or osg::Texture2D.
00084      */
00085     template < typename T >
00086     void bindTexture( osg::ref_ptr< osg::Node > node, osg::ref_ptr< WGETexture< T > > texture, size_t unit = 0, std::string prefix = ""  );
00087 
00088     /**
00089      * Removes the binding associated with the specified unit.
00090      *
00091      * \param unit the unit to unbind
00092      * \param node the node from which the binding should be removed
00093      * \param count the number of units beginning at the specified one should be unbound? 1 is the default.
00094      */
00095     void unbindTexture( osg::ref_ptr< osg::Node > node, size_t unit, size_t count = 1 );
00096 
00097     /**
00098      * Returns the maximum number of textures that can be bound to a node. Call this only from withing the OSG thread!
00099      *
00100      * \return the max number of texture units.
00101      */
00102     size_t getMaxTexUnits();
00103 
00104     /**
00105      * This generates an 1D texture only containing white noise in its channels.
00106      *
00107      * \param sizeX size in x direction (in pixels)
00108      * \param channels the number of channels. Valid are 1, 3 and 4.
00109      *
00110      * \return the generated texture.
00111      */
00112     osg::ref_ptr< WGETexture< osg::Texture1D > > genWhiteNoiseTexture( size_t sizeX, size_t channels );
00113 
00114     /**
00115      * This generates an 2D texture only containing white noise in its channels.
00116      *
00117      * \param sizeX size in x direction (in pixels)
00118      * \param sizeY size in y direction (in pixels)
00119      * \param channels the number of channels. Valid are 1, 3 and 4.
00120      *
00121      * \return the generated texture.
00122      */
00123     osg::ref_ptr< WGETexture< osg::Texture2D > > genWhiteNoiseTexture( size_t sizeX, size_t sizeY, size_t channels );
00124 
00125     /**
00126      * This generates an 3D texture only containing white noise in its channels.
00127      *
00128      * \param sizeX size in x direction (in pixels)
00129      * \param sizeY size in y direction (in pixels)
00130      * \param sizeZ size in z direction (in pixels)
00131      * \param channels the number of channels. Valid are 1, 3 and 4.
00132      *
00133      * \return the generated texture.
00134      */
00135     osg::ref_ptr< WGETexture< osg::Texture3D > > genWhiteNoiseTexture( size_t sizeX, size_t sizeY, size_t sizeZ, size_t channels );
00136 
00137     /**
00138      * Generates an image only containing white noise in its channels.
00139      *
00140      * \param sizeX size in x direction (in pixels)
00141      * \param sizeY size in y direction (in pixels)
00142      * \param sizeZ size in z direction (in pixels)
00143      * \param channels the number of channels. Valid are 1, 3 and 4.
00144      *
00145      * \return the generated image.
00146      */
00147     osg::ref_ptr< osg::Image > genWhiteNoiseImage( size_t sizeX, size_t sizeY, size_t sizeZ, size_t channels = 1 );
00148 
00149     /**
00150      * Generates a 3D turing noise texture. For details, see:
00151      *
00152      * Eichelbaum, Sebastian, et al. "Fabric-like visualization of tensor field data on arbitrary surfaces
00153      * in image space." New Developments in the Visualization and Processing of Tensor Fields. Springer Berlin Heidelberg, 2012. 71-92.
00154      *
00155      * \param sizeX The size of the textures in voxels, should be a power of 2.
00156      * \param sizeY The size of the textures in voxels, should be a power of 2.
00157      * \param sizeZ The size of the textures in voxels, should be a power of 2.
00158      * \param channels The number of channels; either 1, 3 or 4.
00159      *
00160      * \return The texture.
00161      */
00162     osg::ref_ptr< WGETexture< osg::Texture3D > > genTuringNoiseTexture( std::size_t sizeX, std::size_t sizeY,
00163                                                                         std::size_t sizeZ, std::size_t channels = 1 );
00164 }
00165 
00166 template < typename T >
00167 void wge::bindTexture( osg::ref_ptr< osg::Node > node, osg::ref_ptr< T > texture, size_t unit, std::string prefix )
00168 {
00169     if( prefix == "" )
00170     {
00171         prefix = "u_texture" + string_utils::toString( unit );
00172     }
00173 
00174     osg::StateSet* state = node->getOrCreateStateSet();
00175     state->setTextureAttributeAndModes( unit, texture, osg::StateAttribute::ON );
00176     state->addUniform( new osg::Uniform( ( prefix + "Sampler" ).c_str(), static_cast< int >( unit ) ) );
00177     state->addUniform( new osg::Uniform( ( prefix + "Unit" ).c_str(), static_cast< int >( unit ) ) );
00178     state->addUniform( new osg::Uniform( ( prefix + "SizeX" ).c_str(), static_cast< int >( texture->getTextureWidth() ) ) );
00179     state->addUniform( new osg::Uniform( ( prefix + "SizeY" ).c_str(), static_cast< int >( texture->getTextureHeight() ) ) );
00180     state->addUniform( new osg::Uniform( ( prefix + "SizeZ" ).c_str(), static_cast< int >( texture->getTextureDepth() ) ) );
00181 }
00182 
00183 template < typename T >
00184 void wge::bindTexture( osg::ref_ptr< osg::Node > node, osg::ref_ptr< WGETexture< T > > texture, size_t unit, std::string prefix )
00185 {
00186     if( prefix == "" )
00187     {
00188         prefix = "u_texture" + string_utils::toString( unit );
00189     }
00190 
00191     wge::bindTexture< T >( node, osg::ref_ptr< T >( texture ), unit, prefix );
00192 
00193     // set the texture matrix to the stateset
00194     osg::TexMat* texMat = new osg::TexMat( texture->transformation()->get() );
00195     // use a callback to update the tex matrix if needed according to transformation property of texture
00196     texMat->setUpdateCallback( new WGEPropertyTransformationCallback< osg::StateAttribute, osg::TexMat >( texture->transformation() ) );
00197     node->getOrCreateStateSet()->setTextureAttributeAndModes( unit, texMat, osg::StateAttribute::ON );
00198 
00199     // add some additional uniforms containing scaling information
00200     texture->applyUniforms( prefix, node->getOrCreateStateSet() );
00201 }
00202 
00203 #endif  // WGETEXTUREUTILS_H
00204