美文网首页
嵌入OSG模型

嵌入OSG模型

作者: downdemo | 来源:发表于2018-08-14 16:01 被阅读223次

利用osgQt的例子

  • osgdlg.h
#pragma once
#include <QTimer>
#include <QApplication>
#include <QGridLayout>

#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgGA/MultiTouchTrackballManipulator>

#include <osgDB/ReadFile>

#include <osgQt/GraphicsWindowQt>

#include <iostream>

class ViewerWidget : public QWidget, public osgViewer::CompositeViewer
{
public:
    ViewerWidget(QWidget* parent = 0, Qt::WindowFlags f = 0, osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::CompositeViewer::SingleThreaded) : QWidget(parent, f)
    {
        setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint); hide();
        setThreadingModel(threadingModel);
        osgViewer::GraphicsWindowEmbedded
            // disable the default setting of viewer.done() by pressing Escape.
            setKeyEventSetsDone(0);

        QWidget* widget1 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readRefNodeFile("cow.osg"));
        //QWidget* widget2 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readRefNodeFile("glider.osgt"));
        //QWidget* widget3 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readRefNodeFile("axes.osgt"));
        //QWidget* widget4 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readRefNodeFile("fountain.osgt"));

        QGridLayout* grid = new QGridLayout;
        grid->addWidget(widget1, 0, 0);
        //grid->addWidget(widget2, 0, 1);
        //grid->addWidget(widget3, 1, 0);
        //grid->addWidget(widget4, 1, 1);
        setLayout(grid);

        connect(&_timer, SIGNAL(timeout()), this, SLOT(update()));
        _timer.start(10);
    }

    QWidget* addViewWidget(osgQt::GraphicsWindowQt* gw, osg::ref_ptr<osg::Node> scene)
    {
        osgViewer::View* view = new osgViewer::View;
        addView(view);

        osg::Camera* camera = view->getCamera();
        camera->setGraphicsContext(gw);

        const osg::GraphicsContext::Traits* traits = gw->getTraits();

        camera->setClearColor(osg::Vec4(0.2, 0.2, 0.6, 1.0));
        camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));

        // set the draw and read buffers up for a double buffered window with rendering going to back buffer
        camera->setDrawBuffer(GL_BACK);
        camera->setReadBuffer(GL_BACK);

        camera->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width) / static_cast<double>(traits->height), 1.0f, 10000.0f);

        view->setSceneData(scene);
        view->addEventHandler(new osgViewer::StatsHandler);
        view->setCameraManipulator(new osgGA::MultiTouchTrackballManipulator);
        gw->setTouchEventsEnabled(true);
        return gw->getGLWidget();
    }

    osgQt::GraphicsWindowQt* createGraphicsWindow(int x, int y, int w, int h, const std::string& name = "", bool windowDecoration = false)
    {
        osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
        osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
        traits->windowName = name;
        traits->windowDecoration = windowDecoration;
        traits->x = x;
        traits->y = y;
        traits->width = w;
        traits->height = h;
        traits->doubleBuffer = true;
        traits->alpha = ds->getMinimumNumAlphaBits();
        traits->stencil = ds->getMinimumNumStencilBits();
        traits->sampleBuffers = ds->getMultiSamples();
        traits->samples = ds->getNumMultiSamples();

        return new osgQt::GraphicsWindowQt(traits.get());
    }

    virtual void paintEvent(QPaintEvent* /*event*/)
    {
        frame();
    }

protected:

    QTimer _timer;
};
  • 槽函数
void dlg::slot()
{
    ViewerWidget* view = new ViewerWidget(this, Qt::Widget, osgViewer::ViewerBase::SingleThreaded);
    view->setGeometry(0, 0, width(), height());
    view->show();
}

读取.osg文件并显示模型

  • MyOsgModule.h
#pragma once
#include <QTimer>
#include <QApplication>
#include <QGridLayout>

#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgGA/MultiTouchTrackballManipulator>

#include <osgDB/ReadFile>

#include <osgQt/GraphicsWindowQt>

#include <iostream>

class ViewerWidget : public QWidget, public osgViewer::CompositeViewer
{
public:
    ViewerWidget(std::string path = "cow.osg", QWidget* parent = 0, Qt::WindowFlags f = 0, osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::CompositeViewer::SingleThreaded) : QWidget(parent, f)
    {
        setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint); hide();
        setThreadingModel(threadingModel);
        osgViewer::GraphicsWindowEmbedded
            // disable the default setting of viewer.done() by pressing Escape.
            setKeyEventSetsDone(0);

        QWidget* widget1 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readRefNodeFile(path));
        //QWidget* widget2 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readRefNodeFile("glider.osgt"));
        //QWidget* widget3 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readRefNodeFile("axes.osgt"));
        //QWidget* widget4 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readRefNodeFile("fountain.osgt"));

        QGridLayout* grid = new QGridLayout;
        grid->addWidget(widget1, 0, 0);
        //grid->addWidget(widget2, 0, 1);
        //grid->addWidget(widget3, 1, 0);
        //grid->addWidget(widget4, 1, 1);
        setLayout(grid);

        connect(&_timer, SIGNAL(timeout()), this, SLOT(update()));
        _timer.start(10);
    }

    QWidget* addViewWidget(osgQt::GraphicsWindowQt* gw, osg::ref_ptr<osg::Node> scene)
    {
        osgViewer::View* view = new osgViewer::View;
        addView(view);

        osg::Camera* camera = view->getCamera();
        camera->setGraphicsContext(gw);

        const osg::GraphicsContext::Traits* traits = gw->getTraits();

        camera->setClearColor(osg::Vec4(0.2, 0.2, 0.6, 1.0));
        camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));

        // set the draw and read buffers up for a double buffered window with rendering going to back buffer
        camera->setDrawBuffer(GL_BACK);
        camera->setReadBuffer(GL_BACK);

        camera->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width) / static_cast<double>(traits->height), 1.0f, 10000.0f);

        view->setSceneData(scene);
        view->addEventHandler(new osgViewer::StatsHandler);
        view->setCameraManipulator(new osgGA::MultiTouchTrackballManipulator);
        gw->setTouchEventsEnabled(true);
        return gw->getGLWidget();
    }

    osgQt::GraphicsWindowQt* createGraphicsWindow(int x, int y, int w, int h, const std::string& name = "", bool windowDecoration = false)
    {
        osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
        osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
        traits->windowName = name;
        traits->windowDecoration = windowDecoration;
        traits->x = x;
        traits->y = y;
        traits->width = w;
        traits->height = h;
        traits->doubleBuffer = true;
        traits->alpha = ds->getMinimumNumAlphaBits();
        traits->stencil = ds->getMinimumNumStencilBits();
        traits->sampleBuffers = ds->getMultiSamples();
        traits->samples = ds->getNumMultiSamples();

        return new osgQt::GraphicsWindowQt(traits.get());
    }

    virtual void paintEvent(QPaintEvent* /*event*/)
    {
        frame();
    }

protected:

    QTimer _timer;
};
  • 头文件
#pragma once
#include <qwidget.h>
#include "ui_MyWidget.h"
#include "MyOsgModule.h"
#include "qboxlayout.h"

namespace Ui
{
    class MyWidget;
}

class MyWidget : public QWidget
{
    Q_OBJECT
public:
    explicit MyWidget(std::string path = "", QWidget* parent = Q_NULLPTR);
    ~MyWidget();
private:
    Ui::MyWidget* ui;
    QVBoxLayout* layout;
    ViewerWidget* view;
};
  • 源文件
#include "MyWidget.h"

MyWidget::MyWidget(std::string path, QWidget* parent)
    : QWidget(parent), ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    view = new ViewerWidget(path, this, Qt::Widget, osgViewer::ViewerBase::SingleThreaded);
    view->setGeometry(0, 0, width(), height());
    view->show();

    layout = new QVBoxLayout;
    layout->addWidget(view);
    setLayout(layout);
}


MyWidget::~MyWidget()
{
    delete ui;
}
  • 载入模型的槽函数,通过删除原tab并创建新tab的方式防止多个模型重叠
void dlg::slot()
{
    QString path = QFileDialog::getOpenFileName(this, tr("Open File"), "C:/OSG/Data", tr("OSG Model(*.osg*)"));
    if (!path.isEmpty())
    {
        page2 = new MyWidget(path.toStdString()); // tabWidget的第二页
        tabWidget->insertTab(0, page2, tr(u8"osg模型"));
        tabWidget->removeTab(1); // 删除原来的第二页
        tabWidget->setCurrentIndex(0);
    }
}

改变滚轮方向

  • 默认情况下,鼠标滚轮往后滚动是放大。现在要改为,滚轮向前滚动放大。方法从osgGA::OrbitManipulator派生一个类MyScroll,然后在addViewWidget函数中添加view->setCameraManipulator(new MyScroll);
class MyScroll : public osgGA::OrbitManipulator
{
    bool handleMouseWheel(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us)
    {
        osgGA::GUIEventAdapter::ScrollingMotion sm = ea.getScrollingMotion();
        // handle centering 
        if (_flags & SET_CENTER_ON_WHEEL_FORWARD_MOVEMENT)
        {
            if (((sm == osgGA::GUIEventAdapter::SCROLL_DOWN && _wheelZoomFactor > 0.)) ||
                ((sm == osgGA::GUIEventAdapter::SCROLL_UP   && _wheelZoomFactor < 0.)))
            {
                if (getAnimationTime() <= 0.)
                {
                    // center by mouse intersection (no animation) 
                    setCenterByMousePointerIntersection(ea, us);
                }
                else
                {
                    // start new animation only if there is no animation in progress 
                    if (!isAnimating())
                        startAnimationByMousePointerIntersection(ea, us);
                }
            }
        }
        switch (sm)
        {
            // mouse scroll up event 
        case osgGA::GUIEventAdapter::SCROLL_DOWN:
        {
            // perform zoom 
            zoomModel(_wheelZoomFactor, true);
            us.requestRedraw();
            us.requestContinuousUpdate(isAnimating() || _thrown);
            return true;
        }
        // mouse scroll down event  
        case osgGA::GUIEventAdapter::SCROLL_UP:
        {
            // perform zoom  
            zoomModel(-_wheelZoomFactor, true);
            us.requestRedraw();
            us.requestContinuousUpdate(isAnimating() || _thrown);
            return true;
        }
        // unhandled mouse scrolling motion 
        default:
            return false;
        }
    }
};

QWidget* addViewWidget(osgQt::GraphicsWindowQt* gw, osg::ref_ptr<osg::Node> scene)
{
    osgViewer::View* view = new osgViewer::View;
    addView(view);

    osg::Camera* camera = view->getCamera();
    camera->setGraphicsContext(gw);
    const osg::GraphicsContext::Traits* traits = gw->getTraits();
    camera->setClearColor(osg::Vec4(0.2, 0.2, 0.6, 1.0));
    camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
    camera->setDrawBuffer(GL_BACK);
    camera->setReadBuffer(GL_BACK);
    camera->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width) / static_cast<double>(traits->height), 1.0f, 10000.0f);

    view->setSceneData(scene);
    view->addEventHandler(new osgViewer::StatsHandler);
    view->setCameraManipulator(new osgGA::MultiTouchTrackballManipulator);
    view->setCameraManipulator(new MyScroll); // 添加这行
    gw->setTouchEventsEnabled(true);
    return gw->getGLWidget();
}

添加多个节点

  • 原来的MyOsgModule.h中,只添加了一个osg::Node
QWidget* addViewWidget(osgQt::GraphicsWindowQt* gw, osg::ref_ptr<osg::Node> scene)
{
    osgViewer::View* view = new osgViewer::View;
    addView(view);
    ...
    view->setSceneData(scene);
    ...
}
  • 其中view是要显示的视图,只需要一个。若要添加多个osg::Node,应当创建一个osg::Group,然后把所有的osg::Node加到osg::Group中,最后把osg::Group添加到osgViewer::View中
QWidget* addViewWidget(osgQt::GraphicsWindowQt* gw,
    osg::ref_ptr<osg::Node> scene1,
    osg::ref_ptr<osg::Node> scene2,
    osg::ref_ptr<osg::Node> scene3)
{
    osgViewer::View* view = new osgViewer::View;
    addView(view);
    ...
    osg::ref_ptr<osg::Group> group = new osg::Group;
    group->addChild(scene1);
    group->addChild(scene2);
    group->addChild(scene3);
    view->setSceneData(group);
    ...
}

利用Qt对OpenGL的支持

  • GLScene.h
#pragma once
#include <QtWidgets/QGraphicsScene>
#include <QtWidgets/qgraphicsscene.h>
#include <QtWidgets/QGraphicsSceneEvent>
#include <QTimerEvent>
#include <QInputEvent>
#include <QtGui//QPainter>

//#include "OsgLib.h"
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osgGA/TrackballManipulator>
#include <osgViewer/ViewerEventHandlers>

//#include "KeyBoardMap.h"

//static KeyBoardMap s_QtKeyboardMap;//按键映射

class GLScene :
    public QGraphicsScene
{
public:
    GLScene(QObject *parent = 0);
    ~GLScene(void);

protected:
    //绘制场景
    void drawBackground(QPainter *painter, const QRectF &rect);
    //窗口更新函数:使用定时器,定时更新
    void timerEvent(QTimerEvent *);

protected:
    //鼠标事件
    void mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent);
    void mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent);
    void mouseDoubleClickEvent(QGraphicsSceneMouseEvent * mouseEvent);
    void wheelEvent(QGraphicsSceneWheelEvent * wheelEvent);

    //键盘按键
    void keyPressEvent(QKeyEvent * keyEvent);
    void keyReleaseEvent(QKeyEvent * keyEvent);

    int   timer_id;

public:
    //更新OSG窗口
    void resizeViewer();
    void setKeyboardModifiers(QInputEvent* event);//组合键
public:
    osg::ref_ptr<osgViewer::Viewer> m_viewer;
};
  • GLSCene.cpp
#include "GLScene.h"


GLScene::GLScene(QObject *parent) :
    QGraphicsScene(parent)
    , m_viewer(NULL)
    , timer_id(0)
{
    //OSG初始化
    m_viewer = new osgViewer::Viewer;
    m_viewer->setUpViewerAsEmbeddedInWindow(0, 0, 800, 600);//设置窗口的嵌入大小
    m_viewer->setSceneData(osgDB::readNodeFile("cow.osg"));
    m_viewer->setCameraManipulator(new osgGA::TrackballManipulator);//添加操作器
    m_viewer->addEventHandler(new osgViewer::StatsHandler);//状态信息
    m_viewer->realize();//实例化GraphicsContext

    timer_id = startTimer(0);//当定时器触发时,应用程序会发送一个QTimerEvent,如果参数为0,那么定时器事件每次发生时没有窗口系统事件处理。
}


GLScene::~GLScene(void)
{
}

//绘制场景
void GLScene::drawBackground(QPainter *painter, const QRectF &rect)
{
    painter->beginNativePainting();
    painter->setRenderHint(QPainter::Antialiasing);//抗锯齿
    m_viewer->frame();
    //m_viewer->getViewerBase()->frame();
    painter->endNativePainting();

}

//窗口更新函数
void GLScene::timerEvent(QTimerEvent *)
{
    this->update();
}

void GLScene::mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
    //std::cout<<"mousePressEvent"<<std::endl;
    QGraphicsScene::mousePressEvent(mouseEvent);

    int button = 0;
    switch (mouseEvent->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;
    }
    //_gw->getEventQueue()->mouseButtonRelease( event->x(), event->y(), button );
    (dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->mouseButtonPress(mouseEvent->scenePos().x(), mouseEvent->scenePos().y(), button);
}

void GLScene::mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
    //std::cout<<"mouseReleaseEvent"<<std::endl;
    QGraphicsScene::mouseReleaseEvent(mouseEvent);

    int button = 0;
    switch (mouseEvent->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;
    }
    (dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->mouseButtonRelease(mouseEvent->scenePos().x(), mouseEvent->scenePos().y(), button);

}



void GLScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
    //std::cout<<"mouseMoveEvent"<<std::endl;
    QGraphicsScene::mouseMoveEvent(mouseEvent);

    (dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->mouseMotion(mouseEvent->scenePos().x(), mouseEvent->scenePos().y());
}

void GLScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
    //std::cout<<"mouseDoubleClickEvent"<<std::endl;
    QGraphicsScene::mouseDoubleClickEvent(mouseEvent);
    int button = 0;
    switch (mouseEvent->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;
    }

    (dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->mouseDoubleButtonPress(mouseEvent->scenePos().x(), mouseEvent->scenePos().y(), button);
}

void GLScene::wheelEvent(QGraphicsSceneWheelEvent * wheelEvent)
{
    //std::cout<<"wheelEvent"<<std::endl;
    QGraphicsScene::wheelEvent(wheelEvent);

    (dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->mouseScroll(
        wheelEvent->orientation() == Qt::Vertical ?
        (wheelEvent->delta()>0 ? osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN) :
        (wheelEvent->delta()>0 ? osgGA::GUIEventAdapter::SCROLL_LEFT : osgGA::GUIEventAdapter::SCROLL_RIGHT));

}

void GLScene::keyPressEvent(QKeyEvent * keyEvent)
{
    setKeyboardModifiers(keyEvent);

    //int value = s_QtKeyboardMap.remapKey(keyEvent);
//  (dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->keyPress(value);
    QGraphicsScene::keyPressEvent(keyEvent);
}

void GLScene::keyReleaseEvent(QKeyEvent * keyEvent)
{
    //std::cout<<"keyReleaseEvent"<<std::endl;
    QGraphicsScene::keyReleaseEvent(keyEvent);

    //int value = s_QtKeyboardMap.remapKey(keyEvent);
    //(dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->keyRelease(value);
    QGraphicsScene::keyPressEvent(keyEvent);
}

//OSG场景窗口更新
void GLScene::resizeViewer()
{
    //更新OSG窗口大小
    (dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->resized(this->sceneRect().x(), this->sceneRect().y(), this->sceneRect().width(), this->sceneRect().height());
    (dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->windowResize(this->sceneRect().x(), this->sceneRect().y(), this->sceneRect().width(), this->sceneRect().height());//?  更新状态S按键

    (dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->requestRedraw();//?

}

//组合键
void GLScene::setKeyboardModifiers(QInputEvent* event)
{
    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;
    (dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->getCurrentEventState()->setModKeyMask(mask);
}
  • GLView.h
#pragma once
#include <QtWidgets/QGraphicsView>
#include <QtOpenGL/QGLWidget>
#include <QtGui/QResizeEvent>

#include "GLScene.h"

class GLView :
    public QGraphicsView
{
public:
    GLView(QWidget *parent = 0);
    ~GLView(void);

protected:
    //更新视图的时候,更新场景
    void resizeEvent(QResizeEvent *event);

public:
    QGLWidget * m_widget;
    GLScene *m_scene;
};
  • GLView.cpp(视图窗口大小在此设置)
#include "GLView.h"

#include <QtWidgets/QMessageBox>

GLView::GLView(QWidget *parent) :
    QGraphicsView(parent)
    , m_widget(new QGLWidget(QGLFormat(QGL::DoubleBuffer)))
    , m_scene(new GLScene(this))
{
    this->resize(800, 600);//设置视口大小
    this->setViewport(m_widget);//将m_widget设置为视口:为了使用OpenGL渲染,你要设置一个新的QGLWidget作为QGraphicsView的视口
    m_widget->setMouseTracking(true);//鼠标追踪
    this->viewport()->setMinimumSize(1, 1);

    this->setScene(m_scene);
    this->setMinimumSize(1, 1); //设置视图的最小尺寸
    this->scene()->setSceneRect(0, 0, this->width(), this->height());//设置场景大小
    this->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);//设置视图的更新方式:整个视图更新
}


GLView::~GLView(void)
{
}

//更新视图的时候,更新场景
void GLView::resizeEvent(QResizeEvent *event)
{
    //更新场景大小
    m_scene->setSceneRect(this->rect().left(), this->rect().right(), this->rect().width(), this->rect().height());
    m_scene->resizeViewer();
}
  • 槽函数
#include "GLView.h"

void test::slot1()
{
    m_glview = new GLView(this);
    m_glview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_glview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_glview->move(100, 0);
    m_glview->show();
}
  • 选择路径导入模型
// GLScene.h构造函数声明中改为
GLScene(QObject *parent = 0, std::string path = "cow.osg");

// GLScene.cpp构造函数实现改为
GLScene::GLScene(QObject *parent, std::string path) :
    QGraphicsScene(parent)
    , m_viewer(NULL)
    , timer_id(0)
{
    ...
    m_viewer->setSceneData(osgDB::readNodeFile(path));

// GLView.h构造函数声明中改为
GLView(QWidget *parent = 0, std::string path = "aa.osgb");

// GLView.cpp构造函数实现改为
GLView::GLView(QWidget *parent, std::string path) :
    QGraphicsView(parent)
    , m_widget(new QGLWidget(QGLFormat(QGL::DoubleBuffer)))
    , m_scene(new GLScene(this, path))
{
    this->resize(1600, 950);//设置视口大小

// 槽函数
void test::slot1()
{
    QString path = QFileDialog::getOpenFileName(this, tr("Open File"), "D:/TestData", tr("Osg Module(*.osg*)"));
    if (!path.isEmpty())
    {
        m_glview = new GLView(this, path.toStdString());
        m_glview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        m_glview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        m_glview->move(200, 50);
        m_glview->show();
    }
}

// 保存操作
void test::slot2()
{
    QString path = QFileDialog::getSaveFileName(this, tr("Save File"), "D:/TestData", tr("Osg Module(*.osg)"));
    if (!path.isEmpty())
    {
        osg::ref_ptr<osg::Node> root = createSceneGraph(); // 实现如下
        osgDB::writeNodeFile(*(root.get()), path.toStdString());
    }
}

// 模型实现文件
#include <osg/Geode>
#include <osg/Geometry>

#include <osg/ref_ptr>
#include <osgDB/Registry>
#include <osgDB/WriteFile>
#include <osg/Notify>
#include <iostream>
osg::ref_ptr<osg::Node> createSceneGraph()
{
    // 创建一个用于保存几何信息的对象
    osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;

    // 创建四个顶点的数组
    osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
    geom->setVertexArray(v.get());
    v->push_back(osg::Vec3(-1.f, 0.f, -1.f));
    v->push_back(osg::Vec3(1.f, 0.f, -1.f));
    v->push_back(osg::Vec3(1.f, 0.f, 1.f));
    v->push_back(osg::Vec3(-1.f, 0.f, 1.f));

    // 创建四种颜色的数组
    osg::ref_ptr<osg::Vec4Array> c = new osg::Vec4Array;
    geom->setColorArray(c.get());
    geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
    c->push_back(osg::Vec4(1.f, 0.f, 0.f, 1.f));
    c->push_back(osg::Vec4(0.f, 1.f, 0.f, 1.f));
    c->push_back(osg::Vec4(0.f, 0.f, 1.f, 1.f));
    c->push_back(osg::Vec4(1.f, 1.f, 1.f, 1.f));

    // 为唯一的法线创建一个数组
    osg::ref_ptr<osg::Vec3Array> n = new osg::Vec3Array;
    geom->setNormalArray(n.get());
    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
    n->push_back(osg::Vec3(0.f, -1.f, 0.f));

    // 由保存的数据绘制四个顶点的多边形
    geom->addPrimitiveSet(
        new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));

    // 向 Geode 类添加几何体(Drawable)并返回 Geode
    osg::ref_ptr<osg::Geode> geode = new osg::Geode;
    geode->addDrawable(geom.get());
    return geode.get();
}

相关文章

网友评论

      本文标题:嵌入OSG模型

      本文链接:https://www.haomeiwen.com/subject/kjevbftx.html