コード例 #1
0
        private void ResultFunc(
            IPixelBuffer pixelBuffer,
            RendererData rendererData,
            ConcurrentQueue <RenderLineResult> resultQueue,
            AutoResetEvent queueDataAvailableEvent)
        {
            var incompleteRows = new HashSet <int>();

            for (var y = 0; y < pixelBuffer.Height; y++)
            {
                incompleteRows.Add(y);
            }

            while (incompleteRows.Count > 0)
            {
                queueDataAvailableEvent.WaitOne(TimeSpan.FromMilliseconds(1000));

                while (resultQueue.TryDequeue(out var renderLineResult))
                {
                    foreach (var data in renderLineResult.RowPixels)
                    {
                        rendererData.SetPixelData(data);
                    }
                    // assert pixelArray.Width == renderLineResult.Count
                    pixelBuffer.SetPixelRowColors(renderLineResult.Y, renderLineResult.RowPixels.Select(x => x.Color));
                    incompleteRows.Remove(renderLineResult.Y);

                    var totalRows       = Convert.ToSingle(pixelBuffer.Height);
                    var completeRows    = Convert.ToSingle(pixelBuffer.Height - incompleteRows.Count);
                    var percentComplete = completeRows / totalRows * 100.0f;
                    Console.WriteLine($"Percent Complete: {percentComplete:F}%");
                    Progress?.Invoke(this, new RenderProgressEventArgs(percentComplete));
                }
            }
        }
コード例 #2
0
ファイル: PerPixelRenderer.cs プロジェクト: MarkZuber/wkndray
        private void ResultFunc(
            IPixelBuffer pixelBuffer,
            RendererData rendererData,
            ConcurrentQueue <RenderResult> resultQueue,
            AutoResetEvent queueDataAvailableEvent)
        {
            try
            {
                var incompletePixels = new HashSet <Tuple <int, int> >();
                for (var y = 0; y < pixelBuffer.Height; y++)
                {
                    for (int x = 0; x < pixelBuffer.Width; x++)
                    {
                        incompletePixels.Add(Tuple.Create(x, y));
                    }
                }

                var totalPixels = Convert.ToSingle(pixelBuffer.Height * pixelBuffer.Width);

                int previousPercent = 0;

                while (incompletePixels.Count > 0)
                {
                    queueDataAvailableEvent.WaitOne(TimeSpan.FromMilliseconds(1000));

                    while (resultQueue.TryDequeue(out var renderResult))
                    {
                        rendererData.SetPixelData(renderResult.PixelData);

                        // assert pixelArray.Width == renderLineResult.Count
                        pixelBuffer.SetPixelColor(renderResult.X, renderResult.Y, renderResult.PixelData.Color);
                        incompletePixels.Remove(Tuple.Create(renderResult.X, renderResult.Y));

                        var completePixels  = Convert.ToSingle(totalPixels - incompletePixels.Count);
                        var percentComplete = completePixels / totalPixels * 100.0f;
                        int intPercent      = Convert.ToInt32(percentComplete);
                        if (intPercent > previousPercent)
                        {
                            previousPercent = intPercent;
                            Console.WriteLine($"Percent Complete: {percentComplete:F}%");
                            Progress?.Invoke(this, new RenderProgressEventArgs(percentComplete));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
コード例 #3
0
ファイル: PerPixelRenderer.cs プロジェクト: MarkZuber/wkndray
        private RendererData RenderMultiThreaded(
            IPixelBuffer pixelArray,
            Camera camera,
            IHitable world,
            IHitable lightHitable,
            RenderConfig renderConfig,
            Func <Ray, ColorVector> backgroundFunc)
        {
            var rendererData = new RendererData(pixelArray.Width, pixelArray.Height);

            var rayTracer = new RayTracer(camera, world, lightHitable, renderConfig, pixelArray.Width, pixelArray.Height, backgroundFunc);

            ThreadPool.SetMinThreads(renderConfig.NumThreads * 3, renderConfig.NumThreads * 3);

            var queueDataAvailableEvent = new AutoResetEvent(false);
            var inputQueue  = new ConcurrentQueue <RenderInput>();
            var resultQueue = new ConcurrentQueue <RenderResult>();

            for (var y = pixelArray.Height - 1; y >= 0; y--)
            {
                for (var x = 0; x < pixelArray.Width; x++)
                {
                    inputQueue.Enqueue(new RenderInput(x, y));
                }
            }

            var tasks = new List <Task>();

            try
            {
                for (var thid = 0; thid < renderConfig.NumThreads; thid++)
                {
                    Console.WriteLine($"Creating task for thread id: {thid}");
                    tasks.Add(
                        Task.Run(() => RenderFunc(rayTracer, inputQueue, resultQueue, queueDataAvailableEvent)));
                }

                tasks.Add(Task.Run(() => ResultFunc(pixelArray, rendererData, resultQueue, queueDataAvailableEvent)));

                Task.WaitAll(tasks.ToArray());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            return(rendererData);
        }