diff --git a/src/translations/Dyt_zh_CN.ts b/src/translations/Dyt_zh_CN.ts index 02b3d9db..ca96e8d9 100644 --- a/src/translations/Dyt_zh_CN.ts +++ b/src/translations/Dyt_zh_CN.ts @@ -1838,17 +1838,17 @@ osgQOpenGLWidget - + Screen %1 - + Choose fullscreen target screen - + Screen diff --git a/src/viewer/GraphicsWindowEx.cpp b/src/viewer/GraphicsWindowEx.cpp index 3f20fd9a..10a813cb 100644 --- a/src/viewer/GraphicsWindowEx.cpp +++ b/src/viewer/GraphicsWindowEx.cpp @@ -1,15 +1,338 @@ #include "viewer/GraphicsWindowEx.h" + +#include +#include +#include +#include +#include + #include "viewer/StateEx.h" +#include "config.h" +#include "common/SpdLogger.h" +// +//GraphicsWindowEx::GraphicsWindowEx(osg::GraphicsContext::Traits* traits) +// : osgViewer::GraphicsWindowEmbedded(traits) { +// _traits = traits; +// +// init(); +//} -GraphicsWindowEx::GraphicsWindowEx(osg::GraphicsContext::Traits* traits) - : osgViewer::GraphicsWindowEmbedded(traits) { - _traits = traits; +namespace { + + class QtKeyboardMap { + public: + QtKeyboardMap() { + mKeyMap[Qt::Key_Escape] = osgGA::GUIEventAdapter::KEY_Escape; + mKeyMap[Qt::Key_Delete] = osgGA::GUIEventAdapter::KEY_Delete; + mKeyMap[Qt::Key_Home] = osgGA::GUIEventAdapter::KEY_Home; + mKeyMap[Qt::Key_Enter] = osgGA::GUIEventAdapter::KEY_KP_Enter; + mKeyMap[Qt::Key_End] = osgGA::GUIEventAdapter::KEY_End; + mKeyMap[Qt::Key_Return] = osgGA::GUIEventAdapter::KEY_Return; + mKeyMap[Qt::Key_PageUp] = osgGA::GUIEventAdapter::KEY_Page_Up; + mKeyMap[Qt::Key_PageDown] = osgGA::GUIEventAdapter::KEY_Page_Down; + mKeyMap[Qt::Key_Left] = osgGA::GUIEventAdapter::KEY_Left; + mKeyMap[Qt::Key_Right] = osgGA::GUIEventAdapter::KEY_Right; + mKeyMap[Qt::Key_Up] = osgGA::GUIEventAdapter::KEY_Up; + mKeyMap[Qt::Key_Down] = osgGA::GUIEventAdapter::KEY_Down; + mKeyMap[Qt::Key_Backspace] = osgGA::GUIEventAdapter::KEY_BackSpace; + mKeyMap[Qt::Key_Tab] = osgGA::GUIEventAdapter::KEY_Tab; + mKeyMap[Qt::Key_Space] = osgGA::GUIEventAdapter::KEY_Space; + mKeyMap[Qt::Key_Delete] = osgGA::GUIEventAdapter::KEY_Delete; + mKeyMap[Qt::Key_Alt] = osgGA::GUIEventAdapter::KEY_Alt_L; + mKeyMap[Qt::Key_Shift] = osgGA::GUIEventAdapter::KEY_Shift_L; + mKeyMap[Qt::Key_Control] = osgGA::GUIEventAdapter::KEY_Control_L; + mKeyMap[Qt::Key_Meta] = osgGA::GUIEventAdapter::KEY_Meta_L; + mKeyMap[Qt::Key_F1] = osgGA::GUIEventAdapter::KEY_F1; + mKeyMap[Qt::Key_F2] = osgGA::GUIEventAdapter::KEY_F2; + mKeyMap[Qt::Key_F3] = osgGA::GUIEventAdapter::KEY_F3; + mKeyMap[Qt::Key_F4] = osgGA::GUIEventAdapter::KEY_F4; + mKeyMap[Qt::Key_F5] = osgGA::GUIEventAdapter::KEY_F5; + mKeyMap[Qt::Key_F6] = osgGA::GUIEventAdapter::KEY_F6; + mKeyMap[Qt::Key_F7] = osgGA::GUIEventAdapter::KEY_F7; + mKeyMap[Qt::Key_F8] = osgGA::GUIEventAdapter::KEY_F8; + mKeyMap[Qt::Key_F9] = osgGA::GUIEventAdapter::KEY_F9; + mKeyMap[Qt::Key_F10] = osgGA::GUIEventAdapter::KEY_F10; + mKeyMap[Qt::Key_F11] = osgGA::GUIEventAdapter::KEY_F11; + mKeyMap[Qt::Key_F12] = osgGA::GUIEventAdapter::KEY_F12; + mKeyMap[Qt::Key_F13] = osgGA::GUIEventAdapter::KEY_F13; + mKeyMap[Qt::Key_F14] = osgGA::GUIEventAdapter::KEY_F14; + mKeyMap[Qt::Key_F15] = osgGA::GUIEventAdapter::KEY_F15; + mKeyMap[Qt::Key_F16] = osgGA::GUIEventAdapter::KEY_F16; + mKeyMap[Qt::Key_F17] = osgGA::GUIEventAdapter::KEY_F17; + mKeyMap[Qt::Key_F18] = osgGA::GUIEventAdapter::KEY_F18; + mKeyMap[Qt::Key_F19] = osgGA::GUIEventAdapter::KEY_F19; + mKeyMap[Qt::Key_F20] = osgGA::GUIEventAdapter::KEY_F20; + mKeyMap[Qt::Key_hyphen] = '-'; + mKeyMap[Qt::Key_Equal] = '='; + mKeyMap[Qt::Key_division] = osgGA::GUIEventAdapter::KEY_KP_Divide; + mKeyMap[Qt::Key_multiply] = osgGA::GUIEventAdapter::KEY_KP_Multiply; + mKeyMap[Qt::Key_Minus] = '-'; + mKeyMap[Qt::Key_Plus] = '+'; + mKeyMap[Qt::Key_Insert] = osgGA::GUIEventAdapter::KEY_KP_Insert; + } + + ~QtKeyboardMap() {} + + int remapKey(QKeyEvent* event) { + KeyMap::iterator itr = mKeyMap.find(event->key()); + + if (itr == mKeyMap.end()) { + return int(*(event->text().toLatin1().data())); + } else + return itr->second; + } + + private: + typedef std::map KeyMap; + KeyMap mKeyMap; + }; + + static QtKeyboardMap s_QtKeyboardMap; + + static void setKeyboardModifiers(osgGA::EventQueue* eventQueue, QInputEvent* event) { + unsigned int modkey = event->modifiers() & (Qt::ShiftModifier | + Qt::ControlModifier | + Qt::AltModifier); + unsigned int mask = 0; + + if (modkey & Qt::ShiftModifier) mask |= osgGA::GUIEventAdapter::MODKEY_SHIFT; + + if (modkey & Qt::ControlModifier) mask |= osgGA::GUIEventAdapter::MODKEY_CTRL; + + if (modkey & Qt::AltModifier) mask |= osgGA::GUIEventAdapter::MODKEY_ALT; + + eventQueue->getCurrentEventState()->setModKeyMask(mask); + } +} // namespace - init(); -} GraphicsWindowEx::GraphicsWindowEx(int x, int y, int width, int height) : osgViewer::GraphicsWindowEmbedded(x, y, width, height) + , offScreenSurface_(new QOffscreenSurface) + , offScreenContext_(new QOpenGLContext) { + LOG_INFO("actor, self={}", spdlog::fmt_lib::ptr(this)); +} + +GraphicsWindowEx::~GraphicsWindowEx() { + LOG_INFO("dctor isSharedContextSet_:{}, self={}", isSharedContextSet_, spdlog::fmt_lib::ptr(this)); + if (!isSharedContextSet_) { + return; + } + + if (isFrameBufferInitialized_) { + offScreenContext_->makeCurrent(offScreenSurface_.get()); + renderFramebuffer_.reset(); + sharedFrameBuffer_.reset(); + offScreenContext_->doneCurrent(); + } + + offScreenContext_.reset(); + offScreenSurface_.reset(); +} + +bool GraphicsWindowEx::realizeImplementation() { + LOG_INFO("realizeImplementation, isRealized_:{}, self={}", isRealized_, spdlog::fmt_lib::ptr(this)); + if (isRealized_) { + return true; + } + + dyt_check(nullptr != _state); + _state->resetVertexAttributeAlias(false); + + _state->setModeValidity(GL_LIGHTING, false); + _state->setModeValidity(GL_NORMALIZE, false); + _state->setModeValidity(GL_RESCALE_NORMAL, false); + _state->setModeValidity(GL_LINE_STIPPLE, false); + _state->setModeValidity(GL_LINE_SMOOTH, false); + + isRealized_ = true; + return true; +} + +bool GraphicsWindowEx::makeCurrentImplementation() { + LOG_INFO("makeCurrentImplementation, isRealized_:{}, self={}", isRealized_, spdlog::fmt_lib::ptr(this)); + dyt_check(nullptr != offScreenContext_); + offScreenContext_->makeCurrent(offScreenSurface_.get()); + InitFrameBuffer(); + + setDefaultFboId(renderFramebuffer_->handle()); + renderFramebuffer_->bind(); + return true; +} + +bool GraphicsWindowEx::releaseContextImplementation() { + LOG_INFO("releaseContextImplementation, self={}", spdlog::fmt_lib::ptr(this)); + offScreenContext_->doneCurrent(); + return true; +} + +void GraphicsWindowEx::swapBuffersImplementation() { + offScreenContext_->functions()->glFinish(); + frameBufferId_ = renderFramebuffer_->texture(); + if (!isRenderDonwn_) { + return; + } + qSwap(renderFramebuffer_, sharedFrameBuffer_); + isRenderDonwn_ = false; +} + +bool GraphicsWindowEx::SetSharedContext(QOpenGLContext* sharedContext) { + LOG_INFO("Set shared context, {}", isSharedContextSet_); + if (isSharedContextSet_) { + return true; + } + + offScreenContext_->setFormat(sharedContext->format()); + offScreenContext_->setShareContext(sharedContext); + + isSharedContextSet_ = offScreenContext_->create(); + if (!isSharedContextSet_) { + LOG_ERROR("Failed to create offscreen context"); + return false; + } + + offScreenSurface_->setFormat(offScreenContext_->format()); + offScreenSurface_->create(); + return true; +} + +void GraphicsWindowEx::keyPressEvent(QKeyEvent* event) { + setKeyboardModifiers(getEventQueue(), event); + int value = s_QtKeyboardMap.remapKey(event); + getEventQueue()->keyPress(value); +} + +void GraphicsWindowEx::keyReleaseEvent(QKeyEvent* event) { + if (event->isAutoRepeat()) { + event->ignore(); + } else { + setKeyboardModifiers(getEventQueue(), event); + int value = s_QtKeyboardMap.remapKey(event); + getEventQueue()->keyPress(value); + } +} + +void GraphicsWindowEx::mousePressEvent(QMouseEvent* event) { + int button = 0; + + switch (event->button()) { + case Qt::LeftButton: + button = 1; + break; + + case Qt::MidButton: + button = 2; + break; + + case Qt::RightButton: + button = 3; + break; + + case Qt::NoButton: + button = 0; + break; + + default: + button = 0; + break; + } + + setKeyboardModifiers(getEventQueue(), event); + getEventQueue()->mouseButtonPress(event->x() * windowScale_, + event->y() * windowScale_, button); +} + +void GraphicsWindowEx::mouseReleaseEvent(QMouseEvent* event) { + int button = 0; + + switch (event->button()) { + case Qt::LeftButton: + button = 1; + break; + + case Qt::MidButton: + button = 2; + break; + + case Qt::RightButton: + button = 3; + break; + + case Qt::NoButton: + button = 0; + break; + + default: + button = 0; + break; + } + + setKeyboardModifiers(getEventQueue(), event); + getEventQueue()->mouseButtonRelease(event->x() * windowScale_, + event->y() * windowScale_, button); +} + +void GraphicsWindowEx::mouseDoubleClickEvent(QMouseEvent* event) { + int button = 0; + + switch (event->button()) { + case Qt::LeftButton: + button = 1; + break; + + case Qt::MidButton: + button = 2; + break; + + case Qt::RightButton: + button = 3; + break; + + case Qt::NoButton: + button = 0; + break; + + default: + button = 0; + break; + } + + setKeyboardModifiers(getEventQueue(), event); + getEventQueue()->mouseDoubleButtonPress(event->x() * windowScale_, + event->y() * windowScale_, button); +} + +void GraphicsWindowEx::mouseMoveEvent(QMouseEvent* event) { + setKeyboardModifiers(getEventQueue(), event); + getEventQueue()->mouseMotion(event->x() * windowScale_, + event->y() * windowScale_); +} + +void GraphicsWindowEx::wheelEvent(QWheelEvent* event) { + setKeyboardModifiers(getEventQueue(), event); + getEventQueue()->mouseMotion(event->x() * windowScale_, + event->y() * windowScale_); + 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)); +} + +void GraphicsWindowEx::InitFrameBuffer() { + if (isFrameBufferInitialized_) { + return; + } + + QOpenGLFramebufferObjectFormat format; + format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + + dyt_check(nullptr != _traits); + renderFramebuffer_.reset(new QOpenGLFramebufferObject(_traits->width, _traits->height, format)); + sharedFrameBuffer_.reset(new QOpenGLFramebufferObject(_traits->width, _traits->height, format)); + + isFrameBufferInitialized_ = true; } diff --git a/src/viewer/GraphicsWindowEx.h b/src/viewer/GraphicsWindowEx.h index ad2a0bb1..6d7adcdd 100644 --- a/src/viewer/GraphicsWindowEx.h +++ b/src/viewer/GraphicsWindowEx.h @@ -3,14 +3,17 @@ #include +#include +#include +#include + /// Needed for mixing osg rendering with Qt 2D drawing using QPainter... /// See http://forum.openscenegraph.org/viewtopic.php?t=15627&view=previous -class GraphicsWindowEx : public osgViewer::GraphicsWindowEmbedded -{ -public: - GraphicsWindowEx(osg::GraphicsContext::Traits* traits = 0); +class GraphicsWindowEx : public osgViewer::GraphicsWindowEmbedded { +public: GraphicsWindowEx(int x, int y, int width, int height); + ~GraphicsWindowEx() override; virtual bool isSameKindAs(const osg::Object* object) const { @@ -30,27 +33,46 @@ public: { return true; } - virtual bool realizeImplementation() - { - return true; + bool isRealizedImplementation() const override { + return isRealized_; } - virtual bool isRealizedImplementation() const - { - return true; + bool realizeImplementation() override; + bool makeCurrentImplementation() override; + void closeImplementation() override {} + bool releaseContextImplementation() override; + void swapBuffersImplementation() override; + + bool SetSharedContext(QOpenGLContext* sharedContext); + void UpdateWindowScale(float scale) { + windowScale_ = scale; } - virtual void closeImplementation() {} - virtual bool makeCurrentImplementation() - { - return true; - } - virtual bool releaseContextImplementation() - { - return true; - } - virtual void swapBuffersImplementation() {} - virtual void grabFocus() {} - virtual void grabFocusIfPointerInWindow() {} - virtual void raiseWindow() {} + +public: + void keyPressEvent(class QKeyEvent* event); + void keyReleaseEvent(class QKeyEvent* event); + void mousePressEvent(class QMouseEvent* event); + void mouseReleaseEvent(class QMouseEvent* event); + void mouseDoubleClickEvent(class QMouseEvent* event); + void mouseMoveEvent(class QMouseEvent* event); + void wheelEvent(class QWheelEvent* event); + +protected: + void InitFrameBuffer(); + +private: + std::unique_ptr offScreenSurface_{nullptr}; + std::unique_ptr offScreenContext_{ nullptr }; + std::unique_ptr renderFramebuffer_{ nullptr }; + std::unique_ptr sharedFrameBuffer_{ nullptr }; + + bool isSharedContextSet_{ false }; + bool isRealized_{ false }; + bool isFrameBufferInitialized_{ false }; + bool isRenderDonwn_{ false }; + unsigned int frameBufferId_{ 0 }; + + float windowScale_{ 1.0f }; + }; #endif // GRAPHICSWINDOWEX_H diff --git a/src/viewer/OSGRenderer.cpp b/src/viewer/OSGRenderer.cpp index 8c42ac08..2c7af4fa 100644 --- a/src/viewer/OSGRenderer.cpp +++ b/src/viewer/OSGRenderer.cpp @@ -15,7 +15,7 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "viewer/OSGRenderer.h" -#include "viewer/osgQOpenGLWindow.h" +#include "viewer/OsgOpenGLWindow.h" #include "viewer/osgQOpenGLWidget.h" //#include @@ -32,481 +32,66 @@ #include #include -#include +#include -namespace -{ +#include "config.h" +#include "common/SpdLogger.h" - class QtKeyboardMap - { - public: - QtKeyboardMap() - { - mKeyMap[Qt::Key_Escape ] = osgGA::GUIEventAdapter::KEY_Escape; - mKeyMap[Qt::Key_Delete ] = osgGA::GUIEventAdapter::KEY_Delete; - mKeyMap[Qt::Key_Home ] = osgGA::GUIEventAdapter::KEY_Home; - mKeyMap[Qt::Key_Enter ] = osgGA::GUIEventAdapter::KEY_KP_Enter; - mKeyMap[Qt::Key_End ] = osgGA::GUIEventAdapter::KEY_End; - mKeyMap[Qt::Key_Return ] = osgGA::GUIEventAdapter::KEY_Return; - mKeyMap[Qt::Key_PageUp ] = osgGA::GUIEventAdapter::KEY_Page_Up; - mKeyMap[Qt::Key_PageDown ] = osgGA::GUIEventAdapter::KEY_Page_Down; - mKeyMap[Qt::Key_Left ] = osgGA::GUIEventAdapter::KEY_Left; - mKeyMap[Qt::Key_Right ] = osgGA::GUIEventAdapter::KEY_Right; - mKeyMap[Qt::Key_Up ] = osgGA::GUIEventAdapter::KEY_Up; - mKeyMap[Qt::Key_Down ] = osgGA::GUIEventAdapter::KEY_Down; - mKeyMap[Qt::Key_Backspace ] = osgGA::GUIEventAdapter::KEY_BackSpace; - mKeyMap[Qt::Key_Tab ] = osgGA::GUIEventAdapter::KEY_Tab; - mKeyMap[Qt::Key_Space ] = osgGA::GUIEventAdapter::KEY_Space; - mKeyMap[Qt::Key_Delete ] = osgGA::GUIEventAdapter::KEY_Delete; - mKeyMap[Qt::Key_Alt ] = osgGA::GUIEventAdapter::KEY_Alt_L; - mKeyMap[Qt::Key_Shift ] = osgGA::GUIEventAdapter::KEY_Shift_L; - mKeyMap[Qt::Key_Control ] = osgGA::GUIEventAdapter::KEY_Control_L; - mKeyMap[Qt::Key_Meta ] = osgGA::GUIEventAdapter::KEY_Meta_L; - mKeyMap[Qt::Key_F1 ] = osgGA::GUIEventAdapter::KEY_F1; - mKeyMap[Qt::Key_F2 ] = osgGA::GUIEventAdapter::KEY_F2; - mKeyMap[Qt::Key_F3 ] = osgGA::GUIEventAdapter::KEY_F3; - mKeyMap[Qt::Key_F4 ] = osgGA::GUIEventAdapter::KEY_F4; - mKeyMap[Qt::Key_F5 ] = osgGA::GUIEventAdapter::KEY_F5; - mKeyMap[Qt::Key_F6 ] = osgGA::GUIEventAdapter::KEY_F6; - mKeyMap[Qt::Key_F7 ] = osgGA::GUIEventAdapter::KEY_F7; - mKeyMap[Qt::Key_F8 ] = osgGA::GUIEventAdapter::KEY_F8; - mKeyMap[Qt::Key_F9 ] = osgGA::GUIEventAdapter::KEY_F9; - mKeyMap[Qt::Key_F10 ] = osgGA::GUIEventAdapter::KEY_F10; - mKeyMap[Qt::Key_F11 ] = osgGA::GUIEventAdapter::KEY_F11; - mKeyMap[Qt::Key_F12 ] = osgGA::GUIEventAdapter::KEY_F12; - mKeyMap[Qt::Key_F13 ] = osgGA::GUIEventAdapter::KEY_F13; - mKeyMap[Qt::Key_F14 ] = osgGA::GUIEventAdapter::KEY_F14; - mKeyMap[Qt::Key_F15 ] = osgGA::GUIEventAdapter::KEY_F15; - mKeyMap[Qt::Key_F16 ] = osgGA::GUIEventAdapter::KEY_F16; - mKeyMap[Qt::Key_F17 ] = osgGA::GUIEventAdapter::KEY_F17; - mKeyMap[Qt::Key_F18 ] = osgGA::GUIEventAdapter::KEY_F18; - mKeyMap[Qt::Key_F19 ] = osgGA::GUIEventAdapter::KEY_F19; - mKeyMap[Qt::Key_F20 ] = osgGA::GUIEventAdapter::KEY_F20; - mKeyMap[Qt::Key_hyphen ] = '-'; - mKeyMap[Qt::Key_Equal ] = '='; - mKeyMap[Qt::Key_division ] = osgGA::GUIEventAdapter::KEY_KP_Divide; - mKeyMap[Qt::Key_multiply ] = osgGA::GUIEventAdapter::KEY_KP_Multiply; - mKeyMap[Qt::Key_Minus ] = '-'; - mKeyMap[Qt::Key_Plus ] = '+'; - mKeyMap[Qt::Key_Insert ] = osgGA::GUIEventAdapter::KEY_KP_Insert; - } - ~QtKeyboardMap() - { - } - - int remapKey(QKeyEvent* event) - { - KeyMap::iterator itr = mKeyMap.find(event->key()); - - if(itr == mKeyMap.end()) - { - return int(*(event->text().toLatin1().data())); - } - else - return itr->second; - } - - private: - typedef std::map KeyMap; - KeyMap mKeyMap; - }; - - static QtKeyboardMap s_QtKeyboardMap; -} // namespace OSGRenderer::OSGRenderer(QObject* parent) - : QObject(parent), osgViewer::Viewer() -{ - // QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, - // [this]() - // { - // _applicationAboutToQuit = true; - // killTimer(_timerId); - // _timerId = 0; - // }); -} - -OSGRenderer::OSGRenderer(osg::ArgumentParser* arguments, QObject* parent) - : QObject(parent), osgViewer::Viewer(*arguments) -{ - // QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, - // [this]() - // { - // _applicationAboutToQuit = true; - // killTimer(_timerId); - // _timerId = 0; - // }); + : QObject(parent), osgViewer::Viewer() { } OSGRenderer::~OSGRenderer() { } -void OSGRenderer::update() -{ - osgQOpenGLWindow* osgWidgetRendered = dynamic_cast(parent()); - - if(osgWidgetRendered != nullptr) - { - osgWidgetRendered->_osgWantsToRenderFrame = true; - osgWidgetRendered->update(); - } - - else - { - osgQOpenGLWidget* osgWidget = dynamic_cast(parent()); - osgWidget->_osgWantsToRenderFrame = true; - osgWidget->update(); - } -} - -void OSGRenderer::resize(int windowWidth, int windowHeight, float windowScale) -{ - if(!m_osgInitialized) - return; - - m_windowScale = windowScale; - - /* _camera->setViewport(new osg::Viewport(0, 0, windowWidth * windowScale, - windowHeight * windowScale));*/ - - m_osgWinEmb->resized(0, 0, - windowWidth * windowScale, - windowHeight * windowScale); - m_osgWinEmb->getEventQueue()->windowResize(0, 0, - windowWidth * windowScale, - windowHeight * windowScale); - - update(); -} - - -void OSGRenderer::setupOSG(int windowWidth, int windowHeight, float windowScale) -{ - m_osgInitialized = true; - m_windowScale = windowScale; - m_osgWinEmb = new osgViewer::GraphicsWindowEmbedded(0, 0, - windowWidth * windowScale, windowHeight * windowScale); - //m_osgWinEmb = new osgViewer::GraphicsWindowEmbedded(0, 0, windowWidth * windowScale, windowHeight * windowScale); - // make sure the event queue has the correct window rectangle size and input range - m_osgWinEmb->getEventQueue()->syncWindowRectangleWithGraphicsContext(); - _camera->setViewport(new osg::Viewport(0, 0, windowWidth * windowScale, - windowHeight * windowScale)); - _camera->setGraphicsContext(m_osgWinEmb.get()); - // disable key event (default is Escape key) that the viewer checks on each - // frame to see - // if the viewer's done flag should be set to signal end of viewers main - // loop. - setKeyEventSetsDone(0); - setReleaseContextAtEndOfFrameHint(false); - setThreadingModel(osgViewer::Viewer::SingleThreaded); - - osgViewer::Viewer::Windows windows; - getWindows(windows); - - _timerId = startTimer(10, Qt::PreciseTimer); - _lastFrameStartTime.setStartTick(0); -} - -void OSGRenderer::setKeyboardModifiers(QInputEvent* event) -{ - unsigned int modkey = event->modifiers() & (Qt::ShiftModifier | - Qt::ControlModifier | - Qt::AltModifier); - unsigned int mask = 0; - - if(modkey & Qt::ShiftModifier) mask |= osgGA::GUIEventAdapter::MODKEY_SHIFT; - - if(modkey & Qt::ControlModifier) mask |= osgGA::GUIEventAdapter::MODKEY_CTRL; - - if(modkey & Qt::AltModifier) mask |= osgGA::GUIEventAdapter::MODKEY_ALT; - - m_osgWinEmb->getEventQueue()->getCurrentEventState()->setModKeyMask(mask); -} - -void OSGRenderer::keyPressEvent(QKeyEvent* event) -{ - setKeyboardModifiers(event); - int value = s_QtKeyboardMap.remapKey(event); - m_osgWinEmb->getEventQueue()->keyPress(value); -} - -void OSGRenderer::keyReleaseEvent(QKeyEvent* event) -{ - if(event->isAutoRepeat()) - { - event->ignore(); - } - else - { - setKeyboardModifiers(event); - int value = s_QtKeyboardMap.remapKey(event); - m_osgWinEmb->getEventQueue()->keyRelease(value); - } -} - -void OSGRenderer::mousePressEvent(QMouseEvent* event) -{ - int button = 0; - - switch(event->button()) - { - case Qt::LeftButton: - button = 1; - break; - - case Qt::MidButton: - button = 2; - break; - - case Qt::RightButton: - button = 3; - break; - - case Qt::NoButton: - button = 0; - break; - - default: - button = 0; - break; - } - - setKeyboardModifiers(event); - m_osgWinEmb->getEventQueue()->mouseButtonPress(event->x() * m_windowScale, - event->y() * m_windowScale, button); -} - -void OSGRenderer::mouseReleaseEvent(QMouseEvent* event) -{ - int button = 0; - - switch(event->button()) - { - case Qt::LeftButton: - button = 1; - break; - - case Qt::MidButton: - button = 2; - break; - - case Qt::RightButton: - button = 3; - break; - - case Qt::NoButton: - button = 0; - break; - - default: - button = 0; - break; - } - - setKeyboardModifiers(event); - m_osgWinEmb->getEventQueue()->mouseButtonRelease(event->x() * m_windowScale, - event->y() * m_windowScale, button); -} - -void OSGRenderer::mouseDoubleClickEvent(QMouseEvent* event) -{ - int button = 0; - - switch(event->button()) - { - case Qt::LeftButton: - button = 1; - break; - - case Qt::MidButton: - button = 2; - break; - - case Qt::RightButton: - button = 3; - break; - - case Qt::NoButton: - button = 0; - break; - - default: - button = 0; - break; - } - - setKeyboardModifiers(event); - m_osgWinEmb->getEventQueue()->mouseDoubleButtonPress(event->x() * m_windowScale, - event->y() * m_windowScale, button); -} - -void OSGRenderer::mouseMoveEvent(QMouseEvent* event) -{ - setKeyboardModifiers(event); - m_osgWinEmb->getEventQueue()->mouseMotion(event->x() * m_windowScale, - event->y() * m_windowScale); -} - -void OSGRenderer::wheelEvent(QWheelEvent* event) -{ - setKeyboardModifiers(event); - m_osgWinEmb->getEventQueue()->mouseMotion(event->x() * m_windowScale, - event->y() * m_windowScale); - m_osgWinEmb->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)); -} - -bool OSGRenderer::checkEvents() -{ - // check events from any attached sources - for(Devices::iterator eitr = _eventSources.begin(); - eitr != _eventSources.end(); - ++eitr) - { - osgGA::Device* es = eitr->get(); - - if(es->getCapabilities() & osgGA::Device::RECEIVE_EVENTS) - { - if(es->checkEvents()) - return true; - } - - } - - // get events from all windows attached to Viewer. - Windows windows; - getWindows(windows); - - for(Windows::iterator witr = windows.begin(); - witr != windows.end(); - ++witr) - { - if((*witr)->checkEvents()) - return true; - } - - return false; -} - -bool OSGRenderer::checkNeedToDoFrame() -{ - // check if any event handler has prompted a redraw - if(_requestRedraw) - return true; - - if(_requestContinousUpdate) - return true; - - // check if the view needs to update the scene graph - // this check if camera has update callback and if scene requires to update scene graph - if(requiresUpdateSceneGraph()) - return true; - - // check if the database pager needs to update the scene - if(getDatabasePager()->requiresUpdateSceneGraph()) - return true; - - // check if the image pager needs to update the scene - if(getImagePager()->requiresUpdateSceneGraph()) - return true; - - - // check if the scene needs to be redrawn - if(requiresRedraw()) - return true; - - // check if events are available and need processing - if(checkEvents()) - return true; - - // and check again if any event handler has prompted a redraw - if(_requestRedraw) - return true; - - if(_requestContinousUpdate) - return true; - - return false; -} - -// called from ViewerWidget paintGL() method -void OSGRenderer::frame(double simulationTime) -{ - // limit the frame rate - if(getRunMaxFrameRate() > 0.0) - { - double dt = _lastFrameStartTime.time_s(); - double minFrameTime = 1.0 / getRunMaxFrameRate(); - - if(dt < minFrameTime) - QThread::usleep(static_cast(1000000.0 * (minFrameTime - dt))); - } - - // avoid excessive CPU loading when no frame is required in ON_DEMAND mode - if(getRunFrameScheme() == osgViewer::ViewerBase::ON_DEMAND) - { - double dt = _lastFrameStartTime.time_s(); - - if(dt < 0.01) - OpenThreads::Thread::microSleep(static_cast(1000000.0 * - (0.01 - dt))); - } - - // record start frame time - _lastFrameStartTime.setStartTick(); - // make frame - -#if 1 - osgViewer::Viewer::frame(simulationTime); -#else - - if(_done) return; - - // OSG_NOTICE<setGraphicsContext(gc); + getCamera()->setViewport(new osg::Viewport(0, 0, gc->getTraits()->width, gc->getTraits()->height)); + isInited_ = true; } + +void OSGRenderer::Resize(osg::GraphicsContext* gc, int width, int height) { + LOG_INFO("OSGRenderer::Resize {}, gc:{}", isInited_, spdlog::fmt_lib::ptr(gc)); + if (!gc) { + return; + } + + if (isInited_) { + return; + } + + osgViewer::GraphicsWindow* window = dynamic_cast(gc); + dyt_check(nullptr != window); + window->getEventQueue()->windowResize(0, 0, width, height); + window->resized(0, 0, width, height); +} + +bool OSGRenderer::event(QEvent* event) { + switch (event->type()) { + case INIT: { + RenderBindGraphicsContextEvent* e = reinterpret_cast(event); + Init(e->gc_.get()); + return true; + } + case RESIZE: { + GraphicsWindowResizeEvent* e = reinterpret_cast(event); + Resize(e->gc_.get(), e->width_, e->height_); + return true; + } + + } + return QObject::event(event); +} + diff --git a/src/viewer/OSGRenderer.h b/src/viewer/OSGRenderer.h index c7583b45..9fa56f53 100644 --- a/src/viewer/OSGRenderer.h +++ b/src/viewer/OSGRenderer.h @@ -18,79 +18,56 @@ #define OSGRENDERER_H #include +#include #include -class QInputEvent; -class QKeyEvent; -class QMouseEvent; -class QWheelEvent; -namespace eveBIM -{ - class ViewerWidget; +namespace { + enum RenderEvent { + INIT = QEvent::Type(QEvent::User + 1), + RENDER_START, + RESIZE, + RENDER_STOP + }; + + struct RenderBindGraphicsContextEvent : public QEvent { + RenderBindGraphicsContextEvent(osg::GraphicsContext* gc) + : QEvent(QEvent::Type(INIT)) + , gc_(gc) {} + + osg::observer_ptr gc_; + }; + + struct GraphicsWindowResizeEvent : public QEvent { + GraphicsWindowResizeEvent(osg::GraphicsContext* gc, int width, int height) + : QEvent(QEvent::Type(RESIZE)) + , gc_(gc) + , width_(width) + , height_(height) {} + + osg::observer_ptr gc_; + int width_; + int height_; + }; + } -class OSGRenderer : public QObject, public osgViewer::Viewer -{ - bool m_osgInitialized {false}; - osg::ref_ptr m_osgWinEmb; - float m_windowScale {1.0f}; - bool m_continuousUpdate {true}; - - int _timerId{0}; - osg::Timer _lastFrameStartTime; - bool _applicationAboutToQuit {false}; - bool _osgWantsToRenderFrame{true}; - +class OSGRenderer : public QObject, public osgViewer::Viewer { Q_OBJECT - - friend class eveBIM::ViewerWidget; - public: explicit OSGRenderer(QObject* parent = nullptr); - explicit OSGRenderer(osg::ArgumentParser* arguments, QObject* parent = nullptr); ~OSGRenderer() override; - bool continuousUpdate() const - { - return m_continuousUpdate; - } - void setContinuousUpdate(bool continuousUpdate) - { - m_continuousUpdate = continuousUpdate; - } + bool event(QEvent* event) override; - virtual void keyPressEvent(QKeyEvent* event); - virtual void keyReleaseEvent(QKeyEvent* event); - virtual void mousePressEvent(QMouseEvent* event); - virtual void mouseReleaseEvent(QMouseEvent* event); - virtual void mouseDoubleClickEvent(QMouseEvent* event); - virtual void mouseMoveEvent(QMouseEvent* event); - virtual void wheelEvent(QWheelEvent* event); - - virtual void resize(int windowWidth, int windowHeight, float windowScale); - - void setupOSG(int windowWidth, int windowHeight, float windowScale); - - // overrided from osgViewer::Viewer - virtual bool checkNeedToDoFrame() override; - - // overrided from osgViewer::ViewerBase - void frame(double simulationTime = USE_REFERENCE_TIME) override; - - // overrided from osgViewer::Viewer - void requestRedraw() override; - // overrided from osgViewer::Viewer - bool checkEvents() override; - void update(); - -protected: - void timerEvent(QTimerEvent* event) override; - - void setKeyboardModifiers(QInputEvent* event); +private: + void Init(osg::GraphicsContext* gc); + void Resize(osg::GraphicsContext* gc, int width, int height); +private: + bool isInited_{ false }; }; #endif // OSGRENDERER_H diff --git a/src/viewer/OsgOpenGLWindow.cpp b/src/viewer/OsgOpenGLWindow.cpp new file mode 100644 index 00000000..305607cf --- /dev/null +++ b/src/viewer/OsgOpenGLWindow.cpp @@ -0,0 +1,138 @@ +#include "viewer/OsgOpenGLWindow.h" +#include "viewer/OSGRenderer.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "viewer/GraphicsWindowEx.h" + + +OsgOpenGLWindow::OsgOpenGLWindow(QWidget* parent) + : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, nullptr) +{ + widget_ = QWidget::createWindowContainer(this); + renderer_ = new OSGRenderer(this); +} + +OsgOpenGLWindow::~OsgOpenGLWindow() +{ +} + +osgViewer::Viewer* OsgOpenGLWindow::getOsgViewer() +{ + return m_renderer; +} + +OpenThreads::ReadWriteMutex* OsgOpenGLWindow::mutex() +{ + return &_osgMutex; +} + + +void OsgOpenGLWindow::initializeGL() +{ + //// Initializes OpenGL function resolution for the current context. + //initializeOpenGLFunctions(); + //createRenderer(); + //emit initialized(); + context()->doneCurrent(); + gw_->SetSharedContext(context()); + QApplication::postEvent(this, new RenderBindGraphicsContextEvent(gw_)); + + double pixelRatio = screen()->devicePixelRatio(); + gw_->UpdateWindowScale(pixelRatio); + QApplication::postEvent(this, new GraphicsWindowResizeEvent(gw_, width() * pixelRatio, height() * pixelRatio)); + +} + +void OsgOpenGLWindow::resizeGL(int w, int h) +{ + Q_ASSERT(m_renderer); + double pixelRatio = screen()->devicePixelRatio(); + gw_->UpdateWindowScale(pixelRatio); + QApplication::postEvent(this, new GraphicsWindowResizeEvent(gw_, w * pixelRatio, h * pixelRatio)); +} + +void OsgOpenGLWindow::paintGL() +{ + OpenThreads::ScopedReadLock locker(_osgMutex); + if (_isFirstFrame) { + _isFirstFrame = false; + m_renderer->getCamera()->getGraphicsContext()->setDefaultFboId(defaultFramebufferObject()); + } + m_renderer->frame(); +} + +void OsgOpenGLWindow::keyPressEvent(QKeyEvent* event) +{ + Q_ASSERT(gw_); + // forward event to renderer + gw_->keyPressEvent(event); +} + +void OsgOpenGLWindow::keyReleaseEvent(QKeyEvent* event) +{ + Q_ASSERT(gw_); + // forward event to renderer + gw_->keyReleaseEvent(event); +} + +void OsgOpenGLWindow::mousePressEvent(QMouseEvent* event) +{ + Q_ASSERT(gw_); + // forward event to renderer + gw_->mousePressEvent(event); +} + +void OsgOpenGLWindow::mouseReleaseEvent(QMouseEvent* event) +{ + Q_ASSERT(gw_); + // forward event to renderer + gw_->mouseReleaseEvent(event); +} + +void OsgOpenGLWindow::mouseDoubleClickEvent(QMouseEvent* event) +{ + Q_ASSERT(gw_); + // forward event to renderer + gw_->mouseDoubleClickEvent(event); +} + +void OsgOpenGLWindow::mouseMoveEvent(QMouseEvent* event) +{ + Q_ASSERT(gw_); + // forward event to renderer + gw_->mouseMoveEvent(event); +} + +void OsgOpenGLWindow::wheelEvent(QWheelEvent* event) +{ + Q_ASSERT(gw_); + // forward event to renderer + gw_->wheelEvent(event); +} + +void OsgOpenGLWindow::setDefaultDisplaySettings() +{ + osg::DisplaySettings* ds = osg::DisplaySettings::instance().get(); + ds->setNvOptimusEnablement(1); + ds->setStereo(false); +} + +void OsgOpenGLWindow::createRenderer() +{ + // call this before creating a View... + setDefaultDisplaySettings(); + + /*m_renderer = new OSGRenderer(this); + double pixelRatio = screen()->devicePixelRatio(); + m_renderer->setupOSG(width(), height(), pixelRatio);*/ +} diff --git a/src/viewer/osgQOpenGLWindow.h b/src/viewer/OsgOpenGLWindow.h similarity index 77% rename from src/viewer/osgQOpenGLWindow.h rename to src/viewer/OsgOpenGLWindow.h index 4a7fcd8c..8fc5fc9b 100644 --- a/src/viewer/osgQOpenGLWindow.h +++ b/src/viewer/OsgOpenGLWindow.h @@ -19,6 +19,8 @@ #include #include +#include + class OSGRenderer; class QWidget; @@ -27,9 +29,7 @@ namespace osgViewer class Viewer; } -class osgQOpenGLWindow : public QOpenGLWindow, - protected QOpenGLFunctions -{ +class OsgOpenGLWindow : public QOpenGLWindow { Q_OBJECT protected: @@ -39,11 +39,11 @@ protected: bool _isFirstFrame {true}; friend class OSGRenderer; - QWidget* _widget = nullptr; + public: - osgQOpenGLWindow(QWidget* parent = nullptr); - virtual ~osgQOpenGLWindow(); + OsgOpenGLWindow(QWidget* parent = nullptr); + ~OsgOpenGLWindow() override; /** Get osgViewer View */ virtual osgViewer::Viewer* getOsgViewer(); @@ -51,17 +51,15 @@ public: //! get mutex virtual OpenThreads::ReadWriteMutex* mutex(); - QWidget* asWidget() + QWidget* AsWidget() { - return _widget; + return widget_; } signals: void initialized(); protected: - - //! call createRender. If overloaded, this method must send initialized signal at end void initializeGL() override; void resizeGL(int w, int h) override; @@ -81,6 +79,13 @@ protected: void wheelEvent(QWheelEvent* event) override; void createRenderer(); + +private: + QWidget* widget_{ nullptr }; + osg::ref_ptr gw_; + OSGRenderer* renderer_{ nullptr }; + class QOpenGLShaderProgram* shaderProgram_{nullptr}; + class QOpenGLVertexArrayObject* vao_{ nullptr }; }; #endif // OSGQOPENGLWINDOW_H diff --git a/src/viewer/OsgViewWidget.cpp b/src/viewer/OsgViewWidget.cpp index e94ebfbc..bd4ffc7c 100644 --- a/src/viewer/OsgViewWidget.cpp +++ b/src/viewer/OsgViewWidget.cpp @@ -42,9 +42,11 @@ OsgViewWidget::OsgViewWidget(QWidget* parent /*= nullptr*/) traits->width = width(); traits->height = height(); traits->doubleBuffer = true; - traits->depth = 32; - traits->samples = 16; - gw_ = new GraphicsWindowEx(traits.get()); + //traits->depth = 32; + //traits->samples = 16; + traits->sharedContext = nullptr; + traits->setInheritedWindowPixelFormat = true; + //gw_ = new GraphicsWindowEx(traits.get()); setFocusPolicy(Qt::ClickFocus); } diff --git a/src/viewer/osgQOpenGLWidget.cpp b/src/viewer/osgQOpenGLWidget.cpp index 3ffd30d1..1d531b9f 100644 --- a/src/viewer/osgQOpenGLWidget.cpp +++ b/src/viewer/osgQOpenGLWidget.cpp @@ -12,6 +12,8 @@ #include #include +#if 0 + osgQOpenGLWidget::osgQOpenGLWidget(QWidget* parent) : QOpenGLWidget(parent) { @@ -221,3 +223,4 @@ void osgQOpenGLWidget::createRenderer() qApp->screens().front(); m_renderer->setupOSG(width(), height(), screen->devicePixelRatio()); } +#endif \ No newline at end of file diff --git a/src/viewer/osgQOpenGLWidget.h b/src/viewer/osgQOpenGLWidget.h index c873055a..76c54d74 100644 --- a/src/viewer/osgQOpenGLWidget.h +++ b/src/viewer/osgQOpenGLWidget.h @@ -22,6 +22,7 @@ #include class OSGRenderer; +#if 0 namespace osgViewer { @@ -84,5 +85,6 @@ protected: private: }; +#endif -#endif // OSGQOPENGLWIDGET_H +#endif // OSGQOPENGLWIDGET_H \ No newline at end of file diff --git a/src/viewer/osgQOpenGLWindow.cpp b/src/viewer/osgQOpenGLWindow.cpp deleted file mode 100644 index 14f0ef67..00000000 --- a/src/viewer/osgQOpenGLWindow.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include "viewer/osgQOpenGLWindow.h" -#include "viewer/OSGRenderer.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - - -osgQOpenGLWindow::osgQOpenGLWindow(QWidget* parent) - : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, nullptr) -{ - _widget = QWidget::createWindowContainer(this); -} - -osgQOpenGLWindow::~osgQOpenGLWindow() -{ -} - -osgViewer::Viewer* osgQOpenGLWindow::getOsgViewer() -{ - return m_renderer; -} - -OpenThreads::ReadWriteMutex* osgQOpenGLWindow::mutex() -{ - return &_osgMutex; -} - - -void osgQOpenGLWindow::initializeGL() -{ - // Initializes OpenGL function resolution for the current context. - initializeOpenGLFunctions(); - createRenderer(); - emit initialized(); -} - -void osgQOpenGLWindow::resizeGL(int w, int h) -{ - Q_ASSERT(m_renderer); - double pixelRatio = screen()->devicePixelRatio(); - m_renderer->resize(w, h, pixelRatio); -} - -void osgQOpenGLWindow::paintGL() -{ - OpenThreads::ScopedReadLock locker(_osgMutex); - if (_isFirstFrame) { - _isFirstFrame = false; - m_renderer->getCamera()->getGraphicsContext()->setDefaultFboId(defaultFramebufferObject()); - } - m_renderer->frame(); -} - -void osgQOpenGLWindow::keyPressEvent(QKeyEvent* event) -{ - Q_ASSERT(m_renderer); - // forward event to renderer - m_renderer->keyPressEvent(event); -} - -void osgQOpenGLWindow::keyReleaseEvent(QKeyEvent* event) -{ - Q_ASSERT(m_renderer); - // forward event to renderer - m_renderer->keyReleaseEvent(event); -} - -void osgQOpenGLWindow::mousePressEvent(QMouseEvent* event) -{ - Q_ASSERT(m_renderer); - // forward event to renderer - m_renderer->mousePressEvent(event); -} - -void osgQOpenGLWindow::mouseReleaseEvent(QMouseEvent* event) -{ - Q_ASSERT(m_renderer); - // forward event to renderer - m_renderer->mouseReleaseEvent(event); -} - -void osgQOpenGLWindow::mouseDoubleClickEvent(QMouseEvent* event) -{ - Q_ASSERT(m_renderer); - // forward event to renderer - m_renderer->mouseDoubleClickEvent(event); -} - -void osgQOpenGLWindow::mouseMoveEvent(QMouseEvent* event) -{ - Q_ASSERT(m_renderer); - // forward event to renderer - m_renderer->mouseMoveEvent(event); -} - -void osgQOpenGLWindow::wheelEvent(QWheelEvent* event) -{ - Q_ASSERT(m_renderer); - // forward event to renderer - m_renderer->wheelEvent(event); -} - -void osgQOpenGLWindow::setDefaultDisplaySettings() -{ - osg::DisplaySettings* ds = osg::DisplaySettings::instance().get(); - ds->setNvOptimusEnablement(1); - ds->setStereo(false); -} - -void osgQOpenGLWindow::createRenderer() -{ - // call this before creating a View... - setDefaultDisplaySettings(); - - m_renderer = new OSGRenderer(this); - double pixelRatio = screen()->devicePixelRatio(); - m_renderer->setupOSG(width(), height(), pixelRatio); -}