受到了 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: