osg资料收集 - 图文

发布时间 : 星期六 文章osg资料收集 - 图文更新完毕开始阅读

22:55 | 添加评论 | 阅读评论 (4) | 固定链接 | 写入日志 9月17日

OSG的OBJ文件读取插件 - ReadWriterOBJ

OBJ文件是Wavefront公司开发的一种三维图形文件格式,这种格式同样也以通过Maya软件进行读写。

OBJ文件是直接可读的文本文件,用户可以直接用写字板打开对它进行编辑。

与该格式相对应的二进制文件格式使用.MOD为后缀,二进制文件的格式结构目前还没有公开。

OBJ文件的特点是:

1、OBJ文件属于三维模型文件,不包含动画、材质特性、贴图路径、动力学、粒子等信息。 2、OBJ文件主要支持多边形(Polygons)模型,也支持曲线(Curves)、表面(Surfaces)、点组材质(Point Group Materials),但使用Maya导出的OBJ文件并不包括这些信息。

3、OBJ文件支持三个点以上的面。很多其它的模型文件格式只支持三个点的面,使得模型不得不进行三角化,有的时候这对模型的再修改较为不利。

4、OBJ文件支持法线和贴图坐标。在其它软件中调整好贴图后,贴图坐标信息可以存入OBJ文件中。

OBJ文件由多行文本组成,文件中可以任意添加空格和空行。它不需要任何形式的文件头,不过用户往往使用表明文件信息的注释行作为文件头。

注释行以“#”开始,其它行由一个或数个关键字(Keyword)开始,其后为相应的数据信息。关键字用于说明当前行的数据或功能类型。

多行文本可以连接在一起表示一行,方法是在每一行最后添加一个连接符“\\”。注意连接符后面不能出现空格。

OSG目前支持的关键字列表: (readOBJ相关) #,$:注释行。

v:顶点坐标。对应数据为x,y,z。

vn:顶点法线坐标。对应数据为x,y,z。 vt:贴图坐标。对应数据为x,y。

p,l,f:指定多个几何元素组合成点(point),线(line),或者面(face)。对应数据为顶点,法线和贴图坐标的多个索引值。同一点的顶点、贴图和法线索引值之间用“/”分隔,多个点信息之间用空格分隔。

usemtl:指定要使用的材质。对应数据为材质名称。 mtllib:指定材质库。对应数据为材质库名称。

o:指定几何对象的名称。对应数据为文本或者为空。 g:指定几何对象组的名称。对应数据为文本或者为空。 s:指定光滑组的名称。对应数据为文本或者为0。

(readMTL相关)

newmtl:定义新的材质组。对应数据为材质组名称。 Ka,Kd,Ks,Ke:材质的环境(ambient),散射(diffuse),镜面(specular),放射(emissive)参数。对应数据为r,g,b,a。 Ns:材质的光亮度(shininess)。对应一个数据。

d,Tr:均可用于定义材质的Alpha透明度。对应一个数据。

sharpness,illum:材质的锐度(sharpness)和照明度(illumination)。对应一个数据。 Ni:材质的光密度(optical density)。对应一个数据。 Tf:材质的透射滤波(transmission filter)。对应数据为r,g,b,a。(OSG中没有读取滤波文件的功能)

map_Ka,map_Kd,map_Ks:材质的环境(ambient),散射(diffuse)和镜面(specular)贴图。对应数据为贴图文件名称。

refl:材质的反射属性。OSG中没有读取其参数。

关于OBJ文件和MTL文件的格式,以及各个关键字的详细说明,请参阅 http://www.fileformat.info/format/material/

<插件基本结构>

ReaderWriterOBJ类继承自osgDB::ReaderWriter类。为了正确实现一个文件读写插件的应有功能,该插件继承了以下一些函数: 1、插件类的名称

const char* className() const;

2、检查本插件是否可以解析输入的文件扩展名

bool acceptsExtension(const std::string& extension) const; 3、读取模型节点

ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const;

ReadResult readNode(std::istream& fin, const Options* options) const;

当用户程序中执行osgDB::readNodeFile函数时,OSG系统将跳转到Registry::read函数进行执行,寻找符合扩展名要求的节点,并执行相应的readNode函数,将解析结果保存到ReadResult对象中;

在read函数中,系统将按照以下的搜索顺序,寻找可能符合文件扩展名的插件: 1、首先检查文件是否为压缩包格式(.osga),并尝试读取其中的模型;

2、如果文件路径中包含网络地址,那么使用osgdb_net插件读取网络上的模型文件;

3、尝试从已经注册的插件列表_rwList中查找对应当前文件扩展名的插件,并执行文件的读入;

4、尝试根据文件的扩展名,在可搜索目录下查找对应的osgdb_xxx.dll文件,加载并尝试读取模型。

如果模型文件解析完成,那么系统将执行ReaderWriter::ReadResult::takeNode函数,把解析得到的节点返回给用户。

为了实现该插件的注册,定义全局变量

osgDB::RegisterReaderWriterProxy g_objReaderWriterProxy

该全局变量的初始化过程中,会使用Registry::addReaderWriter函数自动注册插件所对应的

扩展名;换句话说,当程序中第一次加载某个插件DLL之后,下一次再载入同扩展名的文件时,系统将从_rwList中获取该DLL信息并执行相应的readNode函数。

OBJ插件的目的是读取用户指定的.obj文件,并返回其中包含的场景图形树的根节点,以便加入到整个场景中来。

该插件中包括以下几个模型相关的类: Model类:模型的读取和分析类 Material类:记录纹理信息

Element类:记录某个几何元素集合信息

ElementState类:记录文件中几何元素组的信息,如组名称,纹理名称

工作流程: readNode

Model::readOBJ

Model::readline 循环执行该函数,按行读取.obj文件内容

Model::addElement 对于l,p,f指定的几何元素组合,使用该函数保存元素信息到链表 Model::readMTL 如果文件中定义了用户纹理库mtllib,则执行该函数读取纹理参数 convertModelToSceneGraph

buildMaterialToStateSetMap 将纹理数据保存成纹理渲染状态信息

convertElementListToGeometry 根据几何元素链表的信息,建立顶点、法线和纹理坐标索引,保存几何体

Model::needReverse 此判断为真的话,翻转几何体法线坐标,以保证OSG与.obj文件的元素顺序一致

osg::Geometry::setStateSet 设置几何体的纹理渲染状态 osgUtil::Tessellator::retessellatePolygons 细分几何体多边形

osgUtil::TriStripVisitor::stripify 对几何体多边形进行三角条带化处理,以增强性能

osgUtil::SmoothingVisitor::smooth 如果没有指定法线的话,由SmoothingVisitor类自动为几何体指定法线

返回osg::Node节点

13:50 | 添加评论 | 固定链接 | 写入日志 | OSG 9月10日

osgshadow示例程序的简介及阴影效果实现

本文的目的是通过对示例程序osgshadow的详细注解和分析,学习OSG阴影库osgShadow的基本使用方法,并进行程序的适当注解和知识总结。

详细的源代码请参阅OSG 2.0发行版的附带示例程序examples/osgshadow.cpp。本文只是针对其中的重点代码进行注解和分析,文中所述的程序代码并不完整,基本无法直接执行。 首先简要地介绍一下osgShadow库的几个基本组件:

osgShadow::ShadowedScene:向场景中添加阴影节点的组节点类。它继承自osg::Group。 osgShadow::ShadowTechnique:用于实现各种阴影技法的基类。它派生出三个子类:ShadowMap,ShadowTexture和ShadowVolume。

osgShadow::ShadowMap:实现阴影贴图(shadow map)的阴影技法类,其原理与示例程序osgdepthshadow中的实现相同。

osgShadow::ShadowTexture:实现阴影纹理(shadow texture)的阴影技法类,其原理与示例

程序osgshadowtexture中的实现相同。 osgShadow::ShadowVolume:实现基于模板缓存的体积阴影(volume shadow)的阴影技法类。

在观察osgshadow的源代码之前,首先可以了解一下这个例子程序的用法。 osgshadow基本演示了osgShadow库中所有可实现的阴影种类,并提供了多种用于承载阴影的几何环境,在运行osgshadow程序时,可以使用下面的命令行参数: -h,--help:显示帮助文档(但是并不完全)。

--SingleThreaded,--CullDrawThreadPerContext,--DrawThreadPerContext, --CullThreadPerCameraDrawThreadPerContext: 启用不同的线程模型。

--positionalLight,--directionalLight:设置为位置光源还是方向光源,使用位置光源时,光源在场景上方。

--noUpdate:设置此参数则光源不会转动。

--screen (num):num表示要在哪一个显示器上显示。 --sv (--two-sided | --two-pass),--st:

--sv设置使用osgShadow::ShadowVolume实现基于模板缓存的体积阴影,并有双面和双通道两个选择(未完全实现);

--st设置使用osgShadow::ShadowTexture,使用-2可以清楚地观察到它与osgShadow::ShadowMap的区别; 缺省下使用osgShadow::ShadowMap。 --base:是否再添加一个地面。

--coloured-light:是否采用有色光源,否则只采用白色系的光照。

-1,-2,-3:采用不同的几何环境,包括一个立方体,飞机与地形图,以及多个几何体的组合。

--with-base-texture,--no-base-texture:是否给-3中的模型赋予纹理,缺省为有纹理。

这里顺便介绍一下,关于渲染时各个线程模型的意义: SingleThreaded - 单CPU,单显示器时使用;

DrawThreadPerContext - 多CPU,单显示器时使用,以增加帧延迟时间为代价,提高屏幕同步刷新率;

CullThreadPerCameraDrawThreadPerContext - 摄像机和显示器的总数不大于CPU数; CullDrawThreadPerContext - 上述情况之外,可以保证较低的帧延迟时间。

在DrawThreadPerContext和CullThreadPerCameraDrawThreadPerContext模式下,渲染遍历renderingTraversals()可能在绘制线程完成之前就会返回,此时如果用户修改STATIC类型的节点,几何体和渲染状态数据,就可能发生危险,必须使用setDataVariance(DYNAMIC)来指定数据类型。

用户可以在程序中随时使用osgViewer::Viewer::setThreadingModel函数来设置任意一个线程模型,不必拘泥于上面所述的限制。

示例程序的全局部分,定义了两个全局变量:

const int ReceivesShadowTraversalMask = 0x1; //标识阴影接收对象(例如地面)的掩码

const int CastsShadowTraversalMask = 0x2; //标识阴影投射对象(例如飞机)的掩码。掩码可以做位运算

在后面的程序中,可以使用osgShadow::ShadowedScene::setReceivesShadowTraversalMask和

联系合同范文客服:xxxxx#qq.com(#替换为@)