public void GetPacked(int i, out int id, out RectangleI rect) { if (i < 0 || i >= PackedCount) { throw new ArgumentOutOfRangeException(nameof(i)); } packer_get(packer, i, out id, out rect.X, out rect.Y, out rect.W, out rect.H); }
public DrawCall(RenderTarget target, Material material) { Target = target; Material = material; Mesh = null; Blend = false; BlendMode = default(BlendMode); Clip = false; ClipRect = default(RectangleI); }
public DrawCall(RenderTarget target, Material material, Mesh mesh, BlendMode blendMode, RectangleI clipRect) { Target = target; Material = material; Mesh = mesh; Blend = true; BlendMode = blendMode; Clip = true; ClipRect = clipRect; }
public DrawCall(RenderTarget target, Material material, Mesh mesh, BlendMode blendMode) { Target = target; Material = material; Mesh = mesh; Blend = true; BlendMode = blendMode; Clip = false; ClipRect = default(RectangleI); }
public DrawCall(Material material, Mesh mesh) { Target = null; Material = material; Mesh = mesh; Blend = false; BlendMode = default(BlendMode); Clip = false; ClipRect = default(RectangleI); }
public void PushClipRect(ref RectangleI rect) { Flush(); ++clipIndex; if (clipIndex == clipRects.Length) { Array.Resize(ref clipRects, clipIndex * 2); } clipRects[clipIndex] = rect; draw.Clip = true; draw.ClipRect = rect; }
public SubTexture(Texture texture, RectangleI rect, int offsetX, int offsetY, int trimWidth, int trimHeight) { Texture = texture; Width = rect.W; Height = rect.H; OffsetX = offsetX; OffsetY = offsetY; TrimWidth = trimWidth; TrimHeight = trimHeight; var size = new Vector2(texture.Width, texture.Height); uv.A = rect.TopLeft / size; uv.B = rect.TopRight / size; uv.C = rect.BottomRight / size; uv.D = rect.BottomLeft / size; }
public void GetSubRect(Bitmap result, RectangleI rect) { result.Resize(rect.W, rect.H); result.CopyPixels(this, rect, Point2.Zero); }
public AtlasImage AddImage(string name, int width, int height, int offsetX, int offsetY, int trimW, int trimH, RectangleI subRect) { Rectangle uvRect = subRect; uvRect.X /= Texture.Width; uvRect.Y /= Texture.Height; uvRect.W /= Texture.Width; uvRect.H /= Texture.Height; return(AddImage(ref name, width, height, offsetX, offsetY, trimW, trimH, ref uvRect, false)); }
public void SetRect(RectangleI rect, Color4 color) { SetRect(rect.X, rect.Y, rect.W, rect.H, color); }
public void BlitTextureTo(RenderTarget target, int textureNum, BlitFilter filter, RectangleI rect) { if (textures[textureNum].ID == 0) { throw new Exception("RenderTarget does not have a texture in slot: " + textureNum); } Bind(null); GL.BindFramebuffer(FramebufferTarget.Read, id); GL.BindFramebuffer(FramebufferTarget.Draw, target != null ? target.id : 0); GL.ReadBuffer((ReadBuffer)((uint)ReadBuffer.Color0 + textureNum)); GL.BlitFramebuffer(new RectangleI(Width, Height), rect, BufferBit.Color, filter); }
public Atlas Build(int pad) { var packer = new RectanglePacker(maxSize, maxSize, packCount); //This ID is used to keep the rectangles ordered (we need to unpack in the same order we packed) int nextID = 0; //Add all the bitmaps (padding them) foreach (var pair in bitmaps) { RectangleI rect; if (!trims.TryGetValue(pair.Value, out rect)) { rect = new RectangleI(pair.Value.Width, pair.Value.Height); } packer.Add(++nextID, rect.W + pad, rect.H + pad, true); } //Add all the font characters (padding them) foreach (var pair in fonts) { FontChar chr; for (int i = 0; i < pair.Value.CharCount; ++i) { pair.Value.GetCharInfoAt(i, out chr); if (!pair.Value.IsEmpty(chr.Char)) { packer.Add(++nextID, chr.Width + pad, chr.Height + pad, true); } } } //Add all the tiles (padding them) foreach (var pair in tiles) { var tileset = pair.Value; RectangleI rect; for (int y = 0; y < tileset.Rows; ++y) { for (int x = 0; x < tileset.Cols; ++x) { var tile = tileset.Bitmaps[x, y]; if (tile != null) { if (!trims.TryGetValue(tile, out rect)) { rect = new RectangleI(tile.Width, tile.Height); } packer.Add(++nextID, rect.W + pad, rect.H + pad, true); } } } } //Pack the rectangles if (!packer.Pack()) { return(null); } //Sort the packed rectangles so they're in the same order we added them var packed = new Packed[packer.PackedCount]; for (int i = 0; i < packed.Length; ++i) { packer.GetPacked(i, out packed[i].ID, out packed[i].Rect); } Array.Sort(packed, (a, b) => a.ID.CompareTo(b.ID)); //Get the atlas size int atlasW, atlasH; packer.GetBounds(out atlasW, out atlasH); atlasW = atlasW.ToPowerOf2(); atlasH = atlasH.ToPowerOf2(); ///Create the atlas with an empty texture for now var atlas = new Atlas(new Texture2D(atlasW, atlasH, TextureFormat.RGBA)); var atlasBitmap = new Bitmap(atlasW, atlasH); var rotBitmap = new Bitmap(1, 1); var trimBitmap = new Bitmap(1, 1); //Reset the ID so we get the correct packed rectangles as we go nextID = 0; AtlasImage AddImage(string name, Bitmap bitmap) { RectangleI trim; if (!trims.TryGetValue(bitmap, out trim)) { trim = new RectangleI(bitmap.Width, bitmap.Height); } //Get the rectangle and unpad it var rect = packed[nextID++].Rect; rect.W -= pad; rect.H -= pad; var img = atlas.AddImage(name, bitmap.Width, bitmap.Height, trim.X, trim.Y, trim.W, trim.H, rect, trim.W != rect.W); //Blit the bitmap onto the atlas, optionally rotating it if (trim.W != rect.W) { //Rotate the bitmap, trimming first if the bitmap was trimmed if (trim.W < bitmap.Width || trim.H < bitmap.Height) { bitmap.GetSubRect(trimBitmap, trim); trimBitmap.RotateRight(rotBitmap); } else { bitmap.RotateRight(rotBitmap); } atlasBitmap.CopyPixels(rotBitmap, rect.X, rect.Y); } else { atlasBitmap.CopyPixels(bitmap, trim.X, trim.Y, trim.W, trim.H, rect.X, rect.Y); } return(img); } //Add the images foreach (var pair in bitmaps) { AddImage(pair.Key, pair.Value); } //Add the fonts Bitmap charBitmap = null; foreach (var pair in fonts) { var size = pair.Value; //This is the bitmap we'll render the character onto if (charBitmap == null) { charBitmap = new Bitmap(size.MaxCharW, size.MaxCharH); } else { charBitmap.Resize(size.MaxCharW, size.MaxCharH); } //Create an atlas font to populate with the characters var font = atlas.AddFont(pair.Key, size.Ascent, size.Descent, size.LineGap); FontChar chr; RectangleI rect; for (int i = 0; i < size.CharCount; ++i) { size.GetCharInfoAt(i, out chr); if (!size.IsEmpty(chr.Char)) { //Get the packed rectangle and unpad it rect = packed[nextID++].Rect; rect.W -= pad; rect.H -= pad; //Rasterize the character and optionally rotate it before blitting size.GetPixels(chr.Char, charBitmap, fontsToPremultiply.Contains(size)); if (chr.Width != rect.W) { charBitmap.RotateRight(rotBitmap); atlasBitmap.CopyPixels(rotBitmap, rect.X, rect.Y); } else { atlasBitmap.CopyPixels(charBitmap, rect.X, rect.Y); } } else { rect = RectangleI.Empty; } var atlasChar = font.AddChar(chr.Char, chr.Width, chr.Height, chr.Advance, chr.OffsetX, chr.OffsetY, rect, chr.Width != rect.W); //Set character kerning for (int j = 0; j < size.CharCount; ++j) { char nextChar = size.GetCharAt(j); int kern = size.GetKerning(chr.Char, nextChar); if (kern != 0) { atlasChar.SetKerning(nextChar, kern); } } } } //Add the tiles foreach (var pair in tiles) { var prefix = pair.Key; var tileset = pair.Value; var atlasTiles = atlas.AddTiles(prefix, tileset.Cols, tileset.Rows, tileset.TileWidth, tileset.TileHeight); for (int y = 0; y < tileset.Rows; ++y) { for (int x = 0; x < tileset.Cols; ++x) { var tile = tileset.Bitmaps[x, y]; if (tile != null) { var image = AddImage($"{prefix}:{x},{y}", tile); atlasTiles.SetTile(x, y, image); } } } } //Now that the bitmap is rendered, upload it to the texture atlas.Texture.SetPixels(atlasBitmap); return(atlas); }
public AtlasChar AddChar(char chr, int width, int height, int advance, int offsetX, int offsetY, RectangleI subRect, bool rotate90) { Rectangle uvRect = subRect; uvRect.X /= Atlas.Width; uvRect.Y /= Atlas.Height; uvRect.W /= Atlas.Width; uvRect.H /= Atlas.Height; return(AddChar(chr, width, height, advance, offsetX, offsetY, uvRect, rotate90)); }
public void SetClipRect(ref RectangleI clipRect) { Clip = true; ClipRect = clipRect; }
public void SetClipRect(RectangleI clipRect) { SetClipRect(ref clipRect); }
public void CopyPixels(Bitmap source, RectangleI src, Point2 dst) { CopyPixels(source, src.X, src.Y, src.W, src.H, dst.X, dst.Y); }
public void PushClipRect(RectangleI rect) { PushClipRect(ref rect); }
public bool HasVisiblePixelsInRect(RectangleI rect) { return(HasVisiblePixelsInRect(rect.X, rect.Y, rect.W, rect.H)); }
public SubTexture(Texture texture, RectangleI rect) : this(texture, rect, 0, 0, rect.W, rect.H) { }