OSGEarth嵌入Qt的QGraphicsView框架(二)

原创 2015年07月08日 21:52:43

上一篇处理了QGraphicsView的鼠标、按键事件,本篇接着嵌入OSGEarth。
新建一继承自EventAdapter(一)的类GraphicsView,完成OSGEarth的嵌入工作。实现思路是QGraphicsView的Viewport用OpenGL来绘制,这样才可以完全OSG的update。而要完成每帧的更新,则需要一个定时器,每隔10ms更新一次,即每10ms调用一次OSG的frame操作。
实现代码:graphicsview.h

class GraphicsView : public EventAdapter
{
    Q_OBJECT

public:
    GraphicsView(QWidget* parent = 0);
    ~GraphicsView();

    osgViewer::Viewer* getOSGViewer(){ return m_pViewer; }
    osg::Group* getRoot(){ return m_pSceneData; }
    osgEarth::MapNode* getMapNode(){ return m_pMapNode; }
    const osgEarth::SpatialReference* getSRS(){ return m_pMapSRS; }
    osgEarth::Util::EarthManipulator* getManipulator(){ return m_pEarthManipulator; }

protected:
    // 完成OSG每一帧的update操作
    virtual void drawBackground(QPainter *painter, const QRectF& rect);
    virtual void timerEvent(QTimerEvent *event);

private:
    void init();

private:
    osgEarth::Map* m_pMap;
    osg::Group* m_pSceneData;
    osg::StateSet* m_pStateSet;
    osgViewer::Viewer* m_pViewer;
    osgEarth::MapNode* m_pMapNode;
    osgEarth::Util::SkyNode* m_pSkyNode;
    const osgEarth::SpatialReference* m_pMapSRS;
    osgEarth::Util::EarthManipulator* m_pEarthManipulator;
};

几个get方法,获取OSGEarth相关的Viewer、Group、MapNode、SpatialReference、EarthManipulator等给外部使用。

实现代码:graphicsview.cpp

GraphicsView::GraphicsView(QWidget *parent)
{
    this->setScene(new QGraphicsScene);
    init();
}

GraphicsView::~GraphicsView()
{

}

void GraphicsView::init()
{
    // QGraphicsViewViewport一定要设置为QGLWidget,因为只有这样才能用OpenGL来对OSG进行更新
    QGLWidget* glViewPort = new QGLWidget;
    glViewPort->setMouseTracking(true);
    glViewPort->setMaximumSize(2000, 2000);
    this->setViewport(glViewPort);
    this->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
    startTimer(10);

    osg::Group* pRoot = new osg::Group;
    pRoot->setName("root");

    m_pSceneData = new osg::Group;
    m_pSceneData->setName("SceneData");

    m_pStateSet = new osg::StateSet;
    m_pStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
    pRoot->setStateSet(m_pStateSet);
    pRoot->addChild(m_pSceneData);

    // 使用earth文件的方式进行数据加载,驱动为TMS
    osg::Node* node = osgDB::readNodeFile("../LiuPanShui.earth");
    if (node)
    {
        m_pMapNode = osgEarth::MapNode::findMapNode(node);
        m_pMapNode->setName("MapNode");
        m_pMap = m_pMapNode->getMap();
        m_pMapSRS = m_pMapNode->getMapSRS();
    }

    m_pViewer = new osgViewer::Viewer;
    m_pEarthManipulator = new osgEarth::Util::EarthManipulator;

    m_pEarthManipulator->getSettings()->setMinMaxPitch(-90.0, -7.0);
    m_pViewer->setCameraManipulator(m_pEarthManipulator);
    m_pViewer->addEventHandler(new osgViewer::StatsHandler);
    m_pViewer->addEventHandler(new osgGA::StateSetManipulator(m_pViewer->getCamera()->getOrCreateStateSet()));
    m_pViewer->getCamera()->addCullCallback(new osgEarth::Util::AutoClipPlaneCullCallback(m_pMapNode));
    m_pViewer->getCamera()->setNearFarRatio(0.0000002);
    m_pViewer->getCamera()->setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES);
    m_pViewer->setUpViewerAsEmbeddedInWindow(0, 0, width(), height());
    m_pViewer->setSceneData(pRoot);
    m_pGraphicsWindow = dynamic_cast<osgViewer::GraphicsWindow*>(
        m_pViewer->getCamera()->getGraphicsContext());
    m_pEarthManipulator->setViewpoint(osgEarth::Util::Viewpoint(
        104.81443, 26.60379, 1811.2336, 0.0, -90.0, 5000));

    m_pSkyNode = osgEarth::Util::SkyNode::create(m_pMapNode);
    m_pSkyNode->setName("SkyNode");
    // 设置时间;
    osgEarth::DateTime dateTime(2015, 8, 15, 6);
    osgEarth::Util::Ephemeris* ephemeris = new osgEarth::Util::Ephemeris;
    m_pSkyNode->setEphemeris(ephemeris);
    m_pSkyNode->setDateTime(dateTime);
    m_pSkyNode->attach(m_pViewer, 0);
    m_pSkyNode->setLighting(true);
    m_pSkyNode->addChild(m_pMapNode);
    pRoot->addChild(m_pSkyNode);
}

void GraphicsView::timerEvent(QTimerEvent *event)
{
    this->scene()->update();
}

void GraphicsView::drawBackground(QPainter *painter, const QRectF& rect)
{
    if (painter->paintEngine()->type() != QPaintEngine::OpenGL2)
    {
        return;
    }

    // Save the painter state
    painter->save();
    painter->beginNativePainting();

    // OSG帧更新
    m_pViewer->frame();

    painter->endNativePainting();
    painter->restore();
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

第1课时《Qt osgEarth 编程入门》

1.首先编译osg /osgEarth 源码,配置环境变量,将osg及osgEarth 对应的bin目录加入系统环境中。 2.在QT中的pro文件中进行引用: include(deployment....

OSGEarth嵌入Qt的QGraphicsView框架(一)

近期在学习OSGEarth,看example,自己结合Qt写了一些小例子,特此记录一下。 首先,考虑到OE(OSGEarth)嵌入到QGraphicsView中,首先收到按键、鼠标事件的就是QGrap...
  • chlk118
  • chlk118
  • 2015年07月08日 21:27
  • 5161

利用 MSYS2 及osgEarth 构建三维地球模型(2) osgEarth 与 Qt的结合

上一篇中,我们已经使用傻瓜化的 pacman -S 安装了 openSceneGraph 与 osgEarth 。为了在Qt中导入osgEarth 的窗口,需要安装 osgQt 模块。 注意,这个包...

QT5.4.1+VS2012+OSG3.2.3+osgearth2.7编译问题总结

问题1:在cmake中配置QT变量的时候出现如下问题: CMake Warning at CMakeLists.txt:5 (FIND_PACKAGE):   By not providing "...

osgEarth嵌入QT的QWidget

一直比较推崇QT这个界面库,所以打算把osg嵌入到QT里面做一个QWidget的子控件。 在查阅了官方的osgViewerQT后,决定写一个子类,同时继承osgViewer::Viewer和QGLW...

OSG获取鼠标点选事件的位置

OSG点选操作的思路是从osgGA::GUIEventHandler继承,并重新实现虚函数virtual bool handle(const osgGA::GUIEventAdapter& ea, o...
  • chlk118
  • chlk118
  • 2015年07月08日 22:13
  • 4622

将OSG嵌入QT窗口系统中,实现拖拽界面

将OSG嵌入QT窗口系统中,实现拖拽界面 一、原理 OSG底层使用的是OpenGL图形系统,QT也增加了对OpenGL的支持,因此,可以通过QT的OpenGL模块,实现将OSG窗口嵌入到Q...

Qt中嵌入OSG

最近因项目需要在Qt中嵌入OSG界面,遂尝试了一番: 实验环境:vs2010+Qt4.8.3+OSG3.0.1 osg能够和很多的GUI界面进行融合,其源码包中含的工程代码为我们展示了使用的示例: ...

OSG嵌入Qt的第二种方式:使用QOpenGLWidget/QGLWidget

几天前有朋友问OSG嵌入Qt的思路。我说整体思路就是用OpenGL的方式来进行OSG的绘制,而正好Qt已经整合了OpenGL的功能,我们可以以此为依托来进行OSG的渲染绘制工作。而在Qt中却有QWid...
  • chlk118
  • chlk118
  • 2015年07月18日 21:00
  • 5685

osg与qt环境搭建+视频的讲解已经录好

我是一个比较喜欢总节的人,而且愿意把它用视频记录下来,在工作的一年多的时间里我录了有不少视频都是我自己总节并学习的视频。      比如说是c++的小游戏做的愤怒的小鸟,还有就是第一年工作人事mfc的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OSGEarth嵌入Qt的QGraphicsView框架(二)
举报原因:
原因补充:

(最多只允许输入30个字)