kendoran
22-08-2009 03:17:24
I am trying to write a custom resource manager to load my map and script files, but am not having much success yet.
The
tutorial (Resources and ResourceManagers) I'm attempting to recreate in python-ogre refers to the _registerResourceManager function in the ResourceManager class, but it seems to be unavailable in python-ogre.
Here is the initial attempt:
class TypeFileManager(ogre.ResourceManager):
def __init__(self):
ogre.ResourceManager.__init__(self)
ogre.ResourceManager.ResourceType = "TypeFile"
ogre.ResourceManager.resourceType = "TypeFile"
ogre.ResourceManager.loadingOrder = "30.0"
s = ogre.ResourceGroupManager.getSingleton()
s._registerResourceManager(ogre.ResourceManager.ResourceType, self);
def createImpl(self, name, handle, group, isManual, loader, createParams):
pass
def load(self, name, group):
pass
Any suggestions on what to do here?
_registerResourceManager is certainly exposed -- what is the actual error you are having?
Andy
kendoran
24-08-2009 10:47:08
Hey, thanks for the reply.
I'm still very new to Ogre and Python-Ogre, and made a newbie mistake

After some investigation, the problem was due to not instantiating ogre.Root(). The error I was getting was the standard python error when methods don't exist in an object. All good now though.
I'm still following the tutorial I linked in the first post, and am having some trouble detailed below. Has anybody written a custom resource manager with python-ogre? Is there any sample code available?
There is another problem I'm having. I declared the custom TextFileManager and TextFile classes like in the tutorial, however when I call self.TFM.load("hello.txt", ogre.ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME), the object returned is of type ogre.Resource, rather than TextFile like I would have expected. The returned object does not contain the getString method, or the "text" field.
The TextFile class is registered, and putting a breakpoint in:
def createImpl(self, name, handle, group, isManual, loader, createParams):
self.textfile = TextFile(self, name, handle, group, isManual, loader)
return self.textfile
I can see that the object is correctly set up and is returned.
The resource returned by self.TFM.load has the same value I set in
def calculateSize(self):
return len(self.text)
Any ideas what is happening here, and why the resource manager is only returning resource, rather than the custom text file resource I set up?
For reference, here is the full source (the textfile "hello.txt" is sitting in the media directory, and just contains "Hello world!"):
#!/usr/bin/env python
import sys
import os
import ogre.renderer.OGRE as ogre
import ogre.gui.CEGUI as CEGUI
import ogre.io.OIS as OIS
class TextFileSerializer(ogre.Serializer):
def exportTextFile(self, text, fileName):
pass
def importTextFile(self, stream, dest):
dest.setString(stream.getAsString())
class TextFile(ogre.Resource):
text = None
serializer = TextFileSerializer()
def __init__(self, creator, name, handle, group, isManual, loader):
ogre.Resource.__init__(self, creator, name, handle, group, isManual, loader)
def __del__(self):
unload()
def loadImpl(self):
rgm = ogre.ResourceGroupManager.getSingleton()
stream = rgm.openResource(self.Name, "General", True, self)
self.serializer.importTextFile(stream, self)
def unloadImpl(self):
self.text = ""
def calculateSize(self):
return len(self.text)
def setString(self, text):
self.text = text
def getString(self):
return self.text
class TextFileManager(ogre.ResourceManager):
# Borg Singleton http://code.activestate.com/recipes/66531/
__shared_state = {}
initialized = False
textfile = None
tx = None
def __init__(self):
self.__dict__ = self.__shared_state # Singleton
if self.initialized: return
ogre.ResourceManager.__init__(self)
ogre.ResourceManager.resourceType = "TextFile"
ogre.ResourceManager.ResourceType = "TextFile"
# low, because it will likely reference other resources
ogre.ResourceManager.LoadingOrder = 30.0
ogre.ResourceManager.loadingOrder = 30.0
rgm = ogre.ResourceGroupManager.getSingleton()
rgm._registerResourceManager(self.resourceType, self)
self.initialized = True
def __del__(self):
rgm = ogre.ResourceGroupManager.getSingleton()
rgm._unregisterResourceManager(resourceType)
def load(self, name, group):
self.tx = self.getByName(name)
if not self.tx:
self.tx = self.create(name, group)
self.tx.load()
return self.tx
def createImpl(self, name, handle, group, isManual, loader, createParams):
self.textfile = TextFile(self, name, handle, group, isManual, loader)
return self.textfile
def removeImpl(self, resource):
pass
def unloadAll(self):
pass
class ManualTextFileLoader(ogre.ManualResourceLoader):
def loadResource(self, resource):
resource.setString("manually loaded")
def getPluginPath():
""" Return the absolute path to a valid plugins.cfg file.
look in the current directory for plugins.cfg followed by plugins.cfg.nt|linux|mac
If not found look one directory up
"""
paths = [os.path.join(os.getcwd(), 'plugins.cfg'),
os.path.join(os.getcwd(), '..','plugins.cfg'),
]
if os.sys.platform == 'darwin':
paths.insert(1, os.path.join(os.getcwd(), 'plugins.cfg.mac'))
paths.append(os.path.join(os.getcwd(), '..', 'plugins.cfg.mac'))
else:
paths.insert(1,os.path.join(os.getcwd(), 'plugins.cfg.'+os.name))
paths.append(os.path.join(os.getcwd(), '..', 'plugins.cfg.'+os.name))
for path in paths:
if os.path.exists(path):
return path
sys.stderr.write("\n"
"** Warning: Unable to locate a suitable plugins.cfg file.\n"
"** Warning: Please check your ogre installation and copy a\n"
"** Warning: working plugins.cfg file to the current directory.\n\n")
raise ogre.Exception(0, "can't locate a suitable 'plugins' file", "")
class Application(object):
"This class is the base for an Ogre application."
debugText=""
def __init__(self):
self.frameListener = None
self.root = None
self.camera = None
self.renderWindow = None
self.sceneManager = None
self.world = None
self.unittest = False
def __del__(self):
"Clear variables, this should not actually be needed."
del self.camera
del self.sceneManager
del self.frameListener
if self.world:
del self.world
del self.root
del self.renderWindow
def go(self):
"Starts the rendering loop."
if not self._setUp():
return
self.root.startRendering()
def goOneFrame(self):
"Starts the rendering loop. Show how to use the renderOneFrame Method"
if not self._setUp():
return
self.root.getRenderSystem()._initRenderTargets()
while True:
ogre.WindowEventUtilities().messagePump()
if not self.root.renderOneFrame():
break
def _setUp(self):
"""This sets up the ogre application, and returns false if the user
hits "cancel" in the dialog box."""
pluginFile = getPluginPath() ## option here to switch to manually loading file if it doesn't exist
if self.unittest:
if os.path.isfile('ogre.cfg'):
self.root = ogre.Root( pluginFile )
else:
self.root = ogre.Root( pluginFile, '../ogre.cfg')
else:
self.root = ogre.Root( pluginFile )
self.root.setFrameSmoothingPeriod (5.0)
self._setUpResources()
if not self._configure():
return False
self._loadResources()
return True
def _setUpResources(self):
"""This sets up Ogre's resources, which are required to be in
resources.cfg."""
config = ogre.ConfigFile()
try:
config.load('resources.cfg')
except ogre.OgreFileNotFoundException:
try:
config.load('../resources.cfg')
except:
raise
except:
raise
seci = config.getSectionIterator()
while seci.hasMoreElements():
SectionName = seci.peekNextKey()
Section = seci.getNext()
for item in Section:
ogre.ResourceGroupManager.getSingleton().\
addResourceLocation(item.value, item.key, SectionName)
def _loadResources(self):
"""This loads all initial resources. Redefine this if you do not want
to load all resources at startup."""
self.TFM = TextFileManager()
self.RGM = ogre.ResourceGroupManager.getSingleton()
self.RGM.declareResource("hello.txt", "TextFile")
self.RGM.initialiseAllResourceGroups()
textfile = self.TFM.load("hello.txt", ogre.ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME)
self.TFM.removeAll()
str = textfile.getString()
pass
def _configure(self):
"""This shows the config dialog and creates the renderWindow."""
if not self.unittest: # we show this if not doing a unittest
carryOn = self.root.showConfigDialog()
else:
carryOn = self.root.restoreConfig()
if carryOn:
windowTitle = os.path.join( os.getcwd(), sys.argv[0])
if not windowTitle:
windotTitle = "Ogre Render Window"
self.renderWindow = self.root.initialise(True,windowTitle)
return carryOn
if __name__ == '__main__':
try:
application = Application()
application.go()
except ogre.OgreException, e:
print e