关闭

OSGEarth嵌入Qt的QGraphicsView框架(二)

3911人阅读 评论(1) 收藏 举报
分类:

上一篇处理了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();
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:114940次
    • 积分:1507
    • 等级:
    • 排名:千里之外
    • 原创:44篇
    • 转载:0篇
    • 译文:0篇
    • 评论:101条
    文章分类
    最新评论