/// <summary> /// Start a full render. It does first check if world has changed or the current render can be upscaled /// </summary> /// <param name="world"></param> /// <param name="raster"></param> public void StartRender(World world, MultiResolutionRaster raster) { // World has not changed and cant upscale if (!world.Changed && (raster.CurrentLevel == raster.MaxLevel || Workers.Count > 0)) { return; } // World has not changed. So upscale if (!world.Changed) { raster.SwitchLevel(raster.CurrentLevel + 1, true); } if (world.Changed) { raster.SwitchLevel(0, false); // World changed. Reset antialias } ++WorkID; Workers.Clear(); Raytracer.Reset(world); Raster = raster; World.Changed = false; DebugRow = (int)(Settings.RaytraceDebugRow * Raster.Height); if (Settings.IsMultithread) { var rpt = Raster.Height / AvailableThreads; for (int i = 0; i < AvailableThreads; ++i) { Workers.Add(new RaytraceWorker(this, i * rpt, (i + 1) * rpt, useDebug)); Workers[i].RunAsync(); } if (!Settings.IsAsync) { foreach (var worker in Workers) { worker.Thread.Join(); } Workers.Clear(); if (useDebug) { DebugRenderer.DebugDraw(Raytracer.DebugData, Raster.CurrentRaster, World); } } } else { var worker = new RaytraceWorker(this, 0, Raster.Height, useDebug); worker.Run(); if (useDebug) { DebugRenderer.DebugDraw(Raytracer.DebugData, Raster.CurrentRaster, World); } } }
/// <summary> /// Splits the work in two of possible /// </summary> /// <returns></returns> public RaytraceWorker Split() { int HalfRow = CurrentRow + (EndRow - CurrentRow) / 2; if (HalfRow == CurrentRow) { return(null); } var ret = new RaytraceWorker(Mother, HalfRow, EndRow); EndRow = HalfRow; // Screams in concurrency return(ret); }