Пример #1
0
void Shader::PerContextShader::compileShader(osg::State& state)
{
    if( ! _needsCompile ) return;
    _needsCompile = false;

#if defined(OSG_GLES2_AVAILABLE)
    if (_shader->getShaderBinary())
    {
        GLint numFormats = 0;
        glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &numFormats);

        if (numFormats>0)
        {
            std::vector<GLint> formats(numFormats);
            glGetIntegerv(GL_SHADER_BINARY_FORMATS, &formats[0]);

            for(GLint i=0; i<numFormats; ++i)
            {
                OSG_NOTICE<<"  format="<<formats[i]<<std::endl;
                GLenum shaderBinaryFormat = formats[i];
                glShaderBinary(1, &_glShaderHandle, shaderBinaryFormat, _shader->getShaderBinary()->getData(), _shader->getShaderBinary()->getSize());
                if (glGetError() == GL_NO_ERROR)
                {
                    _isCompiled = true;
                    return;
                }
            }

            if (_shader->getShaderSource().empty())
            {
                OSG_WARN<<"Warning: No suitable shader of supported format by GLES driver found in shader binary, unable to compile shader."<<std::endl;
                _isCompiled = false;
                return;
            }
            else
            {
                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;
            }
        }
        else
        {
            if (_shader->getShaderSource().empty())
            {
                OSG_WARN<<"Warning: No shader binary formats supported by GLES driver, unable to compile shader."<<std::endl;
                _isCompiled = false;
                return;
            }
            else
            {
                OSG_NOTICE<<"osg::Shader::compileShader(): No shader binary formats supported by GLES driver, falling back to shader source."<<std::endl;
            }
        }
    }
#endif

    std::string source = _shader->getShaderSource();
    if (_shader->getType()==osg::Shader::VERTEX && (state.getUseVertexAttributeAliasing() || state.getUseModelViewAndProjectionUniforms()))
    {
        state.convertVertexShaderSourceToOsgBuiltIns(source);
    }


    if (osg::getNotifyLevel()>=osg::INFO)
    {
        std::string sourceWithLineNumbers = insertLineNumbers(source);
        OSG_INFO << "\nCompiling " << _shader->getTypename()
                 << " source:\n" << sourceWithLineNumbers << std::endl;
    }

    GLint compiled = GL_FALSE;
    const GLchar* sourceText = reinterpret_cast<const GLchar*>(source.c_str());
    _extensions->glShaderSource( _glShaderHandle, 1, &sourceText, NULL );
    _extensions->glCompileShader( _glShaderHandle );
    _extensions->glGetShaderiv( _glShaderHandle, GL_COMPILE_STATUS, &compiled );

    _isCompiled = (compiled == GL_TRUE);
    if( ! _isCompiled )
    {
        OSG_WARN << _shader->getTypename() << " glCompileShader \""
            << _shader->getName() << "\" FAILED" << std::endl;

        std::string infoLog;
        if( getInfoLog(infoLog) )
        {
            OSG_WARN << _shader->getTypename() << " Shader \""
                << _shader->getName() << "\" infolog:\n" << infoLog << std::endl;
        }
    }
    else
    {
        std::string infoLog;
        if( getInfoLog(infoLog) )
        {
            OSG_INFO << _shader->getTypename() << " Shader \""
                << _shader->getName() << "\" infolog:\n" << infoLog << std::endl;
        }
    }

}
Пример #2
0
void Shader::PerContextShader::compileShader(osg::State& state)
{
    if( ! _needsCompile ) return;
    _needsCompile = false;

#if defined(OSG_GLES2_AVAILABLE) || defined(OSG_GLES3_AVAILABLE)
    if (_shader->getShaderBinary())
    {
        GLint numFormats = 0;
        glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &numFormats);

        if (numFormats>0)
        {
            std::vector<GLint> formats(numFormats);
            glGetIntegerv(GL_SHADER_BINARY_FORMATS, &formats[0]);

            for(GLint i=0; i<numFormats; ++i)
            {
                OSG_NOTICE<<"  format="<<formats[i]<<std::endl;
                GLenum shaderBinaryFormat = formats[i];
                glShaderBinary(1, &_glShaderHandle, shaderBinaryFormat, _shader->getShaderBinary()->getData(), _shader->getShaderBinary()->getSize());
                if (glGetError() == GL_NO_ERROR)
                {
                    _isCompiled = true;
                    return;
                }
            }

            if (_shader->getShaderSource().empty())
            {
                OSG_WARN<<"Warning: No suitable shader of supported format by GLES driver found in shader binary, unable to compile shader."<<std::endl;
                _isCompiled = false;
                return;
            }
            else
            {
                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;
            }
        }
        else
        {
            if (_shader->getShaderSource().empty())
            {
                OSG_WARN<<"Warning: No shader binary formats supported by GLES driver, unable to compile shader."<<std::endl;
                _isCompiled = false;
                return;
            }
            else
            {
                OSG_NOTICE<<"osg::Shader::compileShader(): No shader binary formats supported by GLES driver, falling back to shader source."<<std::endl;
            }
        }
    }
#endif

    std::string source = _shader->getShaderSource();
    // if (_shader->getType()==osg::Shader::VERTEX && (state.getUseVertexAttributeAliasing() || state.getUseModelViewAndProjectionUniforms()))
    {
        state.convertVertexShaderSourceToOsgBuiltIns(source);
    }


    GLint compiled = GL_FALSE;

    // OSG_NOTICE<<"Compiling PerContextShader "<<this<<" ShaderDefine="<<getDefineString()<<std::endl;
    bool printOutShaders = osg::getNotifyLevel()>=osg::NOTICE;//INFO;

    if (_defineStr.empty())
    {
        const GLchar* sourceText = reinterpret_cast<const GLchar*>(source.c_str());

        if (printOutShaders)
        {
            std::string sourceToCompile;
            if (!_defineStr.empty()) sourceToCompile += _defineStr;
            if (!source.empty()) sourceToCompile += source;

            std::string sourceWithLineNumbers = insertLineNumbers(sourceToCompile);
            OSG_INFO << "\nCompiling " << _shader->getTypename()
                    << " source:\n" << sourceWithLineNumbers << std::endl;
        }

        _extensions->glShaderSource( _glShaderHandle, 1, &sourceText, NULL );

        if (osg::getNotifyLevel()>=osg::INFO)
        {
            std::string sourceWithLineNumbers = insertLineNumbers(source);
            OSG_INFO << "\nCompiling A :" << _shader->getTypename()
                    << " source:\n" << sourceWithLineNumbers << std::endl;
        }
    }
    else
    {
        // Convert all windows line endings to \n
        replaceAll(source, "\r\n", " \n");

        std::string versionLine;
        unsigned int lineNum = 0;
        std::string::size_type previous_pos = 0;
        do
        {
            std::string::size_type start_of_line = find_first(source, NoneOf(" \t"), previous_pos);
            std::string::size_type end_of_line = (start_of_line != std::string::npos) ? find_first(source, OneOf("\n\r"), start_of_line) : std::string::npos;
            if (end_of_line != std::string::npos)
            {
                // OSG_NOTICE<<"A Checking line "<<lineNum<<" ["<<source.substr(start_of_line, end_of_line-start_of_line)<<"]"<<std::endl;
                if ((end_of_line-start_of_line)>=8 && source.compare(start_of_line, 8, "#version")==0)
                {
                    versionLine = source.substr(start_of_line, end_of_line-start_of_line+1);
                    if (versionLine[versionLine.size()-1]!='\n') versionLine.push_back('\n');

                    source.insert(start_of_line, "// following version spec has been automatically reassigned to start of source list: ");

                    break;
                }
                previous_pos = end_of_line+1<source.size() ? end_of_line+1 : std::string::npos;
            }
            else
            {
                // OSG_NOTICE<<"B Checking line "<<lineNum<<" ["<<source.substr(start_of_line, end_of_line-start_of_line)<<"]"<<std::endl;
                previous_pos = std::string::npos;
            }
            ++lineNum;

        } while (previous_pos != std::string::npos);

        if (!versionLine.empty())
        {
            if (printOutShaders)
            {
                std::string sourceWithLineNumbers = insertLineNumbers(versionLine + _defineStr + source);
                OSG_NOTICE << "\nCompiling " << _shader->getTypename()
                           << " source:\n" << sourceWithLineNumbers << std::endl;
            }

            const GLchar* sourceText[3];
            sourceText[0] = reinterpret_cast<const GLchar*>(versionLine.c_str());
            sourceText[1] = reinterpret_cast<const GLchar*>(_defineStr.c_str());
            sourceText[2] = reinterpret_cast<const GLchar*>(source.c_str());
            _extensions->glShaderSource( _glShaderHandle, 3, sourceText, NULL );

            if (osg::getNotifyLevel()>=osg::INFO)
            {
                std::string sourceWithLineNumbers = insertLineNumbers(versionLine+_defineStr+source);
                OSG_INFO << "\nCompiling B: " << _shader->getTypename()
                        << " source:\n" << sourceWithLineNumbers << std::endl;
            }

            // OSG_NOTICE<<"   Version Line : ["<<std::endl<<versionLine<<"]"<<std::endl;
            // OSG_NOTICE<<"   DefineStr : ["<<std::endl<<_defineStr<<"]"<<std::endl;
            // OSG_NOTICE<<"   Source : ["<<std::endl<<source<<"]"<<std::endl;
        }
        else
        {
            if (printOutShaders)
            {
                std::string sourceWithLineNumbers = insertLineNumbers(_defineStr + source);
                OSG_NOTICE << "\nCompiling " << _shader->getTypename()
                           << " source:\n" << sourceWithLineNumbers << std::endl;
            }

            const GLchar* sourceText[2];
            sourceText[0] = reinterpret_cast<const GLchar*>(_defineStr.c_str());
            sourceText[1] = reinterpret_cast<const GLchar*>(source.c_str());
            _extensions->glShaderSource( _glShaderHandle, 2, sourceText, NULL );


            if (osg::getNotifyLevel()>=osg::INFO)
            {
                std::string sourceWithLineNumbers = insertLineNumbers(_defineStr+source);
                OSG_INFO << "\nCompiling C: " << _shader->getTypename()
                        << " source:\n" << sourceWithLineNumbers << std::endl;
            }

            // OSG_NOTICE<<"   DefineStr : ["<<std::endl<<_defineStr<<"]"<<std::endl;
            // OSG_NOTICE<<"   Source : ["<<std::endl<<source<<"]"<<std::endl;
        }
    }
    _extensions->glCompileShader( _glShaderHandle );
    _extensions->glGetShaderiv( _glShaderHandle, GL_COMPILE_STATUS, &compiled );

    _isCompiled = (compiled == GL_TRUE);
    if( ! _isCompiled )
    {
        OSG_WARN << _shader->getTypename() << " glCompileShader \""
            << _shader->getName() << "\" FAILED" << std::endl;

        std::string infoLog;
        if( getInfoLog(infoLog) )
        {
            OSG_WARN << _shader->getTypename() << " Shader \""
                << _shader->getName() << "\" infolog:\n" << infoLog << std::endl;
        }
    }
    else
    {
        std::string infoLog;
        if( getInfoLog(infoLog) )
        {
            OSG_INFO << _shader->getTypename() << " Shader \""
                << _shader->getName() << "\" infolog:\n" << infoLog << std::endl;
        }

        _extensions->debugObjectLabel(GL_SHADER, _glShaderHandle, _shader->getName());
    }

}