/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * Copyright (C) 2010-10-21 VIRES Simulationstechnologie GmbH * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library 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. See the * OpenSceneGraph Public License for more details. */ /* * mod: Holger Helmich 2010-10-21 */ #include #include using namespace osg; ShaderComposer::ShaderComposer() { OSG_INFO<<"ShaderComposer::ShaderComposer() "<second.get(); } // strip out vertex shaders Shaders vertexShaders; Shaders tessControlShaders; Shaders tessEvaluationShaders; Shaders geometryShaders; Shaders fragmentShaders; Shaders computeShaders; OSG_INFO<<"ShaderComposer::getOrCreateProgram(shaderComponents.size()=="<getShaderComponent(); for(unsigned int i=0; igetNumShaders(); ++i) { const Shader* shader = sc->getShader(i); switch(shader->getType()) { case(Shader::VERTEX): vertexShaders.push_back(shader); break; case(Shader::TESSCONTROL): tessControlShaders.push_back(shader); break; case(Shader::TESSEVALUATION): tessEvaluationShaders.push_back(shader); break; case(Shader::GEOMETRY): geometryShaders.push_back(shader); break; case(Shader::FRAGMENT): fragmentShaders.push_back(shader); break; case(Shader::COMPUTE): computeShaders.push_back(shader); break; case(Shader::UNDEFINED): OSG_WARN<<"Warning: ShaderCompose::getOrCreateProgam(ShaderComponts) encounterd invalid Shader::Type."< program = new osg::Program; if (!vertexShaders.empty()) { addShaderToProgram(program.get(), vertexShaders); } if (!geometryShaders.empty()) { addShaderToProgram(program.get(), geometryShaders); } if (!fragmentShaders.empty()) { addShaderToProgram(program.get(), fragmentShaders); } if (!computeShaders.empty()) { addShaderToProgram(program.get(), computeShaders); } // assign newly created program to map. _programMap[shaderComponents] = program; OSG_INFO<<"ShaderComposer::getOrCreateProgram(..) created new Program"<addShader(mainShader); } else { program->addShader(itr->second.get()); } for(Shaders::const_iterator itr = shaders.begin(); itr != shaders.end(); ++itr) { Shader* shader = const_cast(*itr); if (!(shader->getShaderSource().empty()) || shader->getShaderBinary()) { program->addShader(shader); } } } osg::Shader* ShaderComposer::composeMain(const Shaders& shaders) { OSG_INFO<<"ShaderComposer::composeMain(Shaders) shaders.size()=="<getType(); } else if (type != shader->getType()) { OSG_WARN<<"Warning:ShaderComposer::composeMain() mixing different types of Shaders prohibited."<getCodeInjectionMap(); for(Shader::CodeInjectionMap::const_iterator citr = cim.begin(); citr != cim.end(); ++citr) { codeInjectionMap.insert(*citr); } } // collect together the different parts of the main shader std::string before_main; std::string in_main; std::string after_main; for(Shader::CodeInjectionMap::iterator citr = codeInjectionMap.begin(); citr != codeInjectionMap.end(); ++citr) { float position = citr->first; if (position<0.0) before_main += citr->second; else if (position<=1.0) in_main += citr->second; else after_main += citr->second; } // assembly the final main shader source std::string full_source; full_source += before_main; full_source += std::string("void main(void)\n"); full_source += std::string("{\n"); full_source += in_main; full_source += std::string("}\n"); full_source += after_main; ref_ptr mainShader = new Shader(type, full_source); OSG_INFO<<"type =="<