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; } } }
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; // OSG_NOTICE<<"Compiling PerContextShader "<<this<<" ShaderDefine="<<getDefineString()<<std::endl; if (_defineStr.empty()) { const GLchar* sourceText = reinterpret_cast<const GLchar*>(source.c_str()); _extensions->glShaderSource( _glShaderHandle, 1, &sourceText, NULL ); } else { std::string versionLine; unsigned int lineNum = 0; std::string::size_type previous_pos = 0; do { std::string::size_type start_of_line = source.find_first_not_of(" \t", previous_pos); std::string::size_type end_of_line = (start_of_line != std::string::npos) ? source.find_first_of("\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 (source[source.size()-1]!='\n') source.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()) { // OSG_NOTICE<<"Shader::PerContextShader::compileShader() : Found #version, lineNum = "<<lineNum<<" ["<<versionLine<<"] new source = ["<<source<<"]"<<std::endl; const GLchar* sourceText[3]; //OSG_NOTICE<<"glShaderSource() ["<<versionLine<<"] "<<std::endl<<"["<<_defineStr<<"], ["<<sourceText<<"]"<<std::endl; 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 ); } else { const GLchar* sourceText[2]; //OSG_NOTICE<<"glShaderSource() ["<<_defineStr<<"], ["<<sourceText<<"]"<<std::endl; sourceText[0] = reinterpret_cast<const GLchar*>(_defineStr.c_str()); sourceText[1] = reinterpret_cast<const GLchar*>(source.c_str()); _extensions->glShaderSource( _glShaderHandle, 2, 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; } } }