/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield * Copyright (C) 2003-2005 3Dlabs Inc. Ltd. * * This application is open source and may be redistributed and/or modified * freely and without restriction, both in commericial and non commericial * applications, as long as this copyright notice is maintained. * * This application is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ /* file: include/osg/Uniform * author: Mike Weiblen 2005-06-03 */ #ifndef OSG_UNIFORM #define OSG_UNIFORM 1 #include #include #include #include #include #include #include #include namespace osg { // forward declare class GL2Extensions; class NodeVisitor; /////////////////////////////////////////////////////////////////////////// // C++ classes to represent the GLSL-specific "mat2" & "mat3" types. class OSG_EXPORT Matrix2 { public: Matrix2() { makeIdentity(); } Matrix2( const Matrix2& mat ) { set(mat.ptr()); } Matrix2( float a00, float a01, float a10, float a11 ) { set( a00, a01, a10, a11 ); } ~Matrix2() {} float& operator()(int row, int col) { return _mat[row][col]; } float operator()(int row, int col) const { return _mat[row][col]; } Matrix2& operator = (const Matrix2& rhs) { if( &rhs == this ) return *this; set(rhs.ptr()); return *this; } void set(const Matrix2& rhs) { set(rhs.ptr()); } void set(float const * const ptr) { float* local_ptr = (float*)_mat; for(int i=0;i<4;++i) local_ptr[i]=ptr[i]; } void set(float a00, float a01, float a10, float a11) { _mat[0][0]=a00; _mat[0][1]=a01; _mat[1][0]=a10; _mat[1][1]=a11; } float* ptr() { return (float*)_mat; } const float* ptr() const { return (const float*)_mat; } float& operator [] (int i) {return ptr()[i];} float operator [] (int i) const {return ptr()[i];} void makeIdentity() { set( 1, 0, 0, 1 ); } protected: float _mat[2][2]; }; class OSG_EXPORT Matrix3 { public: Matrix3() { makeIdentity(); } Matrix3( const Matrix3& mat ) { set(mat.ptr()); } Matrix3( float a00, float a01, float a02, float a10, float a11, float a12, float a20, float a21, float a22 ) { set( a00, a01, a02, a10, a11, a12, a20, a21, a22 ); } ~Matrix3() {} float& operator()(int row, int col) { return _mat[row][col]; } float operator()(int row, int col) const { return _mat[row][col]; } Matrix3& operator = (const Matrix3& rhs) { if( &rhs == this ) return *this; set(rhs.ptr()); return *this; } void set(const Matrix3& rhs) { set(rhs.ptr()); } void set(float const * const ptr) { float* local_ptr = (float*)_mat; for(int i=0;i<9;++i) local_ptr[i]=ptr[i]; } void set(float a00, float a01, float a02, float a10, float a11, float a12, float a20, float a21, float a22 ) { _mat[0][0]=a00; _mat[0][1]=a01; _mat[0][2]=a02; _mat[1][0]=a10; _mat[1][1]=a11; _mat[1][2]=a12; _mat[2][0]=a20; _mat[2][1]=a21; _mat[2][2]=a22; } float* ptr() { return (float*)_mat; } const float* ptr() const { return (const float*)_mat; } float& operator [] (int i) {return ptr()[i];} float operator [] (int i) const {return ptr()[i];} void makeIdentity() { set( 1, 0, 0, 0, 1, 0, 0, 0, 1 ); } protected: float _mat[3][3]; }; /////////////////////////////////////////////////////////////////////////// /** Uniform encapsulates glUniform values */ class OSG_EXPORT Uniform : public Object { public: enum Type { FLOAT = GL_FLOAT, FLOAT_VEC2 = GL_FLOAT_VEC2, FLOAT_VEC3 = GL_FLOAT_VEC3, FLOAT_VEC4 = GL_FLOAT_VEC4, INT = GL_INT, INT_VEC2 = GL_INT_VEC2, INT_VEC3 = GL_INT_VEC3, INT_VEC4 = GL_INT_VEC4, BOOL = GL_BOOL, BOOL_VEC2 = GL_BOOL_VEC2, BOOL_VEC3 = GL_BOOL_VEC3, BOOL_VEC4 = GL_BOOL_VEC4, FLOAT_MAT2 = GL_FLOAT_MAT2, FLOAT_MAT3 = GL_FLOAT_MAT3, FLOAT_MAT4 = GL_FLOAT_MAT4, SAMPLER_1D = GL_SAMPLER_1D, SAMPLER_2D = GL_SAMPLER_2D, SAMPLER_3D = GL_SAMPLER_3D, SAMPLER_CUBE = GL_SAMPLER_CUBE, SAMPLER_1D_SHADOW = GL_SAMPLER_1D_SHADOW, SAMPLER_2D_SHADOW = GL_SAMPLER_2D_SHADOW, UNDEFINED = -1 }; public: Uniform(); Uniform( Type type, const std::string& name ); /** Copy constructor using CopyOp to manage deep vs shallow copy. */ Uniform(const Uniform& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY); META_Object(osg, Uniform); /** Set the type of glUniform. */ bool setType( Type t ); /** Get the type of glUniform as enum. */ const Type getType() const { return _type; } /** Set the name of the glUniform, checking to make sure its only set once.*/ void setName( const std::string& name ); /** Return the name of a Type enum as string. */ static const char* getTypename( Type t ); /** Return the Type enum of a Uniform typename string */ static Uniform::Type getTypeId( const std::string& tname ); /** Return the GL API type corresponding to a GLSL type */ static Type getGlApiType( Type t ); /** convenient construction w/ assignment */ explicit Uniform( const char* name, float f ); explicit Uniform( const char* name, int i ); explicit Uniform( const char* name, bool b ); Uniform( const char* name, const osg::Vec2& v2 ); Uniform( const char* name, const osg::Vec3& v3 ); Uniform( const char* name, const osg::Vec4& v4 ); Uniform( const char* name, const osg::Matrix2& m2 ); Uniform( const char* name, const osg::Matrix3& m3 ); Uniform( const char* name, const osg::Matrixf& m4 ); Uniform( const char* name, const osg::Matrixd& m4 ); Uniform( const char* name, int i0, int i1 ); Uniform( const char* name, int i0, int i1, int i2 ); Uniform( const char* name, int i0, int i1, int i2, int i3 ); Uniform( const char* name, bool b0, bool b1 ); Uniform( const char* name, bool b0, bool b1, bool b2 ); Uniform( const char* name, bool b0, bool b1, bool b2, bool b3 ); /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */ virtual int compare(const Uniform& rhs) const; virtual int compareData(const Uniform& rhs) const; bool operator < (const Uniform& rhs) const { return compare(rhs)<0; } bool operator == (const Uniform& rhs) const { return compare(rhs)==0; } bool operator != (const Uniform& rhs) const { return compare(rhs)!=0; } void copyData( const Uniform& rhs ); /** A vector of osg::StateSet pointers which is used to store the parent(s) of this Uniform, the parents could be osg::Node or osg::Drawable.*/ typedef std::vector ParentList; /** Get the parent list of this Uniform. */ inline const ParentList& getParents() const { return _parents; } /** Get the a copy of parent list of node. A copy is returned to * prevent modification of the parent list.*/ inline ParentList getParents() { return _parents; } inline StateSet* getParent(unsigned int i) { return _parents[i]; } /** * Get a single const parent of this Uniform. * @param i index of the parent to get. * @return the parent i. */ inline const StateSet* getParent(unsigned int i) const { return _parents[i]; } /** * Get the number of parents of this Uniform. * @return the number of parents of this Uniform. */ inline unsigned int getNumParents() const { return _parents.size(); } /** value assignment */ bool set( float f ); bool set( int i ); bool set( bool b ); bool set( const osg::Vec2& v2 ); bool set( const osg::Vec3& v3 ); bool set( const osg::Vec4& v4 ); bool set( const osg::Matrix2& m2 ); bool set( const osg::Matrix3& m3 ); bool set( const osg::Matrixf& m4 ); bool set( const osg::Matrixd& m4 ); bool set( int i0, int i1 ); bool set( int i0, int i1, int i2 ); bool set( int i0, int i1, int i2, int i3 ); bool set( bool b0, bool b1 ); bool set( bool b0, bool b1, bool b2 ); bool set( bool b0, bool b1, bool b2, bool b3 ); /** value query */ bool get( float& f ) const; bool get( int& i ) const; bool get( bool& b ) const; bool get( osg::Vec2& v2 ) const; bool get( osg::Vec3& v3 ) const; bool get( osg::Vec4& v4 ) const; bool get( osg::Matrix2& m2 ) const; bool get( osg::Matrix3& m3 ) const; bool get( osg::Matrixf& m4 ) const; bool get( osg::Matrixd& m4 ) const; bool get( int& i0, int& i1 ) const; bool get( int& i0, int& i1, int& i2 ) const; bool get( int& i0, int& i1, int& i2, int& i3 ) const; bool get( bool& b0, bool& b1 ) const; bool get( bool& b0, bool& b1, bool& b2 ) const; bool get( bool& b0, bool& b1, bool& b2, bool& b3 ) const; struct Callback : public virtual osg::Object { Callback() {} Callback(const Callback&,const CopyOp&) {} META_Object(osg,Callback); /** do customized update code.*/ virtual void operator () (Uniform*, NodeVisitor*) {} }; /** Set the UpdateCallback which allows users to attach customize the updating of an object during the update traversal.*/ void setUpdateCallback(Callback* uc); /** Get the non const UpdateCallback.*/ Callback* getUpdateCallback() { return _updateCallback.get(); } /** Get the const UpdateCallback.*/ const Callback* getUpdateCallback() const { return _updateCallback.get(); } /** Set the EventCallback which allows users to attach customize the updating of an object during the Event traversal.*/ void setEventCallback(Callback* ec); /** Get the non const EventCallback.*/ Callback* getEventCallback() { return _eventCallback.get(); } /** Get the const EventCallback.*/ const Callback* getEventCallback() const { return _eventCallback.get(); } /** Increment the modified count on the Uniform so ProgramObjects watching it know it update themselves. * note, autoatmatically call bet Uniform::set(*). */ inline void dirty() { ++_modifiedCount; } inline void setModifiedCount(unsigned int mc) { _modifiedCount = mc; } inline unsigned int getModifiedCount() const { return _modifiedCount; } void apply(const GL2Extensions* ext, GLint location) const; protected: virtual ~Uniform(); Uniform& operator=(const Uniform&) { return *this; } bool isCompatibleType( Type t ) const; void addParent(osg::StateSet* object); void removeParent(osg::StateSet* object); ParentList _parents; friend class osg::StateSet; Type _type; union { GLfloat f1; // float GLfloat f2[2]; // vec2 GLfloat f3[3]; // vec3 GLfloat f4[4]; // vec4, mat2 GLfloat f9[9]; // mat3 GLfloat f16[16]; // mat4 GLint i1; // int, bool, sampler* GLint i2[2]; // ivec2, bvec2 GLint i3[3]; // ivec3, bvec3 GLint i4[4]; // ivec4, bvec4 } _data; ref_ptr _updateCallback; ref_ptr _eventCallback; unsigned int _modifiedCount; }; } #endif /*EOF*/