学习自OpenSceneGraph Quick Start Guide的中文版,建议学习书(比较全面)
OSG的内存管理机制
程序保存一个指向根节点的指针,不保存场景图形中其他节点的指针。根节点将直接或间接地“引用”场景图形中的所有的节点。
当应用程序不再使用场景图形时,每个节点所使用的内存需要释放以避免内存泄漏。
内存引用计数器
所有OSG场景图形节点均采用引用计数,引用计数值为0时,此对象自动释放。
释放根节点的指针,场景图形中的所有节点和数据逐一释放。
ref_ptr<>
Geode类:osg的叶节点,包含了用于渲染的几何信息。
Group节点可以有多个子节点。
代码作用:创建场景图像,写入到名为"Simple.osg"的文件中。
#include <osg/Group>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/ref_ptr>#include <osgDB/Registry>
#include <osgDB/WriteFile>
#include <osg/Notify>
#include <iostream>
using std::endl;
osg::ref_ptr<osg::Node> createSceneGraph()
{// 创建一个用于保存几何信息的对象osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;// 创建四个顶点的数组osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;geom->setVertexArray(v.get());v->push_back(osg::Vec3(-1.f, 0.f, -1.f));v->push_back(osg::Vec3(1.f, 0.f, -1.f));v->push_back(osg::Vec3(1.f, 0.f, 1.f));v->push_back(osg::Vec3(-1.f, 0.f, 1.f));// 创建四种颜色的数组osg::ref_ptr<osg::Vec4Array> c = new osg::Vec4Array;geom->setColorArray(c.get());geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);c->push_back(osg::Vec4(1.f, 0.f, 0.f, 1.f));c->push_back(osg::Vec4(0.f, 1.f, 0.f, 1.f));c->push_back(osg::Vec4(0.f, 0.f, 1.f, 1.f));c->push_back(osg::Vec4(1.f, 1.f, 1.f, 1.f));// 为唯一的法线创建一个数组osg::ref_ptr<osg::Vec3Array> n = new osg::Vec3Array;geom->setNormalArray(n.get());geom->setNormalBinding(osg::Geometry::BIND_OVERALL);n->push_back(osg::Vec3(0.f, -1.f, 0.f));// 由保存的数据绘制四个顶点的多边形geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));// 向 Geode 类添加几何体(Drawable)并返回 Geodeosg::ref_ptr<osg::Geode> geode = new osg::Geode;geode->addDrawable(geom.get());return geode.get();
}
int main(int argc, char* argv[])
{osg::ref_ptr<osg::Node> root = createSceneGraph();if (!root.valid())osg::notify(osg::FATAL) << "Failed in createSceneGraph()."<< endl;bool result = osgDB::writeNodeFile(*(root.get()), "Simple.osg");if (!result)osg::notify(osg::FATAL) << "Failed in osgDB::writeNode()."<< endl;
}
添加一部分代码,使用窗口进行显示。
#include <osgViewer/Viewer>osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;viewer->setUpViewInWindow(50, 50, 800, 600);viewer->setSceneData(root);return viewer->run();