diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c6c77bba..28747b81 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -85,8 +85,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ${Thirdparty}/spdlog/include ${Thirdparty}/breakpad/include - ${Thirdparty}/3rdParty_x64/include - ${Thirdparty}/OpenSceneGraph-3.6.5/include + ${Thirdparty}/3rdParty/include ${Thirdparty}/TritonSDK/PublicHeaders ${Thirdparty}/matlab/include # ${Thirdparty}/Python39/include @@ -94,8 +93,7 @@ INCLUDE_DIRECTORIES( LINK_DIRECTORIES( ${Thirdparty}/spdlog/lib - ${Thirdparty}/3rdParty_x64/lib - ${Thirdparty}/OpenSceneGraph-3.6.5/lib + ${Thirdparty}/3rdParty/lib ${Thirdparty}/matlab/lib/win64/microsoft ${Thirdparty}/TritonSDK/lib/vc143/x64 # ${Thirdparty}/Python39/libs @@ -167,6 +165,9 @@ target_link_libraries( osgSim osgWidget osgEarth + osgEarthUtil + osgEarthAnnotation + osgEarthTriton Triton-MT-DLL libeng libmx diff --git a/src/common/CrashHandler.cpp b/src/common/CrashHandler.cpp index 19ffadac..f2a3b2af 100644 --- a/src/common/CrashHandler.cpp +++ b/src/common/CrashHandler.cpp @@ -1,5 +1,7 @@ #include "CrashHandler.h" +#if 0 + #include #include #include @@ -110,3 +112,4 @@ void TestCrash() { volatile int* a = (int*)(nullptr); *a = 1; } +#endif diff --git a/src/common/CrashHandler.h b/src/common/CrashHandler.h index d5380a74..c799f6f4 100644 --- a/src/common/CrashHandler.h +++ b/src/common/CrashHandler.h @@ -1,5 +1,6 @@ #pragma once - +#if 0 bool InstallCrashHandler(); -void TestCrash(); \ No newline at end of file +void TestCrash(); +#endif diff --git a/src/main.cpp b/src/main.cpp index 432197f0..2243da86 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,4 @@ -#if 1 +#if 0 #include "app/Application.h" #include "common/SpdLogger.h" @@ -34,139 +34,723 @@ int main(int argc, char* argv[]) { return ret; } #else +// +//#include +// +//#include +//#include +//#include +//#include +// +//const unsigned int MASK_2D = 0xF0000000; +// +//// NOTE: THIS IS JUST A TEMPORARY HACK! :) This functionality will all eventually be +//// encapsulate into another class in osgWidget proper. +//bool scrollWindow(osgWidget::Event& ev) { +// // The first thing we need to do is make sure we have a Frame object... +// osgWidget::Frame* frame = dynamic_cast(ev.getWindow()); +// +// if (!frame) return false; +// +// // And now we need to make sure our Frame has a valid internal EmbeddedWindow widget. +// osgWidget::Window::EmbeddedWindow* ew = +// dynamic_cast(frame->getEmbeddedWindow()) +// ; +// +// if (!ew) return false; +// +// // Lets get the visible area so that we can use it to make sure our scrolling action +// // is necessary in the first place. +// const osgWidget::Quad& va = ew->getWindow()->getVisibleArea(); +// +// // The user wants to scroll up; make sure that the visible area's Y origin isn't already +// // at 0.0f, 0.0f. +// if (ev.getWindowManager()->isMouseScrollingUp() && va[1] != 0.0f) +// ew->getWindow()->addVisibleArea(0, -20) +// ; +// +// else if (va[1] <= (ew->getWindow()->getHeight() - ew->getHeight())) +// ew->getWindow()->addVisibleArea(0, 20) +// ; +// +// // We need to manually call update to make sure the visible area scissoring is done +// // properly. +// frame->update(); +// +// return true; +//} +// +//bool changeTheme(osgWidget::Event& ev) { +// std::string theme; +// +// if (ev.key == osgGA::GUIEventAdapter::KEY_Right) +// theme = "osgWidget/theme-1.png" +// ; +// +// else if (ev.key == osgGA::GUIEventAdapter::KEY_Left) +// theme = "osgWidget/theme-2.png" +// ; +// +// else return false; +// +// osgWidget::Frame* frame = dynamic_cast(ev.getWindow()); +// +// if (!frame) return false; +// +// // This is just one way to access all our Widgets; we could just as well have used: +// // +// // for(osgWidget::Frame::Iterator i = frame.begin(); i != frame.end() i++) {} +// // +// // ...and it have worked, too. +// for (unsigned int row = 0; row < 3; row++) { +// for (unsigned int col = 0; col < 3; col++) { +// frame->getByRowCol(row, col)->setImage(theme); +// } +// } +// +// return true; +//} +// +//int main(int, char**) { +// osgViewer::Viewer viewer; +// +// osgWidget::WindowManager* wm = new osgWidget::WindowManager( +// &viewer, +// 1280.0f, +// 1024.0f, +// MASK_2D, +// osgWidget::WindowManager::WM_PICK_DEBUG +// //osgWidget::WindowManager::WM_NO_INVERT_Y +// ); +// +// std::string baes("D:/Project/DYTSrouce/bin/Release/data/"); +// osgWidget::Frame* frame = osgWidget::Frame::createSimpleFrameFromTheme( +// "frame", +// osgDB::readRefImageFile(baes + "osgWidget/theme.png"), +// 40.0f, +// 40.0f, +// osgWidget::Frame::FRAME_ALL +// ); +// +// frame->getBackground()->setColor(0.0f, 0.0f, 0.0f, 0.0f); +// +// // This is our Transformers box. :) +// osgWidget::Box* box = new osgWidget::Box("images", osgWidget::Box::VERTICAL); +// osgWidget::Widget* img1 = new osgWidget::Widget("im1", 512.0f, 512.0f); +// osgWidget::Widget* img2 = new osgWidget::Widget("im2", 512.0f, 512.0f); +// osgWidget::Widget* img3 = new osgWidget::Widget("im3", 512.0f, 512.0f); +// osgWidget::Widget* img4 = new osgWidget::Widget("im4", 512.0f, 512.0f); +// +// const std::string image1 = "D:/Project/DYTSrouce/bin/Release/resources/northarrow/_n.png"; +// img1->setImage(image1, true); +// img2->setImage(baes + "osgWidget/scrolled2.jpg", true); +// img3->setImage(baes + "osgWidget/scrolled3.jpg", true); +// img4->setImage(baes + "osgWidget/scrolled4.jpg", true); +// +// img1->setMinimumSize(10.0f, 10.0f); +// img2->setMinimumSize(10.0f, 10.0f); +// img3->setMinimumSize(10.0f, 10.0f); +// img4->setMinimumSize(10.0f, 10.0f); +// +// box->addWidget(img1); +// box->addWidget(img2); +// box->addWidget(img3); +// box->addWidget(img4); +// box->setEventMask(osgWidget::EVENT_NONE); +// +// //frame->getEmbeddedWindow()->setWindow(box); +// frame->setWindow(box); +// frame->getEmbeddedWindow()->setColor(1.0f, 1.0f, 1.0f, 1.0f); +// frame->resize(300.0f, 300.0f); +// frame->addCallback(new osgWidget::Callback(&scrollWindow, osgWidget::EVENT_MOUSE_SCROLL)); +// frame->addCallback(new osgWidget::Callback(&changeTheme, osgWidget::EVENT_KEY_DOWN)); +// +// wm->addChild(frame); +// +// return osgWidget::createExample(viewer, wm); +//} +#ifdef QT_VERSION +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +//#include -#include -#include -#include -#include +#include +#include +#include "viewer/OSGEnv.h" -const unsigned int MASK_2D = 0xF0000000; +class QtOSGWidget : public QOpenGLWidget { +public: + QtOSGWidget(qreal scaleX, qreal scaleY, QWidget* parent = 0) + : QOpenGLWidget(parent) + //, _mGraphicsWindow(new osgViewer::GraphicsWindowEmbedded(this->x(), this->y(), + //this->width(), this->height())) + , _mViewer(new osgViewer::Viewer) + , m_scaleX(scaleX) + , m_scaleY(scaleY) { -// NOTE: THIS IS JUST A TEMPORARY HACK! :) This functionality will all eventually be -// encapsulate into another class in osgWidget proper. -bool scrollWindow(osgWidget::Event& ev) { - // The first thing we need to do is make sure we have a Frame object... - osgWidget::Frame* frame = dynamic_cast(ev.getWindow()); + osg::ref_ptr ds = osg::DisplaySettings::instance(); + osg::ref_ptr traits + = new osg::GraphicsContext::Traits(ds); + traits->x = 0; + traits->y = 0; + traits->width = width(); + traits->height = height(); + traits->alpha = ds->getMinimumNumAlphaBits(); + traits->stencil = ds->getMinimumNumStencilBits(); + traits->sampleBuffers = ds->getMultiSamples(); + traits->samples = ds->getNumMultiSamples(); + traits->windowDecoration = false; + traits->doubleBuffer = true; + traits->sharedContext = nullptr; + traits->setInheritedWindowPixelFormat = true; - if (!frame) return false; + //_mGraphicsWindow = new osgViewer::GraphicsWindowEmbedded(0, 0, width(), height()); + _mGraphicsWindow = new osgViewer::GraphicsWindowEmbedded(traits); - // And now we need to make sure our Frame has a valid internal EmbeddedWindow widget. - osgWidget::Window::EmbeddedWindow* ew = - dynamic_cast(frame->getEmbeddedWindow()) - ; + //osg::Cylinder* cylinder = new osg::Cylinder(osg::Vec3(0.f, 0.f, 0.f), 0.25f, 0.5f); + //osg::ShapeDrawable* sd = new osg::ShapeDrawable(cylinder); + //sd->setColor(osg::Vec4(0.8f, 0.5f, 0.2f, 1.f)); + //osg::Geode* geode = new osg::Geode; + //geode->addDrawable(sd); - if (!ew) return false; + osg::ref_ptr node = osgDB::readNodeFile("D:/Project/DYT/Tool/TritonSample/TritonSample/triton.earth"); + if (!node.valid()) + return ; - // Lets get the visible area so that we can use it to make sure our scrolling action - // is necessary in the first place. - const osgWidget::Quad& va = ew->getWindow()->getVisibleArea(); + // If the node doesn't contain a MapNode (earth file), bail out: + auto mapNode = osgEarth::MapNode::get(node); + if (!mapNode) + return ; - // The user wants to scroll up; make sure that the visible area's Y origin isn't already - // at 0.0f, 0.0f. - if (ev.getWindowManager()->isMouseScrollingUp() && va[1] != 0.0f) - ew->getWindow()->addVisibleArea(0, -20) - ; - else if (va[1] <= (ew->getWindow()->getHeight() - ew->getHeight())) - ew->getWindow()->addVisibleArea(0, 20) - ; - // We need to manually call update to make sure the visible area scissoring is done - // properly. - frame->update(); + auto sky = osgEarth::Util::SkyNode::create(); + //auto parent = mapNode->getParent(0); + sky->addChild(mapNode); + //parent->addChild(sky); + //parent->removeChild(mapNode); - return true; -} -bool changeTheme(osgWidget::Event& ev) { - std::string theme; + sky->setAtmosphereVisible(true); + sky->setSunVisible(true); + sky->setMoonVisible(true); + sky->setStarsVisible(true); - if (ev.key == osgGA::GUIEventAdapter::KEY_Right) - theme = "osgWidget/theme-1.png" - ; + sky->setDateTime(osgEarth::DateTime(2024, 12, 24, 6)); + //sky->setSimulationTimeTracksDateTime(true); - else if (ev.key == osgGA::GUIEventAdapter::KEY_Left) - theme = "osgWidget/theme-2.png" - ; + - else return false; +//#ifndef OSG_GL3_AVAILABLE +// // If your OSG is build with a GL2 profile, install our custom realize op +// // to get all the shaders working: +// _mViewer->setRealizeOperation(new osgEarth::GL3RealizeOperation()); +//#endif +// _mViewer->realize(); +// +// +// _mViewer->setCameraManipulator(new osgEarth::Util::EarthManipulator()); - osgWidget::Frame* frame = dynamic_cast(ev.getWindow()); + osg::Camera* camera = new osg::Camera; + camera->setViewport(0, 0, this->width(), this->height()); + //camera->setClearColor(osg::Vec4(0.9f, 0.9f, 1.f, 1.f)); + float aspectRatio = static_cast(this->width()) / static_cast(this->height()); + camera->setProjectionMatrixAsPerspective(30.f, aspectRatio, 1.f, 1000.f); + camera->setGraphicsContext(_mGraphicsWindow); - if (!frame) return false; + _mViewer->setCamera(camera); + //_mViewer->setSceneData(geode); + _mViewer->setSceneData(sky); + sky->attach(_mViewer); + osgGA::TrackballManipulator* manipulator = new osgGA::TrackballManipulator; + manipulator->setAllowThrow(false); + this->setMouseTracking(true); + _mViewer->setCameraManipulator(manipulator); - // This is just one way to access all our Widgets; we could just as well have used: - // - // for(osgWidget::Frame::Iterator i = frame.begin(); i != frame.end() i++) {} - // - // ...and it have worked, too. - for (unsigned int row = 0; row < 3; row++) { - for (unsigned int col = 0; col < 3; col++) { - frame->getByRowCol(row, col)->setImage(theme); - } + _mViewer->getDatabasePager()->setUnrefImageDataAfterApplyPolicy(true, false); + //_mViewer->setThreadingModel(osgViewer::Viewer::SingleThreaded); + //_mViewer->setRealizeOperation(new osgEarth::GL3RealizeOperation()); + //_mViewer->realize(); } - return true; -} -int main(int, char**) { - osgViewer::Viewer viewer; + virtual ~QtOSGWidget() {} - osgWidget::WindowManager* wm = new osgWidget::WindowManager( - &viewer, - 1280.0f, - 1024.0f, - MASK_2D, - osgWidget::WindowManager::WM_PICK_DEBUG - //osgWidget::WindowManager::WM_NO_INVERT_Y - ); + void setScale(qreal X, qreal Y) { + m_scaleX = X; + m_scaleY = Y; + this->resizeGL(this->width(), this->height()); + } - std::string baes("D:/Project/DYTSrouce/bin/Release/data/"); - osgWidget::Frame* frame = osgWidget::Frame::createSimpleFrameFromTheme( - "frame", - osgDB::readRefImageFile(baes + "osgWidget/theme.png"), - 40.0f, - 40.0f, - osgWidget::Frame::FRAME_ALL - ); +protected: - frame->getBackground()->setColor(0.0f, 0.0f, 0.0f, 0.0f); + virtual void paintGL() { + _mViewer->frame(); + } - // This is our Transformers box. :) - osgWidget::Box* box = new osgWidget::Box("images", osgWidget::Box::VERTICAL); - osgWidget::Widget* img1 = new osgWidget::Widget("im1", 512.0f, 512.0f); - osgWidget::Widget* img2 = new osgWidget::Widget("im2", 512.0f, 512.0f); - osgWidget::Widget* img3 = new osgWidget::Widget("im3", 512.0f, 512.0f); - osgWidget::Widget* img4 = new osgWidget::Widget("im4", 512.0f, 512.0f); + virtual void resizeGL(int width, int height) { + this->getEventQueue()->windowResize(this->x() * m_scaleX, this->y() * m_scaleY, width * m_scaleX, height * m_scaleY); + _mGraphicsWindow->resized(this->x() * m_scaleX, this->y() * m_scaleY, width * m_scaleX, height * m_scaleY); + osg::Camera* camera = _mViewer->getCamera(); + camera->setViewport(0, 0, this->width() * m_scaleX, this->height() * m_scaleY); + } - const std::string image1 = "D:/Project/DYTSrouce/bin/Release/resources/northarrow/_n.png"; - img1->setImage(image1, true); - img2->setImage(baes + "osgWidget/scrolled2.jpg", true); - img3->setImage(baes + "osgWidget/scrolled3.jpg", true); - img4->setImage(baes + "osgWidget/scrolled4.jpg", true); + virtual void initializeGL() { + //osg::Geode* geode = dynamic_cast(_mViewer->getSceneData()); + //osg::StateSet* stateSet = geode->getOrCreateStateSet(); + //osg::Material* material = new osg::Material; + //material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); + //stateSet->setAttributeAndModes(material, osg::StateAttribute::ON); + //stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON); - img1->setMinimumSize(10.0f, 10.0f); - img2->setMinimumSize(10.0f, 10.0f); - img3->setMinimumSize(10.0f, 10.0f); - img4->setMinimumSize(10.0f, 10.0f); +// osg::ref_ptr node = osgDB::readNodeFile("D:/Project/DYT/Tool/TritonSample/TritonSample/triton.earth"); +// if (!node.valid()) +// return ; +// +// // If the node doesn't contain a MapNode (earth file), bail out: +// auto mapNode = osgEarth::MapNode::get(node); +// if (!mapNode) +// return ; +// +// +// +// auto sky = osgEarth::SkyNode::create(); +// //auto parent = mapNode->getParent(0); +// sky->addChild(mapNode); +// //parent->addChild(sky); +// //parent->removeChild(mapNode); +// +// +// sky->setAtmosphereVisible(true); +// sky->setSunVisible(true); +// sky->setMoonVisible(true); +// sky->setStarsVisible(true); +// +// sky->setDateTime(osgEarth::DateTime(2024, 12, 24, 6)); +// sky->setSimulationTimeTracksDateTime(true); +// +// _mViewer->setSceneData(sky); +// +//#ifndef OSG_GL3_AVAILABLE +// // If your OSG is build with a GL2 profile, install our custom realize op +// // to get all the shaders working: +// _mViewer->setRealizeOperation(new osgEarth::GL3RealizeOperation()); +//#endif +// _mViewer->realize(); +// +// +// _mViewer->setCameraManipulator(new osgEarth::Util::EarthManipulator()); + } - box->addWidget(img1); - box->addWidget(img2); - box->addWidget(img3); - box->addWidget(img4); - box->setEventMask(osgWidget::EVENT_NONE); + virtual void mouseMoveEvent(QMouseEvent* event) { + this->getEventQueue()->mouseMotion(event->x() * m_scaleX, event->y() * m_scaleY); + } - //frame->getEmbeddedWindow()->setWindow(box); - frame->setWindow(box); - frame->getEmbeddedWindow()->setColor(1.0f, 1.0f, 1.0f, 1.0f); - frame->resize(300.0f, 300.0f); - frame->addCallback(new osgWidget::Callback(&scrollWindow, osgWidget::EVENT_MOUSE_SCROLL)); - frame->addCallback(new osgWidget::Callback(&changeTheme, osgWidget::EVENT_KEY_DOWN)); + virtual void mousePressEvent(QMouseEvent* event) { + unsigned int button = 0; + switch (event->button()) { + case Qt::LeftButton: + button = 1; + break; + case Qt::MiddleButton: + button = 2; + break; + case Qt::RightButton: + button = 3; + break; + default: + break; + } + this->getEventQueue()->mouseButtonPress(event->x() * m_scaleX, event->y() * m_scaleY, button); + } - wm->addChild(frame); + virtual void mouseReleaseEvent(QMouseEvent* event) { + unsigned int button = 0; + switch (event->button()) { + case Qt::LeftButton: + button = 1; + break; + case Qt::MiddleButton: + button = 2; + break; + case Qt::RightButton: + button = 3; + break; + default: + break; + } + this->getEventQueue()->mouseButtonRelease(event->x() * m_scaleX, event->y() * m_scaleY, button); + } - return osgWidget::createExample(viewer, wm); + virtual void wheelEvent(QWheelEvent* event) { + int delta = event->delta(); + osgGA::GUIEventAdapter::ScrollingMotion motion = delta > 0 ? + osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN; + this->getEventQueue()->mouseScroll(motion); + } + + virtual bool event(QEvent* event) { + bool handled = QOpenGLWidget::event(event); + this->update(); + return handled; + } + +private: + + osgGA::EventQueue* getEventQueue() const { + osgGA::EventQueue* eventQueue = _mGraphicsWindow->getEventQueue(); + return eventQueue; + } + + osg::ref_ptr _mGraphicsWindow; + osg::ref_ptr _mViewer; + qreal m_scaleX, m_scaleY; +}; + +int main(int argc, char** argv) { + QApplication qapp(argc, argv); + OSGEnv::init(); + + QMainWindow window; + QtOSGWidget* widget = new QtOSGWidget(1, 1, &window); + window.setCentralWidget(widget); + window.show(); + + return qapp.exec(); +} +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LC "[osgearth_triton] " + +using namespace osgEarth; +using namespace osgEarth::Util; +using namespace osgEarth::Triton; +using namespace osgEarth::Annotation; +namespace ui = osgEarth::Util::Controls; + +struct Settings { + optional chop; + optional seaState; + optional alpha; + osg::observer_ptr tritonLayer; + + void apply(Environment& env, Ocean& ocean) { + if (chop.isSet()) { + ocean.SetChoppiness(chop.get()); + chop.clear(); + } + + if (seaState.isSet()) { + env.SimulateSeaState(seaState.get(), 0.0); + seaState.clear(); + } + + osg::ref_ptr layer; + if (alpha.isSet() && tritonLayer.lock(layer)) { + layer->setOpacity(alpha.value()); + alpha.clear(); + } + } +}; + +class TritonCallback : public osgEarth::Triton::Callback { +public: + TritonCallback(Settings& settings) : _settings(settings) {} + + void onInitialize(Environment& env, Ocean& ocean) { + //todo + } + + void onDrawOcean(Environment& env, Ocean& ocean) { + _settings.apply(env, ocean); + } + + Settings& _settings; +}; + + +struct App { + App() { + tritonLayer = NULL; + map = NULL; + const double lon = -118.5406, lat = 32.7838; + + anchor.set( + SpatialReference::get("wgs84"), lon, lat, 0.0, + ALTMODE_ABSOLUTE); + + isect = new Triton::TritonIntersections(); + } + + Map* map; + TritonLayer* tritonLayer; + Settings settings; + osg::ref_ptr isect; + AnnotationLayer* labels; + AnnotationLayer* normals; + LineDrawable* normalDrawable; + GeoPoint anchor; + + void addTriton() { + // Create TritonNode from TritonOptions + osgEarth::Triton::TritonOptions tritonOptions; + tritonOptions.user() = "my_user_name"; + tritonOptions.licenseCode() = "my_license_code"; + tritonOptions.maxAltitude() = 100000; + tritonOptions.useHeightMap() = true; + + const char* ev_t = ::getenv("TRITON_PATH"); + if (ev_t) { + tritonOptions.resourcePath() = osgDB::concatPaths( + std::string(ev_t), + "Resources"); + + OE_INFO << LC + << "Setting resource path to << " << tritonOptions.resourcePath().get() + << std::endl; + } else { + OE_WARN << LC + << "No resource path! Triton might not initialize properly. " + << "Consider setting the TRITON_PATH environment variable." + << std::endl; + } + + + tritonLayer = new TritonLayer(tritonOptions, new TritonCallback(settings)); + map->addLayer(tritonLayer); + settings.tritonLayer = tritonLayer; + + tritonLayer->addIntersections(isect.get()); + } + + void removeTriton() { + if (tritonLayer) + map->removeLayer(tritonLayer); + tritonLayer = 0L; + } + + void addBuoyancyTest(osg::Node* model) { + //labels = new AnnotationLayer(); + //map->addLayer(labels); + + normals = new AnnotationLayer(); + map->addLayer(normals); + + // geometry for a unit normal vector + normalDrawable = new LineDrawable(GL_LINES); + normalDrawable->setColor(osg::Vec4(1, 1, 0, 1)); + normalDrawable->pushVertex(osg::Vec3(0, 0, 0)); + normalDrawable->pushVertex(osg::Vec3(0, 0, 10)); + normalDrawable->pushVertex(osg::Vec3(-2, 0, 0.5)); + normalDrawable->pushVertex(osg::Vec3(2, 0, 0.5)); + normalDrawable->pushVertex(osg::Vec3(0, -2, 0.5)); + normalDrawable->pushVertex(osg::Vec3(0, 2, 0.5)); + normalDrawable->finish(); + + // a single shared anchor point for the intersection set: + isect->setAnchor(anchor); + + // generate a bunch of local points around the anchor: + for (int x = -50; x <= 50; x += 25) { + for (int y = -50; y <= 50; y += 25) { + isect->addLocalPoint(osg::Vec3d(x, y, 0)); + + // a label communicating the wave height: + //PlaceNode* label = new PlaceNode(); + //label->setDynamic(true); + //label->setPosition(anchor); + //label->setIconImage(image); + //label->setText("-"); + //labels->getGroup()->addChild(label); + + // a normal vector and optional model: + GeoPositionNode* normal = new GeoPositionNode(); + normal->setDynamic(true); + normal->getPositionAttitudeTransform()->addChild(normalDrawable); + if (model) + normal->getPositionAttitudeTransform()->addChild(model); + normal->setPosition(anchor); + normals->getGroup()->addChild(normal); + } + } + + //ScreenSpaceLayout::setDeclutteringEnabled(false); + } + + void updateBuoyancyTest() { + for (unsigned i = 0; i < isect->getHeights().size(); ++i) { + osg::Vec3d local = isect->getInput()[i]; + local.z() = isect->getHeights()[i]; + + //PlaceNode* label = dynamic_cast(labels->getGroup()->getChild(i)); + //label->getPositionAttitudeTransform()->setPosition(local); + //label->setText(Stringify()<(normals->getGroup()->getChild(i)); + normalNode->getPositionAttitudeTransform()->setPosition(local); + osg::Quat q; + q.makeRotate(osg::Vec3d(0, 0, 1), isect->getNormals()[i]); + normalNode->getPositionAttitudeTransform()->setAttitude(q); + } + } +}; + +App s_app; + + + +template struct Set : public ui::ControlEventHandler { + optional& _var; + Set(optional& var) : _var(var) {} + void onValueChanged(ui::Control*, double value) { + _var = value; + } +}; + +struct Toggle : public ui::ControlEventHandler { + void onValueChanged(ui::Control*, bool value) { + if (s_app.tritonLayer) + s_app.removeTriton(); + else + s_app.addTriton(); + } +}; + +Container* createUI() { + VBox* box = new VBox(); + box->setBackColor(0, 0, 0, 0.5); + Grid* grid = box->addControl(new Grid()); + int r = 0; + grid->setControl(0, r, new LabelControl("Chop")); + grid->setControl(1, r, new HSliderControl(0, 3, 0, new Set(s_app.settings.chop))); + ++r; + grid->setControl(0, r, new LabelControl("Sea State")); + grid->setControl(1, r, new HSliderControl(0, 12, 5, new Set(s_app.settings.seaState))); + ++r; + grid->setControl(0, r, new LabelControl("Alpha")); + grid->setControl(1, r, new HSliderControl(0, 1.0, 1.0, new Set(s_app.settings.alpha))); + ++r; + grid->setControl(0, r, new LabelControl("Toggle")); + grid->setControl(1, r, new CheckBoxControl(true, new Toggle())); + + grid->getControl(1, r - 1)->setHorizFill(true, 200); + + return box; +} + + +int +usage(const char* name) { + OE_DEBUG + << "\nUsage: " << name << " file.earth" << std::endl + << osgEarth::Util::MapNodeHelper().usage() << std::endl; + + return 0; +} + +int +main(int argc, char** argv) { + osg::ArgumentParser arguments(&argc, argv); + + // help? + if (arguments.read("--help")) + return usage(argv[0]); + + //osg::Node* model = 0L; + std::string filename = "D:/Project/DYT/Tool/TritonSample/TritonSample/triton.earth"; + osg::ref_ptr node = osgDB::readNodeFile(filename); + //if (arguments.read("--model", filename)) { + // model = osgDB::readRefNodeFile(filename).release(); + // Registry::shaderGenerator().run(model); + //} + osg::ref_ptr mapNode = MapNode::get(node.get()); + + + // create a viewer: + osgViewer::Viewer viewer(arguments); + + // Tell the database pager to not modify the unref settings + viewer.getDatabasePager()->setUnrefImageDataAfterApplyPolicy(false, false); + + // install our default manipulator (do this before calling load) + EarthManipulator* manip = new EarthManipulator(); + viewer.setCameraManipulator(manip); + + // load an earth file, and support all or our example command-line options + // and earth file tags + //osg::Group* node = osgEarth::Util::MapNodeHelper().load(arguments, &viewer, createUI()); + osg::Group* root = new osg::Group(); + root->addChild(node); + if (root) { + viewer.getCamera()->setNearFarRatio(0.00002); + viewer.getCamera()->setSmallFeatureCullingPixelSize(-1.0f); + + viewer.setSceneData(node); + + s_app.map = MapNode::get(node)->getMap(); + + s_app.addTriton(); + //s_app.addBuoyancyTest(model); + + // Zoom the camera to our area of interest: + Viewpoint vp; + vp.heading() = 25.0f; + vp.pitch() = -25; + vp.range() = 400.0; + vp.focalPoint() = s_app.anchor; + manip->setViewpoint(vp); + +#ifdef OSG_GL3_AVAILABLE + if (viewer) { + viewer->setRealizeOperation(new GL3RealizeOperation()); + } +#endif + + while (!viewer.done()) { + viewer.frame(); + s_app.updateBuoyancyTest(); + } + } else { + return usage(argv[0]); + } } #endif diff --git a/src/scene/OEScene.cpp b/src/scene/OEScene.cpp index 72088764..719ae8a4 100644 --- a/src/scene/OEScene.cpp +++ b/src/scene/OEScene.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include @@ -76,7 +76,7 @@ void OEScene::AttachView(osgViewer::Viewer* view) { dyt_check(nullptr != g_srs_); } - skyDome_ = osgEarth::SkyNode::create(); + skyDome_ = osgEarth::Util::SkyNode::create(); if (!earthMapNode_) { LOG_WARN("eart map node is nullptr"); return; @@ -106,7 +106,7 @@ void OEScene::AttachView(osgViewer::Viewer* view) { skyDome_->setStarsVisible(true); skyDome_->setDateTime(osgEarth::DateTime(2024, 12, 24, 3)); - skyDome_->setSimulationTimeTracksDateTime(true); + //skyDome_->setSimulationTimeTracksDateTime(true); logarithmicDepthBuffer_->install(view->getCamera()); } diff --git a/src/scene/OEScene.h b/src/scene/OEScene.h index b87ba5f8..e5e02df8 100644 --- a/src/scene/OEScene.h +++ b/src/scene/OEScene.h @@ -4,9 +4,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include //#include "scene/SkyDome.h" @@ -52,7 +52,7 @@ private: osg::ref_ptr earthRootNode_; osg::ref_ptr earthMapNode_; osg::ref_ptr entityRoot_; - osg::ref_ptr skyDome_; + osg::ref_ptr skyDome_; std::unique_ptr logarithmicDepthBuffer_; osg::ref_ptr sceneUI_; }; diff --git a/src/scene/TritonAPIWrapper.cpp b/src/scene/TritonAPIWrapper.cpp deleted file mode 100644 index 73e24fef..00000000 --- a/src/scene/TritonAPIWrapper.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* -*-c++-*- */ -/* osgEarth - Geospatial SDK for OpenSceneGraph - * Copyright 2020 Pelican Mapping - * http://osgearth.org - * - * osgEarth is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - */ -#include "TritonAPIWrapper.h" -#include - -#define LC "[TritonAPI] " - -using namespace osgEarth::Triton; - -#define SETGET_EXPLICIT(NS, SETTER, GETTER, TYPE) \ - void NS :: SETTER (TYPE value) { HANDLE-> SETTER (value); } \ - TYPE NS :: GETTER () const { return HANDLE -> GETTER (); } - -#define SETGET(NS, FUNC, TYPE) \ - SETGET_EXPLICIT(NS, Set##FUNC, Get##FUNC, TYPE) - -#define TOVEC3(X) ::Triton::Vector3(X.x(),X.y(),X.z()) -#define FROMVEC3(X) osg::Vec3(X.x,X.y,X.z) - -//................................ -#undef HANDLE -#define HANDLE ((::Triton::BreakingWavesParameters*)_handle) - -SETGET(BreakingWavesParameters, Steepness, float); -SETGET(BreakingWavesParameters, Wavelength, float); - -//................................ -#undef HANDLE -#define HANDLE ((::Triton::Environment*)_handle) - -BreakingWavesParameters Environment::GetBreakingWavesParameters() const { - return BreakingWavesParameters((uintptr_t)&HANDLE->GetBreakingWavesParameters()); -} -void Environment::SetDirectionalLight(const osg::Vec3& dir, const osg::Vec3& color) { - HANDLE->SetDirectionalLight(TOVEC3(dir), TOVEC3(color)); -} -osg::Vec3 Environment::GetLightDirection() const { - const ::Triton::Vector3& v = HANDLE->GetLightDirection(); - return FROMVEC3(v); -} -osg::Vec3 Environment::GetDirectionalLightColor() const { - const ::Triton::Vector3& v = HANDLE->GetDirectionalLightColor(); - return FROMVEC3(v); -} -void Environment::SetAmbientLight(const osg::Vec3& color) { - HANDLE->SetAmbientLight(TOVEC3(color)); -} -osg::Vec3 Environment::GetAmbientLightColor() const { - const ::Triton::Vector3& v = HANDLE->GetAmbientLightColor(); - return FROMVEC3(v); -} -void Environment::SimulateSeaState(double bscale, double winddir) { - HANDLE->SimulateSeaState(bscale, winddir); -} -void Environment::SetAboveWaterVisibility(double visibility, osg::Vec3 fog_color) { - HANDLE->SetAboveWaterVisibility(visibility, TOVEC3(fog_color)); -} -void Environment::GetAboveWaterVisibility(double &visibility, osg::Vec3 &fog_color) const { - ::Triton::Vector3 triton_fog_col; - HANDLE->GetAboveWaterVisibility(visibility, triton_fog_col); - fog_color = FROMVEC3(triton_fog_col); -} -void Environment::SetEnvironmentMap(GLuint cubeMap, const osg::Matrixd &textureMatrix) { - ::Triton::Matrix3 triton_tex_mat( - textureMatrix(0, 0), textureMatrix(0, 1), textureMatrix(0, 2), - textureMatrix(1, 0), textureMatrix(1, 1), textureMatrix(1, 2), - textureMatrix(2, 0), textureMatrix(2, 1), textureMatrix(2, 2)); - ::Triton::TextureHandle tex_handle = (::Triton::TextureHandle)(static_cast(cubeMap)); - HANDLE->SetEnvironmentMap(tex_handle, triton_tex_mat); -} -GLuint Environment::GetEnvironmentMap() const { - ::Triton::TextureHandle tex_handle = HANDLE->GetEnvironmentMap(); - return static_cast((size_t)tex_handle); -} -osg::Matrixd Environment::GetEnvironmentMapMatrix() const { - ::Triton::Matrix3 m = HANDLE->GetEnvironmentMapMatrix(); - osg::Matrixd env_map_matrix( - m.elem[0][0], m.elem[0][1], m.elem[0][2], 0, - m.elem[1][0], m.elem[1][1], m.elem[1][2], 0, - m.elem[2][0], m.elem[2][1], m.elem[2][2], 0, - 0, 0, 0, 1); - return env_map_matrix; -} -SETGET(Environment, SunIntensity, float); - -//................................ -#undef HANDLE -#define HANDLE ((::Triton::Ocean*)_handle) - -SETGET(Ocean, Choppiness, float); -//SETGET(Ocean, MaximumWavePeriod, double); -SETGET_EXPLICIT(Ocean, EnableSpray, SprayEnabled, bool); -SETGET_EXPLICIT(Ocean, EnableGodRays, GodRaysEnabled, bool); -SETGET(Ocean, GodRaysFade, float); - -void Ocean::EnableWireframe(bool wireframe) { HANDLE->EnableWireframe(wireframe); } -void Ocean::SetQuality(OceanQuality value) { HANDLE->SetQuality((::Triton::OceanQuality)value); } -OceanQuality Ocean::GetQuality() const { return (OceanQuality)HANDLE->GetQuality(); } diff --git a/src/scene/TritonAPIWrapper.h b/src/scene/TritonAPIWrapper.h deleted file mode 100644 index f1921ad6..00000000 --- a/src/scene/TritonAPIWrapper.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -*-c++-*- */ -/* osgEarth - Geospatial SDK for OpenSceneGraph - * Copyright 2020 Pelican Mapping - * http://osgearth.org - * - * osgEarth is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - */ -#ifndef OSGEARTH_TRITON_API_WRAPPER -#define OSGEARTH_TRITON_API_WRAPPER 1 - -//#include "Common" -#include -#include -#include -#include // for uintptr_t - -namespace osgEarth { - namespace Util { - class OceanNode; - } -} - -namespace osgEarth { namespace Triton -{ - /** Enumerates the ocean quality settings used in Ocean::SetQuality() */ - enum OceanQuality { - GOOD, - BETTER, - BEST - }; - - class BreakingWavesParameters - { - public: - void SetSteepness(float); - float GetSteepness() const; - - void SetWavelength(float); - float GetWavelength() const; - - public: - BreakingWavesParameters(uintptr_t handle) : _handle(handle) { } - uintptr_t _handle; - }; - - class Environment - { - public: - void SetDirectionalLight(const osg::Vec3& dir, const osg::Vec3& color); - osg::Vec3 GetLightDirection() const; - osg::Vec3 GetDirectionalLightColor() const; - - void SetAmbientLight(const osg::Vec3& color); - osg::Vec3 GetAmbientLightColor() const; - - void SetSunIntensity(float intensity); - float GetSunIntensity() const; - - BreakingWavesParameters GetBreakingWavesParameters() const; - - void SimulateSeaState(double bs, double winddir); - - void SetAboveWaterVisibility(double visibility, osg::Vec3 fog_color); - void GetAboveWaterVisibility(double &visibility, osg::Vec3 &fog_color) const; - - void SetEnvironmentMap(GLuint id, const osg::Matrixd &textureMatrix = osg::Matrixd()); - GLuint GetEnvironmentMap() const; - osg::Matrixd GetEnvironmentMapMatrix() const; - public: - Environment(uintptr_t handle) : _handle(handle) { } - uintptr_t _handle; - }; - - class Ocean - { - public: - void SetChoppiness(float); - float GetChoppiness() const; - - void EnableWireframe(bool wireframe); - - void SetQuality(OceanQuality value); - OceanQuality GetQuality() const; - - void EnableSpray(bool enabled); - bool SprayEnabled() const; - - void EnableGodRays(bool enabled); - bool GodRaysEnabled() const; - - void SetGodRaysFade(float fadeAmount); - float GetGodRaysFade() const; - - public: - Ocean(uintptr_t handle) : _handle(handle) { } - uintptr_t _handle; - }; - -} } // namespace osgEarth::SilverLining - -#endif // OSGEARTH_TRITON_API_WRAPPER diff --git a/src/scene/TritonCallback.h b/src/scene/TritonCallback.h deleted file mode 100644 index 122aa23c..00000000 --- a/src/scene/TritonCallback.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*-c++-*- */ -/* osgEarth - Geospatial SDK for OpenSceneGraph - * Copyright 2020 Pelican Mapping - * http://osgearth.org - * - * osgEarth is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - */ -#ifndef OSGEARTH_TRITON_CALLBACK_H -#define OSGEARTH_TRITON_CALLBACK_H 1 - -#include "TritonAPIWrapper.h" - -namespace osgEarth { namespace Triton -{ - /** - * A callback that lets you execute code in the proper context. - */ - class Callback : public osg::Referenced - { - public: - virtual void onInitialize(Environment& env, Ocean& ocean) { } - - virtual void onDrawOcean(Environment& env, Ocean& ocean) { } - }; - -} } // namespace osgEarth::Triton - -#endif // OSGEARTH_TRITON_CALLBACK_H diff --git a/src/scene/TritonContext.cpp b/src/scene/TritonContext.cpp deleted file mode 100644 index f6edc18a..00000000 --- a/src/scene/TritonContext.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* -*-c++-*- */ -/* osgEarth - Geospatial SDK for OpenSceneGraph - * Copyright 2020 Pelican Mapping - * http://osgearth.org - * - * osgEarth is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - */ -#include "TritonContext.h" -#include -#include -#include -#include -#include -#include - -#define LC "[TritonContext] " - -using namespace osgEarth::Triton; - - -TritonContext::TritonContext(const TritonLayer::Options& options) : -_options ( options ), -_initAttempted ( false ), -_initFailed ( false ), -_resourceLoader ( 0L ), -_environment ( 0L ), -_environmentWrapper ( 0L ), -_ocean ( 0L ), -_oceanWrapper ( 0L ) -{ - //nop -} - -TritonContext::~TritonContext() -{ - if (_oceanWrapper) - delete _oceanWrapper; - - if (_environmentWrapper) - delete _environmentWrapper; -} - -void -TritonContext::setSRS(const osgEarth::SpatialReference* srs) -{ - _srs = srs; -} - -void -TritonContext::setCallback(Callback* callback) -{ - _callback = callback; -} - -bool -TritonContext::passHeightMapToTriton() const -{ - return _options.useHeightMap() == true; -} - -int -TritonContext::getHeightMapSize() const -{ - return osg::clampBetween(_options.heightMapSize().get(), 64u, 2048u); -} - -const std::string& -TritonContext::getMaskLayerName() const -{ - return _options.maskLayer().externalLayerName().get(); -} - -void -TritonContext::initialize(osg::RenderInfo& renderInfo) -{ - if ( !_initAttempted && !_initFailed ) - { - // lock/double-check: - std::lock_guard excl(_initMutex); - if ( !_initAttempted && !_initFailed ) - { - _initAttempted = true; - - std::string resourcePath = _options.resourcePath().get(); - if (resourcePath.empty() && ::getenv("TRITON_PATH")) - { - resourcePath = osgDB::concatPaths(::getenv("TRITON_PATH"), "Resources"); - } - - if ( resourcePath.empty() ) - { - const QString dir = QString("%1/TritonResources").arg(QApplication::applicationDirPath()); - resourcePath = dir.toStdString(); - } - - _resourceLoader = new ::Triton::ResourceLoader(resourcePath.c_str()); - - _environment = new ::Triton::Environment(); - - _environmentWrapper = new Environment((uintptr_t)_environment); - - _environment->SetLicenseCode( - _options.user()->c_str(), - _options.licenseCode()->c_str() ); - - // "WGS84" is used to represent any ellipsoid. - ::Triton::CoordinateSystem cs = - _srs->isGeographic() ? ::Triton::WGS84_ZUP : - ::Triton::FLAT_ZUP; - - // Set the ellipsoid to match the one in our map's SRS. - if ( _srs->isGeographic() ) - { - const Ellipsoid& ellipsoid = _srs->getEllipsoid(); - - std::string eqRadius = Stringify() << ellipsoid.getRadiusEquator(); - std::string poRadius = Stringify() << ellipsoid.getRadiusPolar(); - - _environment->SetConfigOption( "equatorial-earth-radius-meters", eqRadius.c_str() ); - _environment->SetConfigOption( "polar-earth-radius-meters", poRadius.c_str() ); - } - - //_environment->SetConfigOption("avoid-opengl-stalls", "yes"); - //_environment->SetConfigOption("fft-texture-update-frame-delayed", "yes"); - - float openGLVersion = osg::getGLVersionNumber(); - enum ::Triton::Renderer tritonOpenGlVersion = ::Triton::OPENGL_2_0; -#ifndef OSG_GL_FIXED_FUNCTION_AVAILABLE - if( openGLVersion >= 4.1 ) - tritonOpenGlVersion = ::Triton::OPENGL_4_1; - else if( openGLVersion >= 4.0 ) - tritonOpenGlVersion = ::Triton::OPENGL_4_0; - else if( openGLVersion >= 3.2 ) - tritonOpenGlVersion = ::Triton::OPENGL_3_2; -#endif - - ::Triton::EnvironmentError err = _environment->Initialize( - cs, - tritonOpenGlVersion, - _resourceLoader ); - - if ( err == ::Triton::SUCCEEDED ) - { - ::Triton::WindFetch wf; - wf.SetWind( 10.0, 0.0 ); - _environment->AddWindFetch( wf ); - - _ocean = ::Triton::Ocean::Create( - _environment, - ::Triton::JONSWAP, - true ); // enableHeightTests - activated GetHeight for intersections - } - - if ( _ocean ) - { - _oceanWrapper = new Ocean((uintptr_t)_ocean); - - // fire init callback if available - if (_callback.valid()) - { - _callback->onInitialize(getEnvironmentWrapper(), getOceanWrapper()); - } - - OE_INFO << LC << "Triton initialized OK!" << std::endl; - } - else - { - _initFailed = true; - OE_WARN << LC << "Triton initialization failed- err=" << err << std::endl; - } - } - } -} - -bool -TritonContext::intersect(const osg::Vec3d& start, const osg::Vec3d& dir, float& out_height, osg::Vec3f& out_normal) const -{ - ::Triton::Vector3 p(start.ptr()); - ::Triton::Vector3 d(dir.ptr()); - ::Triton::Vector3 normal; - bool ok = _ocean->GetHeight(p, d, out_height, normal); - out_normal.set(normal.x, normal.y, normal.z); - return ok; -} - -void -TritonContext::resizeGLObjectBuffers(unsigned maxSize) -{ - osg::Object::resizeGLObjectBuffers(maxSize); -} - -void -TritonContext::releaseGLObjects(osg::State* state) const -{ - osg::Object::releaseGLObjects(state); - - OE_DEBUG << LC << "Triton shutting down - releasing GL resources\n"; - if (state) - { - if ( _ocean ) - { - delete _ocean; - _ocean = 0L; - } - - if ( _environment ) - { - delete _environment; - _environment = 0L; - } - - if ( _resourceLoader ) - { - delete _resourceLoader; - _resourceLoader = 0L; - } - } -} diff --git a/src/scene/TritonContext.h b/src/scene/TritonContext.h deleted file mode 100644 index dee9d4cf..00000000 --- a/src/scene/TritonContext.h +++ /dev/null @@ -1,115 +0,0 @@ -/* -*-c++-*- */ -/* osgEarth - Geospatial SDK for OpenSceneGraph - * Copyright 2020 Pelican Mapping - * http://osgearth.org - * - * osgEarth is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - */ -#ifndef OSGEARTH_TRITON_CONTEXT_H -#define OSGEARTH_TRITON_CONTEXT_H - -#include -#include // Triton -#include "TritonLayer.h" -#include "TritonAPIWrapper.h" -#include "TritonCallback.h" -#include -#include -#include - -namespace osgEarth { - class SpatialReference; -} - -namespace osgEarth { namespace Triton -{ - /** - * Contains all the Triton SDK handles. - */ - class TritonContext : public osg::Object - { - public: - META_Object(osgEarth, TritonContext); - - TritonContext(const TritonLayer::Options&); - - /** Sets the spatial reference system of the map */ - void setSRS(const osgEarth::SpatialReference* srs); - - /** Sets the user callback */ - void setCallback(Callback* callback); - Callback* getCallback() const { return _callback.get(); } - - public: // accessors - - bool ready() const { return _initAttempted && !_initFailed; } - - /** Spatial reference of the map */ - const osgEarth::SpatialReference* getSRS() const { return _srs.get(); } - - void initialize(osg::RenderInfo& renderInfo); - - bool intersect(const osg::Vec3d& start, const osg::Vec3d& dir, float& out_height, osg::Vec3f& out_normal) const; - - ::Triton::Environment* getEnvironment() { return _environment; } - Environment& getEnvironmentWrapper() const { return *_environmentWrapper; } - - ::Triton::Ocean* getOcean() { return _ocean; } - Ocean& getOceanWrapper() const { return *_oceanWrapper; } - - bool passHeightMapToTriton() const; - - int getHeightMapSize() const; - - const std::string& getMaskLayerName() const; - - public: // osg::Object - - void resizeGLObjectBuffers(unsigned maxSize); - - /** If State is non-zero, this function releases any associated OpenGL objects for - * the specified graphics context. Otherwise, releases OpenGL objects - * for all graphics contexts. */ - void releaseGLObjects(osg::State* state) const; - - protected: - - virtual ~TritonContext(); - - // hidden ctors (for META_Object) - TritonContext() { } - TritonContext(const TritonContext&, const osg::CopyOp&) { } - - private: - TritonLayer::Options _options; - - bool _initAttempted; - bool _initFailed; - std::mutex _initMutex; - - osg::ref_ptr _srs; - - mutable ::Triton::ResourceLoader* _resourceLoader; - mutable ::Triton::Environment* _environment; - mutable ::Triton::Ocean* _ocean; - - Environment* _environmentWrapper; - Ocean* _oceanWrapper; - - osg::ref_ptr _callback; - }; - -} } // namespace osgEarth::Triton - -#endif // OSGEARTH_TRITON_CONTEXT_H \ No newline at end of file diff --git a/src/scene/TritonDrawable.cpp b/src/scene/TritonDrawable.cpp deleted file mode 100644 index b21c8579..00000000 --- a/src/scene/TritonDrawable.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* -*-c++-*- */ -/* osgEarth - Geospatial SDK for OpenSceneGraph - * Copyright 2020 Pelican Mapping - * http://osgearth.org - * - * osgEarth is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - */ -#include "TritonContext.h" -#include "TritonDrawable.h" -#include "TritonHeightMap.h" -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#undef LC -#define LC "[TritonDrawable] " - -//#define DEBUG_HEIGHTMAP - -using namespace osgEarth::Triton; - - -TritonDrawable::TritonDrawable(TritonContext* TRITON) : - _TRITON(TRITON) -{ - // call this to ensure draw() gets called every frame. - setSupportsDisplayList( false ); - setUseVertexBufferObjects( false ); - - // dynamic variance prevents update/cull overlap when drawing this - setDataVariance( osg::Object::DYNAMIC ); - - _wgs84 = SpatialReference::get("wgs84"); - _ecef = _wgs84->getGeocentricSRS(); -} - -TritonDrawable::~TritonDrawable() -{ - //nop -} - -void -TritonDrawable::setMaskLayer(const osgEarth::ImageLayer* layer) -{ - _maskLayer = layer; -} - -void -TritonDrawable::setHeightMapGenerator(TritonHeightMap* value) -{ - _heightMapGenerator = value; -} - -void -TritonDrawable::setPlanarReflectionMap(osg::Texture2D* map) -{ - _planarReflectionMap = map; -} - -void -TritonDrawable::setPlanarReflectionProjection(osg::RefMatrix* proj) -{ - _planarReflectionProjection = proj; -} - -osg::BoundingBox -TritonDrawable::computeBoundingBox() const -{ - return osg::BoundingBox(); -} - -namespace { - -// Wrapper around Ocean->GetShaderObject() to account for API changes from Triton 3.x to 4.x -GLint -getOceanShader(::Triton::Ocean* ocean, ::Triton::Shaders shaderProgram, void* context, const ::Triton::Camera* camera) -{ -#if (TRITON_MAJOR_VERSION >= 4) - return (GLint)ocean->GetShaderObject( shaderProgram, context, camera ); -#else - return (GLint)ocean->GetShaderObject( shaderProgram ); -#endif -} - -} - -void -TritonDrawable::drawImplementation(osg::RenderInfo& renderInfo) const -{ - OE_GL_ZONE; - - osg::State* state = renderInfo.getState(); - - state->disableAllVertexArrays(); - - _TRITON->initialize( renderInfo ); - if ( !_TRITON->ready() ) - return; - - // Configure the height map generator. - // If configuration fails, attempt to continue without a heightmap. - if (_heightMapGenerator.valid()) - { - bool configOK = _heightMapGenerator->configure(_TRITON->getHeightMapSize(), *state); - if (configOK == false) - { - _heightMapGenerator = 0L; - OE_WARN << LC << "Failed to establish a legal FBO configuration; disabling height map generator!" << std::endl; - } - } - - ::Triton::Environment* environment = _TRITON->getEnvironment(); - - // Find or create the Triton camera for this OSG camera: - CameraLocal& local = _local.get(renderInfo.getCurrentCamera()); - if (local._tritonCam == 0L) - { - local._tritonCam = environment->CreateCamera(); - local._tritonCam->SetName(renderInfo.getCurrentCamera()->getName().c_str()); - } - ::Triton::Camera* tritonCam = local._tritonCam; - - auto cid = GLUtils::getSharedContextID(*state); - osgEarth::NativeProgramAdapterCollection& adapters = _adapters[cid]; - if ( adapters.empty() ) - { - OE_DEBUG << LC << "Initializing Triton program adapters" << std::endl; - const std::vector prefixes = { "osg_", "oe_" }; - adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::WATER_SURFACE, 0L, tritonCam), prefixes, "WATER_SURFACE")); - adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::WATER_SURFACE_PATCH, 0L, tritonCam), prefixes, "WATER_SURFACE_PATCH")); - adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::GOD_RAYS, 0L, tritonCam), prefixes, "GOD_RAYS")); - adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::SPRAY_PARTICLES, 0L, tritonCam), prefixes, "SPRAY_PARTICLES")); - adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::WAKE_SPRAY_PARTICLES, 0L, tritonCam), prefixes, "WAKE_SPRAY_PARTICLES")); -#if 0 - // In older Triton (3.91), this line causes problems in Core profile and prevents the ocean from drawing. In newer Triton (4.01), - // this line causes a crash because there is no context passed in to GetShaderObject(), resulting in multiple NULL references. - adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::WATER_DECALS, 0L, tritonCam), prefixes, "WATER_DECALS")); -#endif - } - adapters.apply( state ); - - - // Pass the final view and projection matrices into Triton. - if ( environment ) - { - tritonCam->SetCameraMatrix(state->getModelViewMatrix().ptr()); - tritonCam->SetProjectionMatrix(state->getProjectionMatrix().ptr()); - } - - // Calculate sea level based on the camera: - if (_verticalDatum.valid()) - { - GeoPoint cam(_ecef, osg::Vec3d(0, 0, 0) * state->getInitialInverseViewMatrix(), ALTMODE_ABSOLUTE); - cam.transformInPlace(_wgs84); - auto msl = _verticalDatum->hae2msl(cam.y(), cam.x(), 0.0); - environment->SetSeaLevel(-msl); - } - - if (_heightMapGenerator.valid()) - { - GLint texName; - osg::Matrix hMM; - if (_heightMapGenerator->getTextureAndMatrix(renderInfo, texName, hMM)) - { - // copy the OSG matrix to a Triton matrix: - ::Triton::Matrix4 texMat( - hMM(0, 0), hMM(0, 1), hMM(0, 2), hMM(0, 3), - hMM(1, 0), hMM(1, 1), hMM(1, 2), hMM(1, 3), - hMM(2, 0), hMM(2, 1), hMM(2, 2), hMM(2, 3), - hMM(3, 0), hMM(3, 1), hMM(3, 2), hMM(3, 3)); - - environment->SetHeightMap((::Triton::TextureHandle)texName, texMat, 0L, tritonCam); - - //OE_DEBUG << LC << "Updating height map, FN=" << renderInfo.getState()->getFrameStamp()->getFrameNumber() << std::endl; - } - } - - state->dirtyAllVertexArrays(); - - // Now light and draw the ocean: - if ( environment ) - { - // User pre-draw callback: - if (_TRITON->getCallback()) - { - _TRITON->getCallback()->onDrawOcean( - _TRITON->getEnvironmentWrapper(), - _TRITON->getOceanWrapper()); - } - - osg::Light* light = renderInfo.getView() ? renderInfo.getView()->getLight() : NULL; - - // This is the light attached to View so there are no transformations above.. - // But in general case you would need to accumulate all transforms above the light into this matrix - osg::Matrix lightLocalToWorldMatrix = osg::Matrix::identity(); - - // If you don't know where the sun lightsource is attached and don't know its local to world matrix you may use - // following elaborate scheme to grab the light source while drawing Triton ocean: - // - Install cull callback to catch CullVisitor and record pointer to its associated RenderStage - // I was hoping RenderStage can be found from renderInfo in drawImplementation but I didn't figure how ... - // - When TritonDrawable::drawImplementation is called all lights will be already applied to OpenGL - // then just find proper infinite directional light by scanning renderStage->PositionalStateContainer. - // - Note that we canot scan for the lights inside cull because they may not be traversed before Triton drawable - // - When you found interesting ligt source that can work as Sun, read its modelview matrix and lighting params - // Multiply light position by ( modelview * inverse camera view ) and pass this to Triton with lighting colors - - if ( light && light->getPosition().w() == 0 ) - { - osg::Vec4 ambient = light->getAmbient(); - osg::Vec4 diffuse = light->getDiffuse(); - osg::Vec4 position = light->getPosition(); - - // Compute light position/direction in the world - position = position * lightLocalToWorldMatrix; - - // Diffuse direction and color - environment->SetDirectionalLight( - ::Triton::Vector3( position[0], position[1], position[2] ), - ::Triton::Vector3( diffuse[0], diffuse[1], diffuse[2] ) ); - - // Sun-based ambient value: - osg::Vec3d up = osg::Vec3d(0,0,0) * renderInfo.getCurrentCamera()->getInverseViewMatrix(); - up.normalize(); - osg::Vec3d pos3 = osg::Vec3d(position.x(), position.y(), position.z()); - pos3.normalize(); - float dot = osg::clampAbove(up*pos3, 0.0); dot*=dot; - float sunAmbient = (float)osg::clampBetween( dot, 0.0f, 0.88f ); - float fa = osg::maximum(sunAmbient, ambient[0]); - - // Ambient color based on the zenith color in the cube map - environment->SetAmbientLight( ::Triton::Vector3(fa, fa, fa) ); - } - - else - { - environment->SetDirectionalLight( ::Triton::Vector3(0,0,1), ::Triton::Vector3(1,1,1) ); - environment->SetAmbientLight( ::Triton::Vector3(0.88f, 0.88f, 0.88f) ); - } - - if ( _cubeMap.valid() ) - { - // Build transform from our cube map orientation space to native Triton orientation - // See worldToCubeMap function used in SkyBox to orient sky texture so that sky is up and earth is down - osg::Matrix m = osg::Matrix::rotate( osg::PI_2, osg::X_AXIS ); // = worldToCubeMap - - ::Triton::Matrix3 transformFromYUpToZUpCubeMapCoords( - m(0,0), m(0,1), m(0,2), - m(1,0), m(1,1), m(1,2), - m(2,0), m(2,1), m(2,2) ); - - // Grab the cube map from our sky box and give it to Triton to use as an _environment map - // GLenum texture = renderInfo.getState()->getLastAppliedTextureAttribute( _stage, osg::StateAttribute::TEXTURE ); - environment->SetEnvironmentMap( - (::Triton::TextureHandle)_cubeMap->getTextureObject(cid)->id(), - transformFromYUpToZUpCubeMapCoords ); - - if( _planarReflectionMap.valid() && _planarReflectionProjection.valid() ) - { - osg::Matrix & p = *_planarReflectionProjection; - - ::Triton::Matrix3 planarProjection( - p(0,0), p(0,1), p(0,2), - p(1,0), p(1,1), p(1,2), - p(2,0), p(2,1), p(2,2) ); - - environment->SetPlanarReflectionMap( - (::Triton::TextureHandle)_planarReflectionMap->getTextureObject(cid)->id(), - planarProjection, - 0.125 ); - } - } - - // Draw the ocean for the current time sample - if ( _TRITON->getOcean() ) - { - osg::GLExtensions* ext = osg::GLExtensions::Get(cid, true); - - bool writeDepth = true; - const osg::Depth* depth = static_cast(state->getLastAppliedAttribute(osg::StateAttribute::DEPTH)); - if (depth) - writeDepth = depth->getWriteMask(); - - double simTime = renderInfo.getView()->getFrameStamp()->getSimulationTime(); - simTime = fmod(simTime, 86400.0); - - _TRITON->getOcean()->Draw( - simTime, - writeDepth, // depth writes - true, // draw water - true, // draw particles - NULL, // optional context - tritonCam); - - } - } - - // Put GL back in a state that won't confuse the OSG state tracking: - state->dirtyAllVertexArrays(); - state->dirtyAllAttributes(); - state->dirtyAllModes(); - -#ifndef OSG_GL_FIXED_FUNCTION_AVAILABLE - // Keep OSG from reapplying GL_LIGHTING on next state change after dirtyAllModes(). - state->setModeValidity(GL_LIGHTING, false); -#endif - - // Keep an eye on this. - // I had to remove something similar in another module (Rex engine) because it was causing - // positional attributes (like clip planes) to re-apply with an incorrect MVM. -gw - state->apply(); -} diff --git a/src/scene/TritonDrawable.h b/src/scene/TritonDrawable.h deleted file mode 100644 index 95f28727..00000000 --- a/src/scene/TritonDrawable.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -*-c++-*- */ -/* osgEarth - Geospatial SDK for OpenSceneGraph - * Copyright 2020 Pelican Mapping - * http://osgearth.org - * - * osgEarth is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - */ -#ifndef OSGEARTH_TRITON_DRAWABLE_H -#define OSGEARTH_TRITON_DRAWABLE_H - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -const unsigned int TRITON_OCEAN_MASK = 0x4; // 0100 - -namespace osgEarth { namespace Triton -{ - class TritonContext; - class TritonHeightMap; - - /** - * Custom drawable for rendering the Triton ocean effects - */ - class TritonDrawable : public osg::Drawable - { - public: - TritonDrawable(TritonContext* TRITON); - - //! Layer to use as an ocean rendering mask - void setMaskLayer(const osgEarth::ImageLayer* maskLayer); - - //! Height map generator to use to mask out the ocean where the - //! terrain has positive elevation - void setHeightMapGenerator(TritonHeightMap* heightMap); - - //! Vertical datum to use to calculate sea level - void setVerticalDatum(VerticalDatum* value) { - _verticalDatum = value; - } - - //! Gets the Triton Camera associated with an osg Camera - ::Triton::Camera* getTritonCam(const osg::Camera* cam) { - return _local.get(cam)._tritonCam; - } - - void setPlanarReflectionMap(osg::Texture2D* map); - - void setPlanarReflectionProjection(osg::RefMatrix* proj); - - public: // osg::Drawable - - void drawImplementation(osg::RenderInfo& ri) const override; - - osg::BoundingBox computeBoundingBox() const override; - - protected: - virtual ~TritonDrawable(); - - osg::observer_ptr _TRITON; - osg::observer_ptr _maskLayer; - osg::ref_ptr _cubeMap; - - osg::ref_ptr _planarReflectionMap; - osg::ref_ptr _planarReflectionProjection; - - mutable osg::ref_ptr _heightMapGenerator; - - osg::ref_ptr _verticalDatum; - osg::ref_ptr _wgs84, _ecef; - - mutable osg::buffered_object _adapters; - - struct CameraLocal - { - ::Triton::Camera* _tritonCam = nullptr; - }; - mutable PerObjectFastMap _local; - }; - -} } // namespace osgEarth::Triton - -#endif // OSGEARTH_TRITON_DRAWABLE_H diff --git a/src/scene/TritonHeightMap.cpp b/src/scene/TritonHeightMap.cpp deleted file mode 100644 index c0057d7a..00000000 --- a/src/scene/TritonHeightMap.cpp +++ /dev/null @@ -1,434 +0,0 @@ -/* -*-c++-*- */ -/* osgEarth - Geospatial SDK for OpenSceneGraph - * Copyright 2020 Pelican Mapping - * http://osgearth.org - * - * osgEarth is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - */ -#include "TritonHeightMap.h" -#include "TritonContext.h" -#include -#include -#include -#include - -#define LC "[TritonHeightMap] " - -using namespace osgEarth::Triton; - -namespace -{ - const char* vertexShader = - "#pragma import_defines(OE_TRITON_MASK_MATRIX);\n" - - "// terrain SDK:\n" - "float oe_terrain_getElevation(); \n" - - "out float oe_triton_elev;\n" - - "#ifdef OE_TRITON_MASK_MATRIX\n" - "out vec2 maskCoords;\n" - "uniform mat4 OE_TRITON_MASK_MATRIX;\n" - "vec4 oe_layer_tilec;\n" - "#endif\n" - - "void oe_triton_setupHeightMap(inout vec4 unused) \n" - "{ \n" - " oe_triton_elev = oe_terrain_getElevation(); \n" - "#ifdef OE_TRITON_MASK_MATRIX\n" - " maskCoords = (OE_TRITON_MASK_MATRIX * oe_layer_tilec).st;\n" - "#endif\n" - "} \n"; - - // The fragment shader simply takes the texture index that we generated - // in the vertex shader and does a texture lookup. In this case we're - // just wholesale replacing the color, so if the map had any existing - // imagery, this will overwrite it. - - const char* fragmentShader = - "#pragma import_defines(OE_TRITON_MASK_SAMPLER);\n" - - "in float oe_triton_elev;\n" - - "#ifdef OE_TRITON_MASK_SAMPLER\n" - "in vec2 maskCoords;\n" - "uniform sampler2D OE_TRITON_MASK_SAMPLER;\n" - "#endif\n" - - "out vec4 out_height; \n" - - "void oe_triton_drawHeightMap(inout vec4 unused) \n" - "{ \n" -#ifdef DEBUG_HEIGHTMAP - // Map to black = -500m, white = +500m - " float nHeight = clamp(oe_triton_elev / 1000.0 + 0.5, 0.0, 1.0);\n" -#else - " float nHeight = oe_triton_elev;\n" - - "#ifdef OE_TRITON_MASK_SAMPLER\n" - " float mask = texture(OE_TRITON_MASK_SAMPLER, maskCoords).a;\n" - " nHeight *= mask; \n" - "#endif\n" - -#endif - " out_height = vec4( nHeight, 0.0, 0.0, 1.0 ); \n" - "} \n"; - - struct TerrainDirtyCallback : public osgEarth::TerrainCallback - { - osg::observer_ptr _hm; - TerrainDirtyCallback(TritonHeightMap* hm) : _hm(hm) { } - void onTileUpdate(const osgEarth::TileKey&, osg::Node*, osgEarth::TerrainCallbackContext&) - { - osg::ref_ptr hm; - if (_hm.lock(hm)) - hm->dirty(); - } - }; -} - -TritonHeightMap::TritonHeightMap() : -_texSize(0u), -_internalFormat((GLint)0), -_sourceFormat((GLenum)0) -{ - setCullingActive(false); -} - -TritonHeightMap::~TritonHeightMap() -{ - osgEarth::TerrainEngineNode* t = dynamic_cast(_terrain.get()); - if (t) - { - t->getTerrain()->removeTerrainCallback(static_cast(_terrainCallback.get())); - _terrainCallback = NULL; - } -} - -void -TritonHeightMap::setTerrain(osg::Node* node) -{ - _terrain = node; - - osgEarth::TerrainEngineNode* t = dynamic_cast(node); - if (t) - { - TerrainDirtyCallback* cb = new TerrainDirtyCallback(this); - t->getTerrain()->addTerrainCallback(cb); - _terrainCallback = cb; - } -} - -void -TritonHeightMap::setMaskLayer(const osgEarth::ImageLayer* layer) -{ - _maskLayer = layer; -} - -void -TritonHeightMap::SetDirty::operator()(CameraLocal& local) -{ - local._mvpw.makeIdentity(); -} - -void -TritonHeightMap::dirty() -{ - SetDirty setDirty; - _local.forEach(setDirty); -} - -bool -TritonHeightMap::configure(unsigned texSize, osg::State& state) -{ - bool result = true; - - if (_texSize == 0u) - { - // first time through, single-lane and set up FBO parameters. - static std::mutex s_mutex; - std::lock_guard lock(s_mutex); - - if (_texSize == 0u) - { - _texSize = texSize; - if (!getBestFBOConfig(state, _internalFormat, _sourceFormat)) - { - result = false; - } - } - } - return result; -} - -namespace { - struct Format { - Format(GLint i, GLenum s, const std::string& n) : - internalFormat(i), sourceFormat(s), name(n) { } - GLint internalFormat; - GLenum sourceFormat; - std::string name; - }; -} - -bool -TritonHeightMap::getBestFBOConfig(osg::State& state, GLint& out_internalFormat, GLenum& out_sourceFormat) -{ -#ifdef GL_LUMINANCE_FLOAT16_ATI -# define GL_LUMINANCE_FLOAT16_ATI 0x881E -#endif - - std::vector formats; - -#ifdef GL_R16F - formats.push_back(Format(GL_R16F, GL_RED, "GL_R16F")); -#endif -#ifdef GL_LUMINANCE16F_ARB - formats.push_back(Format(GL_LUMINANCE16F_ARB, GL_LUMINANCE, "GL_LUMINANCE16F_ARB")); -#endif -#ifdef GL_LUMINANCE_FLOAT16_ATI - formats.push_back(Format(GL_LUMINANCE_FLOAT16_ATI, GL_LUMINANCE, "GL_LUMINANCE_FLOAT16_ATI")); -#endif -#ifdef GL_R32F - formats.push_back(Format(GL_R32F, GL_RED, "GL_R32F")); -#endif -#ifdef GL_LUMINANCE32F_ARB - formats.push_back(Format(GL_LUMINANCE32F_ARB, GL_LUMINANCE, "GL_LUMINANCE32F_ARB")); -#endif -#ifdef GL_RGB16F_ARB - formats.push_back(Format(GL_RGB16F_ARB, GL_RGB, "GL_RGB16F_ARB")); -#endif -#ifdef GL_RGBA16F_ARB - formats.push_back(Format(GL_RGBA16F_ARB, GL_RGBA, "GL_RGBA16F_ARB")); -#endif -#ifdef GL_RGB32F_ARB - formats.push_back(Format(GL_RGB32F_ARB, GL_RGB, "GL_RGB32F_ARB")); -#endif -#ifdef GL_RGBA32F_ARB - formats.push_back(Format(GL_RGBA32F_ARB, GL_RGBA, "GL_RGBA32F_ARB")); -#endif - - - auto cid = GLUtils::getSharedContextID(state); - osg::GLExtensions* ext = osg::GLExtensions::Get(cid, true); - - osg::State::CheckForGLErrors check = state.getCheckForGLErrors(); - state.setCheckForGLErrors(state.NEVER_CHECK_GL_ERRORS); - - bool found = false; - - for(int i=0; i tex = new osg::Texture2D(); - tex->setTextureSize(1, 1); - tex->setInternalFormat( format.internalFormat ); - tex->setSourceFormat ( format.sourceFormat ); - - osg::ref_ptr fbo = new osg::FrameBufferObject(); - fbo->setAttachment( osg::Camera::COLOR_BUFFER0, osg::FrameBufferAttachment(tex.get()) ); - - fbo->apply( state ); - - GLenum status = ext->glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT); - - fbo->releaseGLObjects( &state ); - tex->releaseGLObjects( &state ); - - if ( status == GL_FRAMEBUFFER_COMPLETE_EXT ) - { - out_internalFormat = format.internalFormat; - out_sourceFormat = format.sourceFormat; - found = true; - } - } - - state.setCheckForGLErrors(check); - - return found; -} - -bool -TritonHeightMap::isConfigurationComplete() const -{ - return - _texSize > 0u && - _internalFormat != (GLint)0 && - _sourceFormat != (GLenum)0; -} - -void -TritonHeightMap::setup(CameraLocal& local, const std::string& name) -{ - // make sure the FBO params are configured: - if (!isConfigurationComplete()) - return; - - local._frameNum = 0u; - - local._tex = new osg::Texture2D(); - local._tex->setName(Stringify() << "Triton HM (" << name << ")"); - local._tex->setTextureSize(_texSize, _texSize); - local._tex->setInternalFormat( _internalFormat ); - local._tex->setSourceFormat( _sourceFormat ); - local._tex->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); - local._tex->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR); - - // Triton prob doesn't need this but it's good practice - if (_sourceFormat == GL_RED) - { - local._tex->setSwizzle(osg::Vec4i(GL_RED, GL_RED, GL_RED, GL_ONE)); - } - - local._rtt = new osg::Camera(); - local._rtt->setName(local._tex->getName()); - local._rtt->setReferenceFrame(osg::Transform::ABSOLUTE_RF_INHERIT_VIEWPOINT); - local._rtt->setClearMask(GL_COLOR_BUFFER_BIT); //GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - local._rtt->setClearColor(osg::Vec4(-1000.0, -1000.0, -1000.0, 1.0f)); - local._rtt->setViewport(0, 0, _texSize, _texSize); - local._rtt->setRenderOrder(osg::Camera::PRE_RENDER); - local._rtt->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); - local._rtt->setImplicitBufferAttachmentMask(0, 0); - local._rtt->attach(osg::Camera::COLOR_BUFFER0, local._tex.get()); - //local._rtt->setCullMask( ~TRITON_OCEAN_MASK ); - local._rtt->setAllowEventFocus(false); - local._rtt->setDrawBuffer(GL_FRONT); - local._rtt->setReadBuffer(GL_FRONT); - local._rtt->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); - - // TODO: create this once and just re-use it for all RTT cameras - osg::StateSet* rttSS = local._rtt->getOrCreateStateSet(); - - osgEarth::VirtualProgram* rttVP = osgEarth::VirtualProgram::getOrCreate(rttSS); - rttVP->setName("Triton Height Map"); - rttVP->setFunction( "oe_triton_setupHeightMap", vertexShader, VirtualProgram::LOCATION_VERTEX_MODEL); - rttVP->setFunction( "oe_triton_drawHeightMap", fragmentShader, VirtualProgram::LOCATION_FRAGMENT_OUTPUT); - rttVP->setInheritShaders(false); - - osg::StateAttribute::OverrideValue off = osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE; - rttSS->setDefine("OE_IS_DEPTH_CAMERA"); - rttSS->setDefine("OE_TERRAIN_RENDER_IMAGERY", off); - rttSS->setDefine("OE_TERRAIN_RENDER_NORMAL_MAP", off); - rttSS->setDefine("OE_TERRAIN_BLEND_IMAGERY", off); - rttSS->setDefine("OE_TERRAIN_MORPH_GEOMETRY", off); - - osg::ref_ptr maskLayer; - if (_maskLayer.lock(maskLayer)) - { - rttSS->setDefine("OE_TRITON_MASK_SAMPLER", maskLayer->getSharedTextureUniformName()); - rttSS->setDefine("OE_TRITON_MASK_MATRIX", maskLayer->getSharedTextureMatrixUniformName()); - OE_DEBUG << LC << "Using mask layer \"" << maskLayer->getName() << "\", sampler=" << maskLayer->getSharedTextureUniformName() << ", matrix=" << maskLayer->getSharedTextureMatrixUniformName() << std::endl; - } - - if (_terrain.valid()) - { - local._rtt->addChild(_terrain.get()); - } - else - { - OE_WARN << LC << "Illegal: no terrain set (must call setTerrain)" << std::endl; - } -} - -#define MAXABS4(A,B,C,D) \ - osg::maximum(fabs(A), osg::maximum(fabs(B), osg::maximum(fabs(C),fabs(D)))) - -void -TritonHeightMap::update(CameraLocal& local, const osg::Camera* cam, osgEarth::Horizon* horizon) -{ - osg::Vec3d eye = osg::Vec3d(0,0,0) * cam->getInverseViewMatrix(); - - double hd = horizon->getDistanceToVisibleHorizon(); - - local._rtt->setProjectionMatrix(osg::Matrix::ortho(-hd, hd, -hd, hd, 1.0, eye.length())); - local._rtt->setViewMatrixAsLookAt(eye, osg::Vec3d(0.0,0.0,0.0), osg::Vec3d(0.0,0.0,1.0)); - - static const osg::Matrixd scaleBias( - 0.5, 0.0, 0.0, 0.0, - 0.0, 0.5, 0.0, 0.0, - 0.0, 0.0, 0.5, 0.0, - 0.5, 0.5, 0.5, 1.0); - - // Matrix that Triton will use to position the heightmap for sampling. - local._texMatrix = local._rtt->getViewMatrix() * local._rtt->getProjectionMatrix() * scaleBias; -} - -void -TritonHeightMap::traverse(osg::NodeVisitor& nv) -{ - if (nv.getVisitorType() == nv.CULL_VISITOR) - { - osgUtil::CullVisitor* cv = osgEarth::Culling::asCullVisitor(nv); - const osg::Camera* camera = cv->getCurrentCamera(); - if (camera) - { - CameraLocal& local = _local.get(camera); - - if (isConfigurationComplete()) - { - // create the RTT for this camera on first encounter: - if (!local._rtt.valid()) - { - setup(local, camera->getName()); - } - - // only update when the MVPW changes. - if (local._mvpw != *cv->getMVPW()) - { - // update the RTT based on the current camera: - osg::ref_ptr horizon; - ObjectStorage::get(&nv, horizon); - update(local, camera, horizon); - - // finally, traverse the camera to build the height map. - local._rtt->accept(nv); - - local._frameNum = nv.getFrameStamp()->getFrameNumber(); - local._mvpw = *cv->getMVPW(); - } - } - else - { - //OE_DEBUG << LC << "Configuration not yet complete..." << std::endl; - } - } - } -} - -bool -TritonHeightMap::getTextureAndMatrix(osg::RenderInfo& ri, GLint& out_texName, osg::Matrix& out_matrix) -{ - if (!isConfigurationComplete()) - return false; - - CameraLocal& local = _local.get(ri.getCurrentCamera()); - if (!local._tex.valid()) - return false; - - // did the texture change? - //OE_DEBUG << "FN=" << ri.getState()->getFrameStamp()->getFrameNumber() << "; localFN=" << local._frameNum << std::endl; - - if (ri.getState()->getFrameStamp()->getFrameNumber() > local._frameNum) - return false; - - auto cid = GLUtils::getSharedContextID(*ri.getState()); - osg::Texture::TextureObject* obj = local._tex->getTextureObject(cid); - if (!obj) - return false; - - out_texName = obj->id(); - out_matrix = local._texMatrix; - return true; -} diff --git a/src/scene/TritonHeightMap.h b/src/scene/TritonHeightMap.h deleted file mode 100644 index b7896a7f..00000000 --- a/src/scene/TritonHeightMap.h +++ /dev/null @@ -1,109 +0,0 @@ -/* -*-c++-*- */ -/* osgEarth - Geospatial SDK for OpenSceneGraph - * Copyright 2020 Pelican Mapping - * http://osgearth.org - * - * osgEarth is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - */ -#ifndef OSGEARTH_TRITON_HEIGHT_MAP -#define OSGEARTH_TRITON_HEIGHT_MAP 1 - -#include -#include -#include -#include -#include - -namespace osgEarth { - class Horizon; -} - -namespace osgEarth { namespace Triton -{ - /** - * Creates a height map that Triton can use to mask out the ocean where - * the terrain is above sea level. - */ - class TritonHeightMap : public osg::Node - { - public: - - TritonHeightMap(); - - //! Sets the root of the terrain scene graph - void setTerrain(osg::Node*); - - //! Sets the masking layer - void setMaskLayer(const osgEarth::ImageLayer* layer); - - //! Configure the generator; return success t/f - bool configure(unsigned texSize, osg::State& state); - - //! Fetch the heightmap texture and matrix generated for a camera. - bool getTextureAndMatrix(osg::RenderInfo&, GLint& out_texName, osg::Matrix& out_matrix); - - //! Mark all height maps (for all cameras) for regeneration - void dirty(); - - public: // osg::Node - - void traverse(osg::NodeVisitor&); - - protected: - - virtual ~TritonHeightMap(); - - private: - - struct CameraLocal - { - osg::ref_ptr _rtt; - osg::ref_ptr _tex; - osg::Matrix _texMatrix; - osg::Matrix _mvpw; - unsigned _frameNum; - }; - - typedef osgEarth::PerObjectFastMap Locals; - - struct SetDirty : public Locals::Functor - { - void operator()(CameraLocal&); - }; - - //! Sets up an RTT camera for the first time - void setup(CameraLocal& local, const std::string& name); - - //! Updates an RTT camera for the new view/projection matrices of the camera - void update(CameraLocal& local, const osg::Camera*, osgEarth::Horizon*); - - //! Whether FBO configuration has happened yet - bool isConfigurationComplete() const; - - //! Figures out the best FBO format on this GPU - static bool getBestFBOConfig(osg::State& state, GLint& internalFormat, GLenum& sourceFormat); - - - Locals _local; - osg::observer_ptr _terrain; - unsigned _texSize; - GLint _internalFormat; - GLenum _sourceFormat; - osg::observer_ptr _maskLayer; - osg::ref_ptr _terrainCallback; - }; - -} } // namespace osgEarth::Triton - -#endif // OSGEARTH_TRITON_HEIGHT_MAP diff --git a/src/scene/TritonIntersections.cpp b/src/scene/TritonIntersections.cpp deleted file mode 100644 index 727dbd64..00000000 --- a/src/scene/TritonIntersections.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* -*-c++-*- */ -/* osgEarth - Geospatial SDK for OpenSceneGraph - * Copyright 2020 Pelican Mapping - * http://osgearth.org - * - * osgEarth is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - */ -#include "TritonIntersections.h" - -using namespace osgEarth; -using namespace osgEarth::Triton; - -TritonIntersections::TritonIntersections() : -_maxRange(1.0, Units::KILOMETERS) -{ -} - -void -TritonIntersections::setAnchor(const GeoPoint& value) -{ - _anchor = value; - - // zero out the other stuff: - _anchor.z() = 0.0; - _anchor.altitudeMode() = ALTMODE_ABSOLUTE; -} - -void -TritonIntersections::addLocalPoint(const osg::Vec3d& p) -{ - _input.push_back(p); - _heights.resize(_input.size()); - _normals.resize(_input.size()); -} - -void -TritonIntersections::setMaxRange(const Distance& range) -{ - _maxRange = range; -} diff --git a/src/scene/TritonIntersections.h b/src/scene/TritonIntersections.h deleted file mode 100644 index de35c76a..00000000 --- a/src/scene/TritonIntersections.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -*-c++-*- */ -/* osgEarth - Geospatial SDK for OpenSceneGraph - * Copyright 2020 Pelican Mapping - * http://osgearth.org - * - * osgEarth is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - */ -#ifndef OSGEARTH_TRITON_INTERSECTIONS -#define OSGEARTH_TRITON_INTERSECTIONS 1 - -#include -#include -#include "TritonCallback.h" - -namespace osgEarth { namespace Triton -{ - /** - * Pass this structure to TritonLayer and it will automatically - * populate the results with ocean wave intersections (local coordinates - * and normals.) - */ - class TritonIntersections : public osg::Referenced - { - public: - //! Construct an empty set - TritonIntersections(); - - //! Anchor point for intersectsions in this set. Only the X and Y - //! components are used. Any local points you add to this set will - //! be in the local coordinate system (LTP) around this anchor point. - void setAnchor(const GeoPoint& p); - - //! Adds a point to the intersection set. The point should be in the - //! local coordinate system of the anchor point. - void addLocalPoint(const osg::Vec3d& p); - - //! Maximum range at which to perform intersections. Beyond this - //! range Triton will skip this set. Default is 2km. - void setMaxRange(const Distance& value); - const Distance& getMaxRange() const { return _maxRange; } - - //! Vector of input local points added by addLocalPoint. - const std::vector& getInput() const { return _input; } - - //! Vector of heights resulting from the intersection tests. - const std::vector& getHeights() const { return _heights; } - - //! Vector of normals resulting from the intersection tests. - const std::vector& getNormals() const { return _normals; } - - private: - GeoPoint _anchor; - std::vector _input; - std::vector _heights; - std::vector _normals; - Distance _maxRange; - friend class TritonLayerNode; - }; -} } - -#endif // OSGEARTH_TRITON_INTERSECTIONS diff --git a/src/scene/TritonLayer.cpp b/src/scene/TritonLayer.cpp deleted file mode 100644 index 5c5092b9..00000000 --- a/src/scene/TritonLayer.cpp +++ /dev/null @@ -1,386 +0,0 @@ -/* -*-c++-*- */ -/* osgEarth - Geospatial SDK for OpenSceneGraph - * Copyright 2020 Pelican Mapping - * http://osgearth.org - * - * osgEarth is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - */ -#include "TritonLayer.h" -#include "TritonContext.h" -#include "TritonDrawable.h" -#include "TritonHeightMap.h" -#include "TritonCallback.h" - -#include -#include -#include -#include -#include -#include - -#include - -#define LC "[TritonLayer] " - -using namespace osgEarth::Triton; - -namespace osgEarth { namespace Triton -{ - class TritonLayerNode : public osg::Group - { - public: - TritonLayerNode(osgEarth::Triton::TritonLayer* layer, - LayerReference& mask) : - _tritonLayer(layer), - _maskLayer(mask), - _callback(0L), - _needsMapNode(true) - { - // To detect the map node: - ADJUST_UPDATE_TRAV_COUNT(this, +1); - - // Disable bounds culling - setCullingActive(false); - } - - ~TritonLayerNode() - { - //nop - } - - void setUserCallback(osgEarth::Triton::Callback* callback) - { - _callback = callback; - } - - void dirty() - { - create(); - } - - /** MapNode to use; will be discovered automatically if not set here */ - void setMapNode(osgEarth::MapNode* mapNode) - { - if (!mapNode) - { - this->removeChildren(0, this->getNumChildren()); - _drawable = 0L; - _TRITON = 0L; - _needsMapNode = true; - } - else - { - _mapNode = mapNode; - create(); - } - } - - void create() - { - this->removeChildren(0, this->getNumChildren()); - _drawable = 0L; - - osg::ref_ptr mapNode; - if (!_mapNode.lock(mapNode)) - return; - - const osgEarth::Map* map = mapNode->getMap(); - - // create an object to house Triton data and resources. - if (!_TRITON.valid()) - _TRITON = new TritonContext(_tritonLayer->options()); - - if (map) - _TRITON->setSRS(map->getSRS()); - - if (_callback.valid()) - _TRITON->setCallback(_callback.get()); - - TritonDrawable* drawable = new TritonDrawable(_TRITON.get()); - _drawable = drawable; - _drawable->setNodeMask(TRITON_OCEAN_MASK); - drawable->setMaskLayer(_maskLayer.getLayer()); - this->addChild(_drawable); - - // Place in the depth-sorted bin and set a rendering order. - // We want Triton to render after the terrain. - _drawable->getOrCreateStateSet()->setRenderBinDetails( - _tritonLayer->getRenderBinNumber(), - "DepthSortedBin"); - - // Install a vdatum for sea level calculations: - auto vdatum = VerticalDatum::get(_tritonLayer->options().vdatum().value()); - if (vdatum) - drawable->setVerticalDatum(vdatum); - - // If the user requested a height map, install it now. - // Configuration of the height map generator will take place later when - // we have a valid graphics context. - if (_tritonLayer->getUseHeightMap() == true) - { - TritonHeightMap* heightMapGen = new TritonHeightMap(); - heightMapGen->setTerrain(mapNode->getTerrainEngine()->getNode()); - if (_maskLayer.getLayer()) - heightMapGen->setMaskLayer(_maskLayer.getLayer()); - this->addChild(heightMapGen); - drawable->setHeightMapGenerator(heightMapGen); - } - } - - void traverse(osg::NodeVisitor& nv) - { - if (nv.getVisitorType() == nv.UPDATE_VISITOR) - { - // Find a MapNode in the traversal path if necessary: - if (_needsMapNode) - { - osgEarth::MapNode* mapNode = osgEarth::findInNodePath(nv); - if (mapNode) - { - setMapNode(mapNode); - _needsMapNode = false; - ADJUST_UPDATE_TRAV_COUNT(this, -1); - } - } - } - - else if (nv.getVisitorType() == nv.CULL_VISITOR && _drawable && _TRITON.valid() && _TRITON->getOcean()) - { - // Update any intersections. - // For now this is running in the CULL traversal, which is not ideal. - // However the Triton Ocean::GetHeight method requires a pointer to the Triton "camera" - // and under our framework this is only available in CULL or DRAW. - // Running the intersection in eithe CULL or DRAW will result in a frame - // incoherency w.r.t the Triton update() call that updates the ocean state. - ::Triton::Ocean* ocean = _TRITON->getOcean(); - - // Find the TritonCam associated with this osg Cam - osgUtil::CullVisitor* cv = dynamic_cast(&nv); - ::Triton::Camera* tritonCam = static_cast(_drawable)->getTritonCam(cv->getCurrentCamera()); - - osg::Vec3d eye = osg::Vec3d(0,0,0) * cv->getCurrentCamera()->getInverseViewMatrix(); - - for(std::vector >::iterator i = _isect.begin(); - i != _isect.end(); - ++i) - { - TritonIntersections* ir = i->get(); - - // allocate enough space for the output: - ir->_input.resize(ir->_input.size()); - ir->_normals.resize(ir->_input.size()); - - osg::Matrix local2world; - ir->_anchor.createLocalToWorld(local2world); - - // Make sure it's in range so as not to waste cycles: - osg::Vec3d anchor = osg::Vec3d(0,0,0) * local2world; - double m = ir->getMaxRange().as(Units::METERS); - if ((eye-anchor).length2() > (m)) - { - continue; - } - - osg::Matrix world2local; - world2local.invert(local2world); - - for(unsigned i=0; i_input.size(); ++i) - { - const osg::Vec3d& local = ir->_input[i]; - - // transform the ray to world coordinates - osg::Vec3d start = local * local2world; - osg::Vec3d dir = osg::Matrix::transform3x3(local2world, osg::Vec3d(0,0,1)); - - // intersect the ocean - float& out_height = ir->_heights[i]; - ::Triton::Vector3 out_normalT; - - bool ok = ocean->GetHeight( - ::Triton::Vector3(start.x(), start.y(), start.z()), - ::Triton::Vector3(dir.x(), dir.y(), dir.z()), - out_height, - out_normalT, - true, // visualCorrelation - true, // includeWakes - true, // highResolution - true, // threadSafe, - 0L, // intersectionPoint, - true, // autoFlip - tritonCam); - - if (ok) - { - // populate the output data in local coordinates - osg::Vec3d& normal = ir->_normals[i]; - normal.set(out_normalT.x, out_normalT.y, out_normalT.z); - normal = osg::Matrix::transform3x3(normal, world2local); - } - else - { - // todo...what? - OE_WARN << "GetHeight returned false dude" << std::endl; - } - } - } - } - - osg::Group::traverse(nv); - } - - osg::ref_ptr _TRITON; - osg::Drawable* _drawable; - LayerReference& _maskLayer; - osg::observer_ptr _mapNode; - osg::observer_ptr _tritonLayer; - osg::ref_ptr _callback; - bool _needsMapNode; - std::vector > _isect; - - }; -} } - -//........................................................................ - -void -TritonLayer::Options::fromConfig(const osgEarth::Config& conf) -{ - conf.get("user", _user); - conf.get("license_code", _licenseCode); - conf.get("resource_path", _resourcePath); - conf.get("use_height_map", _useHeightMap); - conf.get("height_map_size", _heightMapSize); - conf.get("render_bin_number", _renderBinNumber); - conf.get("max_altitude", _maxAltitude); - conf.get("vdatum", vdatum()); - maskLayer().get(conf, "mask_layer"); -} - -osgEarth::Config -TritonLayer::Options::getConfig() const -{ - osgEarth::Config conf = osgEarth::VisibleLayer::Options::getConfig(); - conf.set("user", _user); - conf.set("license_code", _licenseCode); - conf.set("resource_path", _resourcePath); - conf.set("use_height_map", _useHeightMap); - conf.set("height_map_size", _heightMapSize); - conf.set("render_bin_number", _renderBinNumber); - conf.set("max_altitude", _maxAltitude); - conf.set("vdatum", vdatum()); - maskLayer().set(conf, "mask_layer"); - - return conf; -} - -//........................................................................ - -/** Register this layer so it can be used in an earth file */ -namespace osgEarth { namespace Triton -{ - REGISTER_OSGEARTH_LAYER(triton, TritonLayer); - REGISTER_OSGEARTH_LAYER(triton_ocean, TritonLayer); -} } - -OE_LAYER_PROPERTY_IMPL(TritonLayer, std::string, UserName, user); -OE_LAYER_PROPERTY_IMPL(TritonLayer, std::string, LicenseCode, licenseCode); -OE_LAYER_PROPERTY_IMPL(TritonLayer, std::string, ResourcePath, resourcePath); -OE_LAYER_PROPERTY_IMPL(TritonLayer, bool, UseHeightMap, useHeightMap); -OE_LAYER_PROPERTY_IMPL(TritonLayer, unsigned, HeightMapSize, heightMapSize); -OE_LAYER_PROPERTY_IMPL(TritonLayer, int, RenderBinNumber, renderBinNumber); -OE_LAYER_PROPERTY_IMPL(TritonLayer, float, MaxAltitude, maxAltitude); -OE_LAYER_PROPERTY_IMPL(TritonLayer, std::string, VerticalDatum, vdatum); - -void -TritonLayer::init() -{ - super::init(); - - _seaLevel = 0.0f; - - // Trick to force the VisibleLayer to install its opacity shader, - // which a modified Triton user-functions.glsl shader needs in order to control - // sea surface opacity. - float opacity = getOpacity(); - setOpacity(0.0f); - setOpacity(opacity); - - this->setName("Triton"); - setRenderType(RENDERTYPE_CUSTOM); - - ElevationLOD* lod = new ElevationLOD(); - _root = lod; - if (options().maxAltitude().isSet()) - { - OE_DEBUG << LC << "Setting max altitude = " << options().maxAltitude().get() << std::endl; - lod->setMaxElevation(options().maxAltitude().get()); - } - - _tritonNode = new TritonLayerNode(this, options().maskLayer()); - _root->addChild(_tritonNode.get()); -} - -void -TritonLayer::setUserCallback(Callback* callback) -{ - static_cast(_tritonNode.get())->setUserCallback(callback); -} - -osg::Node* -TritonLayer::getNode() const -{ - return _root.get(); -} - -void -TritonLayer::setMaskLayer(osgEarth::ImageLayer* maskLayer) -{ - options().maskLayer().setLayer(maskLayer); - static_cast(_tritonNode.get())->dirty(); -} - -osgEarth::ImageLayer* -TritonLayer::getMaskLayer() const -{ - return options().maskLayer().getLayer(); -} - -void -TritonLayer::addedToMap(const osgEarth::Map* map) -{ - VisibleLayer::addedToMap(map); - options().maskLayer().addedToMap(map); -} - -void -TritonLayer::removedFromMap(const osgEarth::Map* map) -{ - VisibleLayer::removedFromMap(map); - options().maskLayer().removedFromMap(map); - setMaskLayer(0L); -} - -void -TritonLayer::addIntersections(TritonIntersections* value) -{ - TritonLayerNode* node = static_cast(_tritonNode.get()); - node->_isect.push_back(value); -} - -osgEarth::Config -TritonLayer::getConfig() const -{ - osgEarth::Config c = osgEarth::VisibleLayer::getConfig(); - return c; -} diff --git a/src/scene/TritonLayer.h b/src/scene/TritonLayer.h deleted file mode 100644 index d5b6cd0c..00000000 --- a/src/scene/TritonLayer.h +++ /dev/null @@ -1,125 +0,0 @@ -/* -*-c++-*- */ -/* osgEarth - Geospatial SDK for OpenSceneGraph - * Copyright 2020 Pelican Mapping - * http://osgearth.org - * - * osgEarth is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - */ -#ifndef OSGEARTH_TRITON_LAYER -#define OSGEARTH_TRITON_LAYER 1 - -#include -#include -#include -#include "TritonCallback.h" -#include "TritonIntersections.h" - -namespace osgEarth { namespace Triton -{ - /** - * Node that roots the Triton adapter. - */ - class TritonLayer : public osgEarth::VisibleLayer - { - public: - class Options : public osgEarth::VisibleLayer::Options { - public: - META_LayerOptions(osgEarth, Options, osgEarth::VisibleLayer::Options); - OE_OPTION(std::string, user); - OE_OPTION(std::string, licenseCode); - OE_OPTION(std::string, resourcePath); - OE_OPTION(bool, useHeightMap, true); - OE_OPTION(unsigned, heightMapSize, 1024); - OE_OPTION(int, renderBinNumber, 12); - OE_OPTION(float, maxAltitude, 50000.0f); - OE_OPTION(std::string, vdatum, "egm96"); - OE_OPTION_LAYER(osgEarth::ImageLayer, maskLayer); - virtual Config getConfig() const; - private: - void fromConfig(const Config& conf); - }; - - public: - META_Layer(osgEarth, TritonLayer, Options, osgEarth::VisibleLayer, triton); - - //! Sets the user callback that's invoked when Triton start up - void setUserCallback(Triton::Callback* callback); - - //! User name for license - void setUserName(const std::string& value); - const std::string& getUserName() const; - - //! License code - void setLicenseCode(const std::string& value); - const std::string& getLicenseCode() const; - - //! Triton resource path - void setResourcePath(const std::string& value); - const std::string& getResourcePath() const; - - //! Whether to use a height map to fade out the ocean at the coastline - void setUseHeightMap(const bool& value); - const bool& getUseHeightMap() const; - - //! Size in texels of the height map (each dimension) - void setHeightMapSize(const unsigned& value); - const unsigned& getHeightMapSize() const; - - //! Render bin number to use for the ocean rendering - void setRenderBinNumber(const int& value); - const int& getRenderBinNumber() const; - - //! Masking layer for the ocean - void setMaskLayer(osgEarth::ImageLayer* maskLayer); - osgEarth::ImageLayer* getMaskLayer() const; - - //! Maximum visibility altitude - void setMaxAltitude(const float& value); - const float& getMaxAltitude() const; - - //! Vertical datum to use to calculate sea level - void setVerticalDatum(const std::string& value); - const std::string& getVerticalDatum() const; - - //! Adds an intersection set. - //! Each frame, Triton will perform intersections against the ocean surface - //! (including the waves) and populate the set with the results. - void addIntersections(TritonIntersections*); - - public: // Layer - - virtual osg::Node* getNode() const; - - //! Serialize - virtual Config getConfig() const; - - protected: // Layer - - virtual void init(); - - virtual void addedToMap(const class osgEarth::Map*); - - virtual void removedFromMap(const class osgEarth::Map*); - - private: - - osg::ref_ptr _root; - osg::ref_ptr _tritonNode; - float _seaLevel; - float _opacity; - }; - -} } // namespace osgEarth::Triton - -#endif // OSGEARTH_TRITON_LAYER diff --git a/src/translations/Dyt_zh_CN.ts b/src/translations/Dyt_zh_CN.ts index 063e10aa..20ced467 100644 --- a/src/translations/Dyt_zh_CN.ts +++ b/src/translations/Dyt_zh_CN.ts @@ -840,12 +840,12 @@ QObject - + error - + the appliaction is crash diff --git a/src/ui/ModelBrowser/ModelTreeWidget.cpp b/src/ui/ModelBrowser/ModelTreeWidget.cpp index 87eebfc4..28276a71 100644 --- a/src/ui/ModelBrowser/ModelTreeWidget.cpp +++ b/src/ui/ModelBrowser/ModelTreeWidget.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include "common/RecourceHelper.h" #include "common/SpdLogger.h" diff --git a/src/utils/StringUtils.cpp b/src/utils/StringUtils.cpp index 92a28cbf..a26ee6e8 100644 --- a/src/utils/StringUtils.cpp +++ b/src/utils/StringUtils.cpp @@ -68,9 +68,9 @@ std::string StringUtils::ViewpointToString(const osgEarth::Viewpoint& value) { double latitude = location->y(); double altitude = location->z(); - double heading = value.heading().get(); - double pitch = value.pitch().get(); - double range = value.range().get(); + double heading = value.heading().get().getValue(); + double pitch = value.pitch().get().getValue(); + double range = value.range().get().getValue(); std::stringstream ss; ss << std::fixed << std::setprecision(6); diff --git a/src/viewer/OSGEnv.cpp b/src/viewer/OSGEnv.cpp index 8c1460e5..99241ac5 100644 --- a/src/viewer/OSGEnv.cpp +++ b/src/viewer/OSGEnv.cpp @@ -11,7 +11,8 @@ bool s_gBChecked = false; bool OSGEnv::init() { - osgEarth::initialize(); + //osgEarth::initialize(); + //osgEarth::Registry::instance()->getCapabilities(); /*const osgEarth::Capabilities& csCapabilities = osgEarth::Registry::instance()->getCapabilities(); s_gBChecked = csCapabilities.supportsGLSL(); if (!s_gBChecked) { @@ -19,33 +20,33 @@ bool OSGEnv::init() { } int nMax, nMin; - sscanf(csCapabilities.getVersion().data(), "%d.%d", &nMax, &nMin); - QSurfaceFormat format = QSurfaceFormat::defaultFormat(); - osg::GraphicsContext::Traits traits(osg::DisplaySettings::instance().get()); + sscanf(csCapabilities.getVersion().data(), "%d.%d", &nMax, &nMin);*/ + //QSurfaceFormat format = QSurfaceFormat::defaultFormat(); + //osg::GraphicsContext::Traits traits(osg::DisplaySettings::instance().get()); - int nHttpThreads = osg::DisplaySettings::instance()->getNumOfDatabaseThreadsHint(); - nHttpThreads = nHttpThreads < 1 ? 1 : nHttpThreads; - osg::DisplaySettings::instance()->setNumOfHttpDatabaseThreadsHint(nHttpThreads); - format.setAlphaBufferSize(traits.alpha); - format.setRedBufferSize(traits.red); - format.setGreenBufferSize(traits.green); - format.setBlueBufferSize(traits.blue); - format.setDepthBufferSize(traits.depth); - format.setStencilBufferSize(traits.stencil); - format.setSamples(traits.samples); - format.setVersion(nMax, nMin); + //int nHttpThreads = osg::DisplaySettings::instance()->getNumOfDatabaseThreadsHint(); + //nHttpThreads = nHttpThreads < 1 ? 1 : nHttpThreads; + //osg::DisplaySettings::instance()->setNumOfHttpDatabaseThreadsHint(nHttpThreads); + //format.setAlphaBufferSize(traits.alpha); + //format.setRedBufferSize(traits.red); + //format.setGreenBufferSize(traits.green); + //format.setBlueBufferSize(traits.blue); + //format.setDepthBufferSize(traits.depth); + //format.setStencilBufferSize(traits.stencil); + //format.setSamples(traits.samples); + //format.setVersion(nMax, nMin); - /// 判断是否支持核心模式 - if (csCapabilities.isCoreProfile()) { - format.setProfile(QSurfaceFormat::CoreProfile); - } else { - format.setProfile(QSurfaceFormat::CompatibilityProfile); - } + ///// 判断是否支持核心模式 + //if (csCapabilities.isCoreProfile()) { + // format.setProfile(QSurfaceFormat::CoreProfile); + //} else { + // format.setProfile(QSurfaceFormat::CompatibilityProfile); + //} - format.setSwapInterval(traits.vsync ? 1 : 0); - format.setStereo(traits.quadBufferStereo ? 1 : 0); + //format.setSwapInterval(traits.vsync ? 1 : 0); + //format.setStereo(traits.quadBufferStereo ? 1 : 0); - QSurfaceFormat::setDefaultFormat(format);*/ + //QSurfaceFormat::setDefaultFormat(format); osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper("osg::Image"); return true; diff --git a/src/viewer/OsgViewWidget.cpp b/src/viewer/OsgViewWidget.cpp index e6d0ddb9..05a5d8e2 100644 --- a/src/viewer/OsgViewWidget.cpp +++ b/src/viewer/OsgViewWidget.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include @@ -34,9 +34,9 @@ OsgViewWidget::OsgViewWidget(QWidget* parent /*= nullptr*/) - : QGLWidget(parent) { + : QOpenGLWidget(parent) { //osgEarth::initialize(); - osg::ref_ptr ds = osg::DisplaySettings::instance(); + /* osg::ref_ptr ds = osg::DisplaySettings::instance(); osg::ref_ptr traits = new osg::GraphicsContext::Traits(ds); traits->x = 0; @@ -45,16 +45,20 @@ OsgViewWidget::OsgViewWidget(QWidget* parent /*= nullptr*/) traits->height = height(); traits->alpha = ds->getMinimumNumAlphaBits(); traits->stencil = ds->getMinimumNumStencilBits(); - traits->sampleBuffers = 2/*ds->getMultiSamples()*/;//_numMultiSamples osg default was 0 - traits->samples = 4/*ds->getNumMultiSamples()*/;//_numMultiSamples osg default was 0 - gw_ = new GraphicsWindowEx(traits); + traits->sampleBuffers = ds->getMultiSamples(); + traits->samples = ds->getNumMultiSamples();*/ - setAttribute(Qt::WA_PaintOnScreen, true); - setAttribute(Qt::WA_StaticContents, true); - setAttribute(Qt::WA_NoSystemBackground, true); - setAttribute(Qt::WA_OpaquePaintEvent, true); - setAttribute(Qt::WA_DontCreateNativeAncestors, false); + //gw_ = new GraphicsWindowEx(traits); + //gw_ = new GraphicsWindowEx(0, 0, width(), height()); + + //setAttribute(Qt::WA_PaintOnScreen, true); + //setAttribute(Qt::WA_StaticContents, true); + //setAttribute(Qt::WA_NoSystemBackground, true); + //setAttribute(Qt::WA_OpaquePaintEvent, true); + //setAttribute(Qt::WA_DontCreateNativeAncestors, false); setFocusPolicy(Qt::ClickFocus); + + connect(this, &OsgViewWidget::signalInitialized, &WorkSpaceManager::Get(), &WorkSpaceManager::OnRendererLoaded); } @@ -75,25 +79,30 @@ void OsgViewWidget::OnLoadDyt(const QString& path) { } void OsgViewWidget::initializeGL() { - QGLWidget::initializeGL(); + //QOpenGLWidget::initializeGL(); - osgViewer::Viewer* viewer = OsgViewer::Get().GetViewer(); - dyt_check(nullptr != viewer); + //osgViewer::Viewer* viewer = OsgViewer::Get().GetViewer(); + //dyt_check(nullptr != viewer); - osg::Camera* camera = viewer->getCamera(); - camera->setGraphicsContext(gw_); - camera->setViewport(new osg::Viewport(0, 0, width(), height())); - camera->setDrawBuffer(GL_BACK); - camera->setReadBuffer(GL_BACK); - camera->setProjectionMatrixAsPerspective(45, 1.0, 0.01, 100.); + //osg::Camera* camera = viewer->getCamera(); + //camera->setGraphicsContext(gw_); + //camera->setViewport(new osg::Viewport(0, 0, width(), height())); + ////camera->setDrawBuffer(GL_BACK); + ////camera->setReadBuffer(GL_BACK); + //camera->setProjectionMatrixAsPerspective(45, 1.0, 0.01, 100.); OsgViewer::Get().Initialize(); - OsgViewer::Get().OnFrame(); + emit signalInitialized(); } void OsgViewWidget::resizeGL(int width, int height) { - gw_->getEventQueue()->windowResize(0, 0, width, height); - gw_->resized(0, 0, width, height); + //gw_->getEventQueue()->windowResize(0, 0, width, height); + //gw_->resized(0, 0, width, height); +} + +void OsgViewWidget::paintGL() { + OsgViewer::Get().OnFrame(); + update(); } void OsgViewWidget::keyPressEvent(QKeyEvent* event) { @@ -123,7 +132,7 @@ void OsgViewWidget::mousePressEvent(QMouseEvent* event) { case(Qt::NoButton): button = 0; break; default: button = 0; break; } - gw_->getEventQueue()->mouseButtonPress(event->x(), event->y(), button); + //gw_->getEventQueue()->mouseButtonPress(event->x(), event->y(), button); } void OsgViewWidget::mouseReleaseEvent(QMouseEvent* event) { @@ -135,7 +144,7 @@ void OsgViewWidget::mouseReleaseEvent(QMouseEvent* event) { case(Qt::NoButton): button = 0; break; default: button = 0; break; } - gw_->getEventQueue()->mouseButtonRelease(event->x(), event->y(), button); + //gw_->getEventQueue()->mouseButtonRelease(event->x(), event->y(), button); } void OsgViewWidget::mouseDoubleClickEvent(QMouseEvent* event) { @@ -154,18 +163,18 @@ void OsgViewWidget::mouseDoubleClickEvent(QMouseEvent* event) { default: button = 0; break; } setKeyboardModifiers(event); - gw_->getEventQueue()->mouseDoubleButtonPress(event->x(), event->y(), button); + //gw_->getEventQueue()->mouseDoubleButtonPress(event->x(), event->y(), button); - QGLWidget::mouseDoubleClickEvent(event); + QOpenGLWidget::mouseDoubleClickEvent(event); } void OsgViewWidget::wheelEvent(QWheelEvent* event) { setKeyboardModifiers(event); - gw_->getEventQueue()->mouseScroll( - event->orientation() == Qt::Vertical ? - (event->delta() > 0 ? osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN) : - (event->delta() > 0 ? osgGA::GUIEventAdapter::SCROLL_LEFT : osgGA::GUIEventAdapter::SCROLL_RIGHT)); - QGLWidget::wheelEvent(event); + //gw_->getEventQueue()->mouseScroll( + // event->orientation() == Qt::Vertical ? + // (event->delta() > 0 ? osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN) : + // (event->delta() > 0 ? osgGA::GUIEventAdapter::SCROLL_LEFT : osgGA::GUIEventAdapter::SCROLL_RIGHT)); + QOpenGLWidget::wheelEvent(event); } void OsgViewWidget::setKeyboardModifiers(QInputEvent* event) { @@ -175,6 +184,6 @@ void OsgViewWidget::setKeyboardModifiers(QInputEvent* event) { if (modkey & Qt::ControlModifier) mask |= osgGA::GUIEventAdapter::MODKEY_CTRL; if (modkey & Qt::AltModifier) mask |= osgGA::GUIEventAdapter::MODKEY_ALT; - gw_->getEventQueue()->getCurrentEventState()->setModKeyMask(mask); + //gw_->getEventQueue()->getCurrentEventState()->setModKeyMask(mask); } diff --git a/src/viewer/OsgViewWidget.h b/src/viewer/OsgViewWidget.h index d4347153..718c32f8 100644 --- a/src/viewer/OsgViewWidget.h +++ b/src/viewer/OsgViewWidget.h @@ -1,7 +1,6 @@ #pragma once - #include -#include + #include #include "scene/OEScene.h" #include "viewer/GraphicsWindowEx.h" @@ -13,7 +12,7 @@ class QKeyEvent; class QInputEvent; class QResizeEvent; -class OsgViewWidget : public QGLWidget { +class OsgViewWidget : public QOpenGLWidget { Q_OBJECT public: explicit OsgViewWidget(QWidget* parent = nullptr); @@ -48,10 +47,12 @@ public: signals: void signalResetWorkSpace(); void signalScaleInfo(const QString&); + void signalInitialized(); protected: void initializeGL(); void resizeGL(int width, int height) override; + void paintGL() override; void keyPressEvent(QKeyEvent* event) override; void keyReleaseEvent(QKeyEvent* event) override; void mousePressEvent(QMouseEvent* event) override; diff --git a/src/viewer/OsgViewer.cpp b/src/viewer/OsgViewer.cpp index 8e28226c..afbc529d 100644 --- a/src/viewer/OsgViewer.cpp +++ b/src/viewer/OsgViewer.cpp @@ -11,20 +11,15 @@ #include "viewer/OsgView.h" #include "viewer/IUpdateRender.h" #include "workspace/WorkSpaceManager.h" +#include template<> OsgViewer* Singleton::instance_ = nullptr; constexpr QEvent::Type sOsgViewUpdateEvent{ QEvent::Type(QEvent::User + 1) }; OsgViewer::OsgViewer(QObject* parent) noexcept - : QObject(parent) - , viewer_(new osgViewer::Viewer) { + : QObject(parent) { LOG_INFO("actor, self={}", fmt::ptr(this)); - viewer_->setKeyEventSetsDone(0); - //compositeViewer_->getDatabasePager()->setUnrefImageDataAfterApplyPolicy(true, false); - osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper("osg::Image"); - viewer_->setThreadingModel(osgViewer::ViewerBase::ThreadingModel::SingleThreaded); - } OsgViewer::~OsgViewer() { @@ -51,7 +46,7 @@ void OsgViewer::OnFrame(void) { viewer_->frame(); } - qApp->postEvent(this, new QEvent(sOsgViewUpdateEvent)); + //qApp->postEvent(this, new QEvent(sOsgViewUpdateEvent)); } OsgView* OsgViewer::CreateView(int x, int y, int width, int height, void* winHandle) { @@ -93,6 +88,13 @@ bool OsgViewer::Initialize(void) { if (initalized_) { return initalized_; } + + viewer_ = new osgViewer::Viewer; + viewer_->setKeyEventSetsDone(0); + //compositeViewer_->getDatabasePager()->setUnrefImageDataAfterApplyPolicy(true, false); + //osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper("osg::Image"); + //viewer_->setThreadingModel(osgViewer::ViewerBase::ThreadingModel::SingleThreaded); + viewer_->setRealizeOperation(new osgEarth::GL3RealizeOperation()); initalized_ = true; //compositeViewer_->setRealizeOperation(new osgEarth::GL3RealizeOperation()); return initalized_; diff --git a/src/viewer/QtOsgViewWidget.cpp b/src/viewer/QtOsgViewWidget.cpp index 242b7a38..6fab7004 100644 --- a/src/viewer/QtOsgViewWidget.cpp +++ b/src/viewer/QtOsgViewWidget.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include diff --git a/src/viewer/ViewWidget.cpp b/src/viewer/ViewWidget.cpp index 7f602258..5f276241 100644 --- a/src/viewer/ViewWidget.cpp +++ b/src/viewer/ViewWidget.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include #include @@ -48,6 +48,7 @@ ViewWidget::ViewWidget(QWidget* parent /*= nullptr*/) //setThreadingModel(osgViewer::ViewerBase::SingleThreaded); //getCamera()->setNearFarRatio(0.0000001); //getCamera()->setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES);//); + } void ViewWidget::Initialize(void) { diff --git a/src/viewer/ViewWidget.h b/src/viewer/ViewWidget.h index c9a38671..2a2bb47d 100644 --- a/src/viewer/ViewWidget.h +++ b/src/viewer/ViewWidget.h @@ -14,4 +14,5 @@ public: void Initialize(void) override; void Uninitialize(void) override; + }; \ No newline at end of file diff --git a/src/workspace/WorkSpaceManager.cpp b/src/workspace/WorkSpaceManager.cpp index 6c60ad48..e1661a02 100644 --- a/src/workspace/WorkSpaceManager.cpp +++ b/src/workspace/WorkSpaceManager.cpp @@ -6,6 +6,7 @@ #include "app/Application.h" #include "workspace/WorkSpace.h" +#include "viewer/OsgViewer.h" #include "workspace/Timestep.h" #include "common/SpdLogger.h" @@ -169,13 +170,13 @@ void WorkSpaceManager::OnFrame() { lastTime_ = t; } -void WorkSpaceManager::OnRendererLoaded(OSGRenderer* renderer) { +void WorkSpaceManager::OnRendererLoaded() { if (scene_) { LOG_INFO("activeScene_ loaded"); return; } - - renderer_ = renderer; + return; + osgViewer::Viewer* renderer = OsgViewer::Get().GetViewer(); scene_ = new OEScene; scene_->AttachView(renderer); scene_->InitEventHandle(renderer); diff --git a/src/workspace/WorkSpaceManager.h b/src/workspace/WorkSpaceManager.h index 006aa123..35d2e662 100644 --- a/src/workspace/WorkSpaceManager.h +++ b/src/workspace/WorkSpaceManager.h @@ -32,7 +32,7 @@ public: void OnFrame(); - void OnRendererLoaded(OSGRenderer* renderer); + void OnRendererLoaded(); signals: void WorkSpaceChanged(WorkSpace*);