Example #1
0
        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");
                });
            }
        }