saridon 发表于 2011-10-28 12:30:16

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

本帖最后由 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::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()->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();
}

tianxiao888 发表于 2011-10-31 11:45:47

支持分享啊~~~~~~~~~~~~~~~

osglwh 发表于 2013-1-20 15:36:07

谢谢楼主

yijavakevin 发表于 2013-3-31 12:59:05


谢谢楼主

cavalry2013 发表于 2013-5-19 15:56:25

谢谢

gispipi 发表于 2013-8-10 15:34:23

学习了。。谢谢

sea_soft 发表于 2014-1-12 13:52:09

很实用的例子啊,谢谢了

EatFish 发表于 2014-1-13 11:37:19

很不错,改成Thread是不是就意味着每次绘制过程介绍后不用等下一次的timer事件,直接就可以开始新的绘制过程了。

friendbaby 发表于 2014-4-22 10:24:00

我调试了一下楼主的代码,viewer_->frame();并未在QThread线程中执行,而是在Qt的主线程中执行
楼主应该先去了解一下connect函数的第五个参数

gispipi 发表于 2014-4-25 22:09:30

感谢分享。。。。:)
页: [1]
查看完整版本: 分享:OSG+QT+QThread结合的示例