Beispiel #1
0
        public static void RenderSection(Rectangle region, Scene scene, SceneOutput output)
        {
            Vector3D directionUnit = (scene.CameraFacingAt - scene.CameraPosition);
            directionUnit.Normalize();

            var pixelHeight = scene.ViewPortHeight / output.Height;
            var pixelWidth = pixelHeight;
            var halfWidth = (output.Width / 2.0);
            var halfHeight = (output.Height / 2.0);

            foreach (var y in Enumerable.Range(region.Y, region.Height))
            {
                foreach (var x in Enumerable.Range(region.X, region.Width))
                {
                    Thread.Sleep(0);
                    Thread.Sleep(0);
                    Thread.Sleep(0);

                    var point = new Vector3D(
                        ((x + 0.5) - halfWidth)*pixelWidth,
                        ((y + 0.5) - halfHeight)*pixelHeight, 0);

                    var direction = point - scene.CameraPosition;
                    direction.Normalize();

                    var pixelColor = RenderPoint(scene, point, direction);
                    output.SetPixel(x, y, pixelColor);

                    Thread.Sleep(0);
                    Thread.Sleep(0);
                    Thread.Sleep(0);
                }
            }
        }
Beispiel #2
0
        private Task RenderAsync()
        {
            //int width = 640, height = 480;
            int width = 1024, height = 768;
            //int width = 1920, height = 1080;

            SceneOutput output = new SceneOutput(width, height);

            Action updateScreen = () =>
            {
                var bitmap = output.CreateBitmap();
                Canvas.Source = bitmap;
            };
            var timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(100);
            timer.Tick += (s, e) => updateScreen();
            timer.Start();

            return Task.Factory.StartNew(
                () =>
                {
                    var horizontalSectionCount = 16;
                    var verticalSectionCount = 16;
                    int sectionWidth = width / horizontalSectionCount;
                    if (sectionWidth*horizontalSectionCount < width)
                    {
                        sectionWidth +=1;
                    }
                    int sectionHeight = height / verticalSectionCount;
                    if (sectionHeight * verticalSectionCount < height)
                    {
                        sectionHeight += 1;
                    }
                    List<RenderTask> taskQueue = new List<RenderTask>();

                    foreach (var y in Enumerable.Range(0, verticalSectionCount))
                    {
                        foreach (var x in Enumerable.Range(0, horizontalSectionCount))
                        {
                            var region = new Rectangle(
                                x * sectionWidth,
                                y *sectionHeight,
                                sectionWidth,
                                sectionHeight);
                            if (region.X + region.Width > width) region.Width = width - region.X;
                            if (region.Y + region.Height> height) region.Height = height- region.Y;
                            taskQueue.Add(new RenderTask {Region = region});
                        }
                    }
                    taskQueue.AsParallel().Select(task =>
                    {

                        RayTracer.RenderSection(task.Region, Scene.Default(), output);

                        return 0;
                    }).Aggregate((_, __) => 0);

                }).ContinueWith(task =>
                {
                    timer.Stop();
                    updateScreen();
                }, TaskScheduler.FromCurrentSynchronizationContext());
        }