OpenSceneGraph | OSG如何存储带纹理osgb格式可以节省空间

  在使用OSG(OpenSceneGraph)存储带纹理osgb格式的过程中,大家会遇到这样一种情况:存储后的osgb文件所占用的大小远大于原始文件的大小,几倍至几十倍。这是为何呢?原因是OSG默认的存储格式是不压缩存储,所以解决方案就是设置参数将存储格式改为压缩存储。方法如下:

osg::ref_ptr<osgDB::ReaderWriter::Options> options = new osgDB::ReaderWriter::Options;
options->setOptionString("WriteImageHint=IncludeFile");			// 设置压缩
osgDB::writeNodeFile(*(node.get()), osgb_path, options);

  如下文档可以找到解决方法的来源:

$ osgconv --format osgb 
Plugin osgPlugins-3.3.9/osgdb_osg.so 
{ 
   ReaderWriter : OSG Reader/Writer 
   { 
       features   : readObject readNode writeObject writeNode   
       extensions : .osg                           OpenSceneGraph Ascii file format 
       extensions : .osgs                          Pseudo OpenSceneGraph file loaded, with file encoded in filename string 
       options    : OutputTextureFiles             Write out the texture images to file 
       options    : includeExternalReferences      Export option 
       options    : precision                      Set the floating point precision when writing out files 
       options    : writeExternalReferenceFiles    Export option 
   } 
   ReaderWriter : OpenSceneGraph Native Format Reader/Writer 
   { 
       features   : readObject readImage readNode writeObject writeImage writeNode   
       extensions : .osg2                    OpenSceneGraph extendable format 
       extensions : .osgb                    OpenSceneGraph extendable binary format 
       extensions : .osgt                    OpenSceneGraph extendable ascii format 
       extensions : .osgx                    OpenSceneGraph extendable XML format 
       options    : Ascii                    Import/Export option: Force reading/writing ascii file 
       options    : Compressor=<name>        Export option: Use an inbuilt or user-defined compressor 
       options    : ForceReadingImage        Import option: Load an empty image instead if required file missed 
       options    : SchemaData               Export option: Record inbuilt schema data into a binary file 
       options    : SchemaFile=<file>        Import/Export option: Use/Record an ascii schema file 
       options    : WriteImageHint=<hint>    Export option: Hint of writing image to stream: <IncludeData> writes Image::data() directly; <IncludeFile> writes the image file itself to stream; <UseExternal> writes only the fi 
lename; <WriteOut> writes Image::data() to disk as external file. 
       options    : XML                      Import/Export option: Force reading/writing XML file 
   } 
} 

  上面文档中,有关WriteImageHint的项的描述(第26行):选择IncludeData是直接写入数据,无压缩,是默认选项。而includeFile则是写入流,按我的理解,就是将原始的影像数据流原原本本的写入osgb,原始的影像是压缩过的,比如jpg格式,那保存出来的osgb就是压缩过的。因此,将WriteImageHint设置为IncludeFile可以解决OSG存储带纹理osgb格式数据量大的问题,节省空间。

OpenSceneGraph中,可以使用`osg::Camera`类将场景渲染到纹理上,然后再将纹理绘制到图片上。以下是将一个几何体渲染到图片上的示例代码: ``` // 创建几何体 osg::ref_ptr<osg::Geometry> geom = createGeometry(); // 创建摄像机 osg::ref_ptr<osg::Camera> camera = new osg::Camera; camera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 0.0f)); camera->setViewport(0, 0, width, height); camera->setProjectionMatrix(osg::Matrix::ortho2D(0, width, 0, height)); camera->setRenderOrder(osg::Camera::PRE_RENDER); camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); // 创建纹理 osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D; texture->setTextureSize(width, height); texture->setInternalFormat(GL_RGBA); texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST); texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST); // 将纹理设置为摄像机的颜色缓冲区 camera->attach(osg::Camera::COLOR_BUFFER, texture.get()); // 创建场景图 osg::ref_ptr<osg::Group> root = new osg::Group; root->addChild(geom); root->addChild(camera); // 渲染场景 osgViewer::Viewer viewer; viewer.setSceneData(root); viewer.setCameraManipulator(new osgGA::TrackballManipulator); viewer.realize(); viewer.frame(); // 将纹理绘制到图片上 osg::ref_ptr<osgDB::ReaderWriter::Options> options = new osgDB::ReaderWriter::Options; options->setOptionString("writeImageHint=png"); osgDB::writeImageFile(*texture->getImage(0), "output.png", options.get()); ``` 在上述代码中,首先创建了一个几何体`geom`。然后,创建了一个摄像机`camera`,并设置其视口、投影矩阵、渲染顺序和渲染目标等属性。接着,创建了一个纹理`texture`,设置其大小、内部格式和过滤器等属性,并将其设置为摄像机的颜色缓冲区。接下来,创建了一个场景图`root`,将几何体和摄像机添加到场景图中。通过`osgViewer::Viewer`类渲染场景,并将纹理绘制到图片上。最后,使用`osgDB::writeImageFile()`方法将纹理保存到图片文件中。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值