Crash on cleanup/reinitialization

maglar

08-08-2008 19:53:05

I get a crash the second or third time I close the window when I modify the ogre\Demo_Basic.py main to


def main():
for i in range(0, 5):
root = OGREMain(plugins_path='plugins.cfg')
weu = ogre.WindowEventUtilities()
while not root.window.isClosed():
weu.messagePump()
if root.window.isActive():
# all eyes are on us, render away
root.renderOneFrame()
time.sleep(.0001)
else:
# we got minimized or de-focused, so slow it down and stop
# rendering until we get focus back
time.sleep(1)
root.shutdown()
root = None
weu = None
sys.exit(0)


I'm running WinXP, Python 2.5.1, Python-Ogre 1.2RC2. Is there some more clean up or other kind of initialization that needs to be done to get it to work?

The reason I came across this is that I'm trying to make it possible to switch between fullscreen and windowed mode. That particular code is using pygame (SDL) for window management, and it crashes when I resize the window (sometimes after 1 resize, other times 10+ but it always happens sooner or later). I don't know if it's the same problem or even if they are even related. It doesn't matter if I use OpenGL or DirectX rendering subsystem, and the crashes in this particular case only happens when I've created a viewport (i.e. it works to repeat the creation/destruction of the root, scenemanager, camera, render window). I've tried all different kinds of shutdowns/initializations I can think of without success. The Python-Ogre+pygame code is below.


import os

import ogre.renderer.OGRE as ogre
import pygame


class CrashDemo(ogre.FrameListener):

def __init__(self):
ogre.FrameListener.__init__(self)

self.__screen = None
self.__root = None
self.__renderWindow = None
self.__sceneManager = None
self.__camera = None
self.__viewport = None


def frameStarted(self, frameEvent):
return True

def frameEnded(self, frameEvent):
return True


def setup(self, width, height):
self.screen = pygame.display.set_mode((width, height), pygame.RESIZABLE)
self.root = ogre.Root("")

plugins = ["RenderSystem_GL.dll", "RenderSystem_Direct3D9.dll"]
for pluginName in plugins:
pluginPath = os.path.join("./plugins", pluginName)

if os.path.exists(pluginPath):
print "Loading plugin '%s'" % pluginPath
self.root.loadPlugin(pluginPath)
else:
raise Exception("Could not load plugin: %s" % pluginName)

directxRenderSystemName = "Direct3D9 Rendering Subsystem"
openglRenderSystemName = "OpenGL Rendering Subsystem"
rendererToUse = self.root.getRenderSystemByName(directxRenderSystemName)
self.root.setRenderSystem(rendererToUse)

autoCreateWindow = False
self.root.initialise(autoCreateWindow)

renderParameters = ogre.NameValuePairList()
wminfo = pygame.display.get_wm_info()
renderParameters["externalWindowHandle"] = str(wminfo["window"])

fullscreen = False
self.renderWindow = self.root.createRenderWindow(
"Title", width, height, fullscreen, renderParameters)

self.root.addFrameListener(self)

self.sceneManager = self.root.createSceneManager(ogre.ST_GENERIC,
"Scene Manager")

self.camera = self.sceneManager.createCamera("Camera")

self.viewport = self.renderWindow.addViewport(self.camera)
self.viewport.backgroundColour = (0.25, 0.25, 0.1)


def tearDown(self):
#self.renderWindow.removeAllViewports()
self.viewport = None
#self.sceneManager.destroyAllCameras()
self.camera = None
#self.root.destroySceneManager(self.sceneManager)
self.sceneManager = None
#self.renderWindow.destroy()
self.renderWindow = None
self.root.shutdown()
self.root = None



def main():
pygame.init()

crash = CrashDemo()

crash.setup(width = 640, height = 480)

quit = False
while not quit:
quit = not crash.root.renderOneFrame()

eventTypes = [pygame.QUIT, pygame.ACTIVEEVENT, pygame.MOUSEMOTION,
pygame.MOUSEBUTTONUP, pygame.MOUSEBUTTONDOWN,
pygame.VIDEORESIZE, pygame.VIDEOEXPOSE, pygame.USEREVENT]
eventlist = pygame.event.get(eventTypes)
for event in eventlist:
if event.type == pygame.QUIT:
print "Quit recieved, exiting"
quit = True
if event.type == pygame.VIDEORESIZE:
print "VIDEORESIZE event, %s" % str(event)
crash.tearDown()
crash.setup(event.w, event.h)
else:
print "Some event '%s'" % str(event)

crash.tearDown()

main()


If anyone has ideas on how to fix this, how to track the problem down or have code that switches between fullscreen/windowed mode or shutsdown/restarts I would appreciate very much if you'd share.

EvanPMeth

10-08-2008 20:58:41

maglar,
There was a few problems with your code the first was properly closing. Your teardown method did close pygame properly, added the line pygame.quit() to the teardown method. The second was, you were listening for resize event which calls on any resize even when the window is created. So to fix this I changed it to a key event (pressing the f Key). I also added the escape key to exit the program. Now to toggle fullscreen in both ogre and pygame we will just tell ogre to toggle and pygame should adjust. to do this i added the method toggleFullscreen Here is the code that works:

import os

import ogre.renderer.OGRE as ogre
import pygame


class CrashDemo(ogre.FrameListener):

def __init__(self):
ogre.FrameListener.__init__(self)

self.__screen = None
self.__root = None
self.__renderWindow = None
self.__sceneManager = None
self.__camera = None
self.__viewport = None


def frameStarted(self, frameEvent):
return True

def frameEnded(self, frameEvent):
return True


def setup(self, width, height):

self.screen = pygame.display.set_mode((width, height), pygame.RESIZABLE)
self.root = ogre.Root("")

plugins = ["RenderSystem_GL.dll", "RenderSystem_Direct3D9.dll"]
for pluginName in plugins:
pluginPath = os.path.join("../plugins", pluginName)

if os.path.exists(pluginPath):
print "Loading plugin '%s'" % pluginPath
self.root.loadPlugin(pluginPath)
else:
raise Exception("Could not load plugin: %s" % pluginName)

directxRenderSystemName = "Direct3D9 Rendering Subsystem"
openglRenderSystemName = "OpenGL Rendering Subsystem"
rendererToUse = self.root.getRenderSystemByName(directxRenderSystemName)
self.root.setRenderSystem(rendererToUse)

autoCreateWindow = False
self.root.initialise(autoCreateWindow)

renderParameters = ogre.NameValuePairList()
wminfo = pygame.display.get_wm_info()
renderParameters["externalWindowHandle"] = str(wminfo["window"])

fullscreen = False
self.renderWindow = self.root.createRenderWindow(
"Title", width, height, fullscreen, renderParameters)

self.root.addFrameListener(self)

self.sceneManager = self.root.createSceneManager(ogre.ST_GENERIC,
"Scene Manager")

self.camera = self.sceneManager.createCamera("Camera")

self.viewport = self.renderWindow.addViewport(self.camera)
self.viewport.backgroundColour = (0.25, 0.25, 0.1)


def tearDown(self):
#pygame close
pygame.quit()
#self.renderWindow.removeAllViewports()
self.viewport = None
#self.sceneManager.destroyAllCameras()
self.camera = None
#self.root.destroySceneManager(self.sceneManager)
self.sceneManager = None
#self.renderWindow.destroy()
self.renderWindow = None
self.root.shutdown()
self.root = None

def toggleFullscreen(self, width, height):

if self.renderWindow.isFullScreen():
self.renderWindow.setFullscreen(False, width, height)
else:
self.renderWindow.setFullscreen(True, width, height)

pass

def main():
pygame.init()

crash = CrashDemo()
width, height = 640, 480
crash.setup(width, height)

quit = False
while not quit:
quit = not crash.root.renderOneFrame()

eventTypes = [pygame.QUIT, pygame.ACTIVEEVENT, pygame.MOUSEMOTION,
pygame.MOUSEBUTTONUP, pygame.MOUSEBUTTONDOWN,
pygame.VIDEORESIZE, pygame.VIDEOEXPOSE, pygame.USEREVENT, pygame.KEYDOWN]
eventlist = pygame.event.get(eventTypes)
for event in eventlist:
if event.type == pygame.QUIT:
print "Quit recieved, exiting"
quit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
quit = True
if event.key == pygame.K_f:
crash.toggleFullscreen(width, height)
else:
print "Some event '%s'" % str(event)

crash.tearDown()

main()



* Also the way you were doing it before to toggle fullscreen by calling the teardown method then adjusting the screensize then recreating a renderwindow is not the proper way. This is uneeded when you can just update the screen size.

Hope this helps,
-Evan

maglar

11-08-2008 10:15:12

Excellent, thank you very much! I now can change resolution without requiring a restart of the game.

I still get crashes when using pygame.quit() and reinitializing though. This menas I can't change between OpenGL and DirectX or change FSAA, colour depth, display frequency or vsync without restarting. But I guess I can live with that.