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_OBJECT

public:
	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 上运行,不过每一帧结束前都会强制同步所有的线程。
	ThreadPerContext
	DrawThreadPerContext:这一线程模型同样会为每个GraphicsContext 创建线程,并分配到不同的CPU 上。十分值得注意的是,这种模式会在当前帧的所有
							线程完成工作之前,开始下一帧。
	CullThreadPerCameraDrawThreadPerContext:这一线程模型将为每个GraphicsContext和每个摄像机创建线程,这种模式同样不会等待前一次的渲染结束,
							而是返回仿真循环并再次开始执行frame 函数。如果您使用四核甚至更高的系统配置,那么使用这一线程模型将最大限度地发挥多CPU 的处理能力。
	ThreadPerCamera
	AutomaticSelection
	*/
	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();
}

最终效果图如下:




  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值