private void ScreenSaverForm_Shown(object sender, EventArgs e) { Graphics formGraphics = this.CreateGraphics(); formGraphics.DrawImageUnscaled(this.initialFractalBitmap, 0, 0); this.stopwatch.Restart(); Task.Run(() => { while (true) { RectangleD fractalArea = this.initialFractalArea; var currentBitmap = this.initialFractalBitmap.Clone() as Bitmap; for (int zoom = 1; zoom < 10; zoom++) { Rectangle zoomRectangle = Mandelbrot.GetNextZoomRectangle(currentBitmap); // If couldn't find suitable area to zoom in, zoom out to starting fractal and start over. if (zoomRectangle == Rectangle.Empty) { break; } fractalArea = Mandelbrot.GetNextZoomArea(this.Size, zoomRectangle.Location, fractalArea); Bitmap nextBitmap = Mandelbrot.RenderFractal(this.Size, fractalArea, BaseMaximumIterations * (zoom + 1), this.colorFunction); IntPtr[] nativeZoomInBitmapHandles = CreateNativeZoomInBitmaps(currentBitmap, nextBitmap, zoomRectangle.Location); // Wait a bit between zooms, even if all computations are complete. this.stopwatch.Stop(); if (this.stopwatch.ElapsedMilliseconds < WaitMilliseconds) { Thread.Sleep(WaitMilliseconds - (int)this.stopwatch.ElapsedMilliseconds); } AnimateBlink(formGraphics, currentBitmap, zoomRectangle); AnimateZoomIn(formGraphics, nativeZoomInBitmapHandles, this.Size); this.stopwatch.Restart(); // Clean up animation bitmaps after use. foreach (IntPtr nativeZoomInBitmapHandle in nativeZoomInBitmapHandles) { NativeMethods.GDI32.DeleteObject(nativeZoomInBitmapHandle); } currentBitmap.Dispose(); currentBitmap = nextBitmap; } // After 10 zoom-ins, zoom out to starting fractal and start over. double percentX = ((fractalArea.Left + (fractalArea.Width / 2D)) - this.initialFractalArea.Left) / this.initialFractalArea.Width; double percentY = ((fractalArea.Top + (fractalArea.Height / 2D)) - this.initialFractalArea.Top) / this.initialFractalArea.Height; var zoomPoint = new Point((int)(this.Width * percentX), (int)(this.Height * percentY)); IntPtr[] nativeZoomOutBitmapHandles = CreateNativeZoomOutBitmaps(currentBitmap, this.initialFractalBitmap, zoomPoint); currentBitmap.Dispose(); // Wait a bit between zooms, even if all computations are complete. this.stopwatch.Stop(); if (this.stopwatch.ElapsedMilliseconds < WaitMilliseconds) { Thread.Sleep(WaitMilliseconds - (int)this.stopwatch.ElapsedMilliseconds); } AnimateZoomOut(formGraphics, nativeZoomOutBitmapHandles, this.Size); this.stopwatch.Restart(); // Clean up animation bitmaps after use. foreach (IntPtr nativeZoomOutBitmapHandle in nativeZoomOutBitmapHandles) { NativeMethods.GDI32.DeleteObject(nativeZoomOutBitmapHandle); } } }); }
private void ScreenSaverForm_Load(object sender, EventArgs e) { this.AssignColorScheme(); this.initialFractalArea = Mandelbrot.GetInitialArea(this.Size); this.initialFractalBitmap = Mandelbrot.RenderInitialFractal(this.Size, this.initialFractalArea, BaseMaximumIterations, this.colorFunction); }