企业网站报价模板下载短视频seo优化排名
上一章节:
十二、OSG学习笔记-Control-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/146082287?spm=1001.2014.3001.5501
一、文件读取原理
ReadNodeFile,读取流程:
二、实现一个简单的读取器
仿造ReaderWriterOSG.CPP原码,自己实现一个文件读写器的dll, 该dll名为osgdb_fs.dll,并用这个文件读写器,读取后缀为.fs自定义模型文件
项目输出为类型设置为dll:
输出路径改为:
编译生成路径如下:
再将你编译好的这个库放到osg的bin目录下,就可以通过osgviewer 查看之前定义的sphere.fs文件。
代码仓库:OsgStudy/ReadFs · CuiQingCheng/OsgStudy - 码云 - 开源中国https://gitee.com/cuiqingcheng/osg-study/tree/master/OsgStudy/ReadFs
读取器ReadFs.cpp代码如下:
/**自定义OSG 文件读写器
**/#include <windows.h>
#include <iostream>
#include <sstream>#include <osg/Image>
#include <osg/Group>
#include <osg/Notify>
#include <osg/Version>
#include <osg/Geode>
#include <osg/Shape>
#include <osg/ShapeDrawable>#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/fstream>
#include <osgDB/Registry>
#include <osgDB/Input>
#include <osgDB/Output>using namespace osg;
using namespace osgDB;class FSReaderWriter : public ReaderWriter
{
public:mutable OpenThreads::Mutex _mutex;mutable bool _wrappersLoaded;FSReaderWriter(){supportsExtension("fs", "FreeSouth 's format");}virtual const char* className() const { return "FSReaderWriter"; }bool loadWrappers() const{
#ifndef OSG_LIBRARY_STATICif (_wrappersLoaded) return true;OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);if (_wrappersLoaded) return true;std::string filename = osgDB::Registry::instance()->createLibraryNameForExtension("fsreadwrite_osg");if (osgDB::Registry::instance()->loadLibrary(filename) == osgDB::Registry::LOADED){OSG_INFO << "FSReaderWriter wrappers loaded OK" << std::endl;_wrappersLoaded = true;return true;}else{OSG_NOTICE << "FSReaderWriter wrappers failed to load" << std::endl;_wrappersLoaded = true;return false;}
#elsereturn true;
#endif}virtual ReadResult readNode(const std::string& file, const Options* opt) const{std::string ext = osgDB::getLowerCaseFileExtension(file);if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;std::string fileName = osgDB::findDataFile(file, opt);if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;osgDB::ifstream fin(fileName.c_str());if (!fin){std::cerr << "Failed to open file: " << fileName << std::endl;return ReadResult::FILE_NOT_FOUND;}return readNode(fin, opt);}virtual ReadResult readNode(std::istream& fin, const Options* options) const{Input fr;fr.attach(&fin);osg::ref_ptr<osg::Geode> gnode = new osg::Geode;osg::Vec3 center;float radius;// load all nodes in file, placing them in a group.while (!fr.eof()){// 匹配文件中中心点,跟半径if (fr.matchSequence("%f%f%f%f")){fr.readSequence(center);fr.readSequence(radius);std::cout << "Center is:" << center.x() << " " << center.y() <<" "<< center.z() << std::endl;std::cout << "Radius:" << radius << std::endl;gnode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(center, radius)));}else {std::cout << "fr is NULL" << std::endl;++fr;}}return gnode;}};// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(fs, FSReaderWriter)
再切换到编写一个exe,程序加载使用这个读写器,读取文件,main.cpp 如下:
#include <windows.h>
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>int main()
{osgDB::Registry::instance()->addFileExtensionAlias("fs", "fs");//将文件扩展名与dll名关联起来osg::ref_ptr<osg::Group> group = new osg::Group;group->addChild(osgDB::readNodeFile("sphere.fs")); // 自定义的fs文件osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;viewer->setUpViewInWindow(100, 100, 1500, 1000);viewer->setSceneData(group.get());viewer->run();return 0;
}
运行结果如下图:
三、实现获取读取OSG文件进度功能
文件读取流程如下:
通过从写文件读取流的方式进行:
代码仓库:
OsgStudy/ReadProcess · CuiQingCheng/OsgStudy - 码云 - 开源中国https://gitee.com/cuiqingcheng/osg-study/tree/master/OsgStudy/ReadProcess
代码如下:
/**自定义文件读取,并实时获得读取进度
**/
#include <windows.h>
#include <iostream>
#include <fstream>
#include <streambuf>#include <osgViewer/Viewer>
#include <osgDB/ReaderWriter>
#include <osgDB/ReadFile>
#include <osgDB/FileUtils>
#include <osgDB/FileNameUtils>
#include <osgDB/Registry>template<class _Elem, class _Traits = std::char_traits<_Elem>>
class ReadStream :public std::basic_filebuf<_Elem, _Traits>
{
public:using int_type = typename _Traits::int_type;ReadStream(const std::string& fileName):_itotalSize(0){if (this->open(fileName.c_str(), std::ios_base::in | std::ios_base::binary)){//std::cout << "Read Success" << std::endl;// 打开文件时,会获得文件指针,将文件指针移动到文件末尾;从而获取文件大小_itotalSize = this->pubseekoff(0, std::ios_base::end, std::ios_base::in);std::cout << "file size:" <<_itotalSize << std::endl; // 获取文件大小字节数// 再回置指针到文件开头this->pubseekoff(0, std::ios_base::beg, std::ios_base::in);}}protected:int_type uflow() override // 读取文件时,会不断的执行这个文件{int_type value = std::basic_filebuf<_Elem, _Traits>::uflow();_iCurSize += (this->egptr() - this->gptr()); // 用结尾指针减去当前读取的指针, 获取当前读取到的字符数;std::cout << 100 * ((float)_iCurSize/_itotalSize)<<"%" << std::endl;return value;}int _iCurSize{ 0 };int _itotalSize{0};
};class ReadFileCB :public osgDB::Registry::ReadFileCallback
{
public:typedef ReadStream<char> ReadStreamString;virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* opt) override {std::cout << "Use our function" << std::endl;// 第一步:获取OSG、IVE ReaderWriterstd::string ext = osgDB::getLowerCaseFileExtension(file);// 用扩展名获取 ReaderWriterosgDB::ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension(ext);if (!rw){return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;}std::string fileName = osgDB::findDataFile(file, opt);if (fileName.empty()){return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND;}//osgDB::ifstream fin(fileName.c_str());ReadStreamString *fin = new ReadStreamString(fileName);if (fin->is_open()){std::cout << "Using default format readerwriter" << std::endl;//rw->readNode(fin);std::istream stream(fin);// 调用接受 std::istream 的 readNode 重载版本osgDB::ReaderWriter::ReadResult result = rw->readNode(stream, opt);if (result.success()) {return result;}}else{return osgDB::ReaderWriter::ReadResult::ERROR_IN_READING_FILE;}return osgDB::Registry::instance()->readNodeImplementation(file, opt);}
};int main()
{osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;viewer->setUpViewInWindow(100, 100, 1500, 1000);osgDB::Registry::instance()->setReadFileCallback(new ReadFileCB);viewer->setSceneData(osgDB::readNodeFile("glider.osg"));viewer->run();return 0;
}
四、osgDB写文件
核心函数接口,osgDB::Registry::RwriteNode();
代码仓库:
OsgStudy/outputNode · CuiQingCheng/OsgStudy - 码云 - 开源中国https://gitee.com/cuiqingcheng/osg-study/tree/master/OsgStudy/outputNode
实例代码:
/**osg 写文件
**/
#include <windows.h>
#include <iostream>#include <osgViewer/Viewer>
#include <osgDB/ReaderWriter>
#include <osgDB/ReadFile>
#include <osgDB/Registry>int main()
{osgDB::Registry::instance()->addFileExtensionAlias("fs", "fs");//将文件扩展名与dll名关联起来osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;viewer->setUpViewInWindow(100, 100, 1500, 1000);osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("sphere.fs"); // 读取自定义文件viewer->setSceneData(osgDB::readNodeFile("sphere.fs"));osg::Node& writeNode = (*(node)); // 将读到的文件节点,写道指定目录下的文件里osgDB::Registry::instance()->writeNode(writeNode, "D:/test.osg", osgDB::Registry::instance()->getOptions());return viewer->run();}
源代码:
/**osg 写文件
**/
#include <windows.h>
#include <iostream>#include <osgViewer/Viewer>
#include <osgDB/ReaderWriter>
#include <osgDB/ReadFile>
#include <osgDB/Registry>
#include <osg/Matrixd>
#include <osg/MatrixTransform>int main()
{osgDB::Registry::instance()->addFileExtensionAlias("fs", "fs");//将文件扩展名与dll名关联起来osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;viewer->setUpViewInWindow(100, 100, 1500, 1000);osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("sphere.fs"); // 读取自定义文件viewer->setSceneData(osgDB::readNodeFile("sphere.fs"));osg::Node& writeNode = (*(node)); // 将读到的文件节点,写道指定目录下的文件里osgDB::Registry::instance()->writeNode(writeNode, "D:/test.fs", osgDB::Registry::instance()->getOptions());osg::ref_ptr<osg::Group> gp = new osg::Group;osg::ref_ptr<osg::Node> node1 = new osg::Node;osg::ref_ptr<osg::MatrixTransform> mx = new osg::MatrixTransform;node1 = osgDB::readNodeFile("glider.osg");mx->addChild(node1.get());mx->setMatrix(osg::Matrix::translate(1.0, 0.0, 0.0));gp->addChild(mx);gp->addChild(node1);viewer->setSceneData(gp);osg::Node& writeNode1 = (*(gp)); // 将读到的文件节点,写道指定目录下的文件里osgDB::Registry::instance()->writeNode(writeNode1, "D:/tt.osg", osgDB::Registry::instance()->getOptions());return viewer->run();
}
osgArchive:将很多osg,文件压缩到一个包文件内。
例如:
# 将两个模型文件压缩到一个ive 文件中
osgconv cow.osg glider.osg d:\\g.ive