关于OSG嵌入浏览器,王锐老师有过一篇文章。但是那篇文章是利用mfc,现如今mfc有点老态龙钟了。本文是使用QT,开发ActiveX插件,实现OSG嵌入QT。 关于QT版本,截止目前不能用QT5,版本跟osg不兼容,会出现各种问题,我在这上面纠结了很久,这里我使用的是QT4.6.1。
在开发之前得先编译osgQT库,编译的方法可以查看我csdn之前的文章。http://blog.csdn.net/villean/article/details/18266991
下面我将要实现的重点进行叙述,为了不罗嗦,不一步步的讲解,如果您不能理解,可以在文章下面回复,视情况如果讲解的不清楚在做向导式文章。
实现的原理其实就是,用QT做一个ActiveX插件,这个插件能在浏览器中运行一个QT工程,我们将OSG嵌入到QT中,这样就能实现OSG嵌入浏览器了。
新建一个ActiveQT Server,配置好相应的目录 库等,这样生成工程后,我们可以看。
生成后事件里面,QT向导会利用idc.exe在系统注册插件。
接着直接上代码:
#ifndef ACTIVITYQT_H
#define ACTIVITYQT_H
#include <QWidget>
#include <QTimer>
#include <ActiveQt/QAxBindable>
#include <QApplication>
#include <QVBoxLayout>
#include <osgViewer/Viewer>
#include "ViewerFrameThread.h"
#include <osgQt/GraphicsWindowQt>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/TrackballManipulator>
#include <osgDB/ReadFile>
#include <osgViewer/CompositeViewer>
class ActivityQT : public QWidget, public QAxBindable, public osgViewer::CompositeViewer
{
Q_OBJECT
Q_CLASSINFO("ClassID", "{4CFCDEDD-F2F6-42E9-8671-D63D7B15AA2C}");
Q_CLASSINFO("InterfaceID", "{615B202B-C4F2-4C9F-B9F5-2F9D52ECF0BC}");
Q_CLASSINFO("EventsID", "{C9C4EB5F-F926-4770-AA7F-50702B53DB3E}");
public:
ActivityQT(QWidget *parent = 0);
osgViewer::Viewer* getViewer();
public:
QWidget *createOsgWm(osgQt::GraphicsWindowQt *,osg::Node *);
osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name="", bool windowDecoration=false );
virtual void paintEvent( QPaintEvent* event )
{ frame(); }
private:
osgViewer::Viewer* m_viewer;
protected:
QTimer _timer;
};
#endif // ACTIVITYQT_H
#include "qtactivity.h"
#include <QLabel>
ActivityQT::ActivityQT(QWidget *parent)
: QWidget(parent)
{
//ui.setupUi(this);
QWidget *widget=createOsgWm( createGraphicsWindow(0,0,100,100,"Popup window"), osgDB::readNodeFile("cow.osg") );
QGridLayout* grid = new QGridLayout;
grid->addWidget(widget,0,1);
QLabel *a=new QLabel();
a->setText("this is a label");
grid->addWidget(a,0,0);
setLayout(grid);
connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );
_timer.start( 1 );
}
QWidget *ActivityQT::createOsgWm(osgQt::GraphicsWindowQt *gw,osg::Node *node)
{
osgViewer::Viewer* viewer = new osgViewer::Viewer;
addView( viewer );
osg::Camera *camera=viewer->getCamera();
camera->setGraphicsContext(gw);
const osg::GraphicsContext::Traits *traits=gw->getTraits();
camera->setClearColor(osg::Vec4(0.2,0.2,00.6,1.0));
camera->setViewport(new osg::Viewport(0,0,traits->width,traits->height));
camera->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0f, 10000.0f );
viewer->setSceneData(node);
viewer->addEventHandler(new osgViewer::StatsHandler);
viewer->setCameraManipulator( new osgGA::TrackballManipulator );
return gw->getGLWidget();
}
osgQt::GraphicsWindowQt* ActivityQT::createGraphicsWindow( int x, int y, int w, int h, const std::string& name, bool windowDecoration )
{
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());
}
osgViewer::Viewer* ActivityQT::getViewer()
{
return m_viewer;
}
#include <ActiveQt/QAxFactory>
#include "qtactivity.h"
QAXFACTORY_BEGIN("{5E2C9F73-03E9-4351-9ECC-C46697D1A8D5}",
"{443A7F7F-FFE1-498A-AECB-D3EBCD5810CB}")
QAXCLASS(ActivityQT)
QAXFACTORY_END()
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
if (!QAxFactory::isServer() )
{
ActivityQT w;
//ViewerFrameThread viewerThread(w.getViewer(), true);
// 新建线程 运行osg view
w.setGeometry( 100, 100, 800, 600 );
w.show();
//viewerThread.startThread();
}
return a.exec();
}
最后 我们在dll生成目录里新建一个html
<OBJECT ID="qtactivity" CLASSID="CLSID:4CFCDEDD-F2F6-42E9-8671-D63D7B15AA2C"
HEIGHT="80%" WIDTH="80%" ALIGN="LEFT">
</OBJECT>
代码不做解释,用到了osg自带的例子,不明白的大家可以回复讨论。