I'm developing an application using OGRE 1.9 on an ARM MALI400, which uses opengles 2. I need to have a constantly updating mesh (vertex and index modification/addition). I use gamekit on top of OGRE, and reload the gamekit mesh each frame. The gamekit mesh is just a thin wrapper around an OGRE mesh, so the reload basically does a basic OGRE unload of the ogre mesh object, and then loads the mesh again using gamekit code, which creates the necessary OGRE hardware buffers and vertex bindings.
Everything runs fine (I see the mesh update in real time), but after some time, I run out of video memory. Nothing else is changing in the scene. If the mesh grows to lets say 1000 vertices, and I don't add any more, but I reload the mesh each frame, it still eventually crashes, if the mesh is smaller, it takes a longer time but it still crashes, which leads me to believe that the hardware buffers are not being freed correctly (and thus accumulate and eventually fill up my video memory). The video memory is not shared with the CPU, so this is extrictly a gpu problem.
The code is part of a bigger project, so right now I'm working on creating a small snippet that reproduces the error, and will post it as soon as I have it, but in the meantime, has anyone run into this sort of problem before, or can point to anything I can verify? The OGRE mesh manager reports the correct ammount of meshes, and they have the amount of vertices/indices I would expect. I'm also calling on the HardwareBufferManager::_releaseBufferCopies and ::_freeUnusedBufferCopies regularly. The code runs fine on PC with OpenGL, it only runs out of memory (even when managing only a mesh with 5000 vertices) only when using the MALi device, which uses OpenGL ES 2.
This is a part of the gamekit code that creates the ogre mesh:
Code: Select all
Ogre::SubMesh* submesh;
submesh->vertexData = new Ogre::VertexData();
submesh->vertexData->vertexCount = vBufSize;
// disable sharing
submesh->useSharedVertices = false;
// converting to tri list
submesh->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
UTsize offs = 0;
// fill in the declaration
Ogre::VertexDeclaration* decl = submesh->vertexData->vertexDeclaration;
// position
decl->addElement(0, offs, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
offs += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
// no, blending weights
// normals
decl->addElement(0, offs, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
offs += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
// texture coordinates
int maxTco = gks->getUvLayerCount();
for (int lay = 0; lay < maxTco; ++lay)
{
decl->addElement(0, offs, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, lay);
offs += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);
}
bool diffuseVert = gks->hasVertexColors();
if (diffuseVert)
{
// diffuse colours
decl->addElement(0, offs, Ogre::VET_COLOUR_ABGR, Ogre::VES_DIFFUSE);
offs += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR_ABGR);
}
// no, specular colours
Ogre::HardwareVertexBufferSharedPtr vertBuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(offs,
submesh->vertexData->vertexCount,
Ogre::HardwareBuffer::HBU_DYNAMIC);
// bind the source
Ogre::VertexBufferBinding* bind = submesh->vertexData->vertexBufferBinding;
bind->setBinding(0, vertBuf);
// index buffer
Ogre::HardwareIndexBuffer::IndexType buff_type = (iBufSize > gk16BitClamp) ?
Ogre::HardwareIndexBuffer::IT_32BIT : Ogre::HardwareIndexBuffer::IT_16BIT;
Ogre::HardwareIndexBufferSharedPtr indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(buff_type,
iBufSize,
Ogre::HardwareBuffer::HBU_DYNAMIC);
submesh->indexData->indexCount = iBufSize;
submesh->indexData->indexBuffer = indexBuffer;