osg播放视频时,需要利用ffmpeg的多媒体播放器插件,所以在播放视频之前需要成功的加载此插件,才能最终显示出画面,现将osg播放本地文件和流文件的方法总结一下:
1、播放本地文件
osgDB::Registry::instance()->addFileExtensionAlias("mp4", "ffmpeg");
osg::ref_ptr<osg::Image> image = osgDB::readRefImageFile("sample.mp4");
2、播放流地址
osg::ref_ptr<osgDB::ReaderWriter> rwter = osgDB::Registry::instance()->getReaderWriterForExtension("ffmpeg");
osgDB::ReaderWriter::ReadResult rr = rwter->readImage("rtsp://192.168.1.111:554/h264/ch1/main/av_stream");
osg::ref_ptr<osg::Image> image = rr.getImage();
//
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osg/ImageStream>
#include <osg/Texture2D>
int main()
{
//注册插件
osgDB::Registry::instance()->addFileExtensionAlias("avi", "ffmpeg");
osg::ref_ptr<osg::Image> image;
//本地视频(自己选择视频路径)
image = osgDB::readImageFile("aaa.avi");
osg::ImageStream* imageStream = dynamic_cast<osg::ImageStream*>(image.get());
if (imageStream)
imageStream->play();
//添加到四边形
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
texture->setImage(image.get());
osg::ref_ptr<osg::Drawable> quad = osg::createTexturedQuadGeometry(
osg::Vec3(), osg::Vec3(-1.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 1.0f));//
quad->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture.get());
//添加到geode
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(quad.get());
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
//添加到场景
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
viewer->setSceneData(geode.get());
viewer->run();
}
加载视频到指定位置
将上面代码中的“添加到四边形”部分修改为以下代码。然后自己设置顶点坐标。
这里我是在场景中选取点保存坐标然后读取的,也可以直接设置顶点坐标:)
顶点选取的顺序为逆时针,第一个从左上角(0,1)开始选取。
( 这里视频和纹理的顶点对应关系存疑,如果不对可以自己尝试修改顶点顺序。)
//添加到四边形
//========================在这里设置顶点坐标=======================================
osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
ifstream inFile;
inFile.open("cameraVideoPoint.txt");
for (int i = 0; i < 4; i++)
{
double x, y, z;
inFile >> x >> y >> z;
v->push_back(osg::Vec3(x, y, z+0.3));
}
//========================在这里设置顶点坐标=======================================
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
geom->setVertexArray(v.get());
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, 4));
//设置纹理坐标
osg::ref_ptr<osg::Vec2Array> tcoords = new osg::Vec2Array();
//加载出来不知道为什么是反的,所以我改为了顺时针
tcoords->push_back(osg::Vec2(0.0f, 0.0f));
tcoords->push_back(osg::Vec2(0.0f, 1.0f));
tcoords->push_back(osg::Vec2(1.0f, 1.0f));
tcoords->push_back(osg::Vec2(1.0f, 0.0f));
geom->setTexCoordArray(0, tcoords);
geom->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture.get());
geode->addDrawable(geom);//geode的drawable改一下