OpenWalnut 1.3.1
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 template < typename T >
00151 void wge::bindTexture( osg::ref_ptr< osg::Node > node, osg::ref_ptr< T > texture, size_t unit, std::string prefix )
00152 {
00153     if( prefix == "" )
00154     {
00155         prefix = "u_texture" + string_utils::toString( unit );
00156     }
00157 
00158     osg::StateSet* state = node->getOrCreateStateSet();
00159     state->setTextureAttributeAndModes( unit, texture, osg::StateAttribute::ON );
00160     state->addUniform( new osg::Uniform( ( prefix + "Sampler" ).c_str(), static_cast< int >( unit ) ) );
00161     state->addUniform( new osg::Uniform( ( prefix + "Unit" ).c_str(), static_cast< int >( unit ) ) );
00162     state->addUniform( new osg::Uniform( ( prefix + "SizeX" ).c_str(), static_cast< int >( texture->getTextureWidth() ) ) );
00163     state->addUniform( new osg::Uniform( ( prefix + "SizeY" ).c_str(), static_cast< int >( texture->getTextureHeight() ) ) );
00164     state->addUniform( new osg::Uniform( ( prefix + "SizeZ" ).c_str(), static_cast< int >( texture->getTextureDepth() ) ) );
00165 }
00166 
00167 template < typename T >
00168 void wge::bindTexture( osg::ref_ptr< osg::Node > node, osg::ref_ptr< WGETexture< T > > texture, size_t unit, std::string prefix )
00169 {
00170     if( prefix == "" )
00171     {
00172         prefix = "u_texture" + string_utils::toString( unit );
00173     }
00174 
00175     wge::bindTexture< T >( node, osg::ref_ptr< T >( texture ), unit, prefix );
00176 
00177     // set the texture matrix to the stateset
00178     osg::TexMat* texMat = new osg::TexMat( texture->transformation()->get() );
00179     // use a callback to update the tex matrix if needed according to transformation property of texture
00180     texMat->setUpdateCallback( new WGEPropertyTransformationCallback< osg::StateAttribute, osg::TexMat >( texture->transformation() ) );
00181     node->getOrCreateStateSet()->setTextureAttributeAndModes( unit, texMat, osg::StateAttribute::ON );
00182 
00183     // add some additional uniforms containing scaling information
00184     texture->applyUniforms( prefix, node->getOrCreateStateSet() );
00185 }
00186 
00187 #endif  // WGETEXTUREUTILS_H
00188