Skip to content

Commit

Permalink
add the TerrainShader extension
Browse files Browse the repository at this point in the history
  • Loading branch information
gwaldron committed Feb 9, 2015
1 parent e7af250 commit 9b91f6c
Show file tree
Hide file tree
Showing 7 changed files with 359 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/osgEarth/ShaderLoader
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ namespace osgEarth
public:
typedef std::map<std::string, std::string> SourceMap;
const SourceMap& context() const { return _sources; }
void add(const std::string& filename, const std::string& inlineSource) {
_sources[filename] = inlineSource; }

protected:
SourceMap _sources;
Expand Down
1 change: 1 addition & 0 deletions src/osgEarthExtensions/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ add_subdirectory(normalmap)
add_subdirectory(splat)
add_subdirectory(viewpoints)
add_subdirectory(billboard)
add_subdirectory(terrainshader)

24 changes: 24 additions & 0 deletions src/osgEarthExtensions/terrainshader/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#
# terrain shader plugin
#
set(TARGET_SRC
TerrainShaderPlugin.cpp
TerrainShaderExtension.cpp
${SHADERS_CPP} )

set(LIB_PUBLIC_HEADERS
TerrainShaderExtension
TerrainShaderOptions)

set(TARGET_H
${LIB_PUBLIC_HEADERS})


set(TARGET_COMMON_LIBRARIES ${TARGET_COMMON_LIBRARIES}
osgEarthUtil)

setup_extension(osgearth_terrainshader)

# to install public driver includes:
set(LIB_NAME terrainshader)

68 changes: 68 additions & 0 deletions src/osgEarthExtensions/terrainshader/TerrainShaderExtension
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/* -*-c++-*- */
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
* Copyright 2008-2014 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_H
#define OSGEARTH_EXT_TERRAIN_SHADER_H 1

#include "TerrainShaderOptions"
#include <osgEarth/Extension>
#include <osgEarth/MapNode>
#include <osgEarthUtil/Controls>

namespace osgEarth { namespace TerrainShader
{
using namespace osgEarth;

class TerrainShaderExtension : public Extension,
public ExtensionInterface<MapNode>
{
public:
META_Object(osgearth_ext_terrainshader, TerrainShaderExtension);

// CTORs
TerrainShaderExtension();
TerrainShaderExtension(const TerrainShaderOptions& options);

// DTOR
virtual ~TerrainShaderExtension();


public: // Extension

void setDBOptions(const osgDB::Options* dbOptions);


public: // ExtensionInterface<MapNode>

bool connect(MapNode* mapNode);

bool disconnect(MapNode* mapNode);


protected: // Object
TerrainShaderExtension(const TerrainShaderExtension& rhs, const osg::CopyOp& op) { }

private:
const TerrainShaderOptions _options;
osg::ref_ptr<const osgDB::Options> _dbOptions;
osg::ref_ptr<class TerrainEffect> _effect;
};

} } // namespace osgEarth::TerrainShader

#endif // OSGEARTH_EXT_TERRAIN_SHADER_H
131 changes: 131 additions & 0 deletions src/osgEarthExtensions/terrainshader/TerrainShaderExtension.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/* -*-c++-*- */
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
* Copyright 2008-2014 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/>
*/
#include "TerrainShaderExtension"
#include <osgEarth/TerrainEffect>
#include <osgEarth/MapNode>
#include <osgEarth/VirtualProgram>
#include <osgEarth/ShaderLoader>

using namespace osgEarth;
using namespace osgEarth::TerrainShader;

#define LC "[TerrainShaderExtension] "

namespace
{
class GLSLEffect : public TerrainEffect
{
public:
GLSLEffect(const std::string& vs, const std::string& fs)
: _vs(vs), _fs(fs)
{
if ( !_vs.empty() )
_package.add( "$vs", _vs );
if ( !_fs.empty() )
_package.add( "$fs", _fs );
}

void onInstall(TerrainEngineNode* engine)
{

if ( !_vs.empty() )
{
VirtualProgram* vp = VirtualProgram::getOrCreate(engine->getOrCreateStateSet());
ShaderLoader::loadFunction(vp, "$vs", _package);
}

if ( !_fs.empty() )
{
VirtualProgram* vp = VirtualProgram::getOrCreate(engine->getOrCreateStateSet());
ShaderLoader::loadFunction(vp, "$fs", _package);
}
}

void onUninstall(TerrainEngineNode* engine)
{
if ( engine && engine->getStateSet() )
{
VirtualProgram* vp = VirtualProgram::get(engine->getStateSet());
if ( vp )
{
if ( !_vs.empty() )
ShaderLoader::unloadFunction( vp, "$vs", _package );

if ( !_fs.empty() )
ShaderLoader::unloadFunction( vp, "$fs", _package );
}
}
}

std::string _vs, _fs;
ShaderPackage _package;
};
}


TerrainShaderExtension::TerrainShaderExtension()
{
//nop
}

TerrainShaderExtension::TerrainShaderExtension(const TerrainShaderOptions& options) :
_options( options )
{
//nop
}

TerrainShaderExtension::~TerrainShaderExtension()
{
//nop
}

void
TerrainShaderExtension::setDBOptions(const osgDB::Options* dbOptions)
{
_dbOptions = dbOptions;
}

bool
TerrainShaderExtension::connect(MapNode* mapNode)
{
if ( !mapNode )
{
OE_WARN << LC << "Illegal: MapNode cannot be null." << std::endl;
return false;
}
_effect = new GLSLEffect( _options.vertex().get(), _options.fragment().get() );
mapNode->getTerrainEngine()->addEffect( _effect.get() );

OE_INFO << LC << "Installed.\n";

return true;
}

bool
TerrainShaderExtension::disconnect(MapNode* mapNode)
{
if ( mapNode && _effect.valid() )
{
mapNode->getTerrainEngine()->removeEffect( _effect.get() );
_effect = 0L;
}

return true;
}

77 changes: 77 additions & 0 deletions src/osgEarthExtensions/terrainshader/TerrainShaderOptions
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/* -*-c++-*- */
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
* Copyright 2008-2014 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/Common>
#include <osgEarth/URI>

namespace osgEarth { namespace TerrainShader
{
using namespace osgEarth;

/**
* Options for applying an inline shader to the terrain.
*/
class TerrainShaderOptions : public DriverConfigOptions // NO EXPORT; header only
{
public:
optional<std::string>& vertex() { return _vertex; }
const optional<std::string>& vertex() const { return _vertex; }

optional<std::string>& fragment() { return _fragment; }
const optional<std::string>& fragment() const { return _fragment; }

public:
TerrainShaderOptions( const ConfigOptions& opt =ConfigOptions() ) : DriverConfigOptions( opt )
{
setDriver( "terrainshader" );
fromConfig( _conf );
}

virtual ~TerrainShaderOptions() { }

public:
Config getConfig() const {
Config conf = DriverConfigOptions::getConfig();
conf.updateIfSet("vertex", _vertex);
conf.updateIfSet("fragment", _fragment);
return conf;
}

protected:
void mergeConfig( const Config& conf ) {
DriverConfigOptions::mergeConfig( conf );
fromConfig( conf );
}

private:
void fromConfig( const Config& conf ) {
conf.getIfSet("vertex", _vertex);
conf.getIfSet("fragment", _fragment);
}

optional<std::string> _vertex;
optional<std::string> _fragment;
};

} } // namespace osgEarth::TerrainShader

#endif // OSGEARTH_EXT_TERRAIN_SHADER_OPTIONS

56 changes: 56 additions & 0 deletions src/osgEarthExtensions/terrainshader/TerrainShaderPlugin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* -*-c++-*- */
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
* Copyright 2008-2014 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/>
*/
#include "TerrainShaderOptions"
#include "TerrainShaderExtension"

#include <osgDB/ReaderWriter>
#include <osgDB/Registry>
#include <osgDB/FileNameUtils>

namespace osgEarth { namespace TerrainShader
{
/**
* Plugin entry point
*/
class TerrainShaderPlugin : public osgDB::ReaderWriter
{
public: // Plugin stuff

TerrainShaderPlugin() {
supportsExtension( "osgearth_terrainshader", "osgEarth Terrain Shader Extension Plugin" );
}

const char* className() {
return "osgEarth Terrain Shader Extension Plugin";
}

virtual ~TerrainShaderPlugin() { }

ReadResult readObject(const std::string& filename, const osgDB::Options* dbOptions) const
{
if ( !acceptsExtension(osgDB::getLowerCaseFileExtension(filename)) )
return ReadResult::FILE_NOT_HANDLED;

return ReadResult( new TerrainShaderExtension(Extension::getConfigOptions(dbOptions)) );
}
};

REGISTER_OSGPLUGIN(osgearth_terrainshader, TerrainShaderPlugin)

} } // namespace osgEarth::BumpMap

0 comments on commit 9b91f6c

Please sign in to comment.