/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield * Copyright (C) 2003 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/osgGL2/ProgramObject * author: Mike Weiblen 2003-10-03 * * See http://www.3dlabs.com/opengl2/ for more information regarding * the OpenGL Shading Language. */ #ifndef OSGGL2_PROGRAMOBJECT #define OSGGL2_PROGRAMOBJECT 1 #include #include #include #include #include #include #include #include #include #include #include #include #include namespace osgGL2 { class ProgramObject; typedef osg::ref_ptr ProgramObjectPtr; class ShaderObject; typedef osg::ref_ptr ShaderObjectPtr; /////////////////////////////////////////////////////////////////////////// /** Encapsulates the OpenGL Shading Language ProgramObject */ class OSGGL2_EXPORT ProgramObject : public osg::StateAttribute { public: ProgramObject(); /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ ProgramObject(const ProgramObject& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_StateAttribute(osgGL2, ProgramObject, PROGRAMOBJECT); /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ virtual int compare(const osg::StateAttribute& sa) const { // check the types are equal and then create the rhs variable // used by the COMPARE_StateAttribute_Paramter macro's below. COMPARE_StateAttribute_Types(ProgramObject,sa) // compare each parameter in turn against the rhs. COMPARE_StateAttribute_Parameter(_shaderObjectList); // COMPARE_StateAttribute_Parameter(_pcpoList); return 0; // passed all the above comparison macro's, must be equal. } virtual void getAssociatedModes(std::vector& ) const {} virtual void apply(osg::State& state) const; virtual void compile(osg::State& state) const { apply(state); } // data access methods. /** Force a relink on next apply() of associated glProgramObject. */ void dirtyProgramObject(); /** Force a recompile of all ShaderObjects on next apply(). */ void dirtyShaderObjects(); /** Set whether rendering of ProgramObject is enabled or disabled */ void enable( bool enabled ) { _enabled = enabled; } /** Attach a ShaderObject to this ProgramObject */ void addShader( ShaderObject* shadObj ); void setUniform( const char* uniformName, int value ); void setUniform( const char* uniformName, float value ); void setUniform( const char* uniformName, osg::Vec2 value ); void setUniform( const char* uniformName, osg::Vec3 value ); void setUniform( const char* uniformName, osg::Vec4 value ); inline void setSampler( const char* uniformName, int value ) { // emphatic alias for setUniform(int) setUniform( uniformName, static_cast(value) ); } /** use deleteObject instead of glDeleteObject to allow * GL2 Objects to cached until they can be deleted * by the OpenGL context in which they were created, specified * by contextID.*/ static void deleteObject(unsigned int contextID, GLhandleARB handle); /** flush all the cached glProgramObjects which need to be deleted * in the OpenGL context related to contextID.*/ static void flushDeletedGL2Objects(unsigned int contextID,double currentTime, double& availableTime); protected: class PerContextProgObj : public osg::Referenced { public: PerContextProgObj(const ProgramObject* progObj, unsigned int contextID); PerContextProgObj(const PerContextProgObj& rhs); GLhandleARB& getHandle() {return _glProgObjHandle;} bool isDirty() const {return _dirty;} void markAsDirty() {_dirty = true; } void build(); void use() const; void updateUniforms( const UniformValueList& univalList ); void applyUniformValues(); void printInfoLog(osg::NotifySeverity severity) const; protected: /*methods*/ PerContextProgObj(); ~PerContextProgObj(); protected: /*data*/ const ProgramObject* _progObj; osg::ref_ptr _extensions; GLhandleARB _glProgObjHandle; bool _dirty; UniformValueList _univalList; const unsigned int _contextID; }; protected: /*methods*/ virtual ~ProgramObject(); PerContextProgObj* getPCPO(unsigned int contextID) const; void updateUniforms( int frameNumber ) const; protected: /*data*/ bool _enabled; std::vector< ShaderObjectPtr > _shaderObjectList; mutable osg::buffered_value< osg::ref_ptr > _pcpoList; mutable int _frameNumberOfLastPCPOUpdate; mutable UniformValueList _univalList; }; /////////////////////////////////////////////////////////////////////////// /** Encapsulates the OpenGL Shading Language ShaderObject */ class OSGGL2_EXPORT ShaderObject : public osg::Object { public: enum Type { VERTEX = GL_VERTEX_SHADER_ARB, FRAGMENT = GL_FRAGMENT_SHADER_ARB, UNKNOWN = -1 }; ShaderObject(); ShaderObject(Type type); ShaderObject(Type type, const char* sourceText); /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ ShaderObject(const ShaderObject& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgGL2, ShaderObject); // data access methods. void setShaderSource( const char* sourceText ); inline const std::string& getShaderSource() const {return _shaderSource; } bool loadShaderSourceFromFile( const char* fileName ); inline Type getType() const { return _type; } const char* getTypename() const; /** Force a recompile on next apply() of associated glShaderObject. */ void dirtyShaderObject(); void build(unsigned int contextID) const; void attach(unsigned int contextID, GLhandleARB progObj) const; protected: class PerContextShaderObj : public osg::Referenced { public: PerContextShaderObj(const ShaderObject* shadObj, unsigned int contextID); PerContextShaderObj(const PerContextShaderObj& rhs); GLhandleARB& getHandle() {return _glShaderObjHandle;} bool isDirty() const {return _dirty;} void markAsDirty() {_dirty = true; } void build(); void attach(GLhandleARB progObj) const; void printInfoLog(osg::NotifySeverity severity) const; protected: /*methods*/ PerContextShaderObj(); ~PerContextShaderObj(); protected: /*data*/ const ShaderObject* _shadObj; osg::ref_ptr _extensions; GLhandleARB _glShaderObjHandle; bool _dirty; const unsigned int _contextID; }; protected: /*methods*/ virtual ~ShaderObject(); PerContextShaderObj* getPCSO(unsigned int contextID) const; friend void ProgramObject::addShader( ShaderObject* shadObj ); // to access addProgObjRef() void addProgObjRef( ProgramObject* progObj ); protected: /*data*/ Type _type; std::string _shaderSource; std::vector< ProgramObjectPtr > _programObjectList; mutable osg::buffered_value< osg::ref_ptr > _pcsoList; }; } #endif