diff --git a/OpenRA.Game/Graphics/Sheet.cs b/OpenRA.Game/Graphics/Sheet.cs index fc880566ec..b6a6c0a764 100644 --- a/OpenRA.Game/Graphics/Sheet.cs +++ b/OpenRA.Game/Graphics/Sheet.cs @@ -52,7 +52,7 @@ namespace OpenRA.Graphics } else if (bitmap != null) { - texture.SetData(Bitmap); + texture.SetData(bitmap); dirty = false; } } @@ -61,9 +61,7 @@ namespace OpenRA.Graphics } } - public Bitmap Bitmap { get { if (bitmap == null) bitmap = new Bitmap(Size.Width, Size.Height); return bitmap; } } public byte[] Data { get { if (data == null) data = new byte[4 * Size.Width * Size.Height]; return data; } } - public void MakeDirty() { dirty = true; } } } diff --git a/OpenRA.Game/Graphics/SpriteFont.cs b/OpenRA.Game/Graphics/SpriteFont.cs index 026c29ec80..09a9008dc5 100644 --- a/OpenRA.Game/Graphics/SpriteFont.cs +++ b/OpenRA.Game/Graphics/SpriteFont.cs @@ -68,8 +68,6 @@ namespace OpenRA.Graphics "chrome"); p.X += g.Advance; } - - // r.Flush(); } public int2 Measure(string text) @@ -100,13 +98,20 @@ namespace OpenRA.Graphics unsafe { var p = (byte*)_glyph.bitmap.buffer; + var dest = s.sheet.Data; + var destStride = s.sheet.Size.Width * 4; for (var j = 0; j < s.size.Y; j++) { for (var i = 0; i < s.size.X; i++) if (p[i] != 0) - s.sheet.Bitmap.SetPixel(i + s.bounds.Left, j + s.bounds.Top, - Color.FromArgb(p[i], c.Second.R, c.Second.G, c.Second.B)); + { + var q = destStride * (j + s.bounds.Top) + 4 * (i + s.bounds.Left); + dest[q] = c.Second.B; + dest[q + 1] = c.Second.G; + dest[q + 2] = c.Second.R; + dest[q + 3] = p[i]; + } p += _glyph.bitmap.pitch; } diff --git a/OpenRA.Game/Graphics/SpriteSheetBuilder.cs b/OpenRA.Game/Graphics/SpriteSheetBuilder.cs index d4a710df3a..0767e4415d 100644 --- a/OpenRA.Game/Graphics/SpriteSheetBuilder.cs +++ b/OpenRA.Game/Graphics/SpriteSheetBuilder.cs @@ -17,7 +17,6 @@ namespace OpenRA.Graphics { public static void Initialize( TileSet tileset ) { - /* .tem: hack to allow incomplete theaters (interior) to work, falling back to temperate for the missing art */ exts = tileset.Extensions; sprites = new Cache( LoadSprites ); } diff --git a/OpenRA.Game/Graphics/Util.cs b/OpenRA.Game/Graphics/Util.cs index 4211b97f64..1b70010dba 100644 --- a/OpenRA.Game/Graphics/Util.cs +++ b/OpenRA.Game/Graphics/Util.cs @@ -65,42 +65,23 @@ namespace OpenRA.Graphics public static void FastCopyIntoChannel(Sprite dest, byte[] src) { - var bitmap = dest.sheet.Bitmap; - BitmapData bits = null; - uint[] channelMasks = { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }; - int[] shifts = { 16, 8, 0, 24 }; + var masks = new int[] { 2, 1, 0, 3 }; // hack, our channel order is nuts. + var data = dest.sheet.Data; + var srcStride = dest.bounds.Width; + var destStride = dest.sheet.Size.Width * 4; + var destOffset = destStride * dest.bounds.Top + dest.bounds.Left * 4 + masks[(int)dest.channel]; + var destSkip = destStride - 4 * srcStride; + var height = dest.bounds.Height; - uint mask = channelMasks[(int)dest.channel]; - int shift = shifts[(int)dest.channel]; - - try + var srcOffset = 0; + for (var j = 0; j < height; j++) { - bits = bitmap.LockBits(dest.bounds, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); - - int width = dest.bounds.Width; - int height = dest.bounds.Height; - - unsafe + for (int i = 0; i < srcStride; i++, srcOffset++) { - fixed (byte* srcbase = &src[0]) - { - byte* s = srcbase; - uint* t = (uint*)bits.Scan0.ToPointer(); - int stride = bits.Stride >> 2; - - for (int j = 0; j < height; j++) - { - uint* p = t; - for (int i = 0; i < width; i++, p++) - *p = (*p & ~mask) | ((mask & ((uint)*s++) << shift)); - t += stride; - } - } + data[destOffset] = src[srcOffset]; + destOffset += 4; } - } - finally - { - bitmap.UnlockBits(bits); + destOffset += destSkip; } }