def _PrepateForFlatDrawing(self, w, h): # Set viewport gl.glDisable(gl.GL_DEPTH_TEST) gl.glViewport(0, 0, w, h) # set camera # Flip up down because we want y=0 to be on top. gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() ortho(0, w, h, 0) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity()
def OnDrawShape(self, clr): # Correct size for labels (shape is the first draw pass) self._CorrectPositionForLabels() # Get picker helper and draw pickerHelper = self.GetFigure()._pickerHelper # Size of figure ... fig = self.GetFigure() w, h = fig.position.size # Find actual position in pixels, do not allow negative values pos = self.position.InPixels() pos._w, pos._h = max(pos.w, 1), max(pos.h, 1) pos.h_fig = h pos._Update() # Set viewport (note that OpenGL has origin in lower-left, visvis # in upper-left) gl.glViewport(pos.absLeft, h - pos.absBottom, pos.w, pos.h) self._OnDrawContent(DRAW_SHAPE, clr, pos, pickerHelper) # Prepare for wibject children (draw in full viewport) gl.glViewport(0, 0, w, h) gl.glDisable(gl.GL_DEPTH_TEST) gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() ortho(0, w, h, 0) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() # Transform self.parent._Transform() # Container self._Transform() # Self
def OnDrawShape(self, clr): # Correct size for labels (shape is the first draw pass) self._CorrectPositionForLabels() # Get picker helper and draw pickerHelper = self.GetFigure()._pickerHelper # Size of figure ... fig = self.GetFigure() w,h = fig.position.size # Find actual position in pixels, do not allow negative values pos = self.position.InPixels() pos._w, pos._h = max(pos.w, 1), max(pos.h, 1) pos.h_fig = h pos._Update() # Set viewport (note that OpenGL has origin in lower-left, visvis # in upper-left) gl.glViewport(pos.absLeft, h-pos.absBottom, pos.w, pos.h) self._OnDrawContent(DRAW_SHAPE, clr, pos, pickerHelper) # Prepare for wibject children (draw in full viewport) gl.glViewport(0,0,w,h) gl.glDisable(gl.GL_DEPTH_TEST) gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() ortho( 0, w, h, 0) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() # Transform self.parent._Transform() # Container self._Transform() # Self
def _dpi_aware_ortho(self, *args): # For when drawing in screen coords pr = self._devicePixelRatio #gl.glScale(pr, pr, 1.0) args = [a * pr for a in args] ortho(*args)
def _normal_ortho(self, *args): # For when drawing in screen coords ortho(*args)
def _OnDrawContent(self, mode, bgcolor, pos, pickerHelper=None): # Draw background if bgcolor: # Set view gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() ortho(0, 1, 0, 1) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() # Overwrite all gl.glDisable(gl.GL_DEPTH_TEST) # Define colors, use gradient? bgcolor1 = bgcolor2 = bgcolor3 = bgcolor4 = bgcolor if mode != DRAW_SHAPE and self.bgcolors: gl.glShadeModel(gl.GL_SMOOTH) if len(self.bgcolors) == 2: bgcolor1 = bgcolor2 = self.bgcolors[0] bgcolor3 = bgcolor4 = self.bgcolors[1] elif len(self.bgcolors) == 4: bgcolor1, bgcolor2, bgcolor3, bgcolor4 = self.bgcolors # Draw gl.glBegin(gl.GL_POLYGON) gl.glColor3f(bgcolor3[0], bgcolor3[1], bgcolor3[2]) gl.glVertex2f(0, 0) gl.glColor3f(bgcolor1[0], bgcolor1[1], bgcolor1[2]) gl.glVertex2f(0, 1) gl.glColor3f(bgcolor2[0], bgcolor2[1], bgcolor2[2]) gl.glVertex2f(1, 1) gl.glColor3f(bgcolor4[0], bgcolor4[1], bgcolor4[2]) gl.glVertex2f(1, 0) gl.glEnd() # Reset gl.glEnable(gl.GL_DEPTH_TEST) # Draw items in world coordinates if True: # Setup the camera self.camera.SetView() # Draw stuff, but wait with lines lines2draw = [] for item in self._wobjects: if isinstance(item, (Line, BaseAxis)): lines2draw.append(item) else: item._DrawTree(mode, pickerHelper) # Lines (and the axis) are a special case. In order to blend # them well, we should draw textures, meshes etc, first. # Note that this does not work if lines textures are children # of each-other. in that case they should be added to the scene # in the correct order. for item in lines2draw: item._DrawTree(mode, pickerHelper) # Draw items in screen coordinates if mode != DRAW_SHAPE: # Set camera to screen coordinates. gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() h = pos.h_fig ortho(pos.absLeft, pos.absRight, h - pos.absBottom, h - pos.absTop) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() # Allow wobjects to draw in screen coordinates # Note that the axis for the 2d camera needs to draw beyond # the viewport of the axes, and is therefore drawn later. gl.glEnable(gl.GL_DEPTH_TEST) is2dcam = isinstance(self.camera, cameras.TwoDCamera) for item in self._wobjects: if is2dcam and isinstance(item, BaseAxis): continue item._DrawTree(DRAW_SCREEN)
def _OnDrawInMode(self, mode, bgcolor, pickerHelper=None): # Draw the background of the axes and the wobjects in it. # Prepare if True: # Get size of figure ... fig = self.GetFigure() w, h = fig.position.size # Find actual position in pixels, do not allow negative values pos = self.position.InPixels() pos._w, pos._h = max(pos.w, 1), max(pos.h, 1) pos.h_fig = h pos._Update() # Set viewport (note that OpenGL has origin in lower-left, visvis # in upper-left) gl.glViewport(pos.absLeft, h - pos.absBottom, pos.w, pos.h) # Select screenshot sshot = self._screenshot # Perform tests if self._useBuffer: # Test if we can use the screenshot canUseScreenshot = ((sshot is not None) and sshot.shape[0] == pos.h and sshot.shape[1] == pos.w) # Test if we want to blur with the screenshot blurWithScreenshot = (bool(self._motionBlur) and self._isdirty and mode == DRAW_FAST) # Test whether we should use the screenshot shouldUseScreenshot = (canUseScreenshot and (not self._isdirty or blurWithScreenshot)) else: # Old school mode shouldUseScreenshot = False blurWithScreenshot = False # Draw content of axes (if we need to) if (not shouldUseScreenshot) or blurWithScreenshot: # Draw fresh self._OnDrawContent(mode, bgcolor, pos, pickerHelper) # Make screenshot and store/combine if self._useBuffer: tmp = _Screenshot() shapesMatch = (sshot is not None) and tmp.shape == sshot.shape if blurWithScreenshot and shapesMatch: f = self._motionBlur sshot[:] = f * sshot + (1.0 - f) * tmp else: self._screenshot = tmp # Draw screenshot (if we should) if shouldUseScreenshot: # Set view gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() ortho(0, 1, 0, 1) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() # Apply bitmap directly sshot = self._screenshot gl.glRasterPos(0, 0) gl.glDrawPixels(pos.w, pos.h, gl.GL_RGB, gl.GL_FLOAT, sshot) # # Set viewport to the full figure and disable depth test if True: gl.glViewport(0, 0, w, h) gl.glDisable(gl.GL_DEPTH_TEST) # Draw axis if using the 2D camera if isinstance(self.camera, cameras.TwoDCamera): # Let axis object for 2D-camera draw in screen coordinates # in the full viewport. # Note that if the buffered screenshot is used and the content # is not drawn, the axis' OnDraw method is not called, and the # ticks are therefore not re-calculated (which is time-consuming). # Set view gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() ortho(0, w, 0, h) # Note that 0 and h are swapped gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() # Draw for item in self._wobjects: if isinstance(item, BaseAxis): item._DrawTree(DRAW_SCREEN) # Prepare for drawing child wibjects in screen coordinates if True: # Set view gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() ortho(0, w, h, 0) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() # Transform self.parent._Transform() # Container self._Transform() # Self # We're clean now ... if mode != DRAW_SHAPE: self._isdirty = False
def _OnDrawContent(self, mode, bgcolor, pos, pickerHelper=None): # Draw background if bgcolor: # Set view gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() ortho( 0, 1, 0, 1) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() # Overwrite all gl.glDisable(gl.GL_DEPTH_TEST) # Define colors, use gradient? bgcolor1 = bgcolor2 = bgcolor3 = bgcolor4 = bgcolor if mode != DRAW_SHAPE and self.bgcolors: gl.glShadeModel(gl.GL_SMOOTH) if len(self.bgcolors) == 2: bgcolor1 = bgcolor2 = self.bgcolors[0] bgcolor3 = bgcolor4 = self.bgcolors[1] elif len(self.bgcolors) == 4: bgcolor1, bgcolor2, bgcolor3, bgcolor4 = self.bgcolors # Draw gl.glBegin(gl.GL_POLYGON) gl.glColor3f(bgcolor3[0], bgcolor3[1], bgcolor3[2]) gl.glVertex2f(0,0) gl.glColor3f(bgcolor1[0], bgcolor1[1], bgcolor1[2]) gl.glVertex2f(0,1) gl.glColor3f(bgcolor2[0], bgcolor2[1], bgcolor2[2]) gl.glVertex2f(1,1) gl.glColor3f(bgcolor4[0], bgcolor4[1], bgcolor4[2]) gl.glVertex2f(1,0) gl.glEnd() # Reset gl.glEnable(gl.GL_DEPTH_TEST) # Draw items in world coordinates if True: # Setup the camera self.camera.SetView() # Draw stuff, but wait with lines lines2draw = [] for item in self._wobjects: if isinstance(item, (Line, BaseAxis)): lines2draw.append(item) else: item._DrawTree(mode, pickerHelper) # Lines (and the axis) are a special case. In order to blend # them well, we should draw textures, meshes etc, first. # Note that this does not work if lines textures are children # of each-other. in that case they should be added to the scene # in the correct order. for item in lines2draw: item._DrawTree(mode, pickerHelper) # Draw items in screen coordinates if mode != DRAW_SHAPE: # Set camera to screen coordinates. gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() h = pos.h_fig ortho( pos.absLeft, pos.absRight, h-pos.absBottom, h-pos.absTop) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() # Allow wobjects to draw in screen coordinates # Note that the axis for the 2d camera needs to draw beyond # the viewport of the axes, and is therefore drawn later. gl.glEnable(gl.GL_DEPTH_TEST) is2dcam = isinstance(self.camera, cameras.TwoDCamera) for item in self._wobjects: if is2dcam and isinstance(item, BaseAxis): continue item._DrawTree(DRAW_SCREEN)
def _OnDrawInMode(self, mode, bgcolor, pickerHelper=None): # Draw the background of the axes and the wobjects in it. # Prepare if True: # Get size of figure ... fig = self.GetFigure() w,h = fig.position.size # Correction of size for labels is normally done in OnDrawShape, # but this is not called if user interaction is disabled ... if not fig.enableUserInteraction: self._CorrectPositionForLabels() # Find actual position in pixels, do not allow negative values pos = self.position.InPixels() pos._w, pos._h = max(pos.w, 1), max(pos.h, 1) pos.h_fig = h pos._Update() # Set viewport (note that OpenGL has origin in lower-left, visvis # in upper-left) gl.glViewport(pos.absLeft, h-pos.absBottom, pos.w, pos.h) # Select screenshot sshot = self._screenshot # Perform tests # Only if enabled on axes and if user interaction is enabled for the figure if self._useBuffer and fig.enableUserInteraction: # Test if we can use the screenshot canUseScreenshot = ( (sshot is not None) and sshot.shape[0] == pos.h and sshot.shape[1] == pos.w ) # Test if we want to blur with the screenshot blurWithScreenshot = ( bool(self._motionBlur) and self._isdirty and mode==DRAW_FAST ) # Test whether we should use the screenshot shouldUseScreenshot = ( canUseScreenshot and (not self._isdirty or blurWithScreenshot) ) else: # Old school mode shouldUseScreenshot = False blurWithScreenshot = False # Draw content of axes (if we need to) if (not shouldUseScreenshot) or blurWithScreenshot: # Draw fresh self._OnDrawContent(mode, bgcolor, pos, pickerHelper) # Make screenshot and store/combine if self._useBuffer and fig.enableUserInteraction: tmp = _Screenshot() shapesMatch = (sshot is not None) and tmp.shape == sshot.shape if blurWithScreenshot and shapesMatch: f = self._motionBlur sshot[:] = f*sshot + (1.0-f)*tmp else: self._screenshot = tmp # Draw screenshot (if we should) if shouldUseScreenshot: # Set view gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() ortho( 0, 1, 0, 1) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() # Apply bitmap directly sshot = self._screenshot gl.glRasterPos(0,0) gl.glDrawPixels(pos.w, pos.h, gl.GL_RGB, gl.GL_FLOAT, sshot) # # Set viewport to the full figure and disable depth test if True: gl.glViewport(0,0,w,h) gl.glDisable(gl.GL_DEPTH_TEST) # Draw axis if using the 2D camera if isinstance(self.camera, cameras.TwoDCamera): # Let axis object for 2D-camera draw in screen coordinates # in the full viewport. # Note that if the buffered screenshot is used and the content # is not drawn, the axis' OnDraw method is not called, and the # ticks are therefore not re-calculated (which is time-consuming). # Set view gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() ortho( 0, w, 0, h) # Note that 0 and h are swapped gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() # Draw for item in self._wobjects: if isinstance(item, BaseAxis): item._DrawTree(DRAW_SCREEN) # Prepare for drawing child wibjects in screen coordinates if True: # Set view gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() ortho( 0, w, h, 0) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() # Transform self.parent._Transform() # Container self._Transform() # Self # We're clean now ... if mode != DRAW_SHAPE: self._isdirty = False