/* -*-c++-*- */ /* osgEarth - Geospatial SDK for OpenSceneGraph * Copyright 2020 Pelican Mapping * http://osgearth.org * * osgEarth is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see */ #ifndef OSGEARTH_EXT_TERRAIN_SHADER_OPTIONS #define OSGEARTH_EXT_TERRAIN_SHADER_OPTIONS 1 #include #include #include namespace osgEarth { namespace TerrainShader { using namespace osgEarth; /** * Options for applying an inline shader to the terrain. */ class TerrainShaderOptions : public ConfigOptions // NO EXPORT; header only { public: struct Code { std::string _source; optional _uri; }; struct Sampler { std::string _name; std::vector _uris; }; struct Uniform { std::string _name; optional _value; }; std::vector& code() { return _code; } const std::vector& code() const { return _code; } std::vector& samplers() { return _samplers; } const std::vector& samplers() const { return _samplers; } std::vector& uniforms() { return _uniforms; } const std::vector& uniforms() const { return _uniforms; } public: TerrainShaderOptions( const ConfigOptions& opt =ConfigOptions() ) : ConfigOptions( opt ) { fromConfig( _conf ); } virtual ~TerrainShaderOptions() { } public: virtual Config getConfig() const { Config conf = ConfigOptions::getConfig(); conf.remove("code"); for(unsigned i=0; i<_code.size(); ++i) { Config c("code", _code[i]._source); c.set("url", _code[i]._uri); conf.add( c ); } conf.remove("sampler"); for(unsigned i=0; i<_samplers.size(); ++i) { Config c("sampler"); c.add("name", _samplers[i]._name); if ( _samplers[i]._uris.size() > 1 ) { Config urlarray("array"); c.add( urlarray ); for( std::vector::const_iterator j = _samplers[i]._uris.begin(); j != _samplers[i]._uris.end(); ++j) { urlarray.add( j->getConfig() ); } } else if ( _samplers[i]._uris.size() == 1 ) { c.add( _samplers[i]._uris.back().getConfig() ); } conf.add( c ); } conf.remove("uniform"); for(unsigned i=0; i<_uniforms.size(); ++i) { Config c("uniform"); c.set("name", _uniforms[i]._name); c.set("value", _uniforms[i]._value); conf.add( c ); } return conf; } protected: virtual void mergeConfig( const Config& conf ) { ConfigOptions::mergeConfig( conf ); fromConfig( conf ); } private: void fromConfig( const Config& conf ) { _code.clear(); _samplers.clear(); _uniforms.clear(); ConfigSet s = conf.children("code"); for(ConfigSet::const_iterator i = s.begin(); i != s.end(); ++i) { _code.push_back(Code()); _code.back()._source = i->value(); i->get("url", _code.back()._uri); } s = conf.children("sampler"); for(ConfigSet::const_iterator i = s.begin(); i != s.end(); ++i) { _samplers.push_back(Sampler()); _samplers.back()._name = i->value("name"); const Config* urlarray = i->find("array"); if ( urlarray ) { ConfigSet uris = urlarray->children("url"); for(ConfigSet::const_iterator j = uris.begin(); j != uris.end(); ++j) { URI uri( j->value(), URIContext(conf.referrer()) ); _samplers.back()._uris.push_back( uri ); } } else { optional uri; i->get("url", uri); if ( uri.isSet() ) _samplers.back()._uris.push_back( uri.get() ); } } s = conf.children("uniform"); for(ConfigSet::const_iterator i = s.begin(); i != s.end(); ++i) { _uniforms.push_back(Uniform()); _uniforms.back()._name = i->value("name"); i->get("value", _uniforms.back()._value); } } std::vector _code; std::vector _samplers; std::vector _uniforms; }; } } // namespace osgEarth::TerrainShader #endif // OSGEARTH_EXT_TERRAIN_SHADER_OPTIONS