ShaderAttribute.h

00001 /***************************************************************************
00002  *   Copyright (c) 2008   Art Tevs                                         *
00003  *                                                                         *
00004  *   This library is free software; you can redistribute it and/or modify  *
00005  *   it under the terms of the GNU Lesser General Public License as        *
00006  *   published by the Free Software Foundation; either version 3 of        *
00007  *   the License, or (at your option) any later version.                   *
00008  *                                                                         *
00009  *   This library is distributed in the hope that it will be useful,       *
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00012  *   GNU Lesse General Public License for more details.                    *
00013  *                                                                         *
00014  *   The full license is in LICENSE file included with this distribution.  *
00015  ***************************************************************************/
00016 
00017 #ifndef _C_SHADER_ATTRIBUTE_H_
00018 #define _C_SHADER_ATTRIBUTE_H_
00019 
00020 //-------------------------------------------------------------------------
00021 // Includes
00022 //-------------------------------------------------------------------------
00023 #include <osg/Shader>
00024 #include <osg/Program>
00025 #include <osg/Uniform>
00026 #include <osg/Texture>
00027 #include <osg/StateAttribute>
00028 
00029 #include <osgPPU/Export.h>
00030 
00031 namespace osgPPU
00032 {
00033 
00034 //! Wrapper class to simplify work with shader and uniforms
00035 /**
00036  * ShaderAttribute class is a simple wrapper for the osg::Shader, osg::Program
00037  * and osg::Uniform classes to simplify the work with shaders. It can be used
00038  * to define shader programs for the osgPPU::Unit or in external applications
00039  * as well.
00040  *
00041  * Current version of the class do not support Uniform StateAttribute values - OVERRIDE and PROTECTED.
00042  * This because the uniforms are applied directly in the apply method of the ShaderAttribute.
00043  * In order to be able to use it you have to apply the uniforms directly with osg methods to the
00044  * according StateSet. This wrapper is just a simpler version of osg's uniform handlings.
00045  **/
00046 class OSGPPU_EXPORT ShaderAttribute : public osg::Program
00047 {
00048     public:
00049         META_StateAttribute(osgPPU, ShaderAttribute, PROGRAM);
00050 
00051         /** Initialize shader to the fixed function pipeline per default **/
00052         ShaderAttribute();
00053 
00054         /**
00055         * Copy constructor to create a shader object from the other one.
00056         * NOTE: copyop is currently ignored. The uniforms will be copied completely,
00057         * hence after the copy you will get two uniforms with the same value.
00058         **/
00059         ShaderAttribute(const ShaderAttribute&, const osg::CopyOp& copyop=osg::CopyOp::DEEP_COPY_ALL);
00060 
00061         /** Release used memory and close all used shader programs **/
00062         virtual ~ShaderAttribute();
00063 
00064         /**
00065         * Add new uniform. The uniform can also represent an array.
00066         * The uniform will be applied in the apply method. Unfortunately
00067         * only the StateAttribute mode ON/OFF is checked. Hence PROTECTED and OVERRIDE are
00068         * currently not supported.
00069         * @param name Name of the uniform
00070         * @param type Type of the uniform
00071         * @param elementCount Number of elements if you add an array, otherwise 1
00072         **/
00073         void add(const std::string& name, osg::Uniform::Type type, unsigned int elementCount = 1, osg::StateAttribute::OverrideValue mode = osg::StateAttribute::ON);
00074 
00075         /**
00076         * Add new uniform. The uniform value will be copied.
00077         **/
00078         void add(osg::Uniform* uniform, osg::StateAttribute::OverrideValue mode = osg::StateAttribute::ON);
00079         void add(osg::StateSet::RefUniformPair uniform);
00080 
00081         /**
00082         * Delete uniform. Uniforms which are deleted are removed from the parental StateSets too.
00083         * @param name Name of the uniform
00084         **/
00085         void del(const std::string& name);
00086 
00087         /**
00088         * Set uniform value.
00089         **/
00090         bool set(const std::string& name, bool b0){return set(0,name,b0);}
00091         bool set(const std::string& name, bool b0, bool b1){return set(0,name,b0,b1);}
00092         bool set(const std::string& name, bool b0, bool b1, bool b2){return set(0,name,b0,b1,b2);}
00093         bool set(const std::string& name, bool b0, bool b1, bool b2, bool b3){return set(0,name,b0,b1,b2,b3);}
00094 
00095         bool set(const std::string& name, int i0){return set(0,name,i0);}
00096         bool set(const std::string& name, int i0, int i1){return set(0,name,i0,i1);}
00097         bool set(const std::string& name, int i0, int i1, int i2){return set(0,name,i0,i1,i2);}
00098         bool set(const std::string& name, int i0, int i1, int i2, int i3){return set(0,name,i0,i1,i2,i3);}
00099 
00100         bool set(const std::string& name, float b0){return set(0,name,b0);}
00101         bool set(const std::string& name, float b0, float b1){return set(0,name,b0,b1);}
00102         bool set(const std::string& name, float b0, float b1, float b2){return set(0,name,b0,b1,b2);}
00103         bool set(const std::string& name, float b0, float b1, float b2, float b3){return set(0,name,b0,b1,b2,b3);}
00104 
00105         bool set(const std::string& name, const osg::Vec2& v){return set(0,name,v);}
00106         bool set(const std::string& name, const osg::Vec3& v){return set(0,name,v);}
00107         bool set(const std::string& name, const osg::Vec4& v){return set(0,name,v);}
00108 
00109         bool set(const std::string& name, const osg::Matrix2& m){return set(0,name,m);}
00110         bool set(const std::string& name, const osg::Matrix3& m){return set(0,name,m);}
00111         bool set(const std::string& name, const osg::Matrixf& m){return set(0,name,m);}
00112 
00113         bool set(unsigned int index, const std::string& name, bool b0);
00114         bool set(unsigned int index, const std::string& name, bool b0, bool b1);
00115         bool set(unsigned int index, const std::string& name, bool b0, bool b1, bool b2);
00116         bool set(unsigned int index, const std::string& name, bool b0, bool b1, bool b2, bool b3);
00117 
00118         bool set(unsigned int index, const std::string& name, int i0);
00119         bool set(unsigned int index, const std::string& name, int i0, int i1);
00120         bool set(unsigned int index, const std::string& name, int i0, int i1, int i2);
00121         bool set(unsigned int index, const std::string& name, int i0, int i1, int i2, int i3);
00122 
00123         bool set(unsigned int index, const std::string& name, float b0);
00124         bool set(unsigned int index, const std::string& name, float b0, float b1);
00125         bool set(unsigned int index, const std::string& name, float b0, float b1, float b2);
00126         bool set(unsigned int index, const std::string& name, float b0, float b1, float b2, float b3);
00127 
00128         bool set(unsigned int index, const std::string& name, const osg::Vec2& v);
00129         bool set(unsigned int index, const std::string& name, const osg::Vec3& v);
00130         bool set(unsigned int index, const std::string& name, const osg::Vec4& v);
00131 
00132         bool set(unsigned int index, const std::string& name, const osg::Matrix2& m);
00133         bool set(unsigned int index, const std::string& name, const osg::Matrix3& m);
00134         bool set(unsigned int index, const std::string& name, const osg::Matrixf& m);
00135 
00136 
00137         /**
00138         * Bind a texture to the specified uniform. This method do siplify your life ;-)
00139         * @param index If uniform is an array element, then specify the index here
00140         * @param name Name of the uniform to which to bound the texture
00141         * @param tex  Texture to bound
00142         * @param unit Texture unit to which to bound the texture. Specify -1 to automagically choose free texture unit
00143         **/
00144         bool bindTexture(unsigned int index, const std::string& name, osg::Texture* tex, int unit = -1);
00145 
00146         //! @copydoc bindTexture()
00147         bool bindTexture(const std::string& name, osg::Texture* tex, int unit = -1) {return bindTexture(0, name, tex, unit);}
00148 
00149         /**
00150         * Bind a vertex attribute to a uniform. You have to take care to deliver correct
00151         * attribute data for the specified attribute.
00152         * @see osg::Programm::addBindAttribLocation()
00153         * @param name Name of the uniform variable
00154         * @param index Attribute index which to bound
00155         **/
00156         bool bindAttribute(const std::string& name, unsigned int index);
00157 
00158         /**
00159         * For shader model 4.0 hardwares you can specify the frag data to bound
00160         **/
00161         bool bindFragData(const std::string& name, unsigned int index);
00162 
00163         /**
00164          * Apply the shader attribute to the given state. This will bind the shader program
00165          * and set the uniforms. NOTE: The uniforms would be bound in this method,
00166          * hence the appropriate uniform value might be propagated to the shader in the next frame.
00167          **/
00168         virtual void apply (osg::State &state) const;
00169 
00170         /** @copydoc osg::StateAttribute::compare() **/
00171         virtual int compare(const osg::StateAttribute& sa) const
00172         {
00173             // Check for equal types, then create the rhs variable
00174             // used by the COMPARE_StateAttribute_Paramter macros below.
00175             COMPARE_StateAttribute_Types(ShaderAttribute, sa)
00176 
00177             // Compare each parameter in turn against the rhs.
00178             COMPARE_StateAttribute_Parameter(mMaxTextureUnits)
00179             COMPARE_StateAttribute_Parameter(mDirtyTextureBindings)
00180 
00181             // TODO: currently no uniform comparison is made
00182 
00183             return 0; // Passed all the above comparison macros, so must be equal.
00184         }
00185 
00186         /**
00187         * Get uniform by a its name. If uniform was previously added or created this method will return it.
00188         * @param name Name of the uniform
00189         **/
00190         osg::Uniform* get(const std::string& name);
00191 
00192         /**
00193         * Set uniform list.
00194         **/
00195         void setUniformList(const osg::StateSet::UniformList& list);
00196 
00197         /**
00198         * Get correpsonding uniform list.
00199         **/
00200         const osg::StateSet::UniformList& getUniformList() const { return mUniforms; }
00201 
00202         /**
00203         * Set the number of maximal supported texture units. Per default this number is set to 8.
00204         * This number is needed to setup automagic texture to uniform binding.
00205         **/
00206         void setMaximalSupportedTextureUnits(int i);
00207 
00208         /**
00209          * Get maximum supported texture units. The results is the same as set by setMaximalSupportedTextureUnits() method
00210          **/
00211         int getMaximalSupportedTextureUnits() const { return mMaxTextureUnits; }
00212 
00213         /**
00214         * Mark the ShaderAttribute as dirty. This will force to reset all the texture binding to
00215         * parental StateSets on the next apply method. @see bindTexture()
00216         **/
00217         void dirty() { mDirtyTextureBindings = true; }
00218 
00219         struct TexUnit{
00220             osg::ref_ptr<osg::Texture> t;
00221             int unit;
00222             unsigned int element;
00223             std::string name;
00224         };
00225 
00226     protected:
00227 
00228 
00229         typedef std::map<std::string, std::map<int,TexUnit> > TexUnitDb;
00230 
00231         //! Database to hold the texture to uniform bindings
00232         TexUnitDb mTexUnits;
00233 
00234         //! List of all added parameters
00235         osg::StateSet::UniformList mUniforms;
00236 
00237         //! mark if boundings are dirty
00238         bool mDirtyTextureBindings;
00239 
00240         //! maximal possible number of supported texture units
00241         int mMaxTextureUnits;
00242 
00243         /**
00244          * Set parameters as uniform values.
00245          **/
00246         void addParameter(const std::string& name, osg::Uniform* param, osg::StateAttribute::OverrideValue mode);
00247 
00248         /**
00249         * Reset texture bindings. Call this if you have rebound textures and want to force
00250         * to recreate texture boundings within the shader. Normally this would be called
00251         * automatically by the update function if you have previously called any bind function
00252         **/
00253         void resetTextureUniforms();
00254 
00255         //! Convert string type name into type
00256         osg::Uniform::Type convertToUniformType(const std::string& name);
00257 
00258 };
00259 
00260 }; // end namespace
00261 
00262 #endif

Back to Homepage of osgPPU

Copyright (C) 2008 by Art Tevs (LGPL)