Ogre中使用Opencv加载视频作为纹理贴图

增强现实中经常要用到真实的2D视频图片再配合虚拟对象(如三维模型)结合,以达到增强现实的效果。这里使用Ogre结合Opencv来实现

在开始前要先了解到纹理贴图的长宽必须是2的n次方,所以假如加载的视频没有达到这个值,必须做一下resize

 

1.创建动态纹理、背景框矩形,并添加到场景

   在CreateScene中加入如下代码

[cpp]  view plain copy
  1. void CreateScene()  
  2. {  
  3.     MaterialPtr material = MaterialManager::getSingleton().create(  
  4.         "DynamicTextureMaterial"// name  
  5.         ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);  
  6.     material->getTechnique(0)->getPass(0)->createTextureUnitState("DynamicBg");  
  7.     material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false);  
  8.     material->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);  
  9.     material->getTechnique(0)->getPass(0)->setLightingEnabled(false);  
  10.   
  11.     // Create background rectangle covering the whole screen  
  12.       
  13.     Rectangle2D* rect = new Rectangle2D(true);  
  14.     rect->setCorners(-1.0, 1.0, 1.0, -1.0);  
  15.     rect->setMaterial("DynamicTextureMaterial");  
  16.   
  17.     // Render the background before everything else  
  18.     rect->setRenderQueueGroup(RENDER_QUEUE_BACKGROUND);  
  19.   
  20.     // Hacky, but we need to set the bounding box to something big  
  21.     // NOTE: If you are using Eihort (v1.4), please see the note below on setting the bounding box  
  22.     rect->setBoundingBox(AxisAlignedBox(-100000.0*Vector3::UNIT_SCALE, 100000.0*Vector3::UNIT_SCALE));  
  23.   
  24.     // Attach background to the scene  
  25.     SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode("Background");  
  26.     node->attachObject(rect);  
  27.   
  28.     //add other scene node here  
  29. }  


 

2.初始化视频图像获取相关数据

[cpp]  view plain copy
  1. <pre name="code" class="cpp">void InitVideoQuery(char *szVideoPath)  
  2. {  
  3.     m_szVideoPath = szVideoPath;  
  4.     m_pFileCamer=cvCreateFileCapture(szVideoPath );              
  5.     m_pVideoImage=cvQueryFrame(m_pFileCamer);  
  6.   
  7.     m_pDrawImage=cvCreateImage(cvSize(1024,1024),8,3);  
  8.       
  9.     m_pTex=TextureManager::getSingleton().createManual("DynamicBg","General",  
  10.         TEX_TYPE_2D,m_pDrawImage->width,m_pDrawImage->height,1,0,PF_A8B8G8R8,TU_WRITE_ONLY);</pre>}<br>  
  11. <br>  
  12. <pre></pre>  
  13. <pre></pre>  
  14. <p> </p>  
  15. <p>3.更新顶点缓存</p>  
  16. <pre class="cpp" name="code">void UpdateTextureImage()  
  17. {  
  18.     m_pVideoImage=cvQueryFrame(m_pFileCamer);  
  19.     if(m_pDrawImage==0)  
  20.     {  
  21.         cvReleaseCapture(&m_pFileCamer);  
  22.         m_pFileCamer=cvCreateFileCapture(m_szVideoPath);  
  23.         m_pVideoImage=cvQueryFrame(m_pFileCamer);  
  24.     }  
  25.     cvShowImage("img",m_pVideoImage);  
  26.   
  27.       
  28.     cvResize(m_pVideoImage,m_pDrawImage);  
  29.   
  30.     HardwarePixelBufferSharedPtr buffer=m_pTex->getBuffer(0,0);  
  31.     buffer->lock(HardwareBuffer::HBL_DISCARD);  
  32.     const PixelBox &pb = buffer->getCurrentLock();  
  33.     uint32 *data = static_cast<uint32*>(pb.data);  
  34.     size_t height = pb.getHeight();  
  35.     size_t width = pb.getWidth();  
  36.     size_t pitch = pb.rowPitch; // Skip between rows of image  
  37.     for(size_t y=0; y<m_pDrawImage->height; ++y)  
  38.     {  
  39.         unsigned char *pImgLine=(unsigned char *)(m_pDrawImage->imageData+y*m_pDrawImage->widthStep);  
  40.         for(size_t x=0; x<m_pDrawImage->width; ++x)  
  41.         {  
  42.             // 0xRRGGBB -> fill the buffer with yellow pixels  
  43.             unsigned char B=pImgLine[3*x];  
  44.             unsigned char G=pImgLine[3*x+1];  
  45.             unsigned char R=pImgLine[3*x+2];  
  46.             uint32 pixel=(R<<16)+(G<<8)+(B);  
  47.             data[pitch*y + x] =pixel ;  
  48.         }  
  49.     }  
  50.   
  51.     buffer->unlock();  
  52. }</pre>  
  53. <p><br>  
  54.  </p>  
  55. <p> </p>  
  56. <p>值得一提的是,在更新顶点缓存的过程中,即lock到unlock之间,由于操作硬件缓存效率低,为了提高效率,应该尽量减少代码的操作量,可选的做法是在外面将数据打包好,然后在更新的时候直接memcpy</p>  
  57. <p><br>  
  58. </p>  
  59. <pre></pre>  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值