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) || 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()); } }