private void BackgroundRender(object state) { var cancellationToken = (CancellationToken)state; RayTracer rayTracer = new RayTracer(_width, _height, (rgb) => { Task.Factory.StartNew(() => { var bmpData = _image.LockBits(_rect, ImageLockMode.WriteOnly, _image.PixelFormat); Marshal.Copy(rgb, 0, bmpData.Scan0, rgb.Length); _image.UnlockBits(bmpData); pbImage.Refresh(); }, CancellationToken.None, TaskCreationOptions.AttachedToParent, _uiScheduler); }); if (_parallel) { rayTracer.RenderParallel(rayTracer.DefaultScene, cancellationToken); } else { rayTracer.RenderSequential(rayTracer.DefaultScene, cancellationToken); } }
private void RenderLoop(object boxedToken) { var cancellationToken = (CancellationToken)boxedToken; // Create a ray tracer, and create a reference to "sphere2" that we are going to bounce var rayTracer = new RayTracer(_width, _height); var scene = rayTracer.DefaultScene; var sphere2 = (Sphere)scene.Things[0]; // The first item is assumed to be our sphere var baseY = sphere2.Radius; sphere2.Center.Y = sphere2.Radius; // Timing determines how fast the ball bounces as well as diagnostics frames/second info var renderingTime = new Stopwatch(); var totalTime = Stopwatch.StartNew(); // Keep rendering until the rendering task has been canceled while (!cancellationToken.IsCancellationRequested) { // Get the next buffer var rgb = _freeBuffers.GetObject(); // Determine the new position of the sphere based on the current time elapsed double dy2 = 0.8 * Math.Abs(Math.Sin(totalTime.ElapsedMilliseconds * Math.PI / 3000)); sphere2.Center.Y = baseY + dy2; // Render the scene renderingTime.Reset(); renderingTime.Start(); ParallelOptions options = new ParallelOptions { MaxDegreeOfParallelism = _degreeOfParallelism, CancellationToken = _cancellation.Token }; if (!_parallel) { rayTracer.RenderSequential(scene, rgb); } else if (_showThreads) { rayTracer.RenderParallelShowingThreads(scene, rgb, options); } else { rayTracer.RenderParallel(scene, rgb, options); } renderingTime.Stop(); // Update the bitmap in the UI thread //var framesPerSecond = (++frame * 1000.0 / renderingTime.ElapsedMilliseconds); var framesPerSecond = (1000.0 / renderingTime.ElapsedMilliseconds); BeginInvoke((Action) delegate { // Copy the pixel array into the bitmap var bmpData = _bitmap.LockBits(_rect, ImageLockMode.WriteOnly, _bitmap.PixelFormat); Marshal.Copy(rgb, 0, bmpData.Scan0, rgb.Length); _bitmap.UnlockBits(bmpData); _freeBuffers.PutObject(rgb); // Refresh the UI pbRenderedImage.Invalidate(); Text = "Ray Tracer - FPS: " + framesPerSecond.ToString("F1"); }); } }