Browse Source

still better open/close window behavior

David Rose 18 years ago
parent
commit
c99351eb7d
1 changed files with 66 additions and 27 deletions
  1. 66 27
      direct/src/showbase/ShowBase.py

+ 66 - 27
direct/src/showbase/ShowBase.py

@@ -436,7 +436,8 @@ class ShowBase(DirectObject.DirectObject):
 
     def openWindow(self, props = None, pipe = None, gsg = None,
                    type = None, name = None, size = None, aspectRatio = None,
-                   makeCamera = 1, scene = None, stereo = None, rawmice = 0):
+                   makeCamera = 1, keepCamera = 0,
+                   scene = None, stereo = None, rawmice = 0):
         """
         Creates a window and adds it to the list of windows that are
         to be updated every frame.
@@ -452,6 +453,19 @@ class ShowBase(DirectObject.DirectObject):
                 # We couldn't get a pipe.
                 return None
 
+        if isinstance(gsg, GraphicsOutput):
+            # If the gsg is a window or buffer, it means to use the
+            # GSG from that buffer.
+            gsg = gsg.getGsg()
+            
+        # If we are using DirectX, force a new GSG to be created,
+        # since at the moment DirectX seems to misbehave if we do
+        # not do this.  This will cause a delay while all textures
+        # etc. are reloaded, so we should revisit this later if we
+        # can fix the underlying bug in our DirectX support.
+        if pipe.getType().getName().startswith('wdx'):
+            gsg = None
+
         if type == None:
             type = self.windowType
 
@@ -492,19 +506,28 @@ class ShowBase(DirectObject.DirectObject):
         if hasattr(win, "requestProperties"):
             win.requestProperties(props)
 
+        mainWindow = False
         if self.win == None:
+            mainWindow = True
             self.win = win
 
         self.winList.append(win)
 
         # Set up a 3-d camera for the window by default.
-        if makeCamera:
+        if keepCamera:
+            self.makeCamera(win, scene = scene, aspectRatio = aspectRatio,
+                            stereo = stereo, useCamera = base.cam)
+        elif makeCamera:
             self.makeCamera(win, scene = scene, aspectRatio = aspectRatio,
-                            stereo = stereo, keepCam = makeCamera)
+                            stereo = stereo)
+
+        messenger.send('open_window', [win, mainWindow])
+        if mainWindow:
+            messenger.send('open_main_window')
 
         return win
 
-    def closeWindow(self, win):
+    def closeWindow(self, win, keepCamera = 0):
         """
         Closes the indicated window and removes it from the list of
         windows.  If it is the main window, clears the main window
@@ -519,7 +542,9 @@ class ShowBase(DirectObject.DirectObject):
             
             dr.setCamera(NodePath())
 
-            if not cam.isEmpty() and cam.node().getNumDisplayRegions() == 0:
+            if not cam.isEmpty() and \
+               cam.node().getNumDisplayRegions() == 0 and \
+               not keepCamera:
                 # If the camera is used by no other DisplayRegions,
                 # remove it.
                 if self.camList.count(cam) != 0:
@@ -539,19 +564,23 @@ class ShowBase(DirectObject.DirectObject):
         self.graphicsEngine.removeWindow(win)
         self.winList.remove(win)
 
-        messenger.send('close_window', [win])
-
-        if not self.winList:
-            # Give the window(s) a chance to actually close before we
-            # continue.
-            base.graphicsEngine.renderFrame()
-
+        mainWindow = False
         if win == self.win:
+            mainWindow = True
             self.win = None
             if self.frameRateMeter:
                 self.frameRateMeter.clearWindow()
                 self.frameRateMeter = None
 
+        messenger.send('close_window', [win, mainWindow])
+        if mainWindow:
+            messenger.send('close_main_window')
+
+        if not self.winList:
+            # Give the window(s) a chance to actually close before we
+            # continue.
+            base.graphicsEngine.renderFrame()
+
     def openDefaultWindow(self, *args, **kw):
         # Creates the main window for the first time, without being
         # too particular about the kind of graphics API that is
@@ -567,6 +596,13 @@ class ShowBase(DirectObject.DirectObject):
         startDirect = kw.get('startDirect', True)
         if 'startDirect' in kw:
             del kw['startDirect']
+
+        if self.win:
+            # If we've already opened a window before, this does
+            # little more work than openMainWindow() alone.
+            self.openMainWindow(*args, **kw)
+            self.graphicsEngine.openWindows()
+            return
             
         self.openMainWindow(*args, **kw)
 
@@ -597,6 +633,13 @@ class ShowBase(DirectObject.DirectObject):
                 # error not to open a window.
                 raise StandardError, 'Could not open window.'
 
+        # The default is trackball mode, which is more convenient for
+        # ad-hoc development in Python using ShowBase.  Applications
+        # can explicitly call base.useDrive() if they prefer a drive
+        # interface.
+        self.mouseInterface = self.trackball
+        self.useTrackball()
+
         if startDirect:
             self.__doStartDirect()
 
@@ -619,6 +662,8 @@ class ShowBase(DirectObject.DirectObject):
         which case base.win may be either None, or the previous,
         closed window).
         """
+        keepCamera = kw.get('keepCamera', 0)
+        
         success = 1
         oldWin = self.win
         oldLens = self.camLens
@@ -630,8 +675,8 @@ class ShowBase(DirectObject.DirectObject):
             oldClearDepthActive = self.win.getClearDepthActive()
             oldClearDepth = self.win.getClearDepth()
             oldClearStencilActive = self.win.getClearStencilActive()
-            oldClearStencil = self.win.getClearStencil()            
-            self.closeWindow(self.win)
+            oldClearStencil = self.win.getClearStencil()
+            self.closeWindow(self.win, keepCamera = keepCamera)
 
         # Open a new window.
         self.openWindow(*args, **kw)
@@ -882,7 +927,7 @@ class ShowBase(DirectObject.DirectObject):
                    displayRegion = (0, 1, 0, 1), stereo = None,
                    aspectRatio = None, clearDepth = 0, clearColor = None,
                    lens = None, camName = 'cam', mask = None,
-                   keepCam = None):
+                   useCamera = None):
         """
         Makes a new 3-d camera associated with the indicated window,
         and creates a display region in the indicated subrectangle.
@@ -892,8 +937,9 @@ class ShowBase(DirectObject.DirectObject):
         camera is created.  If stereo is None or omitted, a stereo
         camera is created if the window says it can render in stereo.
 
-        If keepCam is a NodePath, that is used as the camera to apply
-        to the window, rather than creating a new camera.
+        If useCamera is not None, it is a NodePath to be used as the
+        camera to apply to the window, rather than creating a new
+        camera.
         """
         # self.camera is the parent node of all cameras: a node that
         # we can move around to move all cameras as a group.
@@ -901,10 +947,10 @@ class ShowBase(DirectObject.DirectObject):
             self.camera = self.render.attachNewNode('camera')
             __builtin__.camera = self.camera
 
-        if isinstance(keepCam, NodePath):
+        if useCamera:
             # Use the existing camera node.
-            cam = keepCam
-            camNode = keepCam.node()
+            cam = useCamera
+            camNode = useCamera.node()
             assert(isinstance(camNode, Camera))
             lens = camNode.getLens()
             cam.reparentTo(self.camera)
@@ -1130,13 +1176,6 @@ class ShowBase(DirectObject.DirectObject):
         self.mouse2cam = self.dataUnused.attachNewNode(Transform2SG('mouse2cam'))
         self.mouse2cam.node().setNode(self.camera.node())
 
-        # The default is trackball mode, which is more convenient for
-        # ad-hoc development in Python using ShowBase.  Applications
-        # can explicitly call base.useDrive() if they prefer a drive
-        # interface.
-        self.mouseInterface = self.trackball
-        self.useTrackball()
-
         # A special ButtonThrower to generate keyboard events and
         # include the time from the OS.  This is separate only to
         # support legacy code that did not expect a time parameter; it