查看: 60|回复: 0

OSG嵌入Qt中的QOpenGLWidget

[复制链接]

该用户从未签到

发表于 2019-9-27 11:12:26 | 显示全部楼层 |阅读模式
在网上找了很久,有些是OSGQt插件单该插件是QGLWidget类的,这个类在新版本中废弃了建议用QOpenGLWidget
自己写了个测试类,附件中有Qt例子,使用是注意修改OSG编译后include,lib,bin目录
//头文件
#pragma once
#include <QOpenGLWidget>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QKeyEvent>
#include <QEvent>

#include <osgViewer/Viewer>
#include <osgViewer/GraphicsWindow>
#include <osgViewer/ViewerEventHandlers>
#include <osgDB/ReadFile>
#include <osg/ShapeDrawable>
#include <osg/Material>
#include <osgGA/TrackballManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/GUIEventHandler>
class QtOSGWidget : public QOpenGLWidget
{
        Q_OBJECT

public:
        QtOSGWidget(QWidget *parent = nullptr);
        ~QtOSGWidget();
protected:
        void initializeGL()override;
        void paintGL()override;
        void resizeGL(int w, int h)override;
        //将osgGA::EventQueue事件与Qt鼠标事件相关联
        void mouseDoubleClickEvent(QMouseEvent *event)override;
        void mouseMoveEvent(QMouseEvent *event)override;
        void mousePressEvent(QMouseEvent *event)override;
        void mouseReleaseEvent(QMouseEvent *event)override;
        void wheelEvent(QWheelEvent *event)override;
        void keyPressEvent(QKeyEvent *event)override;
        void keyReleaseEvent(QKeyEvent *event)override;

        bool event(QEvent *event) override;
private:
        osgGA::EventQueue* getEventQueue()const;
        void setKeyboardModifiers(QInputEvent* event);
        osg::ref_ptr<osg::Node> createOSGGlider();
private:
        osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _mGraphicsWindow;
        osg::ref_ptr<osgViewer::Viewer> _mViewer;
};
//源文件
#pragma execution_character_set("utf-8")
#ifdef _DEBUG
#pragma comment(lib,"osgd.lib")
#pragma comment(lib,"osgViewerd.lib")
#pragma comment(lib,"osgGAd.lib")
#pragma comment(lib,"osgDBd.lib")
#else
#pragma comment(lib,"osg.lib")
#pragma comment(lib,"osgViewer.lib")
#pragma comment(lib,"osgGA.lib")
#pragma comment(lib,"osgDB.lib")
#endif

#include "QtOSGWidget.h"
/**
1、创建图形上下文和图形窗口
2、将图形上下文附加到相机
3、将相机设置为主视图
*/
QtOSGWidget:tOSGWidget(QWidget *parent)
        : QOpenGLWidget(parent),
        _mViewer(new osgViewer::Viewer),
        _mGraphicsWindow(new osgViewer::GraphicsWindowEmbedded(this->x(),this->y(),this->width(),this->height()))
{
        setFocusPolicy(Qt::StrongFocus);
        this->setMinimumSize(100, 100);
}

QtOSGWidget::~QtOSGWidget()
{
}
/**
设置OpenGL资源和状态
*/
void QtOSGWidget::initializeGL() {
        osg::Camera* camera = _mViewer->getCamera();
        camera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
        camera->setProjectionMatrixAsPerspective(30, (double)this->width() / this->height(), 1, 1000);
        camera->setViewport(0, 0, this->width(), this->height());
        camera->setGraphicsContext(_mGraphicsWindow.get());

        osg::ref_ptr<osgGA::TrackballManipulator> manipulator = new osgGA::TrackballManipulator();
        manipulator->setAllowThrow(false);
        _mViewer->setCameraManipulator(manipulator.get());
        _mViewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
        _mViewer->addEventHandler((new osgGA::StateSetManipulator(camera->getOrCreateStateSet())));
        //_mViewer->addEventHandler(new osgViewer::WindowSizeHandler);
        _mViewer->addEventHandler(new osgViewer::StatsHandler);
        osg::ref_ptr<osg::Group> root = new osg::Group();

        QByteArray barr = QString("root").toLocal8Bit();
        char* bdata = barr.data();
        root->setName(bdata);
        root->addChild(createOSGGlider().get());
       
        //优化场景数据
        /*osgUtil::Optimizer optimizer;
        optimizer.optimize(root.get());*/
        _mViewer->setSceneData(root);
        _mViewer->realize();
}
/**
在场景更新时渲染OpenGL
*/
void QtOSGWidget::paintGL() {
        _mViewer->frame();
}
/**
设置OpenGL视口,投影等
*/
void QtOSGWidget::resizeGL(int w, int h) {
        this->getEventQueue()->windowResize(this->x(), this->y(), w, h);
        _mGraphicsWindow->resized(this->x(), this->y(), w, h);
        osg::Camera* camera = _mViewer->getCamera();
        camera->setViewport(this->x(), this->y(), w, h);
}
/**
获取OSG事件队列
*/
osgGA::EventQueue* QtOSGWidget::getEventQueue()const {
        return _mGraphicsWindow->getEventQueue();
};
void QtOSGWidget::mouseDoubleClickEvent(QMouseEvent *event) {
        setKeyboardModifiers(event);
        int button = 0;
        switch (event->button())
        {
        case Qt:eftButton:
                button = 1;
                break;
        case Qt::MidButton:
                button = 2;
                break;
        case Qt::RightButton:
                button = 3;
                break;
        }
        getEventQueue()->mouseDoubleButtonPress(event->x(), event->y(), button);
        QOpenGLWidget::mouseDoubleClickEvent(event);
}
void QtOSGWidget::mouseMoveEvent(QMouseEvent *event) {
        setKeyboardModifiers(event);
        getEventQueue()->mouseMotion(event->x(), event->y());
        QOpenGLWidget::mouseMoveEvent(event);
}
void QtOSGWidget::mousePressEvent(QMouseEvent *event) {
        setKeyboardModifiers(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;
        }
        getEventQueue()->mouseButtonPress(event->x(), event->y(), button);
        QOpenGLWidget::mousePressEvent(event);
}
void QtOSGWidget::mouseReleaseEvent(QMouseEvent *event) {
        setKeyboardModifiers(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;
        }
        getEventQueue()->mouseButtonRelease(event->x(), event->y(), button);
        QOpenGLWidget::mouseReleaseEvent(event);
}
void QtOSGWidget::wheelEvent(QWheelEvent *event) {
        setKeyboardModifiers(event);
        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));
        QOpenGLWidget::wheelEvent(event);
}
bool QtOSGWidget::event(QEvent *event) {
        bool handled = QOpenGLWidget::event(event);
        switch (event->type())
        {
        case QEvent::MouseButtonPress:
        case QEvent::MouseButtonRelease:
        case QEvent::MouseMove:
        case QEvent::Wheel:
        case QEvent::MouseButtonDblClick:
        case QEvent::KeyPress:
        case QEvent::KeyRelease:
                this->update();
                break;
        default:
                break;
        }
        return handled;
}
void QtOSGWidget::setKeyboardModifiers(QInputEvent* event) {
        int modkey = event->modifiers() & (Qt::ShiftModifier | Qt::AltModifier | Qt::ControlModifier);
        unsigned mask = 0;
        if (modkey & Qt::ShiftModifier) {
                mask |= osgGA::GUIEventAdapter::MODKEY_SHIFT;
        }
        if (modkey & Qt::AltModifier) {
                mask |= osgGA::GUIEventAdapter::MODKEY_ALT;
        }
        if (modkey & Qt::ControlModifier) {
                mask |= osgGA::GUIEventAdapter::MODKEY_CTRL;
        }
        getEventQueue()->getCurrentEventState()->setModKeyMask(mask);
}
void QtOSGWidget::keyPressEvent(QKeyEvent *event) {
        setKeyboardModifiers(event);
        //QByteArray KeyData = event->text().toLocal8Bit();
        /*const char* cKey = KeyData.data();
        osgGA::GUIEventAdapter::KeySymbol symbol = osgGA::GUIEventAdapter::KeySymbol(event->key());*/
        //getEventQueue()->keyPress();
        switch (event->key())
        {
        case Qt::Key_F:
        {
                //从观察者获取节点的方式
                osg::Geode* geode = dynamic_cast<osg::Geode*>(_mViewer->getSceneData());
                int count = geode->getNumDrawables();
                for (int i = 0; i < count; ++i) {
                        osg::ShapeDrawable* draw = dynamic_cast<osg::ShapeDrawable*> (geode->getDrawable(i));
                        std::string name = draw->getName();
                        if (name == "zidingyi1") {
                                draw->setColor(osg::Vec4(0.0, 1.0, 0.0, 1.0));
                        }
                }
                getEventQueue()->keyPress(osgGA::GUIEventAdapter::KEY_F);
        }
                break;
        case Qt::Key_D:
        {
                //从观察者获取节点的方式
                osg::Geode* geode = dynamic_cast<osg::Geode*>(_mViewer->getSceneData());
                int count = geode->getNumDrawables();
                for (int i = 0; i < count; ++i) {
                        osg:rawable* draw = geode->getDrawable(i);
                        std::string name = draw->getName();
                        if (name == "zidingyi1") {
                                geode->removeDrawable(draw);
                        }
                }
        }
                break;
        case Qt::Key_S:
        {
                getEventQueue()->keyPress(osgGA::GUIEventAdapter::KEY_S);
        }
        break;
        case Qt::Key_L:
        {
                getEventQueue()->keyPress(osgGA::GUIEventAdapter::KEY_L);
        }
        break;
        case Qt::Key_W:
        {
                getEventQueue()->keyPress(osgGA::GUIEventAdapter::KEY_W);
        }
        break;
        default:
                break;
        }
        QOpenGLWidget::keyPressEvent(event);
}
void QtOSGWidget::keyReleaseEvent(QKeyEvent *event) {
        setKeyboardModifiers(event);

        QOpenGLWidget::keyReleaseEvent(event);
}
osg::ref_ptr<osg::Node> QtOSGWidget::createOSGGlider() {
        osg::ref_ptr<osg::Node> node = osgDB::readRefNodeFile("glider.osg");
        QByteArray barr = QString("飞机").toLocal8Bit();
        char* bdata = barr.data();
        node->setName(bdata);
        return node.get();
}

OSGForQOpenGLWidget.zip

4.54 MB, 下载次数: 4, 下载积分: 威望 1

OSG嵌入QOpenGLWidget例子

您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表