现在的位置: 首页 > 综合 > 正文

修改OGRE中模型的顶点色

2018年01月16日 ⁄ 综合 ⁄ 共 6273字 ⁄ 字号 评论关闭

受到了 http://blog.csdn.net/honghaier/article/details/4130136 红孩儿的启发,对Ogre中的模型进行修改。

以下贴出关键的一些代码。

1 创建Mesh 参考了网上流传的天龙八部

void GameState::createTileMesh()
 {
 MeshPtr mesh = MeshManager::getSingleton().createManual("test", "General");  
 SubMesh* sm = mesh->createSubMesh();  
 sm->useSharedVertices = false;   // 不使用共享顶点  
 sm->vertexData = new VertexData();  
 sm->vertexData->vertexCount = 8;  
 // 顶点结构描述  
 VertexDeclaration* decl = sm->vertexData->vertexDeclaration;  
 size_t offset = 0;  
 // 顶点位置  
 decl->addElement(MAIN_BINDING, offset, VET_FLOAT3, VES_POSITION);  
 offset += VertexElement::getTypeSize(VET_FLOAT3);  
 // 法线  
 decl->addElement(MAIN_BINDING, offset, VET_FLOAT3, VES_NORMAL);  
 offset += VertexElement::getTypeSize(VET_FLOAT3);  
 //颜色
 decl->addElement(MAIN_BINDING,offset,VET_FLOAT4,VES_DIFFUSE);
 offset+=VertexElement::getTypeSize(VET_FLOAT4);
 // 顶点缓存  
 HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton()  
   .createVertexBuffer(offset, 8, HardwareBuffer::HBU_STATIC_WRITE_ONLY);  
 // 获得顶点缓存的地址  
 float* pReal = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD)); 
   // 索引缓存  
 sm->indexData->indexCount = (8/2)*3;  
 sm->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, (8/2)*3, HardwareBuffer::HBU_STATIC_WRITE_ONLY); 

 // 获得索引缓存的地址  
 unsigned short* pI = static_cast<unsigned short*>(sm->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
 Ogre::AxisAlignedBox meshBounds;
 Real meshRadius=0;
 // 对mesh每个网格的个顶点编写数据  
 // 点0  
 // position  
 Vector3 position(0, 10, 0);  
 *pReal++ = position.x;  
 *pReal++ = position.y;  
 *pReal++ = position.z;  
 meshBounds.merge(position);     // update bounds  
 meshRadius = std::max(meshRadius, position.length()); // update bounds  
 // normal  
 Vector3 normal = Vector3(1,1,1);
 normal.normalise();
 *pReal++ = normal.x;  
 *pReal++ = normal.y;  
 *pReal++ = normal.z;  
 // 颜色 
 //RGBA col=RGBA(255,255,255,0);
 *pReal++ = 255;
 *pReal++ = 255;
 *pReal++=0;
 *pReal++=0;
 //点1 
 // position  
 position = Vector3(5, 10, 0);  
 *pReal++ = position.x;  
 *pReal++ = position.y;  
 *pReal++ = position.z;  
 meshBounds.merge(position);     // update bounds  
 meshRadius = std::max(meshRadius, position.length()); // update bounds  
 // normal  
 normal = Vector3(1,1,1);  
 normal.normalise();
 *pReal++ = normal.x;  
 *pReal++ = normal.y;  
 *pReal++ = normal.z;  
 //颜色
 //col=Vector3(255,255,255,0);
 *pReal++ = 255;
 *pReal++ = 0;
 *pReal++=255;
 *pReal++=0;

//点2 
 // position  
 position = Vector3(10, 10, 0);  
 *pReal++ = position.x;  
 *pReal++ = position.y;  
 *pReal++ = position.z;  
 meshBounds.merge(position);     // update bounds  
 meshRadius = std::max(meshRadius, position.length()); // update bounds  
 // normal  
 normal = Vector3(1,1,1);  
 normal.normalise();
 *pReal++ = normal.x;  
 *pReal++ = normal.y;  
 *pReal++ = normal.z;  
 //颜色
 //col=Vector3(255,255,255,0);
 *pReal++ = 255;
 *pReal++ = 0;
 *pReal++=255;
 *pReal++=0;

   //点4 
 // position  
 position = Vector3(10, 0, 0);  
 *pReal++ = position.x;  
 *pReal++ = position.y;  
 *pReal++ = position.z;  
 meshBounds.merge(position);     // update bounds  
 meshRadius = std::max(meshRadius, position.length()); // update bounds  
 // normal  
 normal = Vector3(1,1,1);  
 normal.normalise();
 *pReal++ = normal.x;  
 *pReal++ = normal.y;  
 *pReal++ = normal.z;  
 //颜色
 //col=Vector3(255,255,255,0);
 *pReal++ = 255;
 *pReal++ = 0;
 *pReal++=255;
 *pReal++=0;
   //点5 
 // position  
 position = Vector3(5, 0, 0);  
 *pReal++ = position.x;  
 *pReal++ = position.y;  
 *pReal++ = position.z;  
 meshBounds.merge(position);     // update bounds  
 meshRadius = std::max(meshRadius, position.length()); // update bounds  
 // normal  
 normal = Vector3(1,1,1);  
 normal.normalise();
 *pReal++ = normal.x;  
 *pReal++ = normal.y;  
 *pReal++ = normal.z;  
 //颜色
 //col=Vector3(255,255,255,0);
 *pReal++ = 255;
 *pReal++ = 0;
 *pReal++=255;
 *pReal++=0;
   //点6 
 // position  
 position = Vector3(0, 0, 0);  
 *pReal++ = position.x;  
 *pReal++ = position.y;  
 *pReal++ = position.z;  
 meshBounds.merge(position);     // update bounds  
 meshRadius = std::max(meshRadius, position.length()); // update bounds  
 // normal  
 normal = Vector3(1,1,1);  
 normal.normalise();
 *pReal++ = normal.x;  
 *pReal++ = normal.y;  
 *pReal++ = normal.z;  
 //颜色
 //col=Vector3(255,255,255,0);
 *pReal++ = 255;
 *pReal++ = 0;
 *pReal++=255;
 *pReal++=0;

int off=0;
 *pI++=1+off;
 *pI++=0+off;
 *pI++=5+off;

*pI++=1+off;
 *pI++=5+off;
 *pI++=4+off;

*pI++=2+off;
 *pI++=1+off;
 *pI++=4+off;

*pI++=2;
 *pI++=4;
 *pI++=3;

vbuf->unlock();
 sm->vertexData->vertexBufferBinding->setBinding(MAIN_BINDING, vbuf);   // 绑定顶点缓存 

 sm->indexData->indexBuffer->unlock();  
 mesh->_setBounds(meshBounds);  
 mesh->_setBoundingSphereRadius(meshRadius);  

mesh->load();  

 }

//手工修改Mesh的顶点颜色 参考了红孩儿的代码

void GameState::Fun_SetModeColor(DWORD vColor)
 {
 if(mObjEnt)
 {
   Ogre::MeshPtr tpMesh=mObjEnt->getMesh();
   tpMesh->setVertexBufferPolicy(HardwareBuffer::HBU_DYNAMIC,true);
   //遍历对应的模型
   int tSubEngityNum=tpMesh->getNumSubMeshes();
   for(int S=0;S<tSubEngityNum;S++)
   {
    Ogre::SubMesh* tpSubMesh=tpMesh->getSubMesh(S);
    //锁定顶点缓冲区
    VertexData* tVertexData=tpSubMesh->vertexData;
    //色彩
    size_t tSize3=0;
    size_t tOffSet3=0;
    const Ogre::VertexElement* posElem3=tVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE);
    if(posElem3)
    {
     tSize3=posElem3->getSize();
     tOffSet3=posElem3->getOffset();
    }
    else
    {
     ::MessageBox(NULL,"没有顶点色","提示",MB_OK);
     return;
    }
    HardwareVertexBufferSharedPtr dstHVBPos=tVertexData->vertexBufferBinding->getBuffer(posElem3->getSource());
    size_t SizeInBytes=dstHVBPos->getSizeInBytes();
    size_t numVertices=dstHVBPos->getNumVertices();
    size_t SizeVertices=dstHVBPos->getVertexSize();
    size_t VerticesCount=tVertexData->vertexCount;

   unsigned char* pVert=static_cast<unsigned char*>(dstHVBPos->lock(0,SizeInBytes,HardwareBuffer::HBL_DISCARD));
    float *dstDataPos;
    //遍历所有顶点
    for(int i=0;i<VerticesCount;i++,pVert+=SizeVertices)
    {
     posElem3->baseVertexPointerToElement(pVert,&dstDataPos);
   
     if(i==2 || i==3)
     {

    DWORD tRed=dstDataPos[0];
     DWORD tGreen=dstDataPos[1];
     DWORD tBlue=dstDataPos[2];
     DWORD tA=dstDataPos[3];
     dstDataPos[0]=255;
     dstDataPos[1]=255;
     dstDataPos[2]=0;
     dstDataPos[3]=0;
     }

   }
    dstHVBPos->unlock();
   }
 }
 }

void GameState::createScene()
 {
 createTileMesh();
 mObjEnt=m_pSceneMgr->createEntity("hello","test");
 mObjEnt->setMaterialName("Examples/test");
 Fun_SetModeColor(0);
 Ogre::SceneNode* pNode=m_pSceneMgr->getRootSceneNode()->createChildSceneNode("d");
 pNode->attachObject(mObjEnt);
 }

 

Picture:

 

 

抱歉!评论已关闭.