Istari
18-06-2006 14:14:10
Here is a little demo that I'm thinking of putting in the demos folder, so I would like to ask for your comments before I commit it.
It should enable you to change any wx.Window subclass into a render window, handle resizing and rendering.
The rendering will stop when wx is processing other events, but I like this better than overtaking App.MainLoop and having to always listen for the EVT_CLOSE event.
I know this works in Windows but haven't tested it in Linux, I'm pretty sure that it will not work correctly with SDL.
wxogre.py
test.py
It should enable you to change any wx.Window subclass into a render window, handle resizing and rendering.
The rendering will stop when wx is processing other events, but I like this better than overtaking App.MainLoop and having to always listen for the EVT_CLOSE event.
I know this works in Windows but haven't tested it in Linux, I'm pretty sure that it will not work correctly with SDL.
wxogre.py
import atexit
import wx
from pyogre import ogre
class OgreManager(object):
_borgDict = None
def __init__(self):
if self.__class__._borgDict is None:
self.root = ogre.Root(ogre.getPluginPath())
self._configured = False
self._cameraIdCounter = 0
self.__class__._borgDict = self.__dict__
else:
self.__dict__ = self.__class__._borgDict
def _cleanup(self):
del self.root
def _bindWindowEvents(self, window, renderWindow):
def handleClose(event):
renderWindow.destroy()
event.Skip()
def handleIdle(event):
self.root.renderOneFrame()
event.RequestMore()
event.Skip()
def handleBackground(event):
self.root.renderOneFrame()
event.Skip()
def handleResize(event):
renderWindow.windowMovedOrResized()
self.root.renderOneFrame()
event.Skip()
window.Bind(wx.EVT_CLOSE, handleClose)
window.Bind(wx.EVT_IDLE, handleIdle)
window.Bind(wx.EVT_ERASE_BACKGROUND, handleBackground)
window.Bind(wx.EVT_SIZE, handleResize)
def configure(self):
return self.root.showConfigDialog()
def setupResources(self):
config = ogre.ConfigFile()
config.loadFromFile('resources.cfg')
for section, key, path in config.values:
ogre.ResourceGroupManager.getSingleton().addResourceLocation(path, key, section)
def chooseSceneManager(self):
self.sceneManager = self.root.createSceneManager(ogre.ST_GENERIC, "Scene Manager")
def createCamera(self, cameraName):
camera = self.sceneManager.createCamera(cameraName)
camera.position = (0, 0, 500)
camera.lookAt(ogre.Vector3(0, 0, -300))
camera.nearClipDistance = 5
return camera
def createViewport(self, renderWindow, camera):
viewport = renderWindow.addViewport(camera, 0, 0.0, 0.0, 1.0, 1.0)
viewport.backgroundColour = 0, 0, 0
return viewport
def initWindow(self, window, cameraName=None):
shouldInitResources = False
if not self._configured:
self.setupResources()
if not self.configure():
raise RuntimeError('Ogre was not configured')
self.root.initialise(False)
self.chooseSceneManager()
self._configured = True
shouldInitResources = True
renderParameters = ogre._StringStringMap()
renderParameters['externalWindowHandle'] = str(window.GetHandle())
renderWindow = self.root.createRenderWindow('RenderWindow_%i' % id(window), 640, 480, False, renderParameters)
if shouldInitResources:
ogre.ResourceGroupManager.getSingleton().initialiseAllResourceGroups()
if cameraName is None:
cameraName = 'Camera%i' % self._cameraIdCounter
self._cameraIdCounter += 1
camera = self.createCamera(cameraName)
viewport = self.createViewport(renderWindow, camera)
self._bindWindowEvents(window, renderWindow)
return (renderWindow, camera, viewport)
atexit.register(OgreManager()._cleanup)
test.py
import wx
import wxogre
from pyogre import ogre
class MyFrame(wx.Frame):
def __init__(self, *args, **kw):
wx.Frame.__init__(self, *args, **kw)
self.ogreMgr = wxogre.OgreManager()
self.window1 = wx.Window(self, -1)
self.window2 = wx.Window(self, -1)
self.window3 = wx.Window(self, -1)
self.window4 = wx.Window(self, -1)
self.frame2 = wx.Frame(self, -1, 'Another wxOgre', size=(800,600))
self.frame2.Show(True)
sizer = wx.GridSizer(2, 2)
sizer.Add(self.window1, 0, wx.EXPAND)
sizer.Add(self.window2, 0, wx.EXPAND)
sizer.Add(self.window3, 0, wx.EXPAND)
sizer.Add(self.window4, 0, wx.EXPAND)
self.SetSizer(sizer)
(renderWindow1, camera1, viewport1) = self.ogreMgr.initWindow(self.window1)
(renderWindow2, camera2, viewport2) = self.ogreMgr.initWindow(self.window2)
(renderWindow3, camera3, viewport3) = self.ogreMgr.initWindow(self.window3)
(renderWindow4, camera4, viewport4) = self.ogreMgr.initWindow(self.window4)
(renderWindow5, camera5, viewport5) = self.ogreMgr.initWindow(self.frame2)
camera2.position = (500, 0, 0)
camera2.lookAt(ogre.Vector3(-300, 0, 0))
camera3.position = (0, 0, -500)
camera3.lookAt(ogre.Vector3(0, 0, 300))
camera4.position = (-500, 0, 0)
camera4.lookAt(ogre.Vector3(300, 0, 0))
camera5.position = (-500, 500, 0)
camera5.lookAt(ogre.Vector3(300, -300, 0))
self.createScene()
def createScene(self):
sceneManager = self.ogreMgr.sceneManager
sceneManager.ambientLight = 0.2, 0.2, 0.2
sceneManager.setSkyDome(True, 'Examples/CloudySky', 4.0, 8.0)
light = sceneManager.createLight('MainLight')
light.position = (20, 80, 50)
plane = ogre.Plane()
plane.normal = ogre.Vector3(0, 1, 0)
plane.d = 200
ogre.MeshManager.getSingleton().createPlane('FloorPlane', "General",
plane, 200000, 200000,
20, 20, True, 1, 50, 50,
(0, 0, 1))
# create floor entity
entity = sceneManager.createEntity('floor', 'FloorPlane')
entity.setMaterialName('Examples/RustySteel')
sceneManager.rootSceneNode.createChildSceneNode().attachObject(entity)
# create head entity
headNode = sceneManager.rootSceneNode.createChildSceneNode()
entity = sceneManager.createEntity('head', 'ogrehead.mesh')
headNode.attachObject(entity)
# add some fog
sceneManager.setFog(ogre.FOG_EXP, ogre.ColourValue.White, 0.0002)
class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame(None, -1, 'wxOgre', size=(800,600))
self.frame.Show(True)
return True
if __name__ == '__main__':
app = MyApp(False)
app.MainLoop()