Skip to content

Commit

Permalink
Update the viewer with better lighting; Automatically add a normal ar…
Browse files Browse the repository at this point in the history
…ray in the shader generator if one does not exist; add a PhongLightingGroup conveninence class.
  • Loading branch information
gwaldron committed Jul 24, 2024
1 parent b7d6b62 commit b994103
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 42 deletions.
32 changes: 21 additions & 11 deletions src/applications/osgearth_viewer/osgearth_viewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ int
usage(const char* name)
{
std::cout
<< "\nUsage: " << name << " file.earth" << std::endl
<< "View an earth file: " << name << " file.earth" << std::endl
<< "View an OSG model: " << name << " [modelfile.ext] [--light]" << std::endl
<< Util::MapNodeHelper().usage() << std::endl;

return 0;
Expand Down Expand Up @@ -72,35 +73,44 @@ main(int argc, char** argv)
if (MapNode::get(node))
{
viewer.setSceneData(node);
return viewer.run();
}
else
{
// not an earth file? Just view as a normal OSG node or image with basic lighting
viewer.setCameraManipulator(new osgGA::TrackballManipulator);

bool light = arguments.read("--light");
if (light)
if (arguments.read("--light"))
{
osg::LightSource* sunLS = new osg::LightSource();
sunLS->getLight()->setPosition(osg::Vec4d(1, -1, 1, 0));
auto group = new osg::Group();
group->addChild(sunLS);
osg::LightSource* lightSource = new osg::LightSource();
lightSource->getLight()->setAmbient(osg::Vec4(0.75f, 0.75f, 0.75f, 1.0f));

auto group = new PhongLightingGroup();
group->addChild(lightSource);
group->addChild(node);
auto phong = new PhongLightingEffect();
phong->attach(group->getOrCreateStateSet());

ShaderGenerator gen;
gen.run(group);

viewer.setSceneData(group);

while (!viewer.done())
{
auto cam = viewer.getCamera()->getInverseViewMatrix().getTrans();
cam.normalize();
lightSource->getLight()->setPosition(osg::Vec4d(cam.x(), cam.y(), cam.z(), 0));
viewer.frame();
}
return 0;
}
else
{
ShaderGenerator gen;
gen.run(node);
viewer.setSceneData(node);
return viewer.run();
}
}

return Metrics::run(viewer);
}

return usage(argv[0]);
Expand Down
2 changes: 1 addition & 1 deletion src/osgEarth/ExampleResources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ MapNodeHelper::load(osg::ArgumentParser& args, osgViewer::ViewerBase* viewer) co
osg::ref_ptr<MapNode> mapNode = MapNode::get(node.get());
if (!mapNode.valid())
{
OE_WARN << LC << "Loaded scene graph does not contain a MapNode - aborting" << std::endl;
OE_WARN << LC << "Loaded scene graph does not contain a MapNode" << std::endl;
return node;
}

Expand Down
4 changes: 2 additions & 2 deletions src/osgEarth/Lighting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,12 @@ GenerateGL3LightingUniforms::apply(osg::LightSource& lightSource)
lightSource.addCullCallback(new LightSourceGL3UniformGenerator());
}

//#if !defined(OSG_GL_FIXED_FUNCTION_AVAILABLE)
// If there's no FFP, we need to replace the Light with a LightGL3 to prevent
// error messages on the console.
if (dynamic_cast<LightGL3*>(lightSource.getLight()) == 0L)
{
lightSource.setLight(new LightGL3(*lightSource.getLight()));
}
//#endif
}

apply(static_cast<osg::Node&>(lightSource));
Expand Down Expand Up @@ -302,6 +300,8 @@ MaterialGL3::apply(osg::State& state) const
{
#ifdef OSG_GL_FIXED_FUNCTION_AVAILABLE
osg::Material::apply(state);
#else
state.Color(_diffuseFront.r(), _diffuseFront.g(), _diffuseFront.b(), _diffuseFront.a());
#endif
}

Expand Down
6 changes: 3 additions & 3 deletions src/osgEarth/PhongLighting.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void oe_phong_fragment(inout vec4 color)
vec3 totalAmbient = vec3(0.0);
vec3 totalSpecular = vec3(0.0);

int numLights = OE_NUM_LIGHTS; //min(osg_NumLights, MAX_LIGHTS);
int numLights = OE_NUM_LIGHTS;

for (int i=0; i<numLights; ++i)
{
Expand Down Expand Up @@ -121,8 +121,8 @@ void oe_phong_fragment(inout vec4 color)
}

vec3 ambientReflection =
attenuation
* osg_LightSource[i].ambient.rgb;
attenuation *
osg_LightSource[i].ambient.rgb;

float NdotL = max(dot(N,L), 0.0);

Expand Down
10 changes: 10 additions & 0 deletions src/osgEarth/PhongLightingEffect
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <osg/StateSet>
#include <osg/Uniform>
#include <osg/observer_ptr>
#include <osg/Group>

namespace osgEarth { namespace Util
{
Expand Down Expand Up @@ -66,6 +67,15 @@ namespace osgEarth { namespace Util
void init();
};


class OSGEARTH_EXPORT PhongLightingGroup : public osg::Group
{
public:
PhongLightingGroup();
private:
osg::ref_ptr< PhongLightingEffect> _effect;
};

} } // namespace osgEarth::Util

#endif // OSGEARTH_PHONG_LIGHTING_EFFECT_H
8 changes: 8 additions & 0 deletions src/osgEarth/PhongLightingEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,11 @@ PhongLightingEffect::detach(osg::StateSet* stateset)
}
}
}



PhongLightingGroup::PhongLightingGroup()
{
_effect = new PhongLightingEffect(getOrCreateStateSet());
Lighting::installDefaultMaterial(getOrCreateStateSet());
}
2 changes: 1 addition & 1 deletion src/osgEarth/ShaderGenerator
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ namespace osgEarth

virtual void apply( osg::Drawable* );

virtual bool processGeometry(const osg::StateSet* stateSet, osg::ref_ptr<osg::StateSet>& replacement);
virtual bool processGeometry(const osg::Geometry* geom, const osg::StateSet* stateSet, osg::ref_ptr<osg::StateSet>& replacement);

virtual bool processText(const osg::StateSet* stateSet, osg::ref_ptr<osg::StateSet>& replacement);

Expand Down
66 changes: 44 additions & 22 deletions src/osgEarth/ShaderGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include <osgDB/FileUtils>
#include <osgText/Text>
#include <osgSim/LightPointNode>
#include <osgUtil/SmoothingVisitor>

#include <osg/ValueObject>

Expand Down Expand Up @@ -125,7 +126,7 @@ namespace

std::string stripped = osgDB::getNameLessExtension(filename);

OE_INFO << LC << "Loading " << stripped << " from PLOD/Proxy and generating shaders." << std::endl;
OE_DEBUG << LC << "Loading " << stripped << " from PLOD/Proxy and generating shaders." << std::endl;

osgEarth::ReadResult result = URI(stripped).readNode(options);
if ( result.succeeded() && result.getNode() != 0L )
Expand Down Expand Up @@ -423,7 +424,7 @@ ShaderGenerator::run(osg::StateSet* ss)

_state->pushStateSet(ss);
osg::ref_ptr<osg::StateSet> replacement;
processGeometry(ss, replacement);
processGeometry(nullptr, ss, replacement);
_state->popStateSet();
return replacement;
}
Expand Down Expand Up @@ -454,40 +455,40 @@ ShaderGenerator::duplicateSharedNode(osg::Node& node)
void
ShaderGenerator::apply(osg::Node& node)
{
if ( !_active )
if (!_active)
return;

if ( ignore(&node) )
if (ignore(&node))
return;

if ( _duplicateSharedSubgraphs )
if (_duplicateSharedSubgraphs)
duplicateSharedNode(node);

applyNonCoreNodeIfNecessary( node );
applyNonCoreNodeIfNecessary(node);

osg::ref_ptr<osg::StateSet> stateset = node.getStateSet();
if ( stateset.valid() )
if (stateset.valid())
{
_state->pushStateSet( stateset.get() );
disableUnsupportedAttributes(stateset.get());
_state->pushStateSet(stateset.get());
}

traverse(node);

if ( stateset.valid() )
if (stateset.valid())
{
disableUnsupportedAttributes(stateset.get());
_state->popStateSet();
}
}

void
ShaderGenerator::apply( osg::Group& group )
ShaderGenerator::apply(osg::Group& group)
{
apply( static_cast<osg::Node&>(group) );
apply(static_cast<osg::Node&>(group));
}

void
ShaderGenerator::apply( osg::Geode& node )
ShaderGenerator::apply(osg::Geode& node)
{
if ( !_active )
return;
Expand All @@ -501,6 +502,7 @@ ShaderGenerator::apply( osg::Geode& node )
osg::ref_ptr<osg::StateSet> stateset = node.getStateSet();
if ( stateset.valid() )
{
disableUnsupportedAttributes(stateset.get());
_state->pushStateSet( stateset.get() );
}

Expand Down Expand Up @@ -531,7 +533,7 @@ ShaderGenerator::apply( osg::Geode& node )
if (numInheritingGeometry == numDrawables )
{
osg::ref_ptr<osg::StateSet> replacement;
if ( processGeometry(stateset.get(), replacement) )
if ( processGeometry(nullptr, stateset.get(), replacement) )
{
node.setStateSet(replacement.get() );
traverseDrawables = false;
Expand Down Expand Up @@ -560,13 +562,12 @@ ShaderGenerator::apply( osg::Geode& node )

if ( stateset.valid() )
{
disableUnsupportedAttributes(stateset.get());
_state->popStateSet();
}
}

void
ShaderGenerator::apply( osg::Drawable& node )
ShaderGenerator::apply(osg::Drawable& node)
{
if ( !_active )
return;
Expand All @@ -593,6 +594,7 @@ ShaderGenerator::apply( osg::Drawable* drawable )
osg::ref_ptr<osg::StateSet> ss = drawable->getStateSet();
if ( ss.valid() )
{
disableUnsupportedAttributes(ss.get());
_state->pushStateSet(ss.get());
}

Expand All @@ -611,17 +613,23 @@ ShaderGenerator::apply( osg::Drawable* drawable )
{
geom->setUseVertexBufferObjects(true);
geom->setUseDisplayList(false);

// generate normals if none exist
if (geom->getNormalArray() == nullptr)
{
osgUtil::SmoothingVisitor normal_gen;
geom->accept(normal_gen);
}
}

if ( processGeometry(ss.get(), replacement) )
if ( processGeometry(geom, ss.get(), replacement) )
{
drawable->setStateSet(replacement.get());
}
}

if ( ss.valid() )
{
disableUnsupportedAttributes(ss.get());
_state->popStateSet();
}
}
Expand Down Expand Up @@ -714,17 +722,18 @@ ShaderGenerator::apply(osgSim::LightPointNode& node)
osg::ref_ptr<osg::PointSprite> sprite = new osg::PointSprite();
stateset->setTextureAttributeAndModes(0, sprite.get());

disableUnsupportedAttributes(stateset.get());

_state->pushStateSet( stateset.get() );

osg::ref_ptr<osg::StateSet> replacement;
if ( processGeometry(stateset.get(), replacement) )
if ( processGeometry(nullptr, stateset.get(), replacement) )
{
// remove the temporary sprite.
replacement->removeTextureAttribute(0, sprite.get());
node.setStateSet(replacement.get() );
}

disableUnsupportedAttributes(stateset.get());
_state->popStateSet();
}
}
Expand Down Expand Up @@ -762,8 +771,10 @@ ShaderGenerator::processText(const osg::StateSet* ss, osg::ref_ptr<osg::StateSet


bool
ShaderGenerator::processGeometry(const osg::StateSet* original,
osg::ref_ptr<osg::StateSet>& replacement)
ShaderGenerator::processGeometry(
const osg::Geometry* geom,
const osg::StateSet* original,
osg::ref_ptr<osg::StateSet>& replacement)
{
// do nothing if there's no GLSL support
if ( !_active )
Expand Down Expand Up @@ -812,6 +823,14 @@ ShaderGenerator::processGeometry(const osg::StateSet* original,
GenBuffers buf;
buf._stateSet = newStateSet.get();

// if the geometry doesn't have normals, we need to set a default value.
if (geom && geom->getNormalArray() == nullptr)
{
buf._modelHead << INDENT << "vec3 vp_Normal;\n";
buf._modelBody << INDENT << "vp_Normal = vec3(0,0,1);\n";
needNewStateSet = true;
}

// if the stateset changes any texture attributes, we need a new virtual program:
if (current->getTextureAttributeList().size() > 0)
{
Expand Down Expand Up @@ -1167,6 +1186,7 @@ ShaderGenerator::apply(osg::Texture2D* tex, int unit, GenBuffers& buf)
buf._fragHead << "uniform sampler2D " SAMPLER << unit << ";\n";
buf._fragBody << INDENT "texel = texture(" SAMPLER << unit << ", " TEX_COORD << unit << ".xy);\n";
buf._stateSet->getOrCreateUniform( Stringify() << SAMPLER << unit, osg::Uniform::SAMPLER_2D )->set( unit );
buf._stateSet->removeTextureMode(unit, GL_TEXTURE_2D);

return true;
}
Expand Down Expand Up @@ -1264,4 +1284,6 @@ ShaderGenerator::disableUnsupportedAttributes(osg::StateSet* stateset)
{
if (!stateset)
return;

stateset->removeAttribute(osg::StateAttribute::SHADEMODEL);
}
2 changes: 1 addition & 1 deletion src/osgEarth/weejobs.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#define WEEJOBS_VERSION_NUMBER WEEJOBS_COMPUTE_VERSION(WEEJOBS_VERSION_MAJOR, WEEJOBS_VERSION_MINOR, WEEJOBS_VERSION_REV)
#define WEEJOBS_VERSION_STRING WEEJOBS_STR(WEEJOBS_VERSION_MAJOR) "." WEEJOBS_STR(WEEJOBS_VERSION_MINOR) "." WEEJOBS_STR(WEEJOBS_VERSION_REV)

#if __cplusplus >= 201703L
#if __cplusplus >= 201703L || _MSVC_LANG >= 201703L
#define WEEJOBS_NO_DISCARD [[nodiscard]]
#else
#define WEEJOBS_NO_DISCARD
Expand Down
3 changes: 2 additions & 1 deletion src/osgEarthDrivers/gltf/GLTFReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,8 @@ class GLTFReader
tex = insResult.first->second;
}
}
geom->getOrCreateStateSet()->setTextureAttributeAndModes(0, tex.get());
//geom->getOrCreateStateSet()->setTextureAttributeAndModes(0, tex.get());
geom->getOrCreateStateSet()->setTextureAttribute(0, tex.get());
}

if (material.alphaMode != "OPAQUE")
Expand Down

0 comments on commit b994103

Please sign in to comment.