查看: 7271|回复: 9

分享:OSG+QT+QThread结合的示例

[复制链接]

该用户从未签到

发表于 2011-10-28 12:30:16 | 显示全部楼层 |阅读模式
本帖最后由 saridon 于 2011-10-28 13:12 编辑

OSG+QT结合的小例子
参考王老师写的OSG中的osgViewerQt例子,只是把QTimer换成了QThread而已。
  
////////////////////////////////////////////////////////////////////////////////////////////////
/////////RenderThread.h

#ifndef RENDER_THREAD_H
#define RENDER_THREAD_H

#include <QtCore/QThread>
#include <QtCore/QMutex>


class RenderThread : public QThread
{
        Q_OBJECT
public:
        RenderThread(QObject *parent = 0);

public:
        void startRender();
        void stopRender();

protected:
        virtual void run();

signals:
        void notify();

private:
        bool stop_;
        QMutex mutex;
};
#endif

////////////////////////////////////////////////////////////////////////////////////////////////
// RenderThread.cpp
#include "RenderThread.h"

RenderThread::RenderThread(QObject *parent) : QThread(parent)
{
        stop_ = true;
}

void RenderThread::startRender()
{
        stop_ = false;
        start(HighestPriority);
}

void RenderThread::stopRender()
{
        mutex.lock();
        stop_ = true;
        mutex.unlock();
}

void RenderThread::run()
{
        forever
        {
                mutex.lock();

                if(stop_)
                {
                        stop_ = false;
                        mutex.unlock();                       
                        break;
                }

                msleep(50);
                emit notify();

                mutex.unlock();
        }
}


////////////////////////////////////////////////////////////////////////////////////////////////
// AdapterWidget.h
#ifndef ADAPTERWIDGET_H
#define ADAPTERWIDGET_H

#include <QtCore/QString>
#include <QtGui/QKeyEvent>
#include <QtOpenGL/QGLWidget>

#include <osgViewer/Viewer>
#include <osgViewer/CompositeViewer>

#include "RenderThread.h"

using Qt::WindowFlags;

class AdapterWidget : public QGLWidget
{
        Q_OBJECT

public:
        AdapterWidget( osgViewer::Viewer *viewer,
      QWidget * parent = 0,
      const char * name = 0,
      const QGLWidget * shareWidget = 0,
      WindowFlags f = 0 );
        virtual ~AdapterWidget();

        osgViewer::GraphicsWindow* getGraphicsWindow() { return _gw.get(); }
        const osgViewer::GraphicsWindow* getGraphicsWindow() const { return _gw.get(); }


public slots:
        void doNotify();

protected:
        void init();

        virtual void paintGL();
        virtual void resizeGL( int width, int height );
        virtual void keyPressEvent( QKeyEvent* event );
        virtual void keyReleaseEvent( QKeyEvent* event );
        virtual void mousePressEvent( QMouseEvent* event );
        virtual void mouseReleaseEvent( QMouseEvent* event );
        virtual void mouseMoveEvent( QMouseEvent* event );
        virtual void wheelEvent(QWheelEvent *);

        osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _gw;

private:
        osgViewer::Viewer *viewer_;
        RenderThread render_thread_;
};
#endif

////////////////////////////////////////////////////////////////////////////////////////////////
// AdapterWidget.cpp
#include "AdapterWidget.h"

AdapterWidget::AdapterWidget(  osgViewer::Viewer *viewer,
      QWidget * parent,
      const char * name,
      const QGLWidget * shareWidget, WindowFlags f)
      : QGLWidget(parent, shareWidget, f)
{
        viewer_ = viewer;
  _gw = new osgViewer::GraphicsWindowEmbedded(0,0,width(),height());
        setFocusPolicy(Qt::ClickFocus);

        connect(&render_thread_, SIGNAL(notify()), this, SLOT(doNotify()));
        render_thread_.startRender();
}

void AdapterWidget::doNotify()
{
        update();
}

void AdapterWidget::paintGL()
{
        if(viewer_)
        {
                viewer_->frame();
        }
}


void AdapterWidget::resizeGL( int width, int height )
{
    _gw->getEventQueue()->windowResize(0, 0, width, height );
    _gw->resized(0,0,width,height);
}

void AdapterWidget::keyPressEvent( QKeyEvent* event )
{
          _gw->getEventQueue()->keyPress((osgGA::GUIEventAdapter::KeySymbol) *(event->text().toAscii().data() ));
}

void AdapterWidget::keyReleaseEvent( QKeyEvent* event )
{
        _gw->getEventQueue()->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) *(event->text().toAscii().data() ) );
}

void AdapterWidget::mousePressEvent( QMouseEvent* 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;
        case(Qt::NoButton): button = 0; break;
        default: button = 0; break;
    }
    _gw->getEventQueue()->mouseButtonPress(event->x(), event->y(), button);
}

void AdapterWidget::mouseReleaseEvent( QMouseEvent* 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;
        case(Qt::NoButton): button = 0; break;
        default: button = 0; break;
    }
    _gw->getEventQueue()->mouseButtonRelease(event->x(), event->y(), button);
}

void AdapterWidget::mouseMoveEvent( QMouseEvent* event )
{
    _gw->getEventQueue()->mouseMotion(event->x(), event->y());
}

void AdapterWidget::wheelEvent(QWheelEvent * event)
{
        //if(event->orientation()==Qt::Vertical)
        if(event->delta()>0)
                _gw->getEventQueue()->mouseScroll(osgGA::GUIEventAdapter::SCROLL_UP);
        else
                _gw->getEventQueue()->mouseScroll(osgGA::GUIEventAdapter::SCROLL_DOWN);
}

AdapterWidget::~AdapterWidget()
{
        render_thread_.stopRender();
        render_thread_.wait();
}

AdapterWidget.rar

2.06 KB, 下载次数: 507, 下载积分: 威望 1

该用户从未签到

发表于 2011-10-31 11:45:47 | 显示全部楼层
支持分享啊~~~~~~~~~~~~~~~

该用户从未签到

发表于 2013-1-20 15:36:07 | 显示全部楼层
谢谢楼主

该用户从未签到

发表于 2013-3-31 12:59:05 | 显示全部楼层

谢谢楼主

该用户从未签到

发表于 2013-5-19 15:56:25 | 显示全部楼层
谢谢

该用户从未签到

发表于 2013-8-10 15:34:23 | 显示全部楼层
学习了。。谢谢

该用户从未签到

发表于 2014-1-12 13:52:09 | 显示全部楼层
很实用的例子啊,谢谢了

该用户从未签到

发表于 2014-1-13 11:37:19 | 显示全部楼层
很不错,改成Thread是不是就意味着每次绘制过程介绍后不用等下一次的timer事件,直接就可以开始新的绘制过程了。

该用户从未签到

发表于 2014-4-22 10:24:00 | 显示全部楼层
我调试了一下楼主的代码,viewer_->frame();并未在QThread线程中执行,而是在Qt的主线程中执行
楼主应该先去了解一下connect函数的第五个参数
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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