/// <summary> /// Overridden. See <see cref="Control.OnPaint">Control.OnPaint</see>. /// </summary> protected override void OnPaint(PaintEventArgs pe) { PDebug.StartProcessingOutput(); Graphics2D g = new Graphics2D(offscreenGraphics); g.Clip = new Region(pe.ClipRectangle); //Graphics2D g = new Graphics2D(pe.Graphics); // create new paint context and set render quality to lowest common // denominator render quality. //Rectangle clipRect = pe.ClipRectangle; //RectangleF fClipRect = new RectangleF(clipRect.X, clipRect.Y, clipRect.Width, clipRect.Height); PPaintContext paintContext = new PPaintContext(g, this); if (Interacting || Animating) { if (interactingRenderQuality < animatingRenderQuality) { paintContext.RenderQuality = interactingRenderQuality; } else { paintContext.RenderQuality = animatingRenderQuality; } } else { paintContext.RenderQuality = defaultRenderQuality; } // paint camera.FullPaint(paintContext); // if switched state from animating to not animating invalidate the entire // screen so that it will be drawn with the default instead of animating // render quality. if (!Animating && animatingOnLastPaint) { Invalidate(); } animatingOnLastPaint = Animating; // Calling the base class OnPaint base.OnPaint(pe); realGraphics.DrawImage(this.offscreenBitmap, 0, 0); PDebug.EndProcessingOutput(g); }
/// <summary> /// This method is called just after the Piccolo scene graph is painted. /// </summary> /// <param name="g">The graphics context used to paint the scene graph.</param> public static void EndProcessingOutput(Graphics2D g) { processOutputTime += (PUtil.CurrentTimeMillis - startProcessingOutputTime); framesProcessed++; if (PDebug.debugPrintFrameRate) { if (framesProcessed % printResultsFrameRate == 0) { System.Console.WriteLine("Process output frame rate: " + OutputFPS + " fps"); System.Console.WriteLine("Process input frame rate: " + InputFPS + " fps"); System.Console.WriteLine("Total frame rate: " + TotalFPS + " fps"); System.Console.WriteLine(); ResetFPSTiming(); } } if (PDebug.debugPrintUsedMemory) { if (framesProcessed % printResultsFrameRate == 0) { System.Console.WriteLine("Approximate used memory: " + ApproximateUsedMemory / 1024 + " k"); } } if (PDebug.debugRegionManagement) { RectangleF clipBounds = g.ClipBounds; Rectangle iClipBounds = new Rectangle((int)clipBounds.X, (int)clipBounds.Y, (int)clipBounds.Width, (int)clipBounds.Height); g.FillRectangle(new SolidBrush(DebugPaintColor), iClipBounds); } processingOutput = false; }
/* /// <summary> /// Constructs a new PrintDocument, allows the user to select which printer /// to print to, and then prints the node. /// </summary> public virtual void Print() { PrintDocument printDocument = new PrintDocument(); PrintDialog printDialog = new PrintDialog(); printDialog.Document = printDocument; if (printDialog.ShowDialog() == DialogResult.OK) { printDocument.PrintPage += new PrintPageEventHandler(printDocument_PrintPage); printDocument.Print(); } } /// <summary> /// Prints the node into the given Graphics context. /// </summary> /// <param name="sender">The source of the PrintPage event.</param> /// <param name="e">The PrintPageEventArgs.</param> protected virtual void printDocument_PrintPage(object sender, PrintPageEventArgs e) { Graphics g = (Graphics)e.Graphics; RectangleF bounds = FullBounds; // Approximate the printable area of the page. This approximation assumes // the unprintable margins are distributed equally between the left and right, // and top and bottom sides. To exactly determine the printable area, you // must resort to the Win32 API. RectangleF displayRect = new RectangleF( e.MarginBounds.Left - (e.PageBounds.Width - g.VisibleClipBounds.Width) / 2, e.MarginBounds.Top - (e.PageBounds.Height - g.VisibleClipBounds.Height) / 2, e.MarginBounds.Width, e.MarginBounds.Height); ScaleAndDraw(g, bounds, displayRect); } */ /// <summary> /// Scale the Graphics so that this node's full bounds fit in displayRect and then /// render into the given Graphics context. /// </summary> /// <param name="g">The Graphics context to use when rendering the node.</param> /// <param name="bounds">The full bounds of the node to be rendered.</param> /// <param name="displayRect">The imageable area.</param> protected virtual void ScaleAndDraw(Graphics2D g, RectangleF bounds, RectangleF displayRect) { g.TranslateTransform(displayRect.X, displayRect.Y); // scale the graphics so node's full bounds fit in the imageable bounds. float scale = displayRect.Width / bounds.Width; if (displayRect.Height / bounds.Height < scale) { scale = displayRect.Height / bounds.Height; } //g.ScaleTransform(scale, scale); g.ScaleTransform(scale); g.TranslateTransform(-bounds.X, -bounds.Y); PPaintContext pc = new PPaintContext(g, null); pc.RenderQuality = RenderQuality.HighQuality; FullPaint(pc); }
/// <summary> /// Constructs a new PPaintContext. /// </summary> /// <param name="graphics"> /// The graphics context to associate with this paint context. /// </param> /// <param name="canvas">The canvas that the paint context will render on.</param> public PPaintContext(Graphics2D graphics, PCanvas canvas) { this.graphics = graphics; this.canvas = canvas; clipStack = new Stack(); localClipStack = new Stack(); cameraStack = new Stack(); transformStack = new Stack(); RenderQuality = RenderQuality.HighQuality; Region clip = graphics.Clip; if (clip.IsInfinite(graphics.Graphics)) { clip = new Region( new Rectangle(-int.MaxValue / 2, -int.MaxValue / 2, int.MinValue, int.MaxValue)); graphics.Clip = clip; } localClipStack.Push(graphics.ClipBounds); CURRENT_PAINT_CONTEXT = this; }