public ImageBrushImpl( ImageBrush brush, SharpDX.Direct2D1.RenderTarget target, Size targetSize) { if (brush.Source == null) { return; } var image = ((BitmapImpl)brush.Source.PlatformImpl).GetDirect2DBitmap(target); var imageSize = new Size(brush.Source.PixelWidth, brush.Source.PixelHeight); var tileMode = brush.TileMode; var sourceRect = brush.SourceRect.ToPixels(imageSize); var destinationRect = brush.DestinationRect.ToPixels(targetSize); var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceRect.Size); var translate = CalculateTranslate(brush, sourceRect, destinationRect, scale); var intermediateSize = CalculateIntermediateSize(tileMode, targetSize, destinationRect.Size); var brtOpts = CompatibleRenderTargetOptions.None; // TODO: There are times where we don't need to draw an intermediate bitmap. Identify // them and directly use 'image' in those cases. using (var intermediate = new BitmapRenderTarget(target, brtOpts, intermediateSize)) { Rect drawRect; var transform = CalculateIntermediateTransform( tileMode, sourceRect, destinationRect, scale, translate, out drawRect); intermediate.BeginDraw(); intermediate.PushAxisAlignedClip(drawRect.ToDirect2D(), AntialiasMode.Aliased); intermediate.Transform = transform.ToDirect2D(); intermediate.DrawBitmap(image, 1, BitmapInterpolationMode.Linear); intermediate.PopAxisAlignedClip(); intermediate.EndDraw(); this.PlatformBrush = new BitmapBrush( target, intermediate.Bitmap, GetBitmapBrushProperties(brush), GetBrushProperties(brush, destinationRect)); } }
public void Start() { if (ProcessStarted != null) ProcessStarted(); int index = 0; var rendererUtil = new RendererUtil(); // obtain file list var regionList = Directory.GetFiles(Path.Combine(worldLocation, "region"), "*.mca").ToList(); var regionEntries = new List<RegionEntry>(); foreach (string region in regionList) { try { // load the region using (RegionFile regionFile = RegionFile.OpenRegion(File.OpenRead(region))) { var renderedChunks = new List<ChunkEntry>(); if (RegionLoaded != null) RegionLoaded(regionFile); Debug.WriteLine("Rendering region"); DateTime sTime = DateTime.Now; #region Chunk render using (var renderTarget = new BitmapRenderTarget(rendererUtil.D2DDeviceContext, CompatibleRenderTargetOptions.None, new DrawingSizeF(16, 16), new DrawingSize(16, 16), new PixelFormat(Format.R8G8B8A8_UNorm, AlphaMode.Premultiplied))) { foreach (var anvilChunk in regionFile.Content.Select(chunk => new Anvil(chunk))) { ChunkEntry entry; RenderSegment(anvilChunk, renderTarget, out entry); renderedChunks.Add(entry); } } #endregion #region Region compositor using (var renderTarget = new BitmapRenderTarget(rendererUtil.D2DDeviceContext, CompatibleRenderTargetOptions.None, new DrawingSizeF(512, 512), new DrawingSize(512, 512), new PixelFormat(Format.R8G8B8A8_UNorm, AlphaMode.Premultiplied))) { renderTarget.BeginDraw(); renderTarget.Clear(Color.Transparent); // compose the images foreach (ChunkEntry chunk in renderedChunks) { int cxPos = chunk.XPos % 32; int czPos = chunk.ZPos % 32; if (cxPos < 0) cxPos = 32 + cxPos; if (czPos < 0) czPos = 32 + czPos; int xPos = cxPos * 16; int zPos = czPos * 16; renderTarget.Transform = Matrix3x2.Translation(xPos, zPos); renderTarget.DrawBitmap(chunk.RenderedChunk, 1, BitmapInterpolationMode.Linear); } // ReSharper disable PossibleNullReferenceException string[] info = Path.GetFileNameWithoutExtension(region).Split('.'); // ReSharper restore PossibleNullReferenceException regionEntries.Add(new RegionEntry { RenderedRegion = renderTarget.Bitmap, XPos = Convert.ToInt32(info[1]), ZPos = Convert.ToInt32(info[2]) }); renderTarget.EndDraw(); } #endregion Debug.WriteLine("Render time is: " + (DateTime.Now - sTime).Seconds + " seconds."); if (RegionRendered != null) RegionRendered(); #region Cleanup foreach (ChunkEntry chunk in renderedChunks) chunk.RenderedChunk.Dispose(); renderedChunks.Clear(); #endregion } } catch (Exception exception) { if (ProcessFailed != null) ProcessFailed(exception.Message + "\nAt:\n" + exception); } if (ProgressChanged != null) ProgressChanged(++index / (float)regionList.Count); } #region Extrema processor int xMin = 0; int zMin = 0; int xMax = 0; int zMax = 0; foreach (RegionEntry entry in regionEntries) { if (xMin > entry.XPos) xMin = entry.XPos; if (xMax < entry.XPos) xMax = entry.XPos; if (zMin > entry.ZPos) zMin = entry.ZPos; if (zMax < entry.ZPos) zMax = entry.ZPos; } int wSizeX = (xMax - xMin) * 512 + 512; int wSizeZ = (zMax - zMin) * 512 + 512; xMin = Math.Abs(xMin); zMin = Math.Abs(zMin); #endregion #region World compositor var ResultingBitmap = new Bitmap1(rendererUtil.D2DDeviceContext, new DrawingSize(wSizeX, wSizeZ), new BitmapProperties1 { BitmapOptions = BitmapOptions.Target, PixelFormat = new PixelFormat(Format.R8G8B8A8_UNorm, AlphaMode.Premultiplied) }); rendererUtil.D2DDeviceContext.Target = ResultingBitmap; rendererUtil.D2DDeviceContext.BeginDraw(); rendererUtil.D2DDeviceContext.Clear(Color.Transparent); foreach (RegionEntry entry in regionEntries) { int xPos = ((xMin + entry.XPos) * 512); int zPos = ((zMin + entry.ZPos) * 512); rendererUtil.D2DDeviceContext.Transform = Matrix3x2.Translation(xPos, zPos); rendererUtil.D2DDeviceContext.DrawBitmap(entry.RenderedRegion, 1, BitmapInterpolationMode.Linear); } rendererUtil.D2DDeviceContext.EndDraw(); #endregion #region File save FileStream file = File.OpenWrite(Path.GetFileName(worldLocation) + ".png"); var encoder = new PngBitmapEncoder(rendererUtil.ImagingFactory); encoder.Initialize(file); var frameEncode = new BitmapFrameEncode(encoder); frameEncode.Initialize(); var imageEncoder = new ImageEncoder(rendererUtil.ImagingFactory, rendererUtil.D2DDevice); imageEncoder.WriteFrame(ResultingBitmap, frameEncode, new ImageParameters( new PixelFormat(Format.R8G8B8A8_UNorm, AlphaMode.Premultiplied), 96, 96, 0, 0, wSizeX, wSizeZ)); frameEncode.Commit(); encoder.Commit(); #endregion #region Cleanup file.Close(); file.Dispose(); foreach (RegionEntry bitmap in regionEntries) { bitmap.RenderedRegion.Dispose(); } regionEntries.Clear(); rendererUtil.Dispose(); theBlocks.Dispose(); ResultingBitmap.Dispose(); #endregion if (ProcessComplete != null) ProcessComplete(); }