From e0a779adb1114b6f84fd8c10c4ac44534262c719 Mon Sep 17 00:00:00 2001 From: Tim Moore <timoore@redhat.com> Date: Fri, 30 Oct 2009 11:32:58 +0100 Subject: [PATCH 1/2] fix moon lighting at night This hasn't worked since the OSG port was initially checked in. A real phase-of-the-moon bug! --- src/Main/fg_os_osgviewer.cxx | 1 + src/Main/renderer.cxx | 74 +++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 17 deletions(-) diff --git a/src/Main/fg_os_osgviewer.cxx b/src/Main/fg_os_osgviewer.cxx index 3287e7023..9749645f7 100644 --- a/src/Main/fg_os_osgviewer.cxx +++ b/src/Main/fg_os_osgviewer.cxx @@ -147,6 +147,7 @@ void fgOSOpenWindow(bool stencil) viewer->setSceneData(new osg::Group); globals->get_renderer()->setViewer(viewer.get()); CameraGroup::setDefault(cameraGroup); + viewer->setLightingMode(View::NO_LIGHT); } static int status = 0; diff --git a/src/Main/renderer.cxx b/src/Main/renderer.cxx index ef3fe6e10..5e9dba5a4 100644 --- a/src/Main/renderer.cxx +++ b/src/Main/renderer.cxx @@ -66,6 +66,7 @@ #include <simgear/scene/util/SGSceneUserData.hxx> #include <simgear/scene/tgdb/GroundLightManager.hxx> #include <simgear/scene/tgdb/pt_lights.hxx> +#include <simgear/structure/OSGUtils.hxx> #include <simgear/props/props.hxx> #include <simgear/timing/sg_time.hxx> #include <simgear/ephemeris/ephemeris.hxx> @@ -232,6 +233,18 @@ private: class FGLightSourceUpdateCallback : public osg::NodeCallback { public: + + /** + * @param isSun true if the light is the actual sun i.e., for + * illuminating the moon. + */ + FGLightSourceUpdateCallback(bool isSun = false) : _isSun(isSun) {} + FGLightSourceUpdateCallback(const FGLightSourceUpdateCallback& nc, + const CopyOp& op) + : NodeCallback(nc, op), _isSun(nc._isSun) + {} + META_Object(flightgear,FGLightSourceUpdateCallback); + virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) { assert(dynamic_cast<osg::LightSource*>(node)); @@ -239,21 +252,22 @@ public: osg::Light* light = lightSource->getLight(); FGLight *l = static_cast<FGLight*>(globals->get_subsystem("lighting")); - light->setAmbient(toOsg(l->scene_ambient())); - light->setDiffuse(toOsg(l->scene_diffuse())); - light->setSpecular(toOsg(l->scene_specular())); + if (_isSun) { + light->setAmbient(Vec4(0.0f, 0.0f, 0.0f, 0.0f)); + light->setDiffuse(Vec4(1.0f, 1.0f, 1.0f, 1.0f)); + light->setSpecular(Vec4(0.0f, 0.0f, 0.0f, 0.0f)); + } else { + light->setAmbient(toOsg(l->scene_ambient())); + light->setDiffuse(toOsg(l->scene_diffuse())); + light->setSpecular(toOsg(l->scene_specular())); + } osg::Vec4f position(l->sun_vec()[0], l->sun_vec()[1], l->sun_vec()[2], 0); light->setPosition(position); - osg::Vec3f direction(l->sun_vec()[0], l->sun_vec()[1], l->sun_vec()[2]); - light->setDirection(direction); - light->setSpotExponent(0); - light->setSpotCutoff(180); - light->setConstantAttenuation(1); - light->setLinearAttenuation(0); - light->setQuadraticAttenuation(0); traverse(node, nv); } +private: + const bool _isSun; }; class FGWireFrameModeUpdateCallback : public osg::StateAttribute::Callback { @@ -466,16 +480,39 @@ FGRenderer::init( void ) stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON); // need to update the light on every frame - osg::LightSource* lightSource = new osg::LightSource; - lightSource->setUpdateCallback(new FGLightSourceUpdateCallback); + // OSG LightSource objects are rather confusing. OSG only supports + // the 10 lights specified by OpenGL itself; if more than one + // LightSource in the scene graph have the same light number, it's + // indeterminate which values will be used to render geometry that + // has that light number enabled. Also, adding children to a + // LightSource is just a shortcut for setting up a state set that + // has the corresponding OpenGL light enabled: a LightSource will + // affect geometry anywhere in the scene graph that has its light + // number enabled in a state set. + LightSource* lightSource = new LightSource; + lightSource->getLight()->setDataVariance(Object::DYNAMIC); // relative because of CameraView being just a clever transform node lightSource->setReferenceFrame(osg::LightSource::RELATIVE_RF); lightSource->setLocalStateSetModes(osg::StateAttribute::ON); - - lightSource->addChild(sceneGroup); - lightSource->addChild(thesky->getPreRoot()); - mRoot->addChild(lightSource); - + lightSource->setUpdateCallback(new FGLightSourceUpdateCallback); + mRealRoot->addChild(lightSource); + // we need a white diffuse light for the phase of the moon + osg::LightSource* sunLight = new osg::LightSource; + sunLight->getLight()->setDataVariance(Object::DYNAMIC); + sunLight->getLight()->setLightNum(1); + sunLight->setUpdateCallback(new FGLightSourceUpdateCallback(true)); + sunLight->setReferenceFrame(osg::LightSource::RELATIVE_RF); + sunLight->setLocalStateSetModes(osg::StateAttribute::ON); + // Hang a StateSet above the sky subgraph in order to turn off + // light 0 + Group* skyGroup = new Group; + StateSet* skySS = skyGroup->getOrCreateStateSet(); + skySS->setMode(GL_LIGHT0, StateAttribute::OFF); + skyGroup->addChild(thesky->getPreRoot()); + sunLight->addChild(skyGroup); + mRoot->addChild(sceneGroup); + mRoot->addChild(sunLight); + // Clouds are added to the scene graph later stateSet = globals->get_scenery()->get_scene_graph()->getOrCreateStateSet(); stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON); stateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON); @@ -510,6 +547,9 @@ FGRenderer::init( void ) sw->setUpdateCallback(new FGScenerySwitchCallback); sw->addChild(mRoot.get()); mRealRoot->addChild(sw); + // The clouds are attached directly to the scene graph root + // because, in theory, they don't want the same default state set + // as the rest of the scene. This may not be true in practice. mRealRoot->addChild(thesky->getCloudRoot()); mRealRoot->addChild(FGCreateRedoutNode()); } From 28d221cd7cbaa500874b26ba438b5b2af72c3624 Mon Sep 17 00:00:00 2001 From: Tim Moore <timoore@redhat.com> Date: Sat, 31 Oct 2009 23:00:11 +0100 Subject: [PATCH 2/2] Revert lighting "cleanup" for now. The osgViewer headlight appears to be critical for enabling lighting. --- src/Main/fg_os_osgviewer.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Main/fg_os_osgviewer.cxx b/src/Main/fg_os_osgviewer.cxx index 9749645f7..3287e7023 100644 --- a/src/Main/fg_os_osgviewer.cxx +++ b/src/Main/fg_os_osgviewer.cxx @@ -147,7 +147,6 @@ void fgOSOpenWindow(bool stencil) viewer->setSceneData(new osg::Group); globals->get_renderer()->setViewer(viewer.get()); CameraGroup::setDefault(cameraGroup); - viewer->setLightingMode(View::NO_LIGHT); } static int status = 0;