本文主要是介绍18、osg3.2.1+qt5.5+vs2010例子,也是osg中的例子,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1、首先要在vs2010中创建一个基于qt的QWidge工程(OsgQtTest),然后对osgqtest.h进行修改,如下代码:
#ifndef OSGQTTEST_H
#define OSGQTTEST_H
#include <osgLib.h>
#include <QtCore/QTimer>
#include <QtWidgets/QApplication>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>
#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/TrackballManipulator>
#include <osgDB/ReadFile>
#include <osgQt/GraphicsWindowQt>
#include <iostream>
//CompositeViewer是多视景器
//Viewer是单视景器
class OsgQtTest : public QWidget,public osgViewer::CompositeViewer
{Q_OBJECTpublic:OsgQtTest(osgViewer::ViewerBase::ThreadingModel threadingModel=osgViewer::CompositeViewer::SingleThreaded);~OsgQtTest();QWidget* addViewWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene );osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name="", bool windowDecoration=false );virtual void paintEvent( QPaintEvent* event );
protected:QTimer _timer;
};#endif // OSGQTTEST_H
2、osgqttest.cpp代码:
#include "osgqttest.h"OsgQtTest::OsgQtTest(osgViewer::ViewerBase::ThreadingModel threadingModel): QWidget()
{/*设置线程模式,线程模式包括:SingleThreaded表示单线程模式,OSG 不会创建任何新线程来完成场景的筛选和渲染,因而也不会对渲染效率的提高有任何助益。它适合任何配置下使用。CullDrawThreadPerContext:OSG 将为每一个图形设备上下文(GraphicsContext)创建一个图形线程,以实现并行的渲染工作。如果有多个CPU 的话,那么系统将尝试把线程分别放在不同的CPU 上运行,不过每一帧结束前都会强制同步所有的线程。ThreadPerContextDrawThreadPerContext:这一线程模型同样会为每个GraphicsContext 创建线程,并分配到不同的CPU 上。十分值得注意的是,这种模式会在当前帧的所有线程完成工作之前,开始下一帧。CullThreadPerCameraDrawThreadPerContext:这一线程模型将为每个GraphicsContext和每个摄像机创建线程,这种模式同样不会等待前一次的渲染结束,而是返回仿真循环并再次开始执行frame 函数。如果您使用四核甚至更高的系统配置,那么使用这一线程模型将最大限度地发挥多CPU 的处理能力。ThreadPerCameraAutomaticSelection*/setThreadingModel(threadingModel);// disable the default setting of viewer.done() by pressing Escape.setKeyEventSetsDone(0);//来设置自定义的退出键(缺省是GUIEventAdapter::KEY_Escape)。//在坐标(0,0)处创建一个窗口,并将cow.osgt设置到该窗口中QWidget* widget1 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readNodeFile("cow.osgt") );QWidget* widget2 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readNodeFile("glider.osgt") );QWidget* widget3 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readNodeFile("axes.osgt") );QWidget* widget4 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readNodeFile("fountain.osgt") );//在坐标(900,100)处创建一个窗口,并将dumptruck.osgt设置到该窗口中QWidget* popupWidget = addViewWidget( createGraphicsWindow(900,100,320,240,"Popup window",true), osgDB::readNodeFile("dumptruck.osgt") );//以非模态窗口显示,此窗口是与主窗口分割开的popupWidget->show();QGridLayout* grid = new QGridLayout;//创建一个网络布局grid->addWidget( widget1, 0, 0 );//在第0行,0列添加一个窗口grid->addWidget( widget2, 0, 1 );//在第0行,1列添加一个窗口grid->addWidget( widget3, 1, 0 );//在第1行,0列添加一个窗口grid->addWidget( widget4, 1, 1 );//在第1行,1列添加一个窗口setLayout( grid );//将该布局设置到主窗口中connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );_timer.start( 10 );
}OsgQtTest::~OsgQtTest()
{}
QWidget* OsgQtTest::addViewWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene )
{osgViewer::View* view = new osgViewer::View;//创建一个渲染器addView( view );//将渲染器加入到窗口中去osg::Camera* camera = view->getCamera();//获得渲染器中的相机//视景器Viewer 的主/从摄像机均需要使用setGraphicsContext设置对应的图形设备上下文,实际上也就是对应的显示窗口,那么gw就是要显示的窗口camera->setGraphicsContext( gw );const osg::GraphicsContext::Traits* traits = gw->getTraits();//可通过窗口的getTraits获得窗口的属性camera->setClearColor( osg::Vec4(0.2, 0.2, 0.6, 1.0) );//设置清除缓存区背景的颜色。RGBA格式。camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );//设置视口的尺寸与位置。//以透视投影的方式来设置投影矩阵。30为透视投影中的视角,第二个参数一般都是窗口的宽/高,第三个参数投影钟的近视角,第四个参数为投影钟的远视角camera->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0f, 10000.0f );view->setSceneData( scene );//将模型添加到渲染器中view->addEventHandler( new osgViewer::StatsHandler );//添加一些常用状态设置view->setCameraManipulator( new osgGA::TrackballManipulator );//设置一个操作器return gw->getGLWidget();//获得窗口对象,相当于QWidget*,可通过此对象对界面进行设置以及添加到当前的window中
}
osgQt::GraphicsWindowQt* OsgQtTest::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;//是否显示窗口的描述,默认为false不显示traits->x = x;//设置窗口显示的x坐标traits->y = 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());//通过以上的设置参数来创建一个qt的窗口对象
}
void OsgQtTest::paintEvent( QPaintEvent* event )
{ /*frame()函数的源代码如下:void ViewerBase::frame(double simulationTime){if (_done) return;// OSG_NOTICE<<std::endl<<"CompositeViewer::frame()"<<std::endl<<std::endl;if (_firstFrame){viewerInit();//如果这是仿真系统启动后的第一帧,则执行viewerInit()if (!isRealized())//viewerInit();此时如果还没有执行realize()函数,则执行它。{realize();}_firstFrame = false;}advance(simulationTime);//执行advance 函数//执行eventTraversal 函数,顾名思义,这个函数将负责处理系统产生的各种事件,诸//如鼠标的移动,点击,键盘的响应,窗口的关闭等等,以及摄像机与场景图形的事件回调//(EventCallback)。eventTraversal();//执行updateTraversal 函数,这个函数负责遍历所有的更新回调(UpdateCallback);//除此之外,它的另一个重要任务就是负责更新DatabasePager 与ImagePager 这两个重要的分//页数据处理组件。updateTraversal();//执行renderingTraversals 函数,这里将使用较为复杂的线程处理方法,完成场景的筛选(cull)和绘制(draw)工作。renderingTraversals();}*/frame();//实时对其进行渲染
}
3、main.cpp代码:
#include "osgqttest.h"
#include <QtWidgets/QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);OsgQtTest* viewWidget = new OsgQtTest();viewWidget->setGeometry( 100, 100, 640, 480 );viewWidget->show();return a.exec();
}
最终效果图如下:
这篇关于18、osg3.2.1+qt5.5+vs2010例子,也是osg中的例子的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!