X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FMain%2Frenderer.cxx;h=32d7953380b417271fbedd5aead6ba626d1ae3df;hb=b7eb3bd0e128d39101dfa5846de991681aa5456f;hp=ca4ed4f4e8eb11f616ed699002b02a78e520df2c;hpb=398c4c25d0a094c4843b74c1e8614121d817c222;p=flightgear.git diff --git a/src/Main/renderer.cxx b/src/Main/renderer.cxx index ca4ed4f4e..32d795338 100644 --- a/src/Main/renderer.cxx +++ b/src/Main/renderer.cxx @@ -23,6 +23,10 @@ # include #endif +#ifdef HAVE_WINDOWS_H +# include +#endif + #include #include @@ -38,10 +42,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -58,8 +64,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -92,12 +100,8 @@ #include "renderer.hxx" #include "main.hxx" #include "CameraGroup.hxx" -#include "ViewPartitionNode.hxx" - -// XXX Make this go away when OSG 2.2 is released. -#if (FG_OSG_VERSION >= 21004) -#define UPDATE_VISITOR_IN_VIEWER 1 -#endif +#include "FGEventHandler.hxx" +#include
using namespace osg; using namespace simgear; @@ -135,6 +139,7 @@ public: { // Dynamic stuff, do not store geometry setUseDisplayList(false); + setDataVariance(Object::DYNAMIC); osg::StateSet* stateSet = getOrCreateStateSet(); stateSet->setRenderBinDetails(1001, "RenderBin"); @@ -180,6 +185,7 @@ public: { // Dynamic stuff, do not store geometry setUseDisplayList(false); + setDataVariance(Object::DYNAMIC); osg::StateSet* stateSet = getOrCreateStateSet(); stateSet->setRenderBinDetails(1000, "RenderBin"); @@ -230,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)); @@ -237,21 +255,22 @@ public: osg::Light* light = lightSource->getLight(); FGLight *l = static_cast(globals->get_subsystem("lighting")); - light->setAmbient(l->scene_ambient().osg()); - light->setDiffuse(l->scene_diffuse().osg()); - light->setSpecular(l->scene_specular().osg()); - SGVec4f position(l->sun_vec()[0], l->sun_vec()[1], l->sun_vec()[2], 0); - light->setPosition(position.osg()); - SGVec3f direction(l->sun_vec()[0], l->sun_vec()[1], l->sun_vec()[2]); - light->setDirection(direction.osg()); - light->setSpotExponent(0); - light->setSpotCutoff(180); - light->setConstantAttenuation(1); - light->setLinearAttenuation(0); - light->setQuadraticAttenuation(0); + 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); traverse(node, nv); } +private: + const bool _isSun; }; class FGWireFrameModeUpdateCallback : public osg::StateAttribute::Callback { @@ -291,7 +310,7 @@ public: #if 0 FGLight *l = static_cast(globals->get_subsystem("lighting")); - lightModel->setAmbientIntensity(l->scene_ambient().osg()); + lightModel->setAmbientIntensity(toOsg(l->scene_ambient()); #else lightModel->setAmbientIntensity(osg::Vec4(0, 0, 0, 1)); #endif @@ -334,7 +353,7 @@ public: SGUpdateVisitor* updateVisitor = static_cast(nv); osg::Fog* fog = static_cast(sa); fog->setMode(osg::Fog::EXP2); - fog->setColor(updateVisitor->getFogColor().osg()); + fog->setColor(toOsg(updateVisitor->getFogColor())); fog->setDensity(updateVisitor->getFogExp2Density()); } }; @@ -366,14 +385,12 @@ static osg::ref_ptr mRealRoot = new osg::Group; static osg::ref_ptr mRoot = new osg::Group; -static osg::ref_ptr viewPartition = new ViewPartitionNode; - FGRenderer::FGRenderer() { #ifdef FG_JPEG_SERVER jpgRenderFrame = FGRenderer::update; #endif - manipulator = new FGManipulator; + eventHandler = new FGEventHandler; } FGRenderer::~FGRenderer() @@ -395,12 +412,7 @@ FGRenderer::splashinit( void ) { // Scene doesn't seem to pass the frame stamp to the update // visitor automatically. mUpdateVisitor->setFrameStamp(mFrameStamp.get()); -#ifdef UPDATE_VISITOR_IN_VIEWER viewer->setUpdateVisitor(mUpdateVisitor.get()); -#else - osgViewer::Scene* scene = viewer->getScene(); - scene->setUpdateVisitor(mUpdateVisitor.get()); -#endif } void @@ -471,17 +483,41 @@ 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); stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON); @@ -513,11 +549,16 @@ FGRenderer::init( void ) osg::Switch* sw = new osg::Switch; sw->setUpdateCallback(new FGScenerySwitchCallback); sw->addChild(mRoot.get()); - viewPartition->addChild(sw); - viewPartition->addChild(thesky->getCloudRoot()); - - mRealRoot->addChild(viewPartition.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); } @@ -549,9 +590,6 @@ FGRenderer::update( bool refresh_camera_settings ) { SGConfigureDirectionalLights( use_point_sprites, enhanced_lighting, distance_attenuation ); - static const SGPropertyNode *groundlevel_nearplane - = fgGetNode("/sim/current-view/ground-level-nearplane-m"); - FGLight *l = static_cast(globals->get_subsystem("lighting")); // update fog params @@ -581,11 +619,11 @@ FGRenderer::update( bool refresh_camera_settings ) { if ( fgGetBool("/sim/rendering/textures") ) { SGVec4f clearColor(l->adj_fog_color()); - camera->setClearColor(clearColor.osg()); + camera->setClearColor(toOsg(clearColor)); } } else { SGVec4f clearColor(l->sky_color()); - camera->setClearColor(clearColor.osg()); + camera->setClearColor(toOsg(clearColor)); } // update fog params if visibility has changed @@ -607,64 +645,38 @@ FGRenderer::update( bool refresh_camera_settings ) { double sun_horiz_eff, moon_horiz_eff; if (fgGetBool("/sim/rendering/horizon-effect")) { - sun_horiz_eff = 0.67+pow(0.5+cos(l->get_sun_angle())*2/2, 0.33)/3; - moon_horiz_eff = 0.67+pow(0.5+cos(l->get_moon_angle())*2/2, 0.33)/3; + sun_horiz_eff + = 0.67 + pow(osg::clampAbove(0.5 + cos(l->get_sun_angle()), + 0.0), + 0.33) / 3.0; + moon_horiz_eff + = 0.67 + pow(osg::clampAbove(0.5 + cos(l->get_moon_angle()), + 0.0), + 0.33)/3.0; } else { sun_horiz_eff = moon_horiz_eff = 1.0; } - static SGSkyState sstate; - - sstate.view_pos = toVec3f(current__view->get_view_pos()); - sstate.zero_elev = toVec3f(current__view->get_zero_elev()); - sstate.view_up = current__view->get_world_up(); - sstate.lon = current__view->getLongitude_deg() - * SGD_DEGREES_TO_RADIANS; - sstate.lat = current__view->getLatitude_deg() - * SGD_DEGREES_TO_RADIANS; - sstate.alt = current__view->getAltitudeASL_ft() - * SG_FEET_TO_METER; + SGSkyState sstate; + 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_ra = globals->get_ephem()->getSunRightAscension(); - sstate.sun_dec = globals->get_ephem()->getSunDeclination(); sstate.sun_dist = 50000.0 * sun_horiz_eff; - sstate.moon_ra = globals->get_ephem()->getMoonRightAscension(); - sstate.moon_dec = globals->get_ephem()->getMoonDeclination(); 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 ); - */ - - static SGSkyColor scolor; - + 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()); scolor.cloud_color = SGVec3f(l->cloud_color().data()); scolor.sun_angle = l->get_sun_angle(); scolor.moon_angle = l->get_moon_angle(); - scolor.nplanets = globals->get_ephem()->getNumPlanets(); - scolor.nstars = globals->get_ephem()->getNumStars(); - scolor.planet_data = globals->get_ephem()->getPlanets(); - scolor.star_data = globals->get_ephem()->getStars(); - thesky->reposition( sstate, delta_time_sec ); - thesky->repaint( scolor ); + thesky->reposition( sstate, *globals->get_ephem(), delta_time_sec ); + thesky->repaint( scolor, *globals->get_ephem() ); /* SG_LOG( SG_GENERAL, SG_BULK, @@ -726,7 +738,6 @@ FGRenderer::update( bool refresh_camera_settings ) { l->adj_fog_color(), l->get_sun_angle()*SGD_RADIANS_TO_DEGREES); mUpdateVisitor->setVisibility(actual_visibility); - viewPartition->setVisibility(actual_visibility); simgear::GroundLightManager::instance()->update(mUpdateVisitor.get()); bool hotspots = fgGetBool("/sim/panel-hotspots"); osg::Node::NodeMask cullMask = ~simgear::LIGHTS_BITS & ~simgear::PICK_BIT; @@ -734,10 +745,7 @@ FGRenderer::update( bool refresh_camera_settings ) { ->getLightNodeMask(mUpdateVisitor.get()); if (hotspots) cullMask |= simgear::PICK_BIT; - camera->setCullMask(cullMask); - // XXX - for (int i = 0; i < viewer->getNumSlaves(); ++i) - viewer->getSlave(i)._camera->setCullMask(cullMask); + CameraGroup::getDefault()->setCameraCullMasks(cullMask); } @@ -773,21 +781,10 @@ FGRenderer::resize( int width, int height ) { } } -void FGRenderer::setCameraParameters(float vfov, float aspectRatio, - float zNear, float zFar) -{ - zNear = .1; - osgViewer::Viewer* viewer = globals->get_renderer()->getViewer(); - viewer->getCamera()->setProjectionMatrixAsPerspective(vfov, - 1.0f / aspectRatio, - zNear, zFar); - -} bool FGRenderer::pick(std::vector& pickList, const osgGA::GUIEventAdapter* ea) { - osgViewer::Viewer* viewer = globals->get_renderer()->getViewer(); // wipe out the return ... pickList.clear(); typedef osgUtil::LineSegmentIntersector::Intersections Intersections; @@ -810,8 +807,8 @@ FGRenderer::pick(std::vector& pickList, if (!pickCallback) continue; SGSceneryPick sceneryPick; - sceneryPick.info.local = SGVec3d(hit->getLocalIntersectPoint()); - sceneryPick.info.wgs84 = SGVec3d(hit->getWorldIntersectPoint()); + sceneryPick.info.local = toSG(hit->getLocalIntersectPoint()); + sceneryPick.info.wgs84 = toSG(hit->getWorldIntersectPoint()); sceneryPick.callback = pickCallback; pickList.push_back(sceneryPick); } @@ -820,6 +817,18 @@ FGRenderer::pick(std::vector& pickList, return !pickList.empty(); } +void +FGRenderer::setViewer(osgViewer::Viewer* viewer_) +{ + viewer = viewer_; +} + +void +FGRenderer::setEventHandler(FGEventHandler* eventHandler_) +{ + eventHandler = eventHandler_; +} + void FGRenderer::addCamera(osg::Camera* camera, bool useSceneData) {