ogre中提取阴影锥的方法

 

ogre中提取阴影锥的方法
    目前3d渲染显示阴影有两种方法,模板阴影和纹理阴影。其中模板阴影是根据模型的外包轮廓延光照方向生成轮廓体即阴影锥,然后进行zpass或zfail算法来实现的。有些时候我们需要提取这个阴影锥,做一些其他应用。本文介绍在ogre中如何提取阴影锥并生成个mesh文件。
上代码:
    //实体对象
   Entity *ent;
   //光源
  Light *light;
   //注意光源是new处理的这里我并不想让scenemanager来使用它,它仅作为生成阴影锥的一个参数
  light = new Light("light1");
  light->setType(Light::LT_DIRECTIONAL);
  light->setDirection(1, -1, 1);

    //mSceneMgr为Scenemanager指针
  mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));

    //导入一个模型
  ent = mSceneMgr->createEntity("tudorhouse.mesh");
    //是否有边界,无则创建
  bool belist = ent->hasEdgeList();
  if (!belist)
  {
   Ogre::MeshPtr pMeshPtr = ent->getMesh();
   pMeshPtr->buildEdgeList();
  }
  
   //创建阴影锥缓存
  int mShadowIndexBufferSize = 51200;
 HardwareIndexBufferSharedPtr mShadowIndexBuffer = HardwareBufferManager::getSingleton().
  createIndexBuffer(HardwareIndexBuffer::IT_16BIT,
  mShadowIndexBufferSize,
  HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
  false);
  
 ShadowCaster* caster = ent;
    //创建阴影锥renderable,一定要设置成SHADOWTYPE_STENCIL_MODULATIVE
 ShadowCaster::ShadowRenderableListIterator iShadowRenderables =
  caster->getShadowVolumeRenderableIterator(SHADOWTYPE_STENCIL_MODULATIVE,
  light, &mShadowIndexBuffer, true,
  10000, SRF_INCLUDE_LIGHT_CAP|SRF_INCLUDE_DARK_CAP);//ShadowRenderableFlags::SRF_EXTRUDE_TO_INFINITY);

  //此处应该是
  //  while (iShadowRenderables.hasMoreElements())
  //  {
  //这里为了简单就不写顶点和索引合并的了,例子中的tudorhouse.mesh好像也只有一个ShadowRenderable,吼吼
  ShadowRenderable* sr = iShadowRenderables.getNext();
 Ogre::RenderOperation op;
 sr->getRenderOperation(op);
 
 VertexData* pVertexData = op.vertexData;
 IndexData* pIndex = op.indexData;

//会发现pVertexData有2个VertexElement,一个是顶点坐标(float3,我们想 要的),还有一个是的纹理坐标(float1),但不在同一资源
// VertexDeclaration* pDecl = pVertexData->vertexDeclaration;
// int isize = pDecl->getElementCount();

// for (int i=0; i < isize; i++)
// {
//  const VertexElement* pElmt = pDecl->getElement(i);
// }

//只要顶点坐标,故getBuffer(0);
 HardwareVertexBufferSharedPtr vbuf =
  pVertexData->vertexBufferBinding->getBuffer(0);
//x,y,z有3位吗,当然*3了
 std::vector<float> vctData(pVertexData->vertexCount*3);
 float *prPos = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
 {

  for(int i = 0; i < pVertexData->vertexCount; i++)
  {
   vctData[i*3 ] = *prPos++;
   vctData[i*3 +1] = *prPos++;
   vctData[i*3 +2] = *prPos++;

  }
 }
 vbuf->unlock();

//取索引,不废话了
 Ogre::int16* index = new Ogre::int16[pIndex->indexCount];
 pIndex->indexBuffer->readData(0,pIndex->indexCount*sizeof(Ogre::int16),index);

//建立ManualObject,也只是简单的new
 ManualObject* pManu = new ManualObject("TestManual");
 pManu->begin("BaseWhiteNoLighting");
 for (int i =0 ; i< pVertexData->vertexCount; i ++)
 {
  pManu->position(vctData[i*3],vctData[i*3 +1],vctData[i*3 +2]);
 }
 for (int i = 0; i < pIndex->indexCount; i ++)
 {
  pManu->index(index[i]);
 }
 pManu->end();

//建立mesh
 MeshPtr ptrMesh = pManu->convertToMesh("testmesh");

 MeshSerializer messs;
 messs.exportMesh(ptrMesh.get(),"C:\\testmesh.mesh");
 
//最后做清理,不写了
  delete all have to be deleted;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值