Here is a short summation of what I am doing in my application.
1. Create a generic scene manager and set it up. This consists of something like the following (pseudocode)
Code: Select all
sceneMgr = root->createSceneManager(ST_GENERIC, "SceneManager");
for (int i = 0; i < resourceLocations.size(); ++i) {
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(...);
}
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
Code: Select all
void createCamera(Ogre::SceneManager *sceneMgr, Ogre::RenderWindow *renderWindow)
{
Ogre::Camera *camera = sceneMgr->createCamera(CAM_NAME);
Ogre::Viewport *viewport = renderWindow->addViewport(camera);
viewport->setCamera(camera);
viewport->setBackgroundColour(Ogre::ColourValue(0.0f, 0.0f, 0.0f, 0.0f));
viewport->setClearEveryFrame(true);
Ogre::SceneNode* sceneNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
sceneNode->attachObject(camera);
// ... set up camera orientaion, fov, etc etc
}
Code: Select all
void parseSingleMaterial(Ogre::String materialFile)
{
Ogre::DataStreamPtr streamPtr = Ogre::ResourceGroupManager::getSingleton().openResource(materialFile);
if (not streamPtr.isNull()) {
Ogre::MaterialManager::getSingleton().parseScript(streamPtr, Ogre::String("MyResourceGroup"));
streamPtr->close();
}
}
Code: Select all
void createSingleEntity(Ogre::SceneManager *sceneMgr, Ogre::String entityName, Ogre::String meshName)
{
Ogre::SceneNode* sceneNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
Ogre::Entity* entity = sceneMgr->createEntity(entityName, meshName);
sceneNode->attachObject(entity);
}
Here is my unload code, which I have tried to make pretty boiler plate, but with no luck. Note I'm using RTSS in GLES 2.0 on iOS so I need to do the call to remove shader based techniques.
Code: Select all
void clearOgreScene(Ogre::SceneManager *sceneMgr, Ogre::Viewport *viewport, , Ogre::RenderWindow *renderWindow, std::vector<Ogre::Entity *>entities)
{
Ogre::SkeletonManager *skelMgr = Ogre::SkeletonManager::getSingletonPtr();
Ogre::MaterialManager *matMgr = Ogre::MaterialManager::getSingletonPtr();
Ogre::MeshManager *meshMgr = Ogre::MeshManager::getSingletonPtr();
Ogre::TextureManager *textureMgr = Ogre::TextureManager::getSingletonPtr();
// to remove an entity, detach it from it's scene node, destroy it from the scene manager, then destroy the scene node
for (int i = 0; i < entities.size(); ++i) {
Ogre::Entity *entity = m_entities[i];
Ogre::SceneNode* parent = entity->getParentSceneNode();
if (parent) {
parent->detachObject(entity);
}
sceneMgr->destroyEntity(entity);
if (parent) {
sceneMgr->destroySceneNode(parent);
}
}
// deal with the various managers
skelMgr->removeAll();
skelMgr->destroyAllResourcePools();
meshMgr->removeAll();
meshMgr->destroyAllResourcePools();
matMgr->removeAll();
matMgr->destroyAllResourcePools();
// without this, we crash on next render
Ogre::RTShader::ShaderGenerator::getSingleton().removeAllShaderBasedTechniques();
textureMgr->unloadAll();
textureMgr->removeAll();
textureMgr->destroyAllResourcePools();
// first, clear the render buffer without doing a frame update
if (viewport) {
// remove the camera as we did the entities
Ogre::Camera *camera = viewport->getCamera();
Ogre::SceneNode* parent = camera->getParentSceneNode();
if (parent) {
parent->detachObject(camera);
}
sceneMgr->destroyCamera(camera);
if (parent) {
sceneMgr->destroySceneNode(parent);
}
// remove the viewport
viewport->getTarget()->removeAllListeners();
viewport->getTarget()->removeAllViewports();
renderWindow->removeAllViewports();
}
sceneMgr->clearScene();
if (Ogre::ResourceGroupManager::getSingleton().resourceGroupExists("MyResourceGroup")) {
Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup("MyResourceGroup");
}
}
Code: Select all
virtual bool frameEnded (const Ogre::FrameEvent &evt);
Let's say that my app after initializing ogre and before loading the scene is using some baseline amount of memory, call it 0.
I create the camera and viewport, parse all my materials, and rip through my entity list creating and attaching each one, per the code above. Then my app grows to +62mb.
I then call clearScene, expecting it to drop down to 0 again, but it stays at +62. Yikes. I then load the same scene, the same way, and end up at +106. clear, reload, and I'm +150. So my memory footprint grows by 62m the first time I load, and even after a clear, another 44m each consecutive time.
Do I have to destroy ResourceGroups? Root Nodes? How do I reclaim the memory ogre is using? At this point, my application is dead in the water. Can anyone provide some insight? Also, am I alone in being completely shocked that there is no single call to tear down all your resources in Ogre?