osgViewer::Viewer设置setSceneData后程序正常不能退出代码
时间: 2024-03-13 22:46:53 浏览: 73
以下是一个简单的示例代码,演示如何设置场景数据并正确退出osgViewer::Viewer程序:
```
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
int main()
{
// 创建Viewer
osgViewer::Viewer viewer;
// 加载场景数据
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile("cow.osg");
// 设置场景数据
viewer.setSceneData(loadedModel);
// 开始渲染
viewer.realize();
// 进入主循环
while(!viewer.done())
{
// 更新场景
viewer.frame();
}
// 释放场景资源
viewer.setSceneData(nullptr);
// 退出程序
return 0;
}
```
在这个示例代码中,当程序退出时,我们手动释放了场景资源,即通过viewer.setSceneData(nullptr)将场景数据设置为nullptr,这样可以确保程序正确释放资源并退出。
相关问题
osg程序退出回收osgViewer::Viewer怎么做
在使用OpenSceneGraph(以下简称OSG)时,当程序退出时,需要释放分配的内存,包括osgViewer::Viewer对象和相关的场景图等资源。下面是一个简单的示例代码,演示了如何在程序退出时释放OSG相关资源。
```c++
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
int main() {
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
viewer->setSceneData(osgDB::readNodeFile("cow.osg")); // 加载场景图
viewer->realize(); // 初始化视窗
// 运行OSG程序,渲染场景
viewer->run();
// 退出程序前释放分配的内存
viewer->releaseGLObjects();
osg::ref_ptr<osg::Node> scene = viewer->getSceneData();
if (scene.valid()) {
scene->releaseGLObjects();
}
osg::ref_ptr<osgDB::Options> options = new osgDB::Options;
options->setReleaseContextAtFileClose(true);
osgDB::Registry::instance()->closeAllLibraries();
return 0;
}
```
在上面的示例代码中,首先创建了一个osgViewer::Viewer对象,并加载了一个场景图。然后调用viewer->realize()函数来初始化视窗,并使用viewer->run()函数来运行OSG程序,渲染场景。
在程序退出前,需要释放分配的内存。具体的步骤如下:
1. 调用viewer->releaseGLObjects()函数来释放分配的OpenGL对象。
2. 调用viewer->getSceneData()函数获取场景图的根节点,并调用其releaseGLObjects()函数来释放分配的OpenGL对象。
3. 调用osgDB::Registry::instance()->closeAllLibraries()函数来关闭所有打开的插件库,并释放相关资源。
需要注意的是,如果程序中使用了其他OSG相关资源(如纹理、着色器等),也需要在程序退出前对其进行释放。具体的方式可以参考上面的示例代码。
程序结束后osgViewer::Viewer还在运行代码
以下是一个简单的程序结束后强制释放osgViewer::Viewer资源的示例代码:
```
#include <osgViewer/Viewer>
#include <osg/Geode>
#include <osg/ShapeDrawable>
int main(int argc, char** argv)
{
// 创建视图器对象
osgViewer::Viewer viewer;
// 创建场景图
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
osg::ref_ptr<osg::Sphere> sphere = new osg::Sphere(osg::Vec3(0, 0, 0), 1.0f);
osg::ref_ptr<osg::ShapeDrawable> drawable = new osg::ShapeDrawable(sphere);
geode->addDrawable(drawable);
// 添加场景图到视图器
viewer.setSceneData(geode);
// 运行视图器
viewer.run();
// 停止渲染
viewer.setDone(true);
// 停止视图器线程
viewer.stopThreading();
// 确保OpenGL上下文是当前的
viewer.realize();
// 手动触发一次渲染
viewer.frame();
// 释放OpenGL上下文
viewer.releaseContext();
// 等待一段时间,确保所有OpenThreads线程都已经退出
OpenThreads::Thread::microSleep(1000);
// 删除对象
viewer.setSceneData(nullptr);
viewer.getCamera()->setGraphicsContext(nullptr);
viewer.getCamera()->setViewport(nullptr);
viewer.setCameraManipulator(nullptr);
viewer.setScene(nullptr);
viewer.setCamera(nullptr);
// 强制回收内存
osg::Referenced::setThreadSafeReferenceCounting(false);
osg::Referenced::setThreadSafeDeleteHandler(new osg::DeleteHandler);
return 0;
}
```
这个程序创建了一个简单的场景图,并在视图器中运行,待程序结束后,通过调用`viewer.setDone(true)`等方法强制停止渲染,并手动触发一次渲染,最后删除视图器对象并强制回收内存。需要注意的是,在删除视图器对象之前,需要将与之相关的资源全部释放,包括场景图、相机、视口等,以及调用`viewer.releaseContext()`方法释放OpenGL上下文。
阅读全文