168 lines
5.5 KiB
C++
168 lines
5.5 KiB
C++
/* -*-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 <http://www.gnu.org/licenses/>
|
|
*/
|
|
#ifndef OSGEARTH_EXT_TERRAIN_SHADER_OPTIONS
|
|
#define OSGEARTH_EXT_TERRAIN_SHADER_OPTIONS 1
|
|
|
|
#include <osgEarth/Config>
|
|
#include <osgEarth/URI>
|
|
#include <vector>
|
|
|
|
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> _uri;
|
|
};
|
|
|
|
struct Sampler
|
|
{
|
|
std::string _name;
|
|
std::vector<URI> _uris;
|
|
};
|
|
|
|
struct Uniform
|
|
{
|
|
std::string _name;
|
|
optional<float> _value;
|
|
};
|
|
|
|
std::vector<Code>& code() { return _code; }
|
|
const std::vector<Code>& code() const { return _code; }
|
|
|
|
std::vector<Sampler>& samplers() { return _samplers; }
|
|
const std::vector<Sampler>& samplers() const { return _samplers; }
|
|
|
|
std::vector<Uniform>& uniforms() { return _uniforms; }
|
|
const std::vector<Uniform>& 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<URI>::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> 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> _code;
|
|
std::vector<Sampler> _samplers;
|
|
std::vector<Uniform> _uniforms;
|
|
};
|
|
|
|
} } // namespace osgEarth::TerrainShader
|
|
|
|
#endif // OSGEARTH_EXT_TERRAIN_SHADER_OPTIONS
|
|
|