osg.ImageSequence是OpenSceneGraph中用于表示图像序列的节点。
图像序列是一系列在时间序列中按顺序播放的图像。osg.ImageSequence节点允许在场景图中添加类似视频、动画等需要播放图像序列的场合中。
osg::Object → osg::Node → osg::Geode → osg::ImageSequence
#include <osg/ImageSequence>
osg.ImageSequence节点可以通过osgDB库中的readImageSequence()函数从图像文件序列中创建。
osg::ref_ptr<osg::ImageSequence> imgSeq = osgDB::readImageSequenceFile("images/img_%d.png", 0, 10);
readImageSequenceFile()函数的第一个参数表示图像文件序列命名模式,其中%d表示需要替换的数字部分,会按顺序替换成0到10的数字,创建对应的图像文件序列。
第二个和第三个参数表示图像序列的起止帧。在本例中,创建了包含了11帧图像的osg.ImageSequence节点。readImageSequenceFile()函数返回的是osg::ImageList类型,需要将其转换为osg.ImageSequence类型。
// 将osg::ImageList转换为osg::ImageSequence
osg::ref_ptr<osg::ImageSequence> imgSeq = new osg::ImageSequence;
imgSeq->setName("myImageSequence");
for(auto& img : imgList)
imgSeq->addImage(img.get());
imgSeq->setLength(imgList.size());
该代码手动创建了一个osg.ImageSequence节点,并分别添加11帧图像,设置图像序列长度为11帧。
osg.ImageSequence节点具有以下属性:
属性 | 类型 | 说明 |
---|---|---|
Length | unsigned int | 图像序列长度,即图像帧数。 |
ImageList | osg::ImageList* | 图像序列中包含的图像列表(osg::ImageList*类型),一般通过addImage()方法添加。 |
LoopMode | LoopMode | 图像序列的循环模式。 |
FrameRange | osg::Vec2i | 图像序列的帧数范围,Vector2i的x为起始帧,y为结束帧。 |
FrameRate | float | 播放图像序列的帧率。 |
CurrentFrame | float | 当前图像帧。 |
TimeMultiplier | float | 播放速率倍数。 |
osg.ImageSequence节点包含以下方法:
设置图像序列长度,即图像帧数。
imgSeq->setLength(11);
获取图像序列长度,即图像帧数。
unsigned int numFrames = imgSeq->getLength();
设置图像序列中包含的图像列表(osg::ImageList*类型),一般通过addImage()方法添加。
osg::ref_ptr<osg::ImageList> imgList = new osg::ImageList;
for(int i=0; i<11; ++i)
{
osg::ref_ptr<osg::Image> img = osgDB::readImageFile("images/img_"+std::to_string(i)+".png");
imgList->push_back(img);
}
imgSeq->setImageList(imgList.get());
获取图像序列中包含的图像列表(osg::ImageList*类型)。
osg::ImageList* imgList = imgSeq->getImageList();
设置图像序列的循环模式。可选值为LOOPING、SWINGING。
imgSeq->setLoopMode(osg::ImageSequence::LoopMode::LOOPING);
获取图像序列的循环模式。
osg::ImageSequence::LoopMode loopMode = imgSeq->getLoopMode();
设置图像序列的帧数范围,Vector2i的x为起始帧,y为结束帧。
imgSeq->setFrameRange(osg::Vec2i(0, 10));
获取图像序列的帧数范围,Vector2i的x为起始帧,y为结束帧。
const osg::Vec2i& range = imgSeq->getFrameRange();
设置播放图像序列的帧率。
imgSeq->setFrameRate(30.0f);
获取播放图像序列的帧率。
float frameRate = imgSeq->getFrameRate();
获取当前图像帧。
float currentFrame = imgSeq->getCurrentFrame();
设置当前图像帧。
imgSeq->setCurrentFrame(5.0f);
设置播放速率倍数。
imgSeq->setTimeMultiplier(2.0f);
获取播放速率倍数。
float multiplier = imgSeq->getTimeMultiplier();
osg::ref_ptr<osg::ImageSequence> imgSeq = osgDB::readImageSequenceFile("images/img_%d.png", 0, 10);
osg::ref_ptr<osg::Texture2D> tex = new osg::Texture2D(imgSeq.get());
osg::ref_ptr<osg::Geometry> quad = osg::createTexturedQuadGeometry({0, 0, 0}, {1, 0, 0}, {0, 1, 0});
quad->getOrCreateStateSet()->setTextureAttributeAndModes(0, tex.get());
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(quad.get());
osg::ref_ptr<osg::Group> root = new osg::Group;
root->addChild(geode.get());
osgViewer::Viewer viewer;
viewer.setSceneData(root.get());
viewer.run();
该示例中,读入了img_0.png到img_10.png共11帧的图像文件序列,创建了osg.ImageSequence节点imgSeq,并将其传给osg.Texture2D节点的构造函数,创建纹理并应用到一个平面几何体quad上,最终添加到Geode节点中。最后通过Viewer类的run()方法开始渲染图像序列的动画效果。