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();
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

osgOcean笔记

1.osg中设置抗锯齿的方法 osg:DisplaySettings* ds = osg:DisplaySettings::instance(); ds->setNumMultiSamples(16...

OSGEarth嵌入Qt的QGraphicsView框架(一)

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

Linux常用名令--1文件操作命令

1. ls:列出文件列表       格式: ls  option,option可以是: -a 列出隐藏文件,-l 列出文件详细信息 2. pwd:查看当前目录 3. mkdir: 创建目录 4. t...

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

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

OSG 添加操作器及功能列表

本文参考osgChina官网及FreeSouth《OSG程序设计教程》相关信息 //添加一些操作器       osg::ref_ptr keyswitchManipulator = new o...

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

OSG点选操作的思路是从osgGA::GUIEventHandler继承,并重新实现虚函数virtual bool handle(const osgGA::GUIEventAdapter& ea, o...

OSG第二代文件序列化存储分析

花了两天时间仔细研究了一下array贡献的第二代文件序列化存储,收益颇多。今后将得益于它的很强的可扩展性。通过自身的体验,感觉应该还有很多初学者可能需要花费几个小时才能看透,所以特将自己分析的流程发上...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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