OSG概述——b站OSG72讲1-4节(书籍后补)

OSG书籍

一、OSG层次结构:

图形硬件->OpenGL->OSG->应用程序

二、OSG组成模块+注意事项:

1.OSG核心库

主要功能是实现最核心的场景数据库的组织和管理,对场景图形的操作以及外部数据库导入提供接口,提供了基本的场景图形和渲染功能,以及3d图形程序所需的某些特定功能实现。

  • osg库:基本数据类,负责提供基本场景图类,构建场景图形节点,如节点类(创建场景图形)、状态类、绘制类、几何类、向量和矩阵数学计算以及一般的数据类。还有特定功能类,例如命令行解析和错误调试信息等。
  • osgUtil库:工具类库,提供通用的公用类,用于操作场景图形及内容,如更新、裁剪、遍历、数据统计及场景的一些优化、渲染器的创建。还包括几何操作类,delaunay三角面片化,三角面片条带化,纹理坐标生成等。
  • osgDB库:数据的读写类,负责提供场景中数据的读写工作,提供了一个文件工具类。建立和渲染3d数据库的类和函数,允许用户程序加载,使用和写入3d数据库。
  • osgViewer库:视窗管理库,可以集中各种窗体系统,提供OSG与各种GUI的结合,是跨平台的3d管理窗口库。
  • osgGA库:用于改写界面事件。

2.OSG节点工具库(NodeKit)

  • osgFX库:用于特效的渲染,例如异向光照,凹凸贴图,卡通着色等。
  • osgParticle库:提供了基于粒子的渲染特效,如各种天气或者自然现象效果,爆炸,火焰,烟雾。
  • osgSim库:虚拟仿真效果的节点工具,以及渲染OpenFlight数据库所需的特殊渲染功能,例如地形高程图,光点节点,DOF变换节点等。
  • osgText库:此类库提供了向场景中添加文字的得力工具,可以完全支持TrueType字体。
  • osgShadow库:提供了支持阴影渲染的框架结构,用于向场景添加实时阴影,提高场景渲染的真实性。
  • osgTerrain库:生成地形数据的节点工具,用于渲染高程数据,一般通过开源库GDAL读取这些高程数据。
  • osgdem库:一个工具程序 用于读取地理空间图像 和 高程图,生成大规模的3D地形数据库
  • osgAnimation库

3.OSG插件库(特点)

通过各种第三方库,OSG能够直接或者间接导入3D模型或图片等场景数据。具体见第五章(没看

4.OSG内省库(OsgIntrospection)

为了确保osg可以在更多环境中运行,osg提供了一个与语言无关的,可供运行时访问的接口。

5.建议使用OSG提供的智能指针

osg::Geode* geode = new osg::Geode();// 指针的写法
osg::ref_ptr<Geode> geode = new osg::Geode();// 智能指针

6.建议对头文件进行分类处理+基础测试代码

#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
int main()
{
	osgViewer::Viewer viewer;
	osg::Node *node = new osg::Node;
	node = osgDB::readNodeFile("glider.osg");
	viewer.setSceneData(node);
	return viewer.run();
}

三、场景浏览器osgViewer

1.在osgViewer中添加帮助事件(osgGA)

#include <osgViewer/ViewerEventHandlers>
...
osgViewer::Viewer viewer;
// 或osg::ref_ptr<osgViewer::Viewer> viewer = new...
...
viewer.addEventHandler(new osgViewer::HelpHandler);
// 先打印查找到的所有的event,再打印自定义的内容。
// 自定义内容参见HelpeHandler::handle中setUpScene语句中的getUsage语句
...

注意大小写敏感。
可以仿照helpHandler写一个类当作事件,试着替代“添加帮助事件”功能。

class demo :public osgGA::GUIEventHandler
{
public:
	virtual void getUsage(osg::ApplicationUsage &usage) const
	{
		usage.addKeyboardMouseBinding("d","dankokoko");
	}
};
....
viewer.addEventHandler(new osgViewer::HelpHandler);
viewer.addEventHandler(new demo );
...

如果只想响应demo事件,是由HelpeHandler::handle的返回值决定的。

class demo :public osgGA::GUIEventHandler
{
...
	bool handle (const osgGA::GUIEventAdapter &ea,osgGA::GUIActionAdapter &aa)
	{
		return true;// 此时到这个事件进入这个handler就结束了,不会处理这个类下面的事件了。
		// return false;
	}
...
};
viewer.addEventHandler(new demo );
viewer.addEventHandler(new osgViewer::HelpHandler);
...

除了helpeHandler,还有statsHandler,WindowSizeHandler等,更多见osgGA::GUIEventHandler.
其中osgViewer::RecordCameraPathHandler,可以生成一个文件路径,这个文件可以执行,实际上就是按照指定的动画(你的动作)和代码绘制顺序执行。可以来控制场景。

2.通过osg::Timer获得帧速

osg::Timer应用:

// 申请一个定时器
//osg::ref_ptr<osg::Timer> timer = new osg::Timer;// 错误,有些是没有ref_ptr的
osg::Timer *timer = new osg::Timer;
// 得到一个tick值为多少s
std::cout << timer->getSecondsPerTick() << std::endl;
// 计算读取模型时间
// 方法一:
osg::Timer_t start_time = 0;
osg::Timer_t end_time = 0;
start_time = timer->tick();
/*读取模型*/
end_time = timer->tick();
std::cout << "读取模型时间为:" << timer->delta_s(start_time,end_time) << std::endl;
// 这里使用相减

//方法二:
timer->setStartTick();
/*读取模型*/
std::cout << "读取模型时间为:" << timer->time_s() << std::endl;
// 这里使用获得流逝时间

// 方法三:
start_time = viewer->elapsedTime();
/*读取模型*/
end_time = viewer->elapsedTime();
std::cout << "读取模型时间为:" << osg::Timer::instance()->delta_s(start_time,end_time)<< std::endl;
// 但是这里osg::Timer_t是longlong,这里获得时差为0,所以应该改成float

其实viewer.run()是执行主帧循环,等同于:
while (!viewer.done()) viewer.frame();
//Also calls realize() if the viewer is not already realized, and installs trackball //manipulator if one is not already assigned.
// 上面注释内容建议看viewer.run()源码。
``
在这里插入图片描述
如果设定了这个系统变量,则会根据帧数来结束。

可以将return viewer.run()改成,并计算帧速:

// 加操作器
viewer->setCameraManipulator(new osgGA::TrackballManioulator());
int count =0;
while(!viewer.done())
{
	if(count == 0)
		start_time = timer->tick();
	count++;
	viewer.frame();
	if(count == 3)
	{
		count = 0;
		end_time = timer->tick();
		std::cout <<"当前帧速:" << 3/(timer->delta_s(start_time,end_time)) << std::endl;
	}
}
return 0;

3.控制帧速(OpenThreads::Thread::microSleep())

在这里插入图片描述
microSleep单位是百万分之一秒

float sleep_time = 0.0,last_time = 0.0;
while(!viewer.done())
{
	per_start_time = timer->tick();
	viewer.frame();
	per_end_time = timer->tick();
	// 想限制帧速为10,及每帧绘制1/10 = 0.1s
	sleep_time = 0.1 - (timer->delta_s(per_start_time,per_end_time));
	if(sleep_time < 0)
		sleep_time = last_time*0.8;
	last_time = sleep_time;
	OpenThreads::Thread::microSleep(sleep_time*1000000);// 第一帧不睡
}

四、场景图形压缩归档工具osgArchive(打包) ???

生成的压缩文件可以在OSG程序(如osgViewer)运行使用。

五、数据转换工具osgConv ???

用于读取3D数据,执行基本操作,并重新保存为新的3D数据文件。
例如可以读取标准3D文件格式,如OpenFilght,3DS,Alias,OBJ等,并将其转换为OSG本地格式(ASCII形式的.osg或者而精致形式的.ive文件)。
压缩的同时可以生成细化纹理。

  • 17
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值