最近使用 Qt 做二三维数据渲染工作,就从网上找了下代码,希望osg能够嵌入到qt 窗口呢,其实还是有点难度的,各种问题,最后终于是实现了,代码给大家贴出来,共大家参考
class QtOsgView : public osgViewer::Viewer, public AdapterWidget
{
public:
QtOsgView(QWidget * parent = 0, const char * name = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0);
~QtOsgView() {}
virtual void paintGL();
protected:
osg::Timer mTimer; //定时器,控制帧速
double mStrTime; //开始tick时间
double mEndTime; //结束tick时间
double mSleepTime; //需要睡眠的时间
int num;
}; //Osg视图类
class QMainWindow;
typedef std::tuple<std::string, std::string, std::string, int> databaseinfo;
class osgQtWidget : public QWidget
{
Q_OBJECT
public:
osgQtWidget(QWidget *parent = 0);
~osgQtWidget();
public:
QMainWindow * m_mw;
osg::ref_ptr m_view;
osg::ref_ptrosg::Geode m_geode; //几何组节
osg::ref_ptrosg::Group m_root; //渲染数据节点
private:
void initMainWindow();
void initGeomData();
void readShp();
};//接收视图的窗口类
QtOsgView::QtOsgView(QWidget * parent, const char * name, const QGLWidget * shareWidget, Qt::WindowFlags f) :AdapterWidget(parent, name, shareWidget, f)
{
getCamera()->setViewport(new osg::Viewport(0, 0, width(), height()));
getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast(width()) / static_cast(height()), 1.0f, 10000.0f);
getCamera()->setGraphicsContext(getGraphicsWindow());
setThreadingModel(osgViewer::Viewer::SingleThreaded);
mStrTime = 0.0;
mEndTime = 0.0;
mSleepTime = 0.0;
num = 0;
}
void QtOsgView::paintGL()
{
mStrTime = mTimer.tick();
frame();
num++;
mEndTime = mTimer.tick();
//计算需要睡眠的时间
mSleepTime = 1.0 / 60.0 - mTimer.delta_s(mStrTime, mEndTime);
if (mSleepTime < 0)
{
mSleepTime = 0.0;
}
//睡眠
OpenThreads::Thread::microSleep(mSleepTime * 1000000); //微秒
//Sleep(mSleepTime * 1000); //毫秒
double mTime = mTimer.tick();
//std::cout << "帧数:" << mTimer.delta_s(mStrTime, mTime) << std::endl;
//递归调用
update();
}
osgQtWidget::osgQtWidget(QWidget *parent)
:QWidget(parent)
{
initMainWindow();
readShp();
initGeomData();
}
class UseEventHandler :public osgGA::GUIEventHandler
{
public:
virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
osgViewer::Viewer *viewer = dynamic_castosgViewer::Viewer*(&aa);
if (!viewer)return false;
switch (ea.getEventType())
{
}
return false;
}
};
void osgQtWidget::initMainWindow()
{
QHBoxLayout *layout = new QHBoxLayout;
this->setLayout(layout);
m_mw = new QMainWindow(this);
layout->addWidget(m_mw);
m_mw->setWindowFlags(Qt::Widget);
m_view = new QtOsgView(m_mw);
m_root = new osg::Group();
m_geode = new osg::Geode();
m_view->setCameraManipulator(new osgGA::TrackballManipulator);
m_view->addEventHandler(new osgViewer::WindowSizeHandler);
m_view->addEventHandler(new osgViewer::StatsHandler);
m_view->addEventHandler(new UseEventHandler);
}
void osgQtWidget::initGeomData()
{
m_root->addChild(m_geode.get());
m_view->setSceneData(m_root.get());
m_mw->setCentralWidget(m_view);
}
void osgQtWidget::readShp()
{
GDALAllRegister();
auto preadDataSet = (TDOGRDataSource*)GDALOpenEx(“G:\shp\world.shp”, GDAL_OF_VECTOR, NULL, NULL, NULL);
if (preadDataSet == NULL)
{
return;
}
for (int i = 0; i < preadDataSet->GetLayerCount(); i++)
{
auto singlelayer = preadDataSet->GetLayer(i);
TDOGRFeature *poFeature = NULL;
while ((poFeature = singlelayer->GetNextFeature()) != NULL)
{
auto ogrgeometry = dynamic_cast<OGRPolygon *>(poFeature->GetGeometryRef());
if (NULL == ogrgeometry)
{
continue;
}
auto extring = ogrgeometry->getExteriorRing();
auto pointnum = extring->getNumPoints();
osg::ref_ptrosg::Geometry geom = new osg::Geometry();
osg::ref_ptrosg::Vec3Array v = new osg::Vec3Array();//定义一个几何体坐标集合
//v->push_back(osg::Vec3(-1.0, 0.0, -1.0));//左下角坐标点
//v->push_back(osg::Vec3(1.0, 0.0, -1.0));//右下角坐标点
//v->push_back(osg::Vec3(1.0, 0.0, 1.0));//右上角坐标点
//v->push_back(osg::Vec3(-1.0, 0.0, 1.0));//左上角坐标点
/*v->push_back(osg::Vec3(-69.8822327, 12.4111099, 0.000000000));//左下角坐标点
v->push_back(osg::Vec3(-50.0596619, 10.6277761, 0.000000000));//右下角坐标点
v->push_back(osg::Vec3(-59.8969574, 8.4808331, 0.000000000));//右上角坐标点
v->push_back(osg::Vec3(-69.8748627, 12.4152765, 0.000000000));//左上角坐标点 */
for (int i = 0; i < pointnum - 1; i++)
{
auto objpoint = extring->get_point_n(i);
v->push_back(osg::Vec3(objpoint->getX(), objpoint->getY(), 0));
}
//geom->setNormalBinding(osg::Geometry::BIND_OVERALL);//将法线进行绑定
geom->setVertexArray(v.get());//将坐标设置到几何体节点中
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, pointnum - 1));
m_geode->addDrawable(geom.get());
}
}
}
osgQtWidget::~osgQtWidget()
{
}