gwaldron / osgearth

3D Maps for OpenSceneGraph / C++14
https://www.pelicanmapping.com/home-1/opensource
Other
1.51k stars 780 forks source link

Crashed when trying to get multiview of the earth #2321

Closed iamzheng00 closed 1 year ago

iamzheng00 commented 1 year ago

I tried using slave camera to achieve muiltiview of the earth scene, it worked well in osgEarth3.2, but crashed in osgEarth3.4. And I also tried CompositeViewer as osgearth example did, but in 3.4 version of osgearth, the osgearth_windows example also got crashed... Is that a little bug in 3.4version or need some additional configuration options?

result of running osgearth_version.exe --caps : [osgEarth] [Capabilities] Capabilities: [osgEarth] [Capabilities] osgEarth Version: 3.4.0 build 148 [osgEarth] [Capabilities] OSG Version: 3.6.5 [osgEarth] [Capabilities] GDAL Version: 2.4.4 [osgEarth] [Capabilities] GEOS Version: 3.5.2 [osgEarth] [Capabilities] GPU Vendor: NVIDIA Corporation [osgEarth] [Capabilities] GPU Renderer: NVIDIA GeForce RTX 2080 Ti/PCIe/SSE2 [osgEarth] [Capabilities] GL/Driver Version: 3.3.0 NVIDIA 535.98 (330) [osgEarth] [Capabilities] GL Core Profile: yes

here is my test code of slave cameras:

#include <osgViewer/Viewer>

#include <osgEarth/MapNode>
#include <osgEarth/ModelLayer>
#include <osgEarth/GeoTransform>
#include <osgEarth/Registry>
#include <osgEarth/ShaderGenerator>
#include <osgEarth/Lighting>
#include <osgEarth/Sky>
#include <osgEarthDrivers/sky_simple/SimpleSkyOptions>
#include <osgEarth/EarthManipulator>

#include <osgDB/ReadFile>
#include <osgGA/StateSetManipulator>
#include <osgGA/TrackballManipulator>
#include <osgViewer/ViewerEventHandlers>
#include <stdio.h>
#include <istream>

#include <osg/GraphicsContext>
#include <osgViewer/GraphicsWindow>
#include <osgViewer/api/Win32/GraphicsWindowWin32>

using namespace osgEarth;
using namespace osg;
using namespace osgEarth::Util;
using namespace std;

void CreateMultiView(int width, int height, osgViewer::Viewer* viewer)
{

    int _wnd_width = width;
    int _wnd_height = height;

    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
    traits->x = 100;
    traits->y = 100;
    traits->width = width * 3;
    traits->height = height * 3;
    traits->windowDecoration = true;
    traits->doubleBuffer = true;
    traits->sharedContext = 0;
    //traits->samples = 8;
    //traits->sampleBuffers = 1;
    //traits->readDISPLAY();
    //traits->setUndefinedScreenDetailsToDefaultScreen();

    osg::ref_ptr<GraphicsContext> graphWindow = GraphicsContext::createGraphicsContext(traits.get());

    for (int i = 0; i < 9; i++)
    {
        osg::ref_ptr<osg::Camera> slaveCamera = new osg::Camera;
        slaveCamera->setGraphicsContext(graphWindow.get());
        slaveCamera->setViewport(new osg::Viewport((i % 3) * traits->width / 3.0f, traits->height - traits->height / 3.0f * (int)((i) / 3 + 1), traits->width / 3.0f, traits->height / 3.0f));
        viewer->addSlave(slaveCamera.get());
    }

    viewer->updateSlaves();
}

/**
 * How to create a simple osgEarth map and display it.
 */
int
main(int argc, char** argv)
{
    osgEarth::initialize();
    osgViewer::Viewer* viewer = new osgViewer::Viewer();
    // create the empty map.
    Map* map = new Map();

    MapNode* mapnode = new MapNode(map);
    SkyNode* sky = SkyNode::create();
    sky->attach(viewer->asView());
    Ephemeris* eph = new Ephemeris();
    sky->setEphemeris(eph);
    DateTime dt = DateTime(2022, 3, 8, 5);
    sky->setDateTime(dt);
    sky->setLighting(true);
    sky->setAtmosphereVisible(true);
    sky->addChild(mapnode);
    auto manip = new EarthManipulator();
    viewer->setCameraManipulator(manip);
    viewer->setSceneData(sky);

    // add some stock OSG handlers:
    //MapNodeHelper().configureView(viewer);
    viewer->addEventHandler(new osgViewer::StatsHandler());
    viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));
    viewer->addEventHandler(new osgViewer::ThreadingHandler);
    viewer->addEventHandler(new osgViewer::RecordCameraPathHandler);
    viewer->addEventHandler(new osgViewer::LODScaleHandler);
    viewer->addEventHandler(new osgViewer::ScreenCaptureHandler);

    // load a model
    std::string filepath = R"(D:\test data\redball.obj)";
    auto loadedModel3 = osgDB::readRefNodeFile(filepath);
    Registry::shaderGenerator().run(loadedModel3);
    GeoTransform* gtrans = new GeoTransform();
    GeoPoint geoOrigin(mapnode->getMapSRS(), Vec3d(88, 18, 88));
    gtrans->setTerrain(mapnode->getTerrain());
    gtrans->setPosition(geoOrigin);
    gtrans->addChild(loadedModel3);
    mapnode->addChild(gtrans);

    // set HomeViewpoint
    Viewpoint vp;
    vp.focalPoint() = geoOrigin;
    Angle* a_pitch = new Angle((double)(0 - 90), Units::DEGREES);
    osgEarth::Distance* distrange = new osgEarth::Distance(10000, Units::METERS);
    vp.setPitch(*a_pitch);
    vp.setRange(*distrange);
    auto mp = (osgEarth::EarthManipulator*)viewer->getCameraManipulator();
    mp->setHomeViewpoint(vp, 3);

    viewer->setUpViewInWindow(200, 200, 800, 600);

    // using slave cameras to create a window which splitted into 9 parts
    CreateMultiView(400, 300, viewer);

    viewer->run();

    return 1;
}
gwaldron commented 1 year ago

Do you have a stack trace? I ran this code in the master branch and it didn't crash. It only spit out a GL error.

iamzheng00 commented 1 year ago

Thanks for your reply Glenn! I'll upload a screenshot tomorrow. By the way, I'm using osgearth 3.4 release, and I haven't used the master version yet, and I'll try it tomorrow.

iamzheng00 commented 1 year ago

I have run the code many times, and met 3 situations: VPVO6J9@%0XLJ8Q4O00 PXJ

Sometimes met the following error : K)}TC58QX)Q MOU Q141( M

And sometimes crashed like this: 2C79}3L4A}_26QUI27UJWL if click ignore: X3ZJP VLX1}S_6)@F2X9WFQ

iamzheng00 commented 1 year ago

I have build the master branch and ran my code , got the same result. The osgearth_windowsd.exe crashed as before. @gwaldron 1

gwaldron commented 1 year ago

Can you check whether the CMAKE flag "OSGEARTH_ASSUME_SINGLE_GL_CONTEXT" is set? This was set to ON by mistake (fixed in latest master) and should be OFF. (When it's on, multiple windows do not work propertly.)

iamzheng00 commented 1 year ago

Thanks Glenn ! I'll check that flag and try again

---Original--- From: @.> Date: Fri, Oct 20, 2023 23:14 PM To: @.>; Cc: @.**@.>; Subject: Re: [gwaldron/osgearth] Crashed when trying to get multiview of theearth (Issue #2321)

Can you check whether the CMAKE flag "OSGEARTH_ASSUME_SINGLE_GL_CONTEXT" is set? This was set to ON by mistake (fixed in latest master) and should be OFF. (When it's on, multiple windows do not work propertly.)

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

iamzheng00 commented 1 year ago

I turned off the  flag,  and it solved the problem! Thanks so much , Glenn!

---Original--- From: @.> Date: Fri, Oct 20, 2023 23:14 PM To: @.>; Cc: @.**@.>; Subject: Re: [gwaldron/osgearth] Crashed when trying to get multiview of theearth (Issue #2321)

Can you check whether the CMAKE flag "OSGEARTH_ASSUME_SINGLE_GL_CONTEXT" is set? This was set to ON by mistake (fixed in latest master) and should be OFF. (When it's on, multiple windows do not work propertly.)

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

gwaldron commented 1 year ago

Great. This flag is now off by default in version 3.5.