这几天在弄这些。学了不少,把这两天的学习成果贴出来:
Ogre中submesh之间的共享缓存的使用
在ogre的app类中添加如下代码:
void createSphere(const std::string& strName, const float r, const int nRings = 16, const int nSegments = 16)
{
MeshPtr pSphere = MeshManager::getSingleton().createManual(strName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
SubMesh *pSphereVertex = pSphere->createSubMesh();
SubMesh *pSphereVertex1 = pSphere->createSubMesh();
//为mesh分配共享缓存的空间。共享缓存在mesh中保存,而不是submesh
pSphere->sharedVertexData = new VertexData();
VertexData* vertexData = pSphere->sharedVertexData;
// 为共享缓存指定顶点格式
VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
size_t currOffset = 0;
// positions
vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
currOffset += VertexElement::getTypeSize(VET_FLOAT3);
// normals
vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
currOffset += VertexElement::getTypeSize(VET_FLOAT3);
// two dimensional texture coordinates
vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
currOffset += VertexElement::getTypeSize(VET_FLOAT2);
// 为mesh的共享缓的定点数据存分配硬件空间
vertexData->vertexCount = (nRings + 1) * (nSegments+1);
HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
VertexBufferBinding* binding = vertexData->vertexBufferBinding;
//将该硬件缓存和mesh的共享缓存对象绑定
binding->setBinding(0, vBuf);
float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));
//---------------------------
// 分配submesh的索引缓存:这里只需要给submesh分配索引缓存,定点数据缓存从mesh的共享缓存中读取;
pSphereVertex->indexData->indexCount = 6 * nRings * (nSegments + 1);
pSphereVertex->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, pSphereVertex->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
HardwareIndexBufferSharedPtr iBuf = pSphereVertex->indexData->indexBuffer;
unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD));
//为sunmsh2分配索引缓存。
pSphereVertex1->indexData->indexCount = 6 * nRings * (nSegments + 1);
pSphereVertex1->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, pSphereVertex1->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
HardwareIndexBufferSharedPtr iBuf1 = pSphereVertex1->indexData->indexBuffer;
unsigned short* pIndices1 = static_cast<unsigned short*>(iBuf1->lock(HardwareBuffer::HBL_DISCARD));
//-------------------------------------------
//向共享缓存区的vertexdata写入数据
float fDeltaRingAngle = (Math::PI / nRings);
float fDeltaSegAngle = (2 * Math::PI / nSegments);
unsigned short wVerticeIndex = 0 ;
// 填写mesh的共享缓存区的vertexdata和submesh的indexdata
for( int ring = 0; ring <= nRings; ring++ ) {
float r0 = r * sinf (ring * fDeltaRingAngle);
float y0 = r * cosf (ring * fDeltaRingAngle);
// Generate the group of segments for the current ring
for(int seg = 0; seg <= nSegments; seg++) {
float x0 = r0 * sinf(seg * fDeltaSegAngle);
float z0 = r0 * cosf(seg * fDeltaSegAngle);
// 填充mesh的共享缓存的顶点数据
*pVertex++ = x0;
*pVertex++ = y0;
*pVertex++ = z0;
Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy();
*pVertex++ = vNormal.x;
*pVertex++ = vNormal.y;
*pVertex++ = vNormal.z;
*pVertex++ = (float) seg / (float) nSegments;
*pVertex++ = (float) ring / (float) nRings;
if (ring != nRings) {
// each vertex (except the last) has six indices pointing to it
//submesh0设置定点索引
*pIndices++ = wVerticeIndex + nSegments + 1;
*pIndices++ = wVerticeIndex;
*pIndices++ = wVerticeIndex + nSegments;
*pIndices++ = wVerticeIndex + nSegments + 1;
*pIndices++ = wVerticeIndex + 1;
*pIndices++ = wVerticeIndex;
//submesh1设置定点索引
*pIndices1++ = wVerticeIndex + nSegments + 1;
*pIndices1++ = wVerticeIndex;
*pIndices1++ = wVerticeIndex + nSegments;
*pIndices1++ = wVerticeIndex + nSegments + 1;
*pIndices1++ = wVerticeIndex + 1;
*pIndices1++ = wVerticeIndex;
wVerticeIndex ++;
}
}; // end for seg
} // end for ring
// Unlock
vBuf->unlock();
iBuf->unlock();
iBuf1->unlock();
// 开启summesh使用share的设置。
pSphereVertex->useSharedVertices = true;
pSphereVertex1->useSharedVertices = true;
// the original code was missing this line:
pSphere->_setBounds( AxisAlignedBox( Vector3(-r, -r, -r), Vector3(r, r, r) ), false );
pSphere->_setBoundingSphereRadius(r);
// this line makes clear the mesh is loaded (avoids memory leaks)
pSphere->load();
}
然后再createscene函数中添加如下代码:
createSphere("mySphereMesh", 10, 64, 64);
Entity* sphereEntity = mSceneMgr->createEntity("mySphereEntity", "mySphereMesh");
SceneNode* sphereNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
sphereEntity->setMaterialName("Test/ColourTest");
sphereNode->attachObject(sphereEntity);
同时在ogre的资源组中加入"Test/ColourTes’材质脚本,如下所示:
material Test/ColourTest
{
technique
{
pass
{
ambient vertexcolour
}
}
}
之后,编译运行,可以看到一个带颜色的小球出现在场景中。下面给出ogre的共享顶点缓存的工作方法:
1. 创建mesh的submesh,根据需要创建对应的个数。
2. 填充每个submesh的数据项。
3. 设置mesh的共享缓存。并写入相应的数据。
4. 为每个submesh设置该共享缓存的shareindexdata.
5. 打开每个submesh的使用共享缓存设置。
6. 之后对mesh做必要的一些设置,这里省略。
注意:本例子中只设置了mesh的共享缓存,以及每个submesh的共享缓存的索引顺序,并没有为每个submesh设置独立的定点。所以在,这里场景中仅仅显示共享缓存的的部分顶点。