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 }
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(); }