X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FMain%2Frenderer.cxx;h=32d7953380b417271fbedd5aead6ba626d1ae3df;hb=b587400846111cc4d6713dcdd38b715c97923d5a;hp=ef3fe6e104ae7cdd587ec547498dc2cdf6cbac4f;hpb=0cdb9d4efb249dd85b7e56d1885d8183de231373;p=flightgear.git diff --git a/src/Main/renderer.cxx b/src/Main/renderer.cxx index ef3fe6e10..32d795338 100644 --- a/src/Main/renderer.cxx +++ b/src/Main/renderer.cxx @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -66,6 +67,7 @@ #include #include #include +#include #include #include #include @@ -137,6 +139,7 @@ public: { // Dynamic stuff, do not store geometry setUseDisplayList(false); + setDataVariance(Object::DYNAMIC); osg::StateSet* stateSet = getOrCreateStateSet(); stateSet->setRenderBinDetails(1001, "RenderBin"); @@ -182,6 +185,7 @@ public: { // Dynamic stuff, do not store geometry setUseDisplayList(false); + setDataVariance(Object::DYNAMIC); osg::StateSet* stateSet = getOrCreateStateSet(); stateSet->setRenderBinDetails(1000, "RenderBin"); @@ -232,6 +236,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(node)); @@ -239,21 +255,22 @@ public: osg::Light* light = lightSource->getLight(); FGLight *l = static_cast(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 +483,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,8 +550,15 @@ 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()); + // Attach empty program to the scene root so that shader programs + // don't leak into state sets (effects) that shouldn't have one. + stateSet = mRealRoot->getOrCreateStateSet(); + stateSet->setAttributeAndModes(new osg::Program, osg::StateAttribute::ON); } @@ -611,42 +658,16 @@ FGRenderer::update( bool refresh_camera_settings ) { } SGSkyState sstate; - - SGVec3d viewPos = current__view->getViewPosition(); - sstate.view_pos = toVec3f(viewPos); - SGGeod geodViewPos = SGGeod::fromCart(viewPos); - SGGeod geodZeroViewPos = SGGeod::fromGeodM(geodViewPos, 0); - sstate.zero_elev = toVec3f(SGVec3d::fromGeod(geodZeroViewPos)); - SGQuatd hlOr = SGQuatd::fromLonLat(geodViewPos); - sstate.view_up = toVec3f(hlOr.backTransform(-SGVec3d::e3())); - sstate.lon = geodViewPos.getLongitudeRad(); - sstate.lat = geodViewPos.getLatitudeRad(); - sstate.alt = geodViewPos.getElevationM(); + sstate.pos = current__view->getViewPosition(); + sstate.pos_geod = current__view->getPosition(); + sstate.ori = current__view->getViewOrientation(); sstate.spin = l->get_sun_rotation(); sstate.gst = globals->get_time_params()->getGst(); sstate.sun_dist = 50000.0 * sun_horiz_eff; sstate.moon_dist = 40000.0 * moon_horiz_eff; sstate.sun_angle = l->get_sun_angle(); - - /* - SG_LOG( SG_GENERAL, SG_BULK, "thesky->repaint() sky_color = " - << l->sky_color()[0] << " " - << l->sky_color()[1] << " " - << l->sky_color()[2] << " " - << l->sky_color()[3] ); - SG_LOG( SG_GENERAL, SG_BULK, " fog = " - << l->fog_color()[0] << " " - << l->fog_color()[1] << " " - << l->fog_color()[2] << " " - << l->fog_color()[3] ); - SG_LOG( SG_GENERAL, SG_BULK, - " sun_angle = " << l->sun_angle - << " moon_angle = " << l->moon_angle ); - */ - SGSkyColor scolor; - scolor.sky_color = SGVec3f(l->sky_color().data()); scolor.adj_sky_color = SGVec3f(l->adj_sky_color().data()); scolor.fog_color = SGVec3f(l->adj_fog_color().data());