#pragma warning disable 4014 private void DrawMandelbrot(int cw, int ch) { double range, xc, yc; lock (valRWLock) { RenderRange = range = Range; RenderXC = xc = XC; RenderYC = yc = YC; width = cw; height = ch; bytes = new byte[width * height * 4]; } lock (renderLock) { var render = FractalRenderer.SelectRender(AddPixel, CheckAbort, UseSIMD, !UseFloat, UseThreads, UseADT); Unsupported = render == null; if (render == null) { return; } abort = false; done = false; Dispatcher.InvokeAsync(renderClock.Start); double xmin = (xc - range / 2.0).Clamp(-3.0, 1); double xmax = (xc + range / 2.0).Clamp(-3.0, 1); if (xmin > xmax) { double t = xmin; xmin = xmax; xmax = t; } double ymin = (yc - range / 2.0).Clamp(-1.5f, 1.5f); double ymax = (yc + range / 2.0).Clamp(-1.5f, 1.5f); if (ymin > ymax) { double t = ymin; ymin = ymax; ymax = t; } double ystep = (range / (double)ch).Clamp(0, ymax - ymin); double xstep = (range / (double)cw).Clamp(0, xmax - xmin); double step = Math.Max(ystep, xstep); xmin = xc - (cw * step / 2); xmax = xc + (cw * step / 2); ymin = yc - (ch * step / 2); ymax = yc + (ch * step / 2); if (xmin == xmax || ymin == ymax || xmin + xstep <= xmin || ymin + ystep <= ymin || ymax - ystep >= ymax || xmax - xstep >= xmax) { return; } Stopwatch timer = new Stopwatch(); timer.Start(); render((float)xmin, (float)xmax, (float)ymin, (float)ymax, (float)step); ElapsedTime = timer.ElapsedMilliseconds; abort = false; done = true; } }
private void DrawMandelbrot(int cw, int ch) { // Get the renderer the user selected if (!UsePar && !UseSeq && !UseGpu) { MessageBox.Show("Select parallel or sequential."); return; } var render = FractalRenderer.SelectRender(AddPixel, CheckAbort, UseSeq, UsePar, UseGpu); // Create a stopwatch to clock the calculation speed Stopwatch timer = new Stopwatch(); // Allocate a pair of render buffers that will be swapped per frame byte[] buffer1 = new byte[cw * ch * 4]; byte[] buffer2 = new byte[cw * ch * 4]; // This is the buffer selector bool which = false; // Set the two render properties width = cw; height = ch; // Make sure the toImage buffer is null (no animation starting yet) toImage = null; // Start the XX FPS clock tick Dispatcher.InvokeAsync(renderClock.Start); // Start the timer timer.Start(); foreach (var pt in RenderPoints) { // Select the buffer bytes = which ? buffer1 : buffer2; // Get the frame location & scale float scale = pt.Item3; float xc = pt.Item1; float yc = pt.Item2; XC = xc; YC = yc; Scale = scale; // Get the min/max/step values and make sure they're all sensible float xmin = (xc - scale / 2.0f).Clamp(-3.0f, 1f); float xmax = (xc + scale / 2.0f).Clamp(-3.0f, 1f); if (xmin > xmax) { float t = xmin; xmin = xmax; xmax = t; } float ymax = (yc + scale / 2.0f).Clamp(-1.5f, 1.5f); float ymin = (yc - scale / 2.0f).Clamp(-1.5f, 1.5f); if (ymin > ymax) { float t = ymin; ymin = ymax; ymax = t; } float ystep = (scale / (float)ch).Clamp(0, ymax - ymin); float xstep = (scale / (float)cw).Clamp(0, xmax - xmin); float step = Math.Max(ystep, xstep); xmin = xc - (cw * step / 2); xmax = xc + (cw * step / 2); ymin = yc - (ch * step / 2); ymax = yc + (ch * step / 2); // Render this frame render(xmin, xmax, ymin, ymax, step); // Frame's complete: publish the current buffer for the // render thread to draw bytes = Interlocked.Exchange(ref toImage, bytes); if (bytes == null) { // The render thread finished with the previous frame, swap it and keep going which = !which; } else { // We've finished a frame before the rendering thread had a change to // render the previous frame: leave the buffer selection alone, so the // frame we just calculated gets skipped. } // Update the published clock ElapsedTime = timer.Elapsed; } // Stop the timer timer.Stop(); }
public void Initialize() => fractalRenderer = new FractalRenderer(new ComplexPlane(new Range(-1, 1), new Range(-1, 1)), new Size(1024, 1024));