diff --git a/Blarg.GameFramework.SDL2/Blarg.GameFramework.SDL2.csproj b/Blarg.GameFramework.SDL2/Blarg.GameFramework.SDL2.csproj
index 8c7a8ee..11cc35a 100644
--- a/Blarg.GameFramework.SDL2/Blarg.GameFramework.SDL2.csproj
+++ b/Blarg.GameFramework.SDL2/Blarg.GameFramework.SDL2.csproj
@@ -41,6 +41,7 @@
..\Libs\SDL2#.dll
+
@@ -53,6 +54,7 @@
+
@@ -64,5 +66,6 @@
+
\ No newline at end of file
diff --git a/Blarg.GameFramework.SDL2/Graphics/SDLBitmap.cs b/Blarg.GameFramework.SDL2/Graphics/SDLBitmap.cs
new file mode 100644
index 0000000..2b76424
--- /dev/null
+++ b/Blarg.GameFramework.SDL2/Graphics/SDLBitmap.cs
@@ -0,0 +1,125 @@
+using System;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace Blarg.GameFramework.Graphics
+{
+ public class SDLBitmap : IPlatformBitmap
+ {
+ byte[] _pixels;
+ int _width;
+ int _height;
+ Graphics.ImageFormat _format;
+
+ public byte[] Pixels
+ {
+ get { return _pixels; }
+ }
+
+ public int Width
+ {
+ get { return _width; }
+ }
+
+ public int Height
+ {
+ get { return _height; }
+ }
+
+ public Graphics.ImageFormat Format
+ {
+ get { return _format; }
+ }
+
+ public SDLBitmap(Stream file)
+ {
+ _pixels = GetBitmap(file, out _width, out _height, out _format);
+ }
+
+ private byte[] GetBitmap(Stream file, out int width, out int height, out Graphics.ImageFormat format)
+ {
+ if (file == null)
+ throw new ArgumentNullException("file");
+
+ using (Bitmap bitmap = (Bitmap)Bitmap.FromStream(file))
+ {
+ int bpp = 0;
+ if (bitmap.PixelFormat == PixelFormat.Format32bppArgb)
+ {
+ bpp = 32;
+ format = Graphics.ImageFormat.RGBA;
+ }
+ else if (bitmap.PixelFormat == PixelFormat.Format24bppRgb)
+ {
+ bpp = 24;
+ format = Graphics.ImageFormat.RGB;
+ }
+ else if (bitmap.PixelFormat == PixelFormat.Alpha)
+ {
+ bpp = 8;
+ format = Graphics.ImageFormat.A;
+ }
+ else
+ throw new InvalidOperationException(String.Format("Unsupported bitmap pixel format: {0}", bitmap.PixelFormat.ToString()));
+
+ width = bitmap.Width;
+ height = bitmap.Height;
+
+ byte[] pixels;
+
+ var lockRegion = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
+ var bitmapData = bitmap.LockBits(lockRegion, ImageLockMode.ReadOnly, bitmap.PixelFormat);
+ try
+ {
+ int bitmapSizeInBytes = bitmap.Width * bitmap.Height * (bpp / 8);
+ int expectedPitch = bitmap.Width * (bpp / 8);
+ int actualPitch = bitmapData.Stride;
+
+ if (expectedPitch != actualPitch)
+ throw new InvalidOperationException("Expected bitmap pitch mismatch. Uncaught unsupported bitmap format?");
+
+ pixels = new byte[bitmapData.Stride * bitmap.Height];
+ Marshal.Copy(bitmapData.Scan0, pixels, 0, bitmapSizeInBytes);
+ }
+ finally
+ {
+ bitmap.UnlockBits(bitmapData);
+ }
+
+ // TODO: are there any cases where this should *not* be run?
+ SwapRgbOrdering(pixels, format);
+
+ return pixels;
+ }
+ }
+
+ private void SwapRgbOrdering(byte[] pixels, Graphics.ImageFormat pixelFormat)
+ {
+ if (pixelFormat == Graphics.ImageFormat.A)
+ return;
+
+ // assumption is that this will only ever be 3 or 4 (RGB, or RGBA)
+ int pixelSizeBytes;
+ if (pixelFormat == Graphics.ImageFormat.RGB)
+ pixelSizeBytes = 3;
+ else
+ pixelSizeBytes = 4;
+
+ if (pixels.Length % pixelSizeBytes != 0)
+ throw new InvalidDataException("Pixel data format mismatch.");
+
+ // swap R and B values for each pixel
+ for (int i = 0; i < pixels.Length; i += pixelSizeBytes)
+ {
+ byte r = pixels[i];
+ byte b = pixels[i + 2];
+ pixels[i] = b;
+ pixels[i + 2] = r;
+ }
+ }
+
+ }
+}
+
diff --git a/Blarg.GameFramework.SDL2/SDLApplication.cs b/Blarg.GameFramework.SDL2/SDLApplication.cs
index e058207..a0a5371 100644
--- a/Blarg.GameFramework.SDL2/SDLApplication.cs
+++ b/Blarg.GameFramework.SDL2/SDLApplication.cs
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
+using System.IO;
using SDL2;
using PortableGL;
using PortableGL.SDL;
@@ -612,6 +613,15 @@ namespace Blarg.GameFramework
#endregion
+ #region Support Functions
+
+ public override IPlatformBitmap LoadBitmap(Stream file)
+ {
+ return new SDLBitmap(file);
+ }
+
+ #endregion
+
#region IDisposable
protected override void Release()
diff --git a/Blarg.GameFramework/BaseApplication.cs b/Blarg.GameFramework/BaseApplication.cs
index e1743f6..3bdcb45 100644
--- a/Blarg.GameFramework/BaseApplication.cs
+++ b/Blarg.GameFramework/BaseApplication.cs
@@ -1,4 +1,5 @@
using System;
+using System.IO;
using PortableGL;
using Blarg.GameFramework.Graphics;
using Blarg.GameFramework.Input;
@@ -38,6 +39,8 @@ namespace Blarg.GameFramework
public abstract void Run(IGameApp gameApp, IPlatformConfiguration config);
public abstract void Quit();
+ public abstract IPlatformBitmap LoadBitmap(Stream file);
+
protected void OnInit()
{
Logger.Info(LOG_TAG, "Initializing application objects.");
diff --git a/Blarg.GameFramework/Blarg.GameFramework.csproj b/Blarg.GameFramework/Blarg.GameFramework.csproj
index 1ec5ad3..99a9cb3 100644
--- a/Blarg.GameFramework/Blarg.GameFramework.csproj
+++ b/Blarg.GameFramework/Blarg.GameFramework.csproj
@@ -124,6 +124,8 @@
+
+
diff --git a/Blarg.GameFramework/Graphics/IPlatformBitmap.cs b/Blarg.GameFramework/Graphics/IPlatformBitmap.cs
new file mode 100644
index 0000000..a7930be
--- /dev/null
+++ b/Blarg.GameFramework/Graphics/IPlatformBitmap.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace Blarg.GameFramework.Graphics
+{
+ public interface IPlatformBitmap
+ {
+ byte[] Pixels { get; }
+ int Width { get; }
+ int Height { get; }
+ ImageFormat Format { get; }
+ }
+}
diff --git a/Blarg.GameFramework/Graphics/Image.cs b/Blarg.GameFramework/Graphics/Image.cs
index 1625d85..7bf814c 100644
--- a/Blarg.GameFramework/Graphics/Image.cs
+++ b/Blarg.GameFramework/Graphics/Image.cs
@@ -1,14 +1,8 @@
using System;
+using System.IO;
namespace Blarg.GameFramework.Graphics
{
- public enum ImageFormat
- {
- RGB,
- RGBA,
- A
- }
-
public partial class Image
{
private byte[] _pixels;
@@ -47,28 +41,15 @@ namespace Blarg.GameFramework.Graphics
Create(source, copyX, copyY, copyWidth, copyHeight);
}
- private Image(byte[] pixels, int width, int height, ImageFormat format)
+ public Image(Stream file)
{
- if (pixels == null)
- throw new ArgumentNullException("pixels");
+ if (file == null)
+ throw new ArgumentNullException("file");
- int bpp = 0;
- if (format == ImageFormat.RGB)
- bpp = 24;
- else if (format == ImageFormat.RGBA)
- bpp = 32;
- else if (format == ImageFormat.A)
- bpp = 8;
+ var bitmap = Platform.Application.LoadBitmap(file);
- if (bpp == 0)
- throw new ArgumentException("pixelFormat");
-
- _pixels = pixels;
- Width = width;
- Height = height;
- BitsPerPixel = bpp;
- PixelFormat = format;
- Pitch = Width * (BitsPerPixel / 8);
+ CreateBaseImage(bitmap.Width, bitmap.Height, bitmap.Format);
+ Buffer.BlockCopy(bitmap.Pixels, 0, _pixels, 0, bitmap.Pixels.Length);
}
private void CreateBaseImage(int width, int height, ImageFormat pixelFormat)
diff --git a/Blarg.GameFramework/Graphics/ImageFormat.cs b/Blarg.GameFramework/Graphics/ImageFormat.cs
new file mode 100644
index 0000000..156fb7c
--- /dev/null
+++ b/Blarg.GameFramework/Graphics/ImageFormat.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace Blarg.GameFramework.Graphics
+{
+ public enum ImageFormat
+ {
+ RGB,
+ RGBA,
+ A
+ }
+}
diff --git a/Blarg.GameFramework/IApplication.cs b/Blarg.GameFramework/IApplication.cs
index 05d6946..7c28034 100644
--- a/Blarg.GameFramework/IApplication.cs
+++ b/Blarg.GameFramework/IApplication.cs
@@ -1,4 +1,5 @@
using System;
+using System.IO;
using PortableGL;
using Blarg.GameFramework.Graphics;
using Blarg.GameFramework.Input;
@@ -30,6 +31,8 @@ namespace Blarg.GameFramework
void Run(IGameApp gameApp, IPlatformConfiguration config);
void Quit();
+
+ IPlatformBitmap LoadBitmap(Stream file);
}
}