/// <summary> /// Not thread safe /// </summary> /// <param name="info"></param> /// <returns></returns> public TImage GetTextureImage(TextureInfo info) { if (info == null) { return(null); } var localPath = info.Filename; localPath = localPath.Replace("textures/", ""); localPath = localPath.Replace('/', Path.DirectorySeparatorChar); if (Cache.ContainsKey(info)) { return(Cache[info]); } try { string filepath = Path.Combine(path, localPath); TImage b = null; if (File.Exists(filepath + ".png")) { b = graphics.LoadImage(filepath + ".png"); } else if (File.Exists(filepath + ".tga")) { b = graphics.LoadImage(filepath + ".tga"); } if (b == null) { Console.WriteLine("Could not find {0}", filepath); } if (info.Translation != null) { var bnew = graphics.CreateEmptyImage(16, 16); graphics.DrawImage(bnew, b, info.Translation.Dest, info.Translation.Source); b = bnew; } if (info.Rotation != RotateFlip.RotateNoneFlipNone) { graphics.RotateFlip(b, info.Rotation); } if (!Cache.ContainsKey(info)) { Cache.Add(info, b); } return(b); } catch (Exception ex) { Console.WriteLine(ex.Message); } return(null); }
public void RenderZoomLevels() { var sourceZoomLevel = this.NewInitialZoomLevel; var sourceDiameter = this.InitialDiameter; var sourceLevelXmin = XMin / ChunksPerDimension; var sourceLevelXmax = XMax / ChunksPerDimension; var sourceLevelZmin = ZMin / ChunksPerDimension; var sourceLevelZmax = ZMax / ChunksPerDimension; while (sourceZoomLevel > NewLastZoomLevel) { // Force garbage collection (may not be necessary) GC.Collect(); GC.WaitForPendingFinalizers(); var destDiameter = sourceDiameter / 2; var sourceZoom = sourceZoomLevel; var destZoom = sourceZoomLevel - 1; var linesRendered = 0; if (sourceLevelXmin.IsOdd()) // always start at an even coordinate { sourceLevelXmin--; } if (sourceLevelXmax.IsOdd()) { sourceLevelXmax++; } if (sourceLevelZmin.IsOdd()) // always start at an even coordinate { sourceLevelZmin--; } if (sourceLevelZmax.IsOdd()) { sourceLevelZmax++; } Console.WriteLine( $"\nRendering Level {destZoom} with source coordinates X {sourceLevelXmin} to {sourceLevelXmax}, Z {sourceLevelZmin} to {sourceLevelZmax}"); OuterLoopStrategy(BetterEnumerable.SteppedRange(sourceLevelXmin, sourceLevelXmax, 2), new ParallelOptions() { MaxDegreeOfParallelism = RenderSettings.MaxNumberOfThreads }, x => { for (int z = sourceLevelZmin; z < sourceLevelZmax; z += 2) { var b1 = LoadBitmap(sourceZoom, x, z, isUpdate); var b2 = LoadBitmap(sourceZoom, x + 1, z, isUpdate); var b3 = LoadBitmap(sourceZoom, x, z + 1, isUpdate); var b4 = LoadBitmap(sourceZoom, x + 1, z + 1, isUpdate); if (b1 != null || b2 != null || b3 != null || b4 != null) { var bfinal = graphics.CreateEmptyImage(TileSize, TileSize); { b1 = b1 ?? LoadBitmap(sourceZoom, x, z, false); b2 = b2 ?? LoadBitmap(sourceZoom, x + 1, z, false); b3 = b3 ?? LoadBitmap(sourceZoom, x, z + 1, false); b4 = b4 ?? LoadBitmap(sourceZoom, x + 1, z + 1, false); var halfTileSize = TileSize / 2; if (b1 != null) { graphics.DrawImage(bfinal, b1, 0, 0, halfTileSize, halfTileSize); } if (b2 != null) { graphics.DrawImage(bfinal, b2, halfTileSize, 0, halfTileSize, halfTileSize); } if (b3 != null) { graphics.DrawImage(bfinal, b3, 0, halfTileSize, halfTileSize, halfTileSize); } if (b4 != null) { graphics.DrawImage(bfinal, b4, halfTileSize, halfTileSize, halfTileSize, halfTileSize); } SaveBitmap(destZoom, x / 2, z / 2, isUpdate, bfinal); } // Dispose of any bitmaps, releasing memory foreach (var bitmap in new[] { b1, b2, b3, b4, bfinal }.OfType <Bitmap>()) { bitmap.Dispose(); } } } Interlocked.Add(ref linesRendered, 2); ZoomLevelRenderd?.Invoke(this, new ZoomRenderedEventArgs(linesRendered, sourceDiameter, destZoom)); }); sourceLevelZmin /= 2; sourceLevelZmax /= 2; sourceLevelXmin /= 2; sourceLevelXmax /= 2; sourceDiameter = destDiameter; sourceZoomLevel = destZoom; } }