20,741
edits
(https://forum.flightgear.org/viewtopic.php?f=24&t=38294&p=376875#p376865) |
(→for folks wanting to tinker with pbuffer based Canvas ctx: new section) |
||
Line 5: | Line 5: | ||
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 08:52, 26 November 2020 (EST) | --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 08:52, 26 November 2020 (EST) | ||
== for folks wanting to tinker with pbuffer based Canvas ctx == | |||
<syntaxhighlight lang="patch"> | |||
diff --git a/src/Canvas/FGCanvasSystemAdapter.cxx b/src/Canvas/FGCanvasSystemAdapter.cxx | |||
index a0b9b6651..7a69500e1 100644 | |||
--- a/src/Canvas/FGCanvasSystemAdapter.cxx | |||
+++ b/src/Canvas/FGCanvasSystemAdapter.cxx | |||
@@ -69,14 +69,14 @@ namespace canvas | |||
//---------------------------------------------------------------------------- | |||
void FGCanvasSystemAdapter::addCamera(osg::Camera* camera) const | |||
{ | |||
- globals->get_renderer()->addCamera(camera, false); | |||
+ globals->get_renderer()->addCamera(camera, false, true); | |||
} | |||
//---------------------------------------------------------------------------- | |||
void FGCanvasSystemAdapter::removeCamera(osg::Camera* camera) const | |||
{ | |||
if( globals->get_renderer() ) | |||
- globals->get_renderer()->removeCamera(camera); | |||
+ globals->get_renderer()->removeCamera(camera, true); | |||
} | |||
//---------------------------------------------------------------------------- | |||
diff --git a/src/Main/options.cxx b/src/Main/options.cxx | |||
index f0f9c43e3..d82fbb766 100644 | |||
--- a/src/Main/options.cxx | |||
+++ b/src/Main/options.cxx | |||
@@ -2001,6 +2001,10 @@ struct OptionDesc { | |||
{"developer", true, OPTION_IGNORE | OPTION_BOOL, "", false, "", nullptr }, | |||
{"jsbsim-output-directive-file", true, OPTION_STRING, "/sim/jsbsim/output-directive-file", false, "", nullptr }, | |||
{"disable-gui", false, OPTION_FUNC, "", false, "", fgOptDisableGUI }, | |||
+ | |||
+ // this enables pbuffer creation for the main osgviewer window, so that the we have an actual headless option for unit testing/standalone benchmarks | |||
+ {"enable-headless", false, OPTION_BOOL, "/sim/startup/enable-headless-mode", true, "", nullptr }, | |||
+ | |||
{"graphics-preset", true, OPTION_STRING, "/sim/rendering/preset", false, "", nullptr}, | |||
{"composite-viewer", true, OPTION_INT, "/sim/rendering/composite-viewer-enabled", false, "", nullptr}, | |||
{"restart-launcher", false, OPTION_BOOL, "/sim/restart-launcher-on-exit", true, "", nullptr}, | |||
diff --git a/src/Viewer/WindowBuilder.cxx b/src/Viewer/WindowBuilder.cxx | |||
index 4bedcd77e..6cc8eeb91 100644 | |||
--- a/src/Viewer/WindowBuilder.cxx | |||
+++ b/src/Viewer/WindowBuilder.cxx | |||
@@ -126,6 +126,10 @@ void WindowBuilder::makeDefaultTraits(bool stencil) | |||
} | |||
SG_LOG(SG_VIEW,SG_DEBUG,"Using initial window size: " << w << " x " << h); | |||
} | |||
+ | |||
+ if (fgGetBool("/sim/startup/enable-headless-mode",false)) { | |||
+ traits->pbuffer = true; | |||
+ } // enable headless mode | |||
} | |||
} // of namespace flightgear | |||
@@ -251,8 +255,9 @@ GraphicsWindow* WindowBuilder::buildWindow(const SGPropertyNode* winNode, bool i | |||
auto traits = new GraphicsContext::Traits(*defaultTraits); | |||
// Attempt to share context with the window that was created first | |||
- if (!wsa->windows.empty()) | |||
+ if (!wsa->windows.empty() && fgGetBool("/sim/viewer/enable-shared-gl-context",true)) | |||
traits->sharedContext = wsa->windows.front()->gc; | |||
+ | |||
int traitsSet = setFromProperty(traits->hostName, winNode, "host-name"); | |||
traitsSet |= setFromProperty(traits->displayNum, winNode, "display"); | |||
diff --git a/src/Viewer/renderer.cxx b/src/Viewer/renderer.cxx | |||
index 419c01697..31507f8b0 100644 | |||
--- a/src/Viewer/renderer.cxx | |||
+++ b/src/Viewer/renderer.cxx | |||
@@ -56,6 +56,11 @@ | |||
#include <osg/Version> | |||
#include <osg/TexEnv> | |||
+#include <osg/CameraView> | |||
+#include <osg/GraphicsContext> | |||
+#include <osgViewer/CompositeViewer> | |||
+ | |||
+ | |||
#include <osgUtil/LineSegmentIntersector> | |||
#include <osg/io_utils> | |||
@@ -117,6 +122,10 @@ | |||
#include <Viewer/PUICamera.hxx> | |||
#endif | |||
+#include <Viewer/renderer.hxx> | |||
+#include <Viewer/WindowBuilder.hxx> | |||
+#include <Viewer/WindowSystemAdapter.hxx> | |||
+ | |||
using namespace osg; | |||
using namespace flightgear; | |||
@@ -1104,20 +1113,64 @@ FGRenderer::setEventHandler(FGEventHandler* eventHandler_) | |||
} | |||
void | |||
-FGRenderer::addCamera(osg::Camera* camera, bool useSceneData) | |||
+FGRenderer::addCamera(osg::Camera* camera, bool useSceneData, bool isCanvasCam) | |||
{ | |||
- osg::Camera *guiCamera = getGUICamera(CameraGroup::getDefault()); | |||
- osg::GraphicsContext *gc = guiCamera->getGraphicsContext(); | |||
- camera->setGraphicsContext(gc); | |||
- if (composite_viewer) { | |||
- composite_viewer->getView(0)->addSlave(camera, false); | |||
+ osg::Camera *guiCamera = nullptr; | |||
+ osg::ref_ptr<osg::GraphicsContext> gc = nullptr; | |||
+ guiCamera = getGUICamera(CameraGroup::getDefault()); | |||
+ gc = guiCamera->getGraphicsContext(); | |||
+ if(isCanvasCam) { // we're about to set up a new canvas cam | |||
+ SG_LOG(SG_VIEW, SG_ALERT, "Adding new Canvas Camera"); | |||
+ | |||
+ if (_CanvasGraphicsContext) { // the ctx is already set up | |||
+ SG_LOG(SG_VIEW, SG_ALERT, " [Using exising Canvas pbuffer ctx]"); | |||
+ camera->setGraphicsContext( _CanvasGraphicsContext.get() ); | |||
+ SG_LOG(SG_GENERAL, SG_ALERT, "Canvas Camera GC set up!"); | |||
+ | |||
+ }else { // we don't have a ctx yet, so need to set up a new pbuffer ctx first | |||
+ SG_LOG(SG_VIEW, SG_ALERT, "==> Initial Canvas GraphicsContext Setup (Canvas renders on a separate GL ctx)"); | |||
+ | |||
+ osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; | |||
+ traits->x=0; traits->y=0; | |||
+ traits->width = fgGetInt("/sim/rendering/canvas/ctx-width",1); | |||
+ traits->height = fgGetInt("/sim/rendering/canvas/ctx-height",1); | |||
+ traits->windowDecoration = false; | |||
+ bool useDoubleBuffering = fgGetBool("/sim/rendering/canvas/enable-double-buffering",true); | |||
+ traits->doubleBuffer = useDoubleBuffering; | |||
+ bool useSharedCtx = fgGetBool("/sim/rendering/canvas/enable-shared-ctx",false); | |||
+ traits->sharedContext = (useSharedCtx)?gc:0; //NOTE: By default, we're not using a shared context here, despite being on a separate GL context | |||
+ traits->pbuffer=fgGetBool("/sim/rendering/canvas/enable-pbuffer-ctx",true); | |||
+ | |||
+ traits->readDISPLAY(); | |||
+ traits->setUndefinedScreenDetailsToDefaultScreen(); | |||
+ | |||
+ _CanvasGraphicsContext = osg::GraphicsContext::createGraphicsContext(traits); | |||
+ if(!_CanvasGraphicsContext || !_CanvasGraphicsContext->valid() ) { | |||
+ SG_LOG(SG_GENERAL, SG_ALERT, "Canvas pbuffer GC not valid"); | |||
+ } | |||
+ else { | |||
+ _CanvasGraphicsContext->realize(); | |||
+ _CanvasGraphicsContext->makeCurrent(); | |||
+ camera->setGraphicsContext( _CanvasGraphicsContext.get() ); | |||
+ SG_LOG(SG_GENERAL, SG_ALERT, "Canvas Camera GC set up!"); | |||
+ } // we have a valid ctx | |||
+ } // custom Canvas specific GC | |||
+ } else { | |||
+ SG_LOG(SG_GENERAL, SG_ALERT, "Setting up a non Canvas camera"); | |||
+ camera->setGraphicsContext( gc ); | |||
+ SG_LOG(SG_GENERAL, SG_ALERT, "Camera GC set up!"); | |||
+ } | |||
+ | |||
+ if (composite_viewer) { | |||
+ composite_viewer->getView(0)->addSlave(camera, useSceneData); | |||
+ SG_LOG(SG_GENERAL, SG_ALERT, "Slave cam added to CV viewer"); | |||
} else { | |||
- viewer->addSlave(camera, false); | |||
+ viewer->addSlave(camera, useSceneData); | |||
} | |||
} | |||
void | |||
-FGRenderer::removeCamera(osg::Camera* camera) | |||
+FGRenderer::removeCamera(osg::Camera* camera, bool isCanvasCam) | |||
{ | |||
if (composite_viewer) { | |||
unsigned int index = composite_viewer->getView(0) | |||
diff --git a/src/Viewer/renderer.hxx b/src/Viewer/renderer.hxx | |||
index e87afedae..01ad2c935 100644 | |||
--- a/src/Viewer/renderer.hxx | |||
+++ b/src/Viewer/renderer.hxx | |||
@@ -91,9 +91,9 @@ public: | |||
/** Add a top level camera. | |||
*/ | |||
- void addCamera(osg::Camera* camera, bool useSceneData); | |||
+ void addCamera(osg::Camera* camera, bool useSceneData, bool isCanvasCam=false); | |||
- void removeCamera(osg::Camera* camera); | |||
+ void removeCamera(osg::Camera* camera, bool isCanvasCam = false); | |||
SGSky* getSky() const { return _sky; } | |||
@@ -101,6 +101,7 @@ public: | |||
protected: | |||
int composite_viewer_enabled = -1; | |||
+ osg::ref_ptr<osg::GraphicsContext> _CanvasGraphicsContext; | |||
osg::ref_ptr<osgViewer::Viewer> viewer; | |||
osg::ref_ptr<osgViewer::CompositeViewer> composite_viewer; | |||
osg::ref_ptr<flightgear::FGEventHandler> eventHandler; | |||
diff --git a/src/Viewer/sview.cxx b/src/Viewer/sview.cxx | |||
index 230099311..0c0c8e5a5 100644 | |||
--- a/src/Viewer/sview.cxx | |||
+++ b/src/Viewer/sview.cxx | |||
@@ -1730,7 +1730,7 @@ std::shared_ptr<SviewView> SviewCreate(SGPropertyNode* config) | |||
/* https://www.mail-archive.com/osg-users@lists.openscenegraph.org/msg29820.html | |||
Passing (false, false) here seems to cause a hang on startup. */ | |||
view->getDatabasePager()->setUnrefImageDataAfterApplyPolicy(true, false); | |||
- osg::GraphicsContext::createNewContextID(); | |||
+ //osg::GraphicsContext::createNewContextID(); | |||
osg::Camera* main_camera = main_view->getCamera(); | |||
osg::Camera* camera = view->getCamera(); | |||
</syntaxhighlight> |