文件I/O
命名规则
osgdb_xxx
比如:
osgdb_osg
osgdb_jpeg
关联文件后缀和加载器
osgDB::Registry::instance()->addFileExtensionAlias( "jpeg", "jpeg" );
osgDB::Registry::instance()->addFileExtensionAlias( "jpg", "jpeg" );
使用
osg::Node* node = osgDB::readNodeFile( "cow.osg" );
osg::Image* image = osgDB::readImageFile( "Images/lz.rgb" );
说明
加载文件两个步骤
- osgDB::Registry
- 单一实例
- 管理着常用文件I/O插件列表
- 逐一向下传递
- 外部共享模块
已支持

伪加载
并非实际的文件后缀
自定义加载
osgDB::ReaderWriter
-
supportsExtension
-
acceptsExtension
-
fileExists
-
readNode
osgDB::ReaderWriter::ReadResult readNode(const std::string& file,const osgDB::Options* options) const { // Check if the file extension is recognizable and file exists bool recognizableExtension = …; bool fileExists = …; if (!recognizableExtension) return ReadResult::FILE_NOT_HANDLED; if (!fileExists) return ReadResult::FILE_NOT_FOUND; … // Construct the scene graph according to format specification osg::Node* root = …; … // In case there are fatal errors during the process, // return an invalid message; otherwise return the root node bool errorInParsing = …; if (!errorInParsing) return ReadResult::ERROR_IN_READING_FILE; return root; }- osgDB::ReaderWriter::ReadResult重载构造器
- node
- image
- status enumeration
- other special object
- error message string
- 方法
- success
- takeNode
- osgDB::Options
- setOptionString
- getOptionString
- 直接传入readNodeFile第二个参数
- osgDB::ReaderWriter::ReadResult重载构造器
-
writeNode
-
readImage
-
writeImage
流加载
-
定义读写接口
osgDB::ReaderWriter::ReadResult readNode(const std::string& file,const osgDB::Options* options) const { … osgDB::ifstream stream( file.c_str(), std::ios::binary ); if ( !stream ) return ReadResult::ERROR_IN_READING_FILE; return readNode(stream, options); } osgDB::ReaderWriter::ReadResult readNode(std::istream& stream,const osgDB::Options* options) const { // Construct the scene graph according to format specification osg::Node* root = …; return root; } -
利用已有读写器处理流
osgDB::ReaderWriter* rw =osgDB::Registry::instance()->getReaderWriterForExtension("osg"); if (rw) { osgDB::ReaderWriter::ReadResult rr = reader->readNode(stream); if ( rr.success() ) node = rr.takeNode(); }
示例
CMakeLists.txt
add_library( osgdb_tri SHARED readerwriter.cpp )
readerwriter.cpp
#include <osg/Geometry>
#include <osg/Geode>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/Registry>
#include <osgUtil/SmoothingVisitor>
#include <iostream>
class ReaderWriterTRI : public osgDB::ReaderWriter
{
public:
ReaderWriterTRI();
virtual ReadResult readNode(
const std::string&, const osgDB::ReaderWriter::Options*)
const;
virtual ReadResult readNode(
std::istream&, const osgDB::ReaderWriter::Options*) const;
};
ReaderWriterTRI::ReaderWriterTRI()
{
supportsExtension("tri", "Triangle strip points");
}
ReaderWriterTRI::ReadResult ReaderWriterTRI::readNode(
const std::string& file, const osgDB::ReaderWriter::Options* options)
const
{
std::string ext = osgDB::getLowerCaseFileExtension(file);
if (!acceptsExtension(ext))
return ReadResult::FILE_NOT_HANDLED;
std::string fileName = osgDB::findDataFile(file, options);
if (fileName.empty())
return ReadResult::FILE_NOT_FOUND;
std::ifstream stream(fileName.c_str(), std::ios::in);
if (!stream)
return ReadResult::ERROR_IN_READING_FILE;
return readNode(stream, options);
}
ReaderWriterTRI::ReadResult ReaderWriterTRI::readNode(
std::istream& stream, const osgDB::ReaderWriter::Options*) const
{
unsigned int index = 0, numPoints = 0;
stream >> numPoints;
osg::ref_ptr<osg::Vec3Array> va = new osg::Vec3Array;
while (index<numPoints && !stream.eof() &&
!(stream.rdstate()&std::istream::failbit))
{
osg::Vec3 point;
stream >> point.x() >> point.y() >> point.z();
va->push_back(point);
index++;
}
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
geom->setVertexArray(va.get());
geom->addPrimitiveSet(
new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, numPoints));
osgUtil::SmoothingVisitor smoother;
smoother.smooth(*geom);
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(geom.get());
return geode.release();
}
REGISTER_OSGPLUGIN(tri, ReaderWriterTRI);
使用
osgviewer example.tri
序列化osg格式
前提
- 继承osg::Object
- META_Object 正确定义命名空间和类名
- 每一个成员变量需要有getter和setter方法
示例
#include <osg/Node>
#include <osgDB/ObjectWrapper>
#include <osgDB/Registry>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <iostream>
namespace testNS {
class ExampleNode : public osg::Node
{
public:
ExampleNode() : osg::Node(), _exampleID(0) {}
ExampleNode(const ExampleNode& copy,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY)
: osg::Node(copy, copyop), _exampleID(copy._exampleID) {}
META_Node(testNS, ExampleNode)
void setExampleID( unsigned int id ) { _exampleID = id; }
unsigned int getExampleID() const { return _exampleID; }
protected:
unsigned int _exampleID;
};
}
REGISTER_OBJECT_WRAPPER( ExampleNode_Wrapper,new testNS::ExampleNode,testNS::ExampleNode,"osg::Object osg::Node testNS::ExampleNode" )
{
ADD_UINT_SERIALIZER( ExampleID, 0 );
}
int main(int argc, char** argv)
{
osg::ArgumentParser arguments( &argc, argv );
unsigned int writingValue = 0;
arguments.read( "-w", writingValue );
if ( writingValue!=0 )
{
osg::ref_ptr<testNS::ExampleNode> node = new testNS::ExampleNode;
node->setExampleID( writingValue );
osgDB::writeNodeFile( *node, "examplenode.osgt" );
}else
{
testNS::ExampleNode* node = dynamic_cast<testNS::ExampleNode*>(osgDB::readNodeFile("examplenode.osgt") );
if ( node!=NULL )
{
std::cout << "Example ID: " << node->getExampleID() << std::endl;
}
}
}
本文详细介绍了osg库中的文件输入输出操作,包括命名规则、文件后缀与加载器的关联、使用方法以及自定义加载。重点讨论了osgDB::ReaderWriter类在读取和写入节点、图像时的角色,还展示了如何实现流加载和序列化osg格式的步骤。
1493

被折叠的 条评论
为什么被折叠?



