您的位置:首页 > 其它

Ogre 处理顶点/索引数据

2011-06-24 15:51 330 查看
处理Maya、3D Max模型时,我们首先需要处理顶点/索引数据。这里分两步进行:

(1)得到顶点/索引数据

这里可以参考OGRE官网上的代码,需要注意的是官网上参数Mesh为指针类型,而今Mesh已经有了MeshPtr类作为Mesh的指针。代码如下:

void getMeshInfo(const Ogre::MeshPtr mesh,
size_t &vertex_count,
Ogre::Vector3* &vertices,
size_t &index_count,
unsigned long* &indices,
const Ogre::Vector3 &position = Vector3::ZERO,
const Ogre::Quaternion &orient = Quaternion::IDENTITY,
const Ogre::Vector3 &scale = Vector3::UNIT_SCALE)
{
bool   added_shared   = false;
size_t current_offset = 0;
size_t shared_offset  = 0;
size_t next_offset    = 0;
size_t index_offset   = 0;
vertex_count = index_count = 0;
// Calculate how many vertices and indices we're going to need
for(unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
{
Ogre::SubMesh* submesh = mesh->getSubMesh(i);

// We noly need to add the shared vertices once
if(submesh->useSharedVertices)
{
if(!added_shared)
{
vertex_count += mesh->sharedVertexData->vertexCount;
added_shared = true;
}
}
else
{
vertex_count += submesh->vertexData->vertexCount;
}
// Add the indices
index_count += submesh->indexData->indexCount;
}
// Allocate space for the vertices and indices
vertices = new Ogre::Vector3[vertex_count];
indices  = new unsigned long[index_count];
added_shared = false;
// Run through the submeshes again, adding the data into arrays
for(unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
{
Ogre::SubMesh*    submesh = mesh->getSubMesh(i);
Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
if( (!submesh->useSharedVertices) || (submesh->useSharedVertices && !added_shared) )
{
if(submesh->useSharedVertices)
{
added_shared = true;
shared_offset = current_offset;
}
const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
float* pReal;
for(size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
{
posElem->baseVertexPointerToElement(vertex, &pReal);
Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]);
vertices[current_offset + j] = (orient * (pt * scale)) + position;
}
vbuf->unlock();
next_offset += vertex_data->vertexCount;
}
Ogre::IndexData* index_data = submesh->indexData;
size_t numTris = index_data->indexCount / 3;
Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;
bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
unsigned long*  pLong  = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong);
size_t offset = (submesh->useSharedVertices) ? shared_offset : current_offset;
if(use32bitindexes)
{
for(size_t k = 0; k < numTris * 3; ++k)
{
indices[index_offset++] = pLong[k] + static_cast<unsigned long>(offset);
}
}
else
{
for(size_t k = 0; k < numTris * 3; ++k)
{
indices[index_offset++] = static_cast<unsigned long>(pShort[k]) + static_cast<unsigned long>(offset);
}
}
ibuf->unlock();
current_offset = next_offset;
}
}


该函数使用方法如下:

Entity* mEye = mSceneMgr->createEntity("MyEye", "eye.mesh");
//get the mesh info
size_t vertex_count, index_count;
Vector3* vertices;
unsigned long* indices;
getMeshInfo(mEye->getMesh(), vertex_count, vertices, index_count, indices);
Ogre::String output;
stringstream ss;
ss<<"***************Vertices in mesh: ";
ss<<vertices[0].x <<"  "<<vertices[0].y <<"  "<<vertices[0].z <<"  ";
ss<<"***************";
output = ss.str();
LogManager::getSingleton().logMessage(output);


这样就可以在Ogre.log中看到输出信息了。

(2)修改顶点/索引数据并再次渲染模型

void updateMesh(const MeshPtr mesh)
{
bool added_shared = false;
size_t current_offset = 0;
size_t shared_offset = 0;
size_t next_offset = 0;
// foreach SubMesh
for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
{
Ogre::SubMesh* submesh = mesh->getSubMesh(i);
Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !added_shared))
{
if (submesh->useSharedVertices)
{
added_shared = true;
shared_offset = current_offset;
}
// the real vertex data is wrapped into lots of classes
const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
float* pReal;
for (size_t j = 0; j < vertex_data->vertexCount; j++, vertex += vbuf->getVertexSize())
{
// get vertex data
posElem->baseVertexPointerToElement(vertex, &pReal);
// modify vertex data
pReal[2] += 0.0001;
}
vbuf->unlock();
next_offset += vertex_data->vertexCount;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: