9#include <simgear/compiler.h>
18#include <osg/CullFace>
19#include <osg/CullStack>
20#include <osg/GraphicsContext>
24#include <osg/NodeCallback>
26#include <osg/PolygonMode>
28#include <osgUtil/LineSegmentIntersector>
29#include <osgDB/WriteFile>
31#include <simgear/ephemeris/ephemeris.hxx>
32#include <simgear/scene/material/EffectCullVisitor.hxx>
33#include <simgear/scene/sky/sky.hxx>
34#include <simgear/scene/tgdb/GroundLightManager.hxx>
35#include <simgear/scene/tgdb/pt_lights.hxx>
36#include <simgear/scene/tgdb/userdata.hxx>
37#include <simgear/scene/util/SGUpdateVisitor.hxx>
38#include <simgear/scene/util/RenderConstants.hxx>
39#include <simgear/scene/util/SGSceneUserData.hxx>
40#include <simgear/scene/util/OsgUtils.hxx>
41#include <simgear/timing/sg_time.hxx>
65#if defined(ENABLE_QQ_UI)
79 void run(osg::GraphicsContext* gc)
81 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
83 SGPropertyNode* p_rendering =
fgGetNode(
"/sim/rendering/gl-info",
true);
84 auto query_gl_string =
85 [p_rendering](
const std::string& prop_name, GLenum
name) {
86 const char* value = (
const char*)glGetString(
name);
88 std::string str(value ? value :
"");
89 p_rendering->setStringValue(prop_name, str);
90 SG_LOG(SG_GL, SG_INFO,
" " << prop_name <<
": " << str);
94 [p_rendering](
const std::string& prop_name, GLenum
name) {
96 glGetIntegerv(
name, &value);
97 p_rendering->setIntValue(prop_name, value);
98 SG_LOG(SG_GL, SG_INFO,
" " << prop_name <<
": " << value);
101 SG_LOG(SG_GL, SG_INFO,
"OpenGL context info:");
102 query_gl_string(
"gl-vendor", GL_VENDOR);
103 query_gl_string(
"gl-renderer", GL_RENDERER);
104 query_gl_string(
"gl-version", GL_VERSION);
105 query_gl_string(
"gl-shading-language-version", GL_SHADING_LANGUAGE_VERSION);
106 query_gl_int(
"gl-max-texture-size", GL_MAX_TEXTURE_SIZE);
107 query_gl_int(
"gl-max-texture-units", GL_MAX_TEXTURE_UNITS);
111 OpenThreads::Mutex _mutex;
117 static SGSceneFeatures* sceneFeatures = SGSceneFeatures::instance();
118 sceneFeatures->setEnablePointSpriteLights(node->getIntValue());
125 static SGSceneFeatures* sceneFeatures = SGSceneFeatures::instance();
126 sceneFeatures->setEnableDistanceAttenuationLights(node->getIntValue());
133 static SGSceneFeatures* sceneFeatures = SGSceneFeatures::instance();
134 sceneFeatures->setEnableTriangleDirectionalLights(node->getIntValue());
143 cg->setLODScale(node->getFloatValue());
154 void operator()(osg::StateAttribute* stateAttribute, osg::NodeVisitor*)
override
156 assert(
dynamic_cast<osg::Hint*
>(stateAttribute));
157 osg::Hint* hint =
static_cast<osg::Hint*
>(stateAttribute);
158 std::string value = mConfigNode->getStringValue();
160 hint->setMode(GL_DONT_CARE);
161 else if (value ==
"nicest")
162 hint->setMode(GL_NICEST);
163 else if (value ==
"fastest")
164 hint->setMode(GL_FASTEST);
166 hint->setMode(GL_DONT_CARE);
169 SGPropertyNode_ptr mConfigNode;
175 mWireframe(
fgGetNode(
"/sim/rendering/wireframe", true))
178 void operator()(osg::StateAttribute* stateAttribute, osg::NodeVisitor*)
override
180 assert(
dynamic_cast<osg::PolygonMode*
>(stateAttribute));
181 osg::PolygonMode* polygonMode =
static_cast<osg::PolygonMode*
>(stateAttribute);
182 if (mWireframe->getBoolValue()) {
183 polygonMode->setMode(osg::PolygonMode::FRONT_AND_BACK,
184 osg::PolygonMode::LINE);
186 polygonMode->setMode(osg::PolygonMode::FRONT_AND_BACK,
187 osg::PolygonMode::FILL);
191 SGPropertyNode_ptr mWireframe;
197 void operator()(osg::Node* node, osg::NodeVisitor* nv)
override
199 assert(
dynamic_cast<osg::Switch*
>(node));
200 osg::Switch* sw =
static_cast<osg::Switch*
>(node);
202 sw->setValue(0, enabled);
218 SGPropertyChangeListenerVec::iterator
i = _listeners.begin();
219 for (;
i != _listeners.end(); ++
i) {
224 getView()->setSceneData(
new osg::Group);
235 osg::initNotifyLevel();
237 osg::DisplaySettings* display_settings = osg::DisplaySettings::instance();
238 assert(display_settings);
240 display_settings->setShaderHint(osg::DisplaySettings::SHADER_NONE,
false);
243 _update_visitor =
new SGUpdateVisitor;
249 sgUserDataInit(
globals->get_props());
251 if (_composite_viewer) {
254 _composite_viewer =
new osgViewer::CompositeViewer;
255 std::string affinity =
fgGetString(
"/sim/thread-cpu-affinity");
256 bool osg_affinity_flag =
true;
257 if (affinity ==
"") {}
258 else if (affinity ==
"none") {
259 osg_affinity_flag =
false;
261 else if (affinity ==
"osg") {
265 SG_LOG(SG_VIEW, SG_ALERT,
"Unrecognised value for /sim/thread-cpu-affinity: " << affinity);
267 _composite_viewer->setUseConfigureAffinity(osg_affinity_flag);
271 _composite_viewer->setReleaseContextAtEndOfFrameHint(
false);
272 _composite_viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
274 _scenery_loaded =
fgGetNode(
"/sim/sceneryloaded",
true);
275 _position_finalized =
fgGetNode(
"/sim/position-finalized",
true);
276 _panel_hotspots =
fgGetNode(
"/sim/panel-hotspots",
true);
278 _sim_delta_sec =
fgGetNode(
"/sim/time/delta-sec",
true);
280 _xsize =
fgGetNode(
"/sim/startup/xsize",
true);
281 _ysize =
fgGetNode(
"/sim/startup/ysize",
true);
282 _xpos =
fgGetNode(
"/sim/startup/xpos",
true);
283 _ypos =
fgGetNode(
"/sim/startup/ypos",
true);
284 _splash_alpha =
fgGetNode(
"/sim/startup/splash-alpha",
true);
285 _splashHiddenSignal =
fgGetNode(
"/sim/signals/splash-hidden",
true);
287 _altitude_ft =
fgGetNode(
"/position/altitude-ft",
true);
289 _cloud_status =
fgGetNode(
"/environment/clouds/status",
true);
290 _visibility_m =
fgGetNode(
"/environment/visibility-m",
true);
293 bool use_point_sprites =
fgGetBool(
"/sim/rendering/point-sprites",
true);
294 bool distance_attenuation =
fgGetBool(
"/sim/rendering/distance-attenuation",
false);
295 bool triangles =
fgGetBool(
"/sim/rendering/triangle-directional-lights",
true);
296 SGConfigureDirectionalLights(use_point_sprites, distance_attenuation, triangles);
304 std::string tc =
fgGetString(
"/sim/rendering/texture-compression");
306 if (tc ==
"false" || tc ==
"off" ||
307 tc ==
"0" || tc ==
"no" ||
310 SGSceneFeatures::instance()->setTextureCompression(SGSceneFeatures::DoNotUseCompression);
311 }
else if (tc ==
"arb") {
312 SGSceneFeatures::instance()->setTextureCompression(SGSceneFeatures::UseARBCompression);
313 }
else if (tc ==
"dxt1") {
314 SGSceneFeatures::instance()->setTextureCompression(SGSceneFeatures::UseDXT1Compression);
315 }
else if (tc ==
"dxt3") {
316 SGSceneFeatures::instance()->setTextureCompression(SGSceneFeatures::UseDXT3Compression);
317 }
else if (tc ==
"dxt5") {
318 SGSceneFeatures::instance()->setTextureCompression(SGSceneFeatures::UseDXT5Compression);
320 SG_LOG(SG_VIEW, SG_WARN,
"Unknown texture compression setting!");
323 SGSceneFeatures::instance()->setTextureCompressionPath(
globals->get_texture_cache_dir());
329 const SGPath texture_path =
globals->get_fg_root() /
"Textures" /
"Sky";
331 SGCloudLayer * layer =
new SGCloudLayer(texture_path);
332 _sky->add_cloud_layer(layer);
342 osgViewer::View* view =
getView();
343 _scene_root =
new osg::Group;
344 _scene_root->setName(
"viewerSceneRoot");
345 view->setSceneData(_scene_root);
357 fgSetBool(
"/sim/menubar/overlap-hide",
true);
364 getView()->getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
368 _scene_root->getOrCreateStateSet()->setAttributeAndModes(
369 new osg::Program, osg::StateAttribute::ON);
404 osg::ref_ptr<simgear::SGReaderWriterOptions> opt;
405 opt = simgear::SGReaderWriterOptions::fromPath(
globals->get_fg_root());
406 opt->setPropertyNode(
globals->get_props());
407 _sky->build(80000.0, 80000.0,
409 *ephemerisSub->data(),
414 _scene_root->addChild(_sky->getPreRoot());
416 _scene_root->addChild(_sky->getCloudRoot());
420 osg::Group* scenery_group =
globals->get_scenery()->get_scene_graph();
421 scenery_group->setName(
"Scenery group");
422 scenery_group->setNodeMask(~simgear::BACKGROUND_BIT);
423 osg::Switch* scenery_switch =
new osg::Switch;
424 scenery_switch->setName(
"Scenery switch");
426 scenery_switch->addChild(scenery_group);
427 _scene_root->addChild(scenery_switch);
430 osg::PolygonMode* polygonMode =
new osg::PolygonMode;
432 scenery_group->getOrCreateStateSet()->setAttributeAndModes(polygonMode);
436#if defined(ENABLE_QQ_UI)
437 osgViewer::Viewer* viewer =
dynamic_cast<osgViewer::Viewer*
>(view);
439 std::string rootQMLPath =
fgGetString(
"/sim/gui/qml-root-path");
440 auto graphicsWindow =
dynamic_cast<osgViewer::GraphicsWindow*
>(guiCamera->getGraphicsContext());
442 if (!rootQMLPath.empty()) {
444 _quickDrawable->
setup(graphicsWindow, viewer);
445 _quickDrawable->setSourcePath(rootQMLPath);
447 osg::Geode* qqGeode =
new osg::Geode;
448 qqGeode->addDrawable(_quickDrawable);
449 guiCamera->addChild(qqGeode);
459 static osg::ref_ptr<QueryGLParametersOperation> genOp;
460 static bool didInit =
false;
466 if (!genOp.valid()) {
469 wsa->
windows[0]->gc->add(genOp.get());
472 if (!genOp->isFinished())
485 if (!_position_finalized || !_scenery_loaded->getBoolValue()) {
486 _splash_alpha->setDoubleValue(1.0);
487 if (_splashHiddenSignal->getBoolValue()) {
488 _splashHiddenSignal->setBoolValue(
false);
491 if (!_maximum_texture_size) {
494 osg::GraphicsContext *gc = guiCamera->getGraphicsContext();
495 osg::GLExtensions* gl2ext = gc->getState()->get<osg::GLExtensions>();
497 _maximum_texture_size = gl2ext->maxTextureSize;
498 SGSceneFeatures::instance()->setMaxTextureSize(_maximum_texture_size);
505 if (_splash_alpha->getDoubleValue() > 0.0) {
507 const double fade_time = 0.5;
508 const double fade_steps_per_sec = 10;
509 double delay_time = SGMiscd::min(fade_time/fade_steps_per_sec,
510 (SGTimeStamp::now() - _splash_time).toSecs());
511 _splash_time = SGTimeStamp::now();
512 double sAlpha = _splash_alpha->getDoubleValue();
513 sAlpha -= SGMiscd::max(0.0,delay_time/fade_time);
517 _splashHiddenSignal->setBoolValue(
true);
521 _splash_alpha->setDoubleValue((sAlpha < 0) ? 0.0 : sAlpha);
524 fgSetBool(
"/sim/menubar/overlap-hide",
false);
530 double actual_visibility;
531 if (_cloud_status->getBoolValue()) {
532 actual_visibility = _sky->get_visibility();
534 actual_visibility = _visibility_m->getDoubleValue();
553 SGVec3f sundirection(l->sun_vec()[0], l->sun_vec()[1], l->sun_vec()[2]);
554 SGVec3f moondirection(l->moon_vec()[0], l->moon_vec()[1], l->moon_vec()[2]);
556 _update_visitor->setLight(sundirection, moondirection,
557 l->get_sun_angle()*SGD_RADIANS_TO_DEGREES);
558 _update_visitor->setVisibility(actual_visibility);
561 cullMask |= simgear::GroundLightManager::instance()
562 ->getLightNodeMask(_update_visitor.get());
563 if (_panel_hotspots->getBoolValue())
564 cullMask |= simgear::PICK_BIT;
569FGRenderer::updateSky()
572 double visibility_meters = _visibility_m->getDoubleValue();
573 _sky->set_visibility(visibility_meters);
575 double altitude_m = _altitude_ft->getDoubleValue() * SG_FEET_TO_METER;
576 _sky->modify_vis( altitude_m, 0.0 );
584 sstate.pos =
globals->get_current_view()->getViewPosition();
585 sstate.pos_geod =
globals->get_current_view()->getPosition();
586 sstate.ori =
globals->get_current_view()->getViewOrientation();
587 sstate.spin = l->get_sun_rotation();
588 sstate.gst =
globals->get_time_params()->getGst();
589 sstate.sun_dist = 50000.0;
590 sstate.moon_dist_bare = 40000.0;
591 sstate.moon_dist_factor = 1.0;
592 sstate.sun_angle = l->get_sun_angle();
595 scolor.sun_angle = l->get_sun_angle();
596 scolor.moon_angle = l->get_moon_angle();
597 scolor.altitude_m = altitude_m;
600 double delta_time_sec = _sim_delta_sec->getDoubleValue();
601 _sky->reposition( sstate, *ephemerisSub->data(), delta_time_sec );
602 _sky->repaint( scolor, *ephemerisSub->data() );
608 SG_LOG(SG_VIEW, SG_DEBUG,
"FGRenderer::resize: new size " << width <<
" x " << height);
610 if (width != _xsize->getIntValue()) _xsize->setIntValue(width);
611 if (height != _ysize->getIntValue()) _ysize->setIntValue(height);
612 if (x != _xpos->getIntValue()) _xpos->setIntValue(x);
613 if (y != _ypos->getIntValue()) _ypos->setIntValue(y);
616 _splash->resize(width, height);
617#if defined(ENABLE_QQ_UI)
618 if (_quickDrawable) {
619 _quickDrawable->resize(width, height);
627 resize(width, height, _xpos->getIntValue(), _ypos->getIntValue());
632typedef osgUtil::LineSegmentIntersector::Intersection Intersection;
634SGVec2d uvFromIntersection(
const Intersection& hit)
638 osg::Drawable* drawable = hit.drawable.get();
639 osg::Geometry* geometry = drawable ? drawable->asGeometry() :
nullptr;
640 osg::Vec3Array* vertices = geometry ?
641 dynamic_cast<osg::Vec3Array*
>(geometry->getVertexArray()) : nullptr;
644 SG_LOG(SG_INPUT, SG_WARN,
"Unable to get vertices for intersection.");
645 return SGVec2d(-9999,-9999);
649 const Intersection::IndexList& indices = hit.indexList;
650 const Intersection::RatioList& ratios = hit.ratioList;
652 if (indices.size() != 3 || ratios.size() != 3) {
653 SG_LOG(SG_INPUT, SG_WARN,
"Intersection has insufficient indices to work with.");
654 return SGVec2d(-9999,-9999);
657 unsigned int i1 = indices[0];
658 unsigned int i2 = indices[1];
659 unsigned int i3 = indices[2];
661 float r1 = ratios[0];
662 float r2 = ratios[1];
663 float r3 = ratios[2];
665 osg::Array* texcoords = (geometry->getNumTexCoordArrays() > 0) ?
666 geometry->getTexCoordArray(0) :
nullptr;
667 osg::Vec2Array* texcoords_Vec2Array =
dynamic_cast<osg::Vec2Array*
>(texcoords);
669 if (!texcoords_Vec2Array) {
670 SG_LOG(SG_INPUT, SG_WARN,
"Unable to get texcoords for intersection.");
671 return SGVec2d(-9999,-9999);
676 osg::Vec2 tc1 = (*texcoords_Vec2Array)[i1];
677 osg::Vec2 tc2 = (*texcoords_Vec2Array)[i2];
678 osg::Vec2 tc3 = (*texcoords_Vec2Array)[i3];
680 return toSG(osg::Vec2d(tc1 * r1 + tc2 * r2 + tc3 * r3));
688 osgUtil::LineSegmentIntersector::Intersections intersections;
696 int highlight_num_props = 0;
698 for (
const auto& hit : intersections) {
699 const osg::NodePath& np = hit.nodePath;
700 osg::NodePath::const_reverse_iterator npi;
702 for (npi = np.rbegin(); npi != np.rend(); ++npi) {
703 if (!highlight_num_props && highlight) {
704 highlight_num_props = highlight->highlightNodes(*npi);
706 SGSceneUserData* ud = SGSceneUserData::getSceneUserData(*npi);
707 if (!ud || (ud->getNumPickCallbacks() == 0))
710 for (
unsigned i = 0;
i < ud->getNumPickCallbacks(); ++
i) {
711 SGPickCallback* pickCallback = ud->getPickCallback(
i);
714 SGSceneryPick sceneryPick;
715 sceneryPick.info.local = toSG(hit.getLocalIntersectPoint());
716 sceneryPick.info.wgs84 = toSG(hit.getWorldIntersectPoint());
718 if( pickCallback->needsUV() )
719 sceneryPick.info.uv = uvFromIntersection(hit);
721 sceneryPick.callback = pickCallback;
722 result.push_back(sceneryPick);
735 bool should_restart_threading =
getViewerBase()->areThreadsRunning();
736 if (should_restart_threading) {
742 osg::GraphicsContext *gc = guiCamera->getGraphicsContext();
743 camera->setGraphicsContext(gc);
746 _composite_viewer->getView(0)->addSlave(camera,
false);
747 simgear::installEffectCullVisitor(camera);
749 if (should_restart_threading) {
759 bool should_restart_threading =
getViewerBase()->areThreadsRunning();
760 if (should_restart_threading) {
766 camera->removeChildren(0, camera->getNumChildren());
768 auto view = _composite_viewer->getView(0);
769 unsigned int index = view->findSlaveIndexForCamera(camera);
770 if (index < view->getNumSlaves()) {
771 view->removeSlave(index);
773 SG_LOG(SG_GL, SG_WARN,
"Attempted to remove unregistered Canvas camera");
776 if (should_restart_threading) {
781osgViewer::ViewerBase*
784 return _composite_viewer;
787osg::ref_ptr<osgViewer::CompositeViewer>
790 return _composite_viewer;
796 _composite_viewer = composite_viewer;
802 assert(_composite_viewer);
803 return _composite_viewer->getFrameStamp();
812 if (_composite_viewer && _composite_viewer->getNumViews() > 0) {
813 assert(_composite_viewer->getNumViews());
814 return _composite_viewer->getView(0);
819const osgViewer::View*
829 if (_composite_viewer && _composite_viewer->getNumViews() == 0) {
830 SG_LOG(SG_VIEW, SG_DEBUG,
"adding view to composite_viewer.");
831 _composite_viewer->stopThreading();
832 _composite_viewer->addView(view);
833 _composite_viewer->startThreading();
840 return _event_handler.get();
846 return _event_handler.get();
852 _event_handler = event_handler;
870FGRenderer::addChangeListener(SGPropertyChangeListener* l,
const char* path)
872 _listeners.push_back(l);
881 osgViewer::View* view =
globals->get_renderer()->getView();
882 return osgDB::writeNodeFile(*view->getSceneData(), filename);
888 return osgDB::writeNodeFile(*
globals->get_scenery()->get_terrain_branch(),
895 return osgDB::writeNodeFile(*node, filename);
902class VisibleSceneInfoVisitor :
public NodeVisitor, CullStack {
904 VisibleSceneInfoVisitor() :
905 NodeVisitor(CULL_VISITOR, TRAVERSE_ACTIVE_CHILDREN)
907 setCullingMode(CullSettings::SMALL_FEATURE_CULLING
908 | CullSettings::VIEW_FRUSTUM_CULLING);
909 setComputeNearFarMode(CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
912 VisibleSceneInfoVisitor(
const VisibleSceneInfoVisitor& rhs) :
913 osg::Object(rhs), NodeVisitor(rhs), CullStack(rhs)
917 META_NodeVisitor(
"flightgear",
"VisibleSceneInfoVistor")
919 typedef std::map<const std::
string,
int> InfoMap;
921 void getNodeInfo(Node* node)
923 const char* typeName =
typeid(*node).name();
924 classInfo[typeName]++;
925 const std::string& nodeName = node->getName();
926 if (!nodeName.empty())
927 nodeInfo[nodeName]++;
933 typedef vector<InfoMap::iterator> FreqVector;
934 auto freqComp = [](
const InfoMap::iterator& lhs,
const InfoMap::iterator& rhs) {
935 return lhs->second > rhs->second;
937 cout <<
"class info:\n";
939 for (InfoMap::iterator itr = classInfo.begin(), end = classInfo.end();
942 classes.push_back(itr);
943 sort(classes.begin(), classes.end(), freqComp);
944 for (FreqVector::iterator itr = classes.begin(), end = classes.end();
947 cout << (*itr)->first <<
" " << (*itr)->second <<
"\n";
949 cout <<
"\nnode info:\n";
951 for (InfoMap::iterator itr = nodeInfo.begin(), end = nodeInfo.end();
954 nodes.push_back(itr);
956 sort (nodes.begin(), nodes.end(), freqComp);
957 for (FreqVector::iterator itr = nodes.begin(), end = nodes.end();
960 cout << (*itr)->first <<
" " << (*itr)->second <<
"\n";
965 void doTraversal(Camera* camera, Node* root, Viewport* viewport)
967 ref_ptr<RefMatrix> projection
968 = createOrReuseMatrix(camera->getProjectionMatrix());
969 ref_ptr<RefMatrix> mv = createOrReuseMatrix(camera->getViewMatrix());
971 viewport = camera->getViewport();
973 pushViewport(viewport);
974 pushProjectionMatrix(projection.get());
975 pushModelViewMatrix(mv.get(), Transform::ABSOLUTE_RF);
977 popModelViewMatrix();
978 popProjectionMatrix();
984 void apply(Node& node)
994 void apply(Group& node)
1004 void apply(Transform& node)
1009 ref_ptr<RefMatrix> matrix = createOrReuseMatrix(*getModelViewMatrix());
1010 node.computeLocalToWorldMatrix(*matrix,
this);
1011 pushModelViewMatrix(matrix.get(), node.getReferenceFrame());
1014 popModelViewMatrix();
1018 void apply(Camera& camera)
1021 CullSettings saved_cull_settings(*
this);
1024 setCullSettings(camera);
1026 inheritCullSettings(saved_cull_settings, camera.getInheritanceMask());
1029 unsigned int savedTraversalMask = getTraversalMask();
1030 bool mustSetCullMask = (camera.getInheritanceMask()
1031 & osg::CullSettings::CULL_MASK) == 0;
1032 if (mustSetCullMask)
1033 setTraversalMask(camera.getCullMask());
1035 osg::RefMatrix* projection = 0;
1036 osg::RefMatrix* modelview = 0;
1038 if (camera.getReferenceFrame()==osg::Transform::RELATIVE_RF) {
1039 if (camera.getTransformOrder()==osg::Camera::POST_MULTIPLY) {
1040 projection = createOrReuseMatrix(*getProjectionMatrix()
1041 *camera.getProjectionMatrix());
1042 modelview = createOrReuseMatrix(*getModelViewMatrix()
1043 * camera.getViewMatrix());
1046 projection = createOrReuseMatrix(camera.getProjectionMatrix()
1047 * (*getProjectionMatrix()));
1048 modelview = createOrReuseMatrix(camera.getViewMatrix()
1049 * (*getModelViewMatrix()));
1053 projection = createOrReuseMatrix(camera.getProjectionMatrix());
1054 modelview = createOrReuseMatrix(camera.getViewMatrix());
1056 if (camera.getViewport())
1057 pushViewport(camera.getViewport());
1059 pushProjectionMatrix(projection);
1060 pushModelViewMatrix(modelview, camera.getReferenceFrame());
1065 popModelViewMatrix();
1068 popProjectionMatrix();
1070 if (camera.getViewport()) popViewport();
1073 if (mustSetCullMask)
1074 setTraversalMask(savedTraversalMask);
1077 setCullSettings(saved_cull_settings);
1089 osgViewer::View* view = renderer->
getView();
1090 VisibleSceneInfoVisitor vsv;
1091 osg::Viewport* vp = 0;
1092 if (!view->getCamera()->getViewport() && view->getNumSlaves() > 0) {
1093 const osg::View::Slave& slave = view->getSlave(0);
1094 vp = slave._camera->getViewport();
1096 vsv.doTraversal(view->getCamera(), view->getSceneData(), vp);
1102 osg::ref_ptr<osg::GraphicsContext::Traits> traits =
1103 new osg::GraphicsContext::Traits;
1106 traits->x = 0; traits->y = 0;
1107 traits->width = 1; traits->height = 1;
1109 traits->red = 8; traits->green = 8; traits->blue = 8; traits->alpha = 8;
1112 traits->pbuffer =
true;
1114 traits->windowDecoration =
false;
1115 traits->doubleBuffer =
true;
1116 traits->sharedContext =
nullptr;
1117 traits->readDISPLAY();
1118 traits->setUndefinedScreenDetailsToDefaultScreen();
1121 traits->glContextVersion =
"4.1";
1122 traits->glContextProfileMask = 0x1;
1124 osg::ref_ptr<osg::GraphicsContext> pbuffer
1125 = osg::GraphicsContext::createGraphicsContext(traits.get());
1126 return pbuffer.valid();
virtual void valueChanged(SGPropertyNode *node)
virtual void valueChanged(SGPropertyNode *node)
Wrap SGEphemeris in a subsystem/property interface.
void operator()(osg::StateAttribute *stateAttribute, osg::NodeVisitor *) override
FGHintUpdateCallback(const char *configNode)
void removeCanvasCamera(osg::Camera *camera)
Remove a Canvas RTT camera from the renderer.
osgViewer::View * getView()
SplashScreen * getSplash()
osg::ref_ptr< osgViewer::CompositeViewer > getCompositeViewer()
Both should only be used on reset.
void setView(osgViewer::View *view)
void setupView()
Setup the scene graph root.
flightgear::FGEventHandler * getEventHandler()
PickList pick(const osg::Vec2 &windowPos)
Pick into the scene and return the pick callbacks on the way.
void init()
Initialize the renderer.
void addCanvasCamera(osg::Camera *camera)
Add a Canvas RTT camera to the renderer.
osgViewer::ViewerBase * getViewerBase() const
void update()
Update rendering-related parameters.
bool runInitOperation()
Run a graphics operation that retrieves some OpenGL parameters.
void setEventHandler(flightgear::FGEventHandler *event_handler)
void postinit()
Called after init() was called, the graphics window has been created and the CameraGroup has been ini...
void setCompositeViewer(osg::ref_ptr< osgViewer::CompositeViewer > composite_viewer)
void resize(int width, int height)
Handle a window resize event.
std::vector< SGSceneryPick > PickList
osg::FrameStamp * getFrameStamp() const
static bool scenery_enabled
void operator()(osg::Node *node, osg::NodeVisitor *nv) override
static flightgear::SceneryPager * getPagerSingleton()
void operator()(osg::StateAttribute *stateAttribute, osg::NodeVisitor *) override
FGWireFrameModeUpdateCallback()
void valueChanged(SGPropertyNode *node) override
virtual void valueChanged(SGPropertyNode *node)
void setup(osgViewer::GraphicsWindow *gw, osgViewer::Viewer *viewer)
void run(osg::GraphicsContext *gc)
The body of the operation.
QueryGLParametersOperation()
static CameraGroup * getDefault()
Get the default CameraGroup.
void setCameraCullMasks(osg::Node::NodeMask nm)
Set the cull mask on all non-GUI cameras.
void setChangeStatsCameraRenderOrder(bool c)
GraphicsContextOperation(const std::string &name)
const SGQuatd & getViewOrientation()
const SGVec3d & getViewPosition()
Adapter from windows system / graphics context management API to functions used by flightgear.
WindowVector windows
Vector of all the registered windows.
static WindowSystemAdapter * getWSA()
Get the global WindowSystemAdapter.
void fgAddChangeListener(SGPropertyChangeListener *listener, const char *path)
Add a listener to a node.
std::string fgGetString(const char *name, const char *defaultValue)
Get a string value for a property.
void syncPausePopupState()
synchronize /sim/freeze properties with visiblity of the popup-dialog which informs the user
FlightPlan.hxx - defines a full flight-plan object, including departure, cruise, arrival information ...
void addSentryBreadcrumb(const std::string &, const std::string &)
osg::Camera * getGUICamera(CameraGroup *cgroup)
Get the osg::Camera that draws the GUI, if any, from a camera group.
bool computeIntersections(const CameraGroup *cgroup, const osg::Vec2d &windowPos, osgUtil::LineSegmentIntersector::Intersections &intersections)
Choose a camera using an event and do intersection testing on its view of the scene.
Precipitation manager This manager calculate the intensity of precipitation in function of the altitu...
bool fgSetDouble(const char *name, double defaultValue)
Set a double value for a property.
bool fgGetBool(char const *name, bool def)
Get a bool value for a property.
bool fgSetBool(char const *name, bool val)
Set a bool value for a property.
SGPropertyNode * fgGetNode(const char *path, bool create)
Get a property node.
bool fgPrintVisibleSceneInfo(FGRenderer *renderer)
bool fgDumpTerrainBranchToFile(const char *filename)
bool fgPreliminaryGLVersionCheck()
Attempt to create an off-screen pixel buffer to check whether our target OpenGL version is available ...
bool fgDumpNodeToFile(osg::Node *node, const char *filename)
bool fgDumpSceneGraphToFile(const char *filename)