Changeset 10754

Show
Ignore:
Timestamp:
11/16/09 13:32:41 (4 years ago)
Author:
robert
Message:

Added new osg::ShaderBinary? class, and support for it in osg::Shader.

Location:
OpenSceneGraph/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/include/osg/Shader

    r10642 r10754  
    3131class Program; 
    3232 
     33/** Simple class for wrapping up the data used in OpenGL ES 2's glShaderBinary calls.   
     34  * ShaderBinary is set up with the binary data then assigned to one or more osg::Shader. */ 
     35class OSG_EXPORT ShaderBinary : public osg::Object 
     36{ 
     37    public: 
     38         
     39        ShaderBinary(); 
     40 
     41        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ 
     42        ShaderBinary(const ShaderBinary& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); 
     43 
     44        META_Object(osg, ShaderBinary); 
     45 
     46        /** Allocated a data buffer of specified size/*/ 
     47        void allocate(unsigned int size); 
     48         
     49        /** Assign shader binary data, copying the specified data into locally stored data buffer, the original data can then be deleted.*/ 
     50        void assign(unsigned int size, const unsigned char* data); 
     51         
     52        /** Get the size of the shader binary data.*/ 
     53        unsigned int getSize() const { return _data.size(); } 
     54 
     55        /** Get a ptr to the shader binary data.*/ 
     56        unsigned char* getData() { return _data.empty() ? 0 : &(_data.front()); } 
     57 
     58        /** Get a const ptr to the shader binary data.*/ 
     59        const unsigned char* getData() const { return _data.empty() ? 0 : &(_data.front()); } 
     60         
     61    protected: 
     62         
     63        typedef std::vector<unsigned char> Data; 
     64        Data _data; 
     65}; 
     66 
     67 
    3368/////////////////////////////////////////////////////////////////////////// 
    3469/** osg::Shader is an application-level abstraction of an OpenGL glShader. 
     
    5287        }; 
    5388 
    54         Shader( Type type = UNDEFINED); 
    55         Shader( Type type, const std::string& source ); 
     89        Shader(Type type = UNDEFINED); 
     90        Shader(Type type, const std::string& source ); 
     91        Shader(Type type, ShaderBinary* shaderBinary ); 
    5692 
    5793        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ 
     
    6298        int compare(const Shader& rhs) const; 
    6399 
    64         bool setType( Type t ); 
    65          
    66  
    67         /** Load the Shader's source code text from a string. */ 
    68         void setShaderSource( const std::string& sourceText ); 
     100        /** Set the Shader type as an enum. */ 
     101        bool setType(Type t); 
     102 
     103        /** Get the Shader type as an enum. */ 
     104        inline Type getType() const { return _type; } 
     105 
     106        /** Get the Shader type as a descriptive string. */ 
     107        const char* getTypename() const; 
     108         
     109 
     110        /** Set file name for the shader source code. */ 
     111        inline void setFileName(const std::string& fileName) { _shaderFileName = fileName; } 
     112 
     113        /** Get filename to which the shader source code belongs. */ 
     114        inline const std::string& getFileName() const { return _shaderFileName; } 
     115 
     116 
     117        /** Set the Shader's source code text from a string. */ 
     118        void setShaderSource(const std::string& sourceText); 
     119 
     120        /** Query the shader's source code text */ 
     121        inline const std::string& getShaderSource() const { return _shaderSource; } 
     122 
     123 
     124        /** Set the Shader using a ShaderBinary. */ 
     125        void setShaderBinary(ShaderBinary* shaderBinary) { _shaderBinary = shaderBinary; }  
     126         
     127        /** Get the Shader's ShaderBinary, return NULL if none is assigned. */ 
     128        ShaderBinary* getShaderBinary() { return _shaderBinary.get(); }  
     129 
     130        /** Get the const Shader's ShaderBinary, return NULL if none is assigned. */ 
     131        const ShaderBinary* getShaderBinary() const { return _shaderBinary.get(); }  
     132 
    69133 
    70134        /** Read shader source from file and then constructor shader of specified type. 
     
    75139        bool loadShaderSourceFromFile( const std::string& fileName ); 
    76140 
    77         /** Query the shader's source code text */ 
    78         inline const std::string& getShaderSource() const { return _shaderSource; } 
    79  
    80         /** Get the Shader type as an enum. */ 
    81         inline Type getType() const { return _type; } 
    82  
    83         /** Get the Shader type as a descriptive string. */ 
    84         const char* getTypename() const; 
    85  
    86         /** Set file name for the shader source code. */ 
    87         inline void setFileName(const std::string& fileName) { _shaderFileName = fileName; } 
    88  
    89         /** Get filename to which the shader source code belongs. */ 
    90         inline const std::string& getFileName() const { return _shaderFileName; } 
     141 
    91142 
    92143        /** Resize any per context GLObject buffers to specified size. */ 
     
    183234 
    184235    protected:        /*data*/ 
    185         Type _type; 
    186         std::string _shaderSource; 
    187         std::string _shaderFileName; 
     236        Type                            _type; 
     237        std::string                     _shaderFileName; 
     238        std::string                     _shaderSource; 
     239        osg::ref_ptr<ShaderBinary>      _shaderBinary; 
     240         
    188241        /** osg::Programs that this osg::Shader is attached to */ 
    189242        typedef std::set< osg::Program* > ProgramSet; 
    190         ProgramSet _programSet; 
     243        ProgramSet                      _programSet; 
    191244        mutable osg::buffered_value< osg::ref_ptr<PerContextShader> > _pcsList; 
    192245 
  • OpenSceneGraph/trunk/src/osg/Shader.cpp

    r10642 r10754  
    3737using namespace osg; 
    3838 
    39 /////////////////////////////////////////////////////////////////////////// 
     39ShaderBinary::ShaderBinary() 
     40{ 
     41} 
     42 
     43ShaderBinary::ShaderBinary(const ShaderBinary& rhs, const osg::CopyOp&): 
     44    _data(rhs._data) 
     45{ 
     46} 
     47 
     48void ShaderBinary::allocate(unsigned int size) 
     49{ 
     50    _data.clear(); 
     51    _data.resize(size); 
     52} 
     53 
     54void ShaderBinary::assign(unsigned int size, const unsigned char* data) 
     55{ 
     56    allocate(size); 
     57    if (data) 
     58    { 
     59        for(unsigned int i=0; i<size; ++i) 
     60        { 
     61            _data[i] = data[i]; 
     62        } 
     63    } 
     64} 
     65 
     66        /////////////////////////////////////////////////////////////////////////// 
    4067// static cache of glShaders flagged for deletion, which will actually 
    4168// be deleted in the correct GL context. 
     
    110137} 
    111138 
     139Shader::Shader(Type type, ShaderBinary* shaderBinary) : 
     140    _type(type) 
     141{ 
     142} 
     143 
     144 
    112145Shader::Shader(const Shader& rhs, const osg::CopyOp& copyop): 
    113146    osg::Object( rhs, copyop ), 
    114147    _type(rhs._type), 
     148    _shaderFileName(rhs._shaderFileName), 
    115149    _shaderSource(rhs._shaderSource), 
    116     _shaderFileName(rhs._shaderFileName) 
     150    _shaderBinary(rhs._shaderBinary) 
    117151{ 
    118152} 
     
    122156} 
    123157 
    124 bool Shader::setType( Type t ) 
     158bool Shader::setType(Type t) 
    125159{ 
    126160    if (_type==t) return true; 
     
    380414    _needsCompile = false; 
    381415 
     416#if defined(OSG_GLES2_AVAILABLE) 
     417    if (_shader->getShaderBinary()) 
     418    { 
     419        GLint numFormats; 
     420        glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &numFormats); 
     421 
     422        if (numFormats>0) 
     423        { 
     424            GLint* formats = new GLint[numFormats]; 
     425            glGetIntegerv(GL_SHADER_BINARY_FORMATS, formats); 
     426 
     427            for(GLint i=0; i<numFormats; ++i) 
     428            { 
     429                osg::notify(osg::NOTICE)<<"  format="<<formats[i]<<std::endl; 
     430                GLenum shaderBinaryFormat = formats[i]; 
     431                glShaderBinary(1, &_glShaderHandle, shaderBinaryFormat, _shader->getShaderBinary()->getData(), _shader->getShaderBinary()->getSize()); 
     432                if (glGetError() == GL_NO_ERROR) 
     433                { 
     434                    _isCompiled = true; 
     435                    return; 
     436                } 
     437            } 
     438            delete [] formats; 
     439             
     440            if (_shader->getShaderSource().empty()) 
     441            { 
     442                osg::notify(osg::WARN)<<"Warning: No suitable shader of supported format by GLES driver found in shader binary, unable to compile shader."<<std::endl; 
     443                _isCompiled = false; 
     444                return; 
     445            } 
     446            else 
     447            { 
     448                osg::notify(osg::NOTICE)<<"osg::Shader::compileShader(): No suitable shader of supported format by GLES driver found in shader binary, falling back to shader source."<<std::endl; 
     449            } 
     450        } 
     451        else 
     452        { 
     453            if (_shader->getShaderSource().empty()) 
     454            { 
     455                osg::notify(osg::WARN)<<"Warning: No shader binary formats supported by GLES driver, unable to compile shader."<<std::endl; 
     456                _isCompiled = false; 
     457                return; 
     458            } 
     459            else 
     460            { 
     461                osg::notify(osg::NOTICE)<<"osg::Shader::compileShader(): No shader binary formats supported by GLES driver, falling back to shader source."<<std::endl; 
     462            } 
     463        } 
     464    } 
     465#endif 
     466 
    382467    std::string source = _shader->getShaderSource(); 
    383468    if (_shader->getType()==osg::Shader::VERTEX && (state.getUseVertexAttributeAliasing() || state.getUseModelViewAndProjectionUniforms()))