public override void Render(RayCasting caster, IEnumerable <TiledBitmap.Tile> tiles)
        {
            #region Progressive Render from http://www.cc.gatech.edu/~phlosoft/photon/
            //float resX = caster.Scene.DefaultCamera.ResX; //g.VisibleClipBounds.Width;
            //float resY = caster.Scene.DefaultCamera.ResY; //g.VisibleClipBounds.Height;
            ManualResetEvent fineshedHandle         = new ManualResetEvent(false);
            IEnumerable <TiledBitmap.Tile> imgTiles = tiles as IList <TiledBitmap.Tile> ?? tiles.ToList();

            int numberOfWorkers = imgTiles.Count();
            foreach (var imgTile in imgTiles)
            {
                caster = caster.Clone();
                Tuple <RayCasting, TiledBitmap.Tile> casterTile = new Tuple <RayCasting, TiledBitmap.Tile>(caster, imgTile);
                ThreadPool.QueueUserWorkItem(state =>
                {
                    try
                    {
                        Tuple <RayCasting, TiledBitmap.Tile> localCasterAndTile = state as Tuple <RayCasting, TiledBitmap.Tile>;
                        TiledBitmap.Tile tile = localCasterAndTile.Item2;
                        RayCasting caster1    = localCasterAndTile.Item1;

                        tile.CompleteCycle(TiledBitmap.RenderCycleType.Start);

                        int iterations = 0;
                        int pCol       = 0, pRow = 0, pIteration = 1, pMax = 2;

                        float resTotal = tile.Width * tile.Height;
                        while (iterations < resTotal)
                        {
                            //Render Pixels Out of Order With Increasing Resolution: 2x2, 4x4, 16x16... 512x512
                            if (pCol >= pMax)
                            {
                                pRow++;
                                pCol = 0;
                                if (pRow >= pMax)
                                {
                                    pIteration++;
                                    pRow   = 0;
                                    pMax <<= 1; //Equals: pMax = (int)Math.Pow(2, pIteration);
                                }
                            }
                            bool pNeedsDrawing = (pIteration == 1 || (pRow % 2 != 0) || (pRow % 2 == 0 && (pCol % 2 != 0)));
                            float x            = pCol * (tile.Width / pMax) + tile.X;
                            float y            = pRow * (tile.Height / pMax) + tile.Y;
                            pCol++;
                            if (pNeedsDrawing)
                            {
                                iterations++;
                                Ray ray;
                                RGBColor finalColor = RGBColor.Black;
                                if (caster1.Scene.Sampler.NumberOfSamples > 1)
                                {
                                    foreach (Point2D sample in caster1.Scene.Sampler.GetSamplesFor(x, y))
                                    {
                                        //ray = this.scene.DefaultCamera.CreateRayFromScreen(x + sample.X, y + sample.Y);
                                        ray = caster1.Scene.DefaultCamera.CreateRayFromScreen(sample.X, sample.Y);
                                        ray.PrevRefractIndex = caster1.Scene.RefractIndex;
                                        finalColor          += caster1.Trace(ray, 0);
                                    }
                                    //brush.Color = (finalColor * (1f / this.scene.Sampler.NumberOfSamples)).ToColor();
                                    finalColor = (finalColor / caster1.Scene.Sampler.NumberOfSamples);


                                    //Graphics graphics = Graphics.FromImage(tile.Image);
                                    tile.Graphics.FillRectangle(new SolidBrush(finalColor.ToColor()), x - tile.X, y - tile.Y, (tile.Width / pMax), (tile.Height / pMax));
                                    //graphics.Flush();
                                    //graphics.Dispose();
                                }
                                else
                                {
                                    ray        = caster1.Scene.DefaultCamera.CreateRayFromScreen(x, y);
                                    finalColor = caster1.Trace(ray, 0);

                                    // Debug.WriteLine("Graphics: " + tile.Graphics.GetHashCode());

                                    tile.Graphics.FillRectangle(new SolidBrush(finalColor.ToColor()), x - tile.X, y - tile.Y, (tile.Width / pMax), (tile.Height / pMax));

                                    //tile.Graphics.Flush(FlushIntention.Sync);
                                }
                                tile.CompleteCycle(TiledBitmap.RenderCycleType.Partial);
                            }
                        }
                        tile.CompleteCycle(TiledBitmap.RenderCycleType.Finish);
                    }
                    finally
                    {
                        if (Interlocked.Decrement(ref numberOfWorkers) == 0)
                        {
                            fineshedHandle.Set();
                        }
                    }
                }, casterTile);
            }//);
            fineshedHandle.WaitOne();
            #endregion
        }
Esempio n. 2
0
        public override void Render(RayCasting caster, IEnumerable <TiledBitmap.Tile> tiles)
        {
            //float resX = caster.Scene.DefaultCamera.ResX; //g.VisibleClipBounds.Width;
            //float resY = caster.Scene.DefaultCamera.ResY; //g.VisibleClipBounds.Height;
            //Parallel.ForEach(tiles, tile => {
            ManualResetEvent fineshedHandle         = new ManualResetEvent(false);
            IEnumerable <TiledBitmap.Tile> imgTiles = tiles as IList <TiledBitmap.Tile> ?? tiles.ToList();

            numberOfWorkers = imgTiles.Count();
            foreach (var imgTile in imgTiles)
            {
                caster = caster.Clone();
                Tuple <RayCasting, TiledBitmap.Tile> casterTile = new Tuple <RayCasting, TiledBitmap.Tile>(caster, imgTile);
                //new Thread(state =>
                ThreadPool.QueueUserWorkItem(state =>
                {
                    try
                    {
                        Tuple <RayCasting, TiledBitmap.Tile> localCasterAndTile = state as Tuple <RayCasting, TiledBitmap.Tile>;
                        TiledBitmap.Tile tile = localCasterAndTile.Item2;
                        RayCasting caster1    = localCasterAndTile.Item1;
                        //Stopwatch timer = new Stopwatch();
                        //timer.Start();
                        //Console.WriteLine("Started@" + DateTime.Now.ToString("mm:ss.fff tt"));


                        float total   = tile.Width * tile.Height;
                        float partial = 0;
                        for (int y = tile.Y; y < tile.Y + tile.Height; y++)
                        {
                            if (cancelRender)
                            {
                                break;
                            }
                            for (int x = tile.X; x < tile.X + tile.Width; x++)
                            {
                                if (cancelRender)
                                {
                                    break;
                                }
                                Ray ray;
                                RGBColor finalColor = RGBColor.Black;
                                if (caster1.Scene.Sampler.NumberOfSamples > 1)
                                {
                                    foreach (Point2D sample in caster1.Scene.Sampler.GetSamplesFor(x, y))
                                    {
                                        ray = caster1.Scene.DefaultCamera.CreateRayFromScreen(sample.X, sample.Y);
                                        ray.PrevRefractIndex = caster1.Scene.RefractIndex;
                                        finalColor          += caster1.Trace(ray, 0);
                                    }
                                    finalColor = (finalColor * 1f / caster1.Scene.Sampler.NumberOfSamples);
                                }
                                else
                                {
                                    ray        = caster1.Scene.DefaultCamera.CreateRayFromScreen(x, y);
                                    finalColor = caster1.Trace(ray, 0);
                                }

                                tile.Image.SetPixel(x - tile.X, y - tile.Y, finalColor.ToColor());
                                //unsafe
                                //{
                                //    Bitmap img = tile.Image;
                                //    BitmapData imgData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, img.PixelFormat);
                                //    byte bitsPerPixel = Texture.GetBitsPerPixel(imgData.PixelFormat);
                                //    byte* scan0 = (byte*)imgData.Scan0.ToPointer();
                                //    byte* data = scan0 + (x - tile.X) * imgData.Stride + (y - tile.Y) * bitsPerPixel / 8;

                                //    data[0] = (byte)(finalColor.R * 255);
                                //    data[1] = (byte)(finalColor.G * 255);
                                //    data[2] = (byte)(finalColor.B * 255);
                                //    img.UnlockBits(imgData);
                                //}
                            }
                            partial += tile.Height;
                            if (((partial / total) * 100) >= 20)
                            {
                                partial = 0;
                                tile.CompleteCycle(TiledBitmap.RenderCycleType.Partial);
                            }
                        }
                        tile.CompleteCycle(TiledBitmap.RenderCycleType.Finish);

                        //timer.Stop();
                    }
                    finally
                    {
                        if (Interlocked.Decrement(ref numberOfWorkers) == 0)
                        {
                            fineshedHandle.Set();
                            cancelHandle.Set();
                            cancelRender = false;
                        }
                    }
                }, casterTile);
                //}){IsBackground = false}.Start(casterTile);
            }//);
            cancelHandle.Set();
            fineshedHandle.WaitOne();
        }