260 lines
10 KiB
C++
260 lines
10 KiB
C++
// Copyright (C) 2017 Mike Krus
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU 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
|
|
// General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
#include "viewer/OSGRenderer.h"
|
|
|
|
//#include <osgQOpenGL/CullVisitorEx>
|
|
//#include <osgQOpenGL/GraphicsWindowEx>
|
|
|
|
#include <QApplication>
|
|
#include <QScreen>
|
|
#include <QOpenGLContext>
|
|
#include <QOpenGLFunctions>
|
|
#include <QOpenGLShaderProgram>
|
|
#include <QOpenGLVertexArrayObject>
|
|
|
|
#include <QKeyEvent>
|
|
#include <QMouseEvent>
|
|
#include <QWheelEvent>
|
|
|
|
#include <QThread>
|
|
|
|
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<unsigned int, int> KeyMap;
|
|
KeyMap mKeyMap;
|
|
};
|
|
|
|
static QtKeyboardMap s_QtKeyboardMap;
|
|
} // namespace
|
|
|
|
|
|
OSGRenderer::OSGRenderer(QObject *parent)
|
|
: QObject(parent)
|
|
, m_osgInitialized(false)
|
|
, m_windowScale(1.f)
|
|
, m_continuousUpdate(true)
|
|
{
|
|
|
|
}
|
|
|
|
void OSGRenderer::render()
|
|
{
|
|
if (m_osgViewer.getSceneData())
|
|
m_osgViewer.frame();
|
|
if (m_continuousUpdate)
|
|
update();
|
|
}
|
|
|
|
void OSGRenderer::resize(int windowWidth, int windowHeight, float windowScale)
|
|
{
|
|
if (!m_osgInitialized)
|
|
return;
|
|
m_windowScale = windowScale;
|
|
m_osgViewer.getCamera()->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 );
|
|
}
|
|
|
|
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);
|
|
// make sure the event queue has the correct window rectangle size and input range
|
|
m_osgWinEmb->getEventQueue()->syncWindowRectangleWithGraphicsContext();
|
|
|
|
m_osgViewer.getCamera()->setViewport(new osg::Viewport(0, 0, windowWidth * windowScale, windowHeight * windowScale));
|
|
m_osgViewer.getCamera()->setGraphicsContext(m_osgWinEmb.get());
|
|
m_osgViewer.getCamera()->setClearColor(osg::Vec4(1., 1., 1., 1.));
|
|
m_osgViewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
|
|
|
|
osgViewer::Viewer::Windows windows;
|
|
m_osgViewer.getWindows(windows);
|
|
for(osgViewer::Viewer::Windows::iterator itr = windows.begin(); itr != windows.end(); ++itr)
|
|
{
|
|
(*itr)->getState()->setUseModelViewAndProjectionUniforms(true);
|
|
(*itr)->getState()->setUseVertexAttributeAliasing(true);
|
|
}
|
|
}
|
|
|
|
void OSGRenderer::setKeyboardModifiers( QInputEvent* event ) const
|
|
{
|
|
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()->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) );
|
|
}
|