数据库的应用——直接从内存中读取osg节点

本文介绍了一种从内存缓冲区直接读取OpenSceneGraph(OSG)节点的方法,避免了通过文件系统的转换过程。利用osg::ReaderWriter的虚函数readNode及自定义流缓冲区实现节点数据的读取,并提供了完整的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据库的应用——直接从内存中读取osg节点

目的:要从数据库中读取节点数据到osg

 

一开始的方法是这样的,每当我要添加一个数据库中的节点数据时,首先把它读取到内存中,然后写入一个文件,最后再次从文件中用osgosgDB::readNodeFile()读取,这个方法是可行的,但是却很糟糕。我的初衷是不要经过文件转换。

 

现在问题解决了,多亏了osg::ReaderWriter提供一个虚函数:

virtual ReadResult  readNode (std::istream &, const Options *=NULL) const

这样的话,就可以从istream类中直接读取到osg了,现在的问题是,只要解决从一个buffer的数据能转换到istream的数据,我们的问题就解决了。

下面一段代码演示了如何从buffer中把节点数据转化为istream,然后显示节点,稍加修改就可以读取图像等信息。

 

#include <iostream>

#include <fstream>

#include <osgDB/ReadFile>

#include <osg/Node>

#include <osgViewer/Viewer>

 

class NodeBuf : public std::basic_streambuf<char, std::char_traits<char>> {

public:

     //构造函数,参数意义:buffer的地址和长度

     NodeBuf(char * mem, int sz) {

         //参数意义:起始位置,当前位置,最后的位置

         setg(mem, mem, mem + sz);

     }

};

 

osg::Node* readNodeFromBuffer(char* buffer, size_t length, const char*

                                   extension)

{

     osgDB::ReaderWriter* rw =

         osgDB::Registry::instance()->getReaderWriterForExtension(extension);

     if (rw)

     {

         NodeBuf sb(buffer, length);

         std::istream stream(&sb);

         osgDB::ReaderWriter::ReadResult rr = rw->readNode(stream);

 

         return rr.takeNode();

     }

     return NULL;

}

 

 

int main( int argc, char **argv )

{

     //输入自己要读取的节点位置

     std::ifstream fin("E://OSG2.2//OpenSceneGraph-Data//axes.osg");

     //得到文件的长度

     fin.seekg(0,std::ios_base::end);

     unsigned long sz=fin.tellg();

     //指针指向文件头

     fin.seekg(0,std::ios_base::beg);

 

     char *buffer=new char[sz];

     fin.read(buffer,sz);

     fin.close();

 

     NodeBuf my_buf(buffer, sz);

     std::istream stream(&my_buf);

 

     osgViewer::Viewer viewer;

     //第三个参数是后缀名

     viewer.setSceneData(readNodeFromBuffer(buffer,sz,"osg"));

     delete buffer;

     viewer.run();

}

 

### 如何使用 OpenSceneGraph (OSG) 加载 GLB 格式的 3D 模型 为了实现这一目标,可以利用 OSG 提供的功能来读取并渲染 `.glb` 文件。下面是一个简单的 C++ 程序示例,展示了如何通过 OSG 来加载和显示一个 `GLB` 格式的三维模型。 ```cpp #include <osg/Node> #include <osgDB/ReadFile> #include <osgViewer/Viewer> int main(int argc, char* argv[]) { // 创建查看器对象 osgViewer::Viewer viewer; // 如果提供了命令行参数,则尝试从中加载场景图;否则,默认加载 "cessna.gltf" std::string filename = argc > 1 ? argv[1] : "cessna.glb"; // 使用 OSG数据库接口读取指定路径下的 glb 文件 osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(filename); if (!loadedModel) { std::cerr << "无法加载模型:" << filename << std::endl; return -1; } // 将加载好的节点添加到查看器中 viewer.setSceneData(loadedModel.get()); // 启动应用程序的消息循环 return viewer.run(); } ``` 此程序首先创建了一个 `osgViewer::Viewer` 实例作为窗口管理的核心组件[^4]。接着定义了要加载的文件名为命令行的第一个参数或者是默认值 `"cessna.glb"`。之后调用了 `osgDB::readNodeFile()` 函数去解析给定路径中的 `.glb` 文件,并返回表示该模型的数据结构——即 `osg::Node` 类型的对象实例[^2]。最后一步就是把得到的节点设置成查看器的内容源,并启动消息处理过程以便于交互操作。 需要注意的是,在编译这段代码之前,请确保已经安装好了 OSG 库以及其依赖项,并且配置好开发环境使得能够链接这些库函数。对于 Linux 用户来说,可以通过包管理器获取预构建版本或者按照官方文档指导自行编译源码。此外,由于不同平台上的具体细节有所差异,建议查阅最新的 OSG 文档获得最准确的帮助信息。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值