diff --git a/src/ImGui.NET.SampleProgram.XNA/DrawVertDeclaration.cs b/src/ImGui.NET.SampleProgram.XNA/DrawVertDeclaration.cs
new file mode 100644
index 0000000..633d640
--- /dev/null
+++ b/src/ImGui.NET.SampleProgram.XNA/DrawVertDeclaration.cs
@@ -0,0 +1,29 @@
+using Microsoft.Xna.Framework.Graphics;
+
+namespace ImGuiNET.SampleProgram.XNA
+{
+ public static class DrawVertDeclaration
+ {
+ public static readonly VertexDeclaration Declaration;
+
+ public static readonly int Size;
+
+ static DrawVertDeclaration()
+ {
+ unsafe { Size = sizeof(DrawVert); }
+
+ Declaration = new VertexDeclaration(
+ Size,
+
+ // Position
+ new VertexElement(0, VertexElementFormat.Vector2, VertexElementUsage.Position, 0),
+
+ // UV
+ new VertexElement(8, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0),
+
+ // Color
+ new VertexElement(16, VertexElementFormat.Color, VertexElementUsage.Color, 0)
+ );
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ImGui.NET.SampleProgram.XNA/ImGui.NET.SampleProgram.XNA.csproj b/src/ImGui.NET.SampleProgram.XNA/ImGui.NET.SampleProgram.XNA.csproj
new file mode 100644
index 0000000..d360c32
--- /dev/null
+++ b/src/ImGui.NET.SampleProgram.XNA/ImGui.NET.SampleProgram.XNA.csproj
@@ -0,0 +1,26 @@
+
+
+
+ true
+ false
+ ImGuiNET.SampleProgram.XNA
+ ImGuiNET.SampleProgram.XNA
+ net462
+ Exe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ImGui.NET.SampleProgram.XNA/ImGuiRenderer.cs b/src/ImGui.NET.SampleProgram.XNA/ImGuiRenderer.cs
new file mode 100644
index 0000000..aaba78a
--- /dev/null
+++ b/src/ImGui.NET.SampleProgram.XNA/ImGuiRenderer.cs
@@ -0,0 +1,377 @@
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace ImGuiNET.SampleProgram.XNA
+{
+ ///
+ /// ImGui renderer for use with XNA-likes (FNA & MonoGame)
+ ///
+ public class ImGuiRenderer
+ {
+ private Game _game;
+
+ // Graphics
+ private GraphicsDevice _graphicsDevice;
+
+ private BasicEffect _effect;
+ private RasterizerState _rasterizerState;
+
+ private byte[] _vertexData;
+ private VertexBuffer _vertexBuffer;
+ private int _vertexBufferSize;
+
+ private byte[] _indexData;
+ private IndexBuffer _indexBuffer;
+ private int _indexBufferSize;
+
+ // Textures
+ private Dictionary _loadedTextures;
+
+ private int _textureId;
+ private IntPtr? _fontTextureId;
+
+ // Input
+ private int _scrollWheelValue;
+
+ private List _keys = new List();
+
+ public ImGuiRenderer(Game game)
+ {
+ _game = game ?? throw new ArgumentNullException(nameof(game));
+ _graphicsDevice = game.GraphicsDevice;
+
+ _loadedTextures = new Dictionary();
+
+ _rasterizerState = new RasterizerState()
+ {
+ CullMode = CullMode.None,
+ DepthBias = 0,
+ FillMode = FillMode.Solid,
+ MultiSampleAntiAlias = false,
+ ScissorTestEnable = true,
+ SlopeScaleDepthBias = 0
+ };
+
+ SetupInput();
+ }
+
+ #region ImGuiRenderer
+
+ ///
+ /// Creates a texture and loads the font data from ImGui. Should be called when the is initialized but before any rendering is done
+ ///
+ public virtual void RebuildFontAtlas()
+ {
+ // Get font texture from ImGui
+ var io = ImGui.GetIO();
+ var texData = io.FontAtlas.GetTexDataAsRGBA32();
+
+ // Copy the data to a managed array
+ var pixels = new byte[texData.Width * texData.Height * texData.BytesPerPixel];
+ unsafe { Marshal.Copy(new IntPtr(texData.Pixels), pixels, 0, pixels.Length); }
+
+ // Create and register the texture as an XNA texture
+ var tex2d = new Texture2D(_graphicsDevice, texData.Width, texData.Height, false, SurfaceFormat.Color);
+ tex2d.SetData(pixels);
+
+ // Should a texture already have been build previously, unbind it first so it can be deallocated
+ if (_fontTextureId.HasValue) UnbindTexture(_fontTextureId.Value);
+
+ // Bind the new texture to an ImGui-friendly id
+ _fontTextureId = BindTexture(tex2d);
+
+ // Let ImGui know where to find the texture
+ io.FontAtlas.SetTexID(_fontTextureId.Value);
+ io.FontAtlas.ClearTexData(); // Clears CPU side texture data
+ }
+
+ ///
+ /// Creates a pointer to a texture, which can be passed through ImGui calls such as . That pointer is then used by ImGui to let us know what texture to draw
+ ///
+ public virtual IntPtr BindTexture(Texture2D texture)
+ {
+ var id = new IntPtr(_textureId++);
+
+ _loadedTextures.Add(id, texture);
+
+ return id;
+ }
+
+ ///
+ /// Removes a previously created texture pointer, releasing its reference and allowing it to be deallocated
+ ///
+ public virtual void UnbindTexture(IntPtr textureId)
+ {
+ _loadedTextures.Remove(textureId);
+ }
+
+ ///
+ /// Sets up ImGui for a new frame, should be called at frame start
+ ///
+ public virtual void BeforeLayout(GameTime gameTime)
+ {
+ ImGui.GetIO().DeltaTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
+
+ UpdateInput();
+
+ ImGui.NewFrame();
+ }
+
+ ///
+ /// Asks ImGui for the generated geometry data and sends it to the graphics pipeline, should be called after the UI is drawn using ImGui.** calls
+ ///
+ public virtual void AfterLayout()
+ {
+ ImGui.Render();
+
+ unsafe { RenderDrawData(ImGui.GetDrawData()); }
+ }
+
+ #endregion ImGuiRenderer
+
+ #region Setup & Update
+
+ ///
+ /// Maps ImGui keys to XNA keys. We use this later on to tell ImGui what keys were pressed
+ ///
+ protected virtual void SetupInput()
+ {
+ var io = ImGui.GetIO();
+
+ _keys.Add(io.KeyMap[GuiKey.Tab] = (int)Keys.Tab);
+ _keys.Add(io.KeyMap[GuiKey.LeftArrow] = (int)Keys.Left);
+ _keys.Add(io.KeyMap[GuiKey.RightArrow] = (int)Keys.Right);
+ _keys.Add(io.KeyMap[GuiKey.UpArrow] = (int)Keys.Up);
+ _keys.Add(io.KeyMap[GuiKey.DownArrow] = (int)Keys.Down);
+ _keys.Add(io.KeyMap[GuiKey.PageUp] = (int)Keys.PageUp);
+ _keys.Add(io.KeyMap[GuiKey.PageDown] = (int)Keys.PageDown);
+ _keys.Add(io.KeyMap[GuiKey.Home] = (int)Keys.Home);
+ _keys.Add(io.KeyMap[GuiKey.End] = (int)Keys.End);
+ _keys.Add(io.KeyMap[GuiKey.Delete] = (int)Keys.Delete);
+ _keys.Add(io.KeyMap[GuiKey.Backspace] = (int)Keys.Back);
+ _keys.Add(io.KeyMap[GuiKey.Enter] = (int)Keys.Enter);
+ _keys.Add(io.KeyMap[GuiKey.Escape] = (int)Keys.Escape);
+ _keys.Add(io.KeyMap[GuiKey.A] = (int)Keys.A);
+ _keys.Add(io.KeyMap[GuiKey.C] = (int)Keys.C);
+ _keys.Add(io.KeyMap[GuiKey.V] = (int)Keys.V);
+ _keys.Add(io.KeyMap[GuiKey.X] = (int)Keys.X);
+ _keys.Add(io.KeyMap[GuiKey.Y] = (int)Keys.Y);
+ _keys.Add(io.KeyMap[GuiKey.Z] = (int)Keys.Z);
+
+ // MonoGame-specific //////////////////////
+ _game.Window.TextInput += (s, a) =>
+ {
+ if (a.Character == '\t') return;
+
+ ImGui.AddInputCharacter(a.Character);
+ };
+ ///////////////////////////////////////////
+
+ // FNA-specific ///////////////////////////
+ //TextInputEXT.TextInput += c =>
+ //{
+ // if (c == '\t') return;
+
+ // ImGui.AddInputCharacter(c);
+ //};
+ ///////////////////////////////////////////
+
+ ImGui.GetIO().FontAtlas.AddDefaultFont();
+ }
+
+ ///
+ /// Updates the to the current matrices and texture
+ ///
+ protected virtual Effect UpdateEffect(Texture2D texture)
+ {
+ _effect = _effect ?? new BasicEffect(_graphicsDevice);
+
+ var io = ImGui.GetIO();
+
+ // MonoGame-specific //////////////////////
+ var offset = .5f;
+ ///////////////////////////////////////////
+
+ // FNA-specific ///////////////////////////
+ //var offset = 0f;
+ ///////////////////////////////////////////
+
+ _effect.World = Matrix.Identity;
+ _effect.View = Matrix.Identity;
+ _effect.Projection = Matrix.CreateOrthographicOffCenter(offset, io.DisplaySize.X + offset, io.DisplaySize.Y + offset, offset, -1f, 1f);
+ _effect.TextureEnabled = true;
+ _effect.Texture = texture;
+ _effect.VertexColorEnabled = true;
+
+ return _effect;
+ }
+
+ ///
+ /// Sends XNA input state to ImGui
+ ///
+ protected virtual void UpdateInput()
+ {
+ var io = ImGui.GetIO();
+
+ var mouse = Mouse.GetState();
+ var keyboard = Keyboard.GetState();
+
+ for (int i = 0; i < _keys.Count; i++)
+ {
+ io.KeysDown[_keys[i]] = keyboard.IsKeyDown((Keys)_keys[i]);
+ }
+
+ io.ShiftPressed = keyboard.IsKeyDown(Keys.LeftShift) || keyboard.IsKeyDown(Keys.RightShift);
+ io.CtrlPressed = keyboard.IsKeyDown(Keys.LeftControl) || keyboard.IsKeyDown(Keys.RightControl);
+ io.AltPressed = keyboard.IsKeyDown(Keys.LeftAlt) || keyboard.IsKeyDown(Keys.RightAlt);
+ io.SuperPressed = keyboard.IsKeyDown(Keys.LeftWindows) || keyboard.IsKeyDown(Keys.RightWindows);
+
+ io.DisplaySize = new System.Numerics.Vector2(_graphicsDevice.PresentationParameters.BackBufferWidth, _graphicsDevice.PresentationParameters.BackBufferHeight);
+ io.DisplayFramebufferScale = new System.Numerics.Vector2(1f, 1f);
+
+ io.MousePosition = new System.Numerics.Vector2(mouse.X, mouse.Y);
+
+ io.MouseDown[0] = mouse.LeftButton == ButtonState.Pressed;
+ io.MouseDown[1] = mouse.RightButton == ButtonState.Pressed;
+ io.MouseDown[2] = mouse.MiddleButton == ButtonState.Pressed;
+
+ var scrollDelta = mouse.ScrollWheelValue - _scrollWheelValue;
+ io.MouseWheel = scrollDelta > 0 ? 1 : scrollDelta < 0 ? -1 : 0;
+ _scrollWheelValue = mouse.ScrollWheelValue;
+ }
+
+ #endregion Setup & Update
+
+ #region Internals
+
+ ///
+ /// Gets the geometry as set up by ImGui and sends it to the graphics device
+ ///
+ private unsafe void RenderDrawData(DrawData* drawData)
+ {
+ // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers
+ var lastViewport = _graphicsDevice.Viewport;
+ var lastScissorBox = _graphicsDevice.ScissorRectangle;
+
+ _graphicsDevice.BlendFactor = Color.White;
+ _graphicsDevice.BlendState = BlendState.NonPremultiplied;
+ _graphicsDevice.RasterizerState = _rasterizerState;
+ _graphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
+
+ // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays)
+ ImGui.ScaleClipRects(drawData, ImGui.GetIO().DisplayFramebufferScale);
+
+ // Setup projection
+ _graphicsDevice.Viewport = new Viewport(0, 0, _graphicsDevice.PresentationParameters.BackBufferWidth, _graphicsDevice.PresentationParameters.BackBufferHeight);
+
+ UpdateBuffers(drawData);
+
+ RenderCommandLists(drawData);
+
+ // Restore modified state
+ _graphicsDevice.Viewport = lastViewport;
+ _graphicsDevice.ScissorRectangle = lastScissorBox;
+ }
+
+ private unsafe void UpdateBuffers(DrawData* drawData)
+ {
+ // Expand buffers if we need more room
+ if (drawData->TotalVtxCount > _vertexBufferSize)
+ {
+ _vertexBuffer?.Dispose();
+
+ _vertexBufferSize = (int)(drawData->TotalVtxCount * 1.5f);
+ _vertexBuffer = new VertexBuffer(_graphicsDevice, DrawVertDeclaration.Declaration, _vertexBufferSize, BufferUsage.None);
+ _vertexData = new byte[_vertexBufferSize * DrawVertDeclaration.Size];
+ }
+
+ if (drawData->TotalIdxCount > _indexBufferSize)
+ {
+ _indexBuffer?.Dispose();
+
+ _indexBufferSize = (int)(drawData->TotalIdxCount * 1.5f);
+ _indexBuffer = new IndexBuffer(_graphicsDevice, IndexElementSize.SixteenBits, _indexBufferSize, BufferUsage.None);
+ _indexData = new byte[_indexBufferSize * sizeof(ushort)];
+ }
+
+ // Copy ImGui's vertices and indices to a set of managed byte arrays
+ int vtxOffset = 0;
+ int idxOffset = 0;
+
+ for (int n = 0; n < drawData->CmdListsCount; n++)
+ {
+ var cmdList = drawData->CmdLists[n];
+
+ fixed (void* vtxDstPtr = &_vertexData[vtxOffset * DrawVertDeclaration.Size])
+ fixed (void* idxDstPtr = &_indexData[idxOffset * sizeof(ushort)])
+ {
+ Buffer.MemoryCopy(cmdList->VtxBuffer.Data, vtxDstPtr, _vertexData.Length, cmdList->VtxBuffer.Size * DrawVertDeclaration.Size);
+ Buffer.MemoryCopy(cmdList->IdxBuffer.Data, idxDstPtr, _indexData.Length, cmdList->IdxBuffer.Size * sizeof(ushort));
+ }
+
+ vtxOffset += cmdList->VtxBuffer.Size;
+ idxOffset += cmdList->IdxBuffer.Size;
+ }
+
+ // Copy the managed byte arrays to the gpu vertex- and index buffers
+ _vertexBuffer.SetData(_vertexData, 0, drawData->TotalVtxCount * DrawVertDeclaration.Size);
+ _indexBuffer.SetData(_indexData, 0, drawData->TotalIdxCount * sizeof(ushort));
+ }
+
+ private unsafe void RenderCommandLists(DrawData* drawData)
+ {
+ _graphicsDevice.SetVertexBuffer(_vertexBuffer);
+ _graphicsDevice.Indices = _indexBuffer;
+
+ int vtxOffset = 0;
+ int idxOffset = 0;
+
+ for (int n = 0; n < drawData->CmdListsCount; n++)
+ {
+ var cmdList = drawData->CmdLists[n];
+
+ for (int cmdi = 0; cmdi < cmdList->CmdBuffer.Size; cmdi++)
+ {
+ var drawCmd = &(((DrawCmd*)cmdList->CmdBuffer.Data)[cmdi]);
+
+ if (!_loadedTextures.ContainsKey(drawCmd->TextureId)) throw new InvalidOperationException($"Could not find a texture with id '{drawCmd->TextureId}', please check your bindings");
+
+ _graphicsDevice.ScissorRectangle = new Rectangle(
+ (int)drawCmd->ClipRect.X,
+ (int)drawCmd->ClipRect.Y,
+ (int)(drawCmd->ClipRect.Z - drawCmd->ClipRect.X),
+ (int)(drawCmd->ClipRect.W - drawCmd->ClipRect.Y)
+ );
+
+ var effect = UpdateEffect(_loadedTextures[drawCmd->TextureId]);
+
+ foreach (var pass in effect.CurrentTechnique.Passes)
+ {
+ pass.Apply();
+
+#pragma warning disable CS0618 // // FNA does not expose an alternative method.
+ _graphicsDevice.DrawIndexedPrimitives(
+ primitiveType: PrimitiveType.TriangleList,
+ baseVertex: vtxOffset,
+ minVertexIndex: 0,
+ numVertices: cmdList->VtxBuffer.Size,
+ startIndex: idxOffset,
+ primitiveCount: (int)drawCmd->ElemCount / 3
+ );
+#pragma warning restore CS0618
+ }
+
+ idxOffset += (int)drawCmd->ElemCount;
+ }
+
+ vtxOffset += cmdList->VtxBuffer.Size;
+ }
+ }
+
+ #endregion Internals
+ }
+}
\ No newline at end of file
diff --git a/src/ImGui.NET.SampleProgram.XNA/Program.cs b/src/ImGui.NET.SampleProgram.XNA/Program.cs
new file mode 100644
index 0000000..4e1aeee
--- /dev/null
+++ b/src/ImGui.NET.SampleProgram.XNA/Program.cs
@@ -0,0 +1,10 @@
+namespace ImGuiNET.SampleProgram.XNA
+{
+ public static class Program
+ {
+ public static void Main(string[] args)
+ {
+ new SampleGame().Run();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ImGui.NET.SampleProgram.XNA/README.md b/src/ImGui.NET.SampleProgram.XNA/README.md
new file mode 100644
index 0000000..c64b329
--- /dev/null
+++ b/src/ImGui.NET.SampleProgram.XNA/README.md
@@ -0,0 +1,12 @@
+# ImGui.NET renderer for XNA-likes (FNA & MonoGame)
+
+To run this sample program:
+
+## MonoGame (default, NuGet package for "DesktopGL"-version already installed)
+- Download the SDL2 dll from https://www.libsdl.org/download-2.0.php and copy it to the project output directory
+
+## FNA
+- Remove the MonoGame.Framework.DesktopGL NuGet package
+- Download FNA from https://github.com/FNA-XNA/FNA/releases and add a reference to it
+- Download the native FNA dependencies from https://github.com/FNA-XNA/FNA/wiki/3:-Distributing-FNA-Games and copy them to the project output directory
+- Replace the marked MonoGame-specific parts of the code with their commented FNA counterparts (search for "FNA-specific")
diff --git a/src/ImGui.NET.SampleProgram.XNA/SampleGame.cs b/src/ImGui.NET.SampleProgram.XNA/SampleGame.cs
new file mode 100644
index 0000000..0596007
--- /dev/null
+++ b/src/ImGui.NET.SampleProgram.XNA/SampleGame.cs
@@ -0,0 +1,134 @@
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using System;
+using System.IO;
+using Num = System.Numerics;
+
+namespace ImGuiNET.SampleProgram.XNA
+{
+ ///
+ /// Simple FNA + ImGui example
+ ///
+ public class SampleGame : Game
+ {
+ private GraphicsDeviceManager _graphics;
+ private ImGuiRenderer _imGuiRenderer;
+
+ private Texture2D _xnaTexture;
+ private IntPtr _imGuiTexture;
+
+ public SampleGame()
+ {
+ _graphics = new GraphicsDeviceManager(this);
+ _graphics.PreferredBackBufferWidth = 1024;
+ _graphics.PreferredBackBufferHeight = 768;
+ _graphics.PreferMultiSampling = true;
+
+ IsMouseVisible = true;
+ }
+
+ protected override void Initialize()
+ {
+ _imGuiRenderer = new ImGuiRenderer(this);
+ _imGuiRenderer.RebuildFontAtlas();
+
+ base.Initialize();
+ }
+
+ protected override void LoadContent()
+ {
+ // Texture loading example
+
+ // First, load the texture as a Texture2D (can also be done using the XNA/FNA content pipeline)
+ _xnaTexture = Texture2D.FromStream(GraphicsDevice, GenerateImage(300, 150));
+
+ // Then, bind it to an ImGui-friendly pointer, that we can use during regular ImGui.** calls (see below)
+ _imGuiTexture = _imGuiRenderer.BindTexture(_xnaTexture);
+
+ base.LoadContent();
+ }
+
+ protected override void Draw(GameTime gameTime)
+ {
+ GraphicsDevice.Clear(new Color(clear_color.X, clear_color.Y, clear_color.Z));
+
+ // Call BeforeLayout first to set things up
+ _imGuiRenderer.BeforeLayout(gameTime);
+
+ // Draw our UI
+ ImGuiLayout();
+
+ // Call AfterLayout now to finish up and draw all the things
+ _imGuiRenderer.AfterLayout();
+
+ base.Draw(gameTime);
+ }
+
+ // Direct port of the example at https://github.com/ocornut/imgui/blob/master/examples/sdl_opengl2_example/main.cpp
+ private float f = 0.0f;
+
+ private bool show_test_window = false;
+ private bool show_another_window = false;
+ private Num.Vector3 clear_color = new Num.Vector3(114f / 255f, 144f / 255f, 154f / 255f);
+ private byte[] _textBuffer = new byte[100];
+
+ protected virtual void ImGuiLayout()
+ {
+ // 1. Show a simple window
+ // Tip: if we don't call ImGui.Begin()/ImGui.End() the widgets appears in a window automatically called "Debug"
+ {
+ ImGui.Text("Hello, world!");
+ ImGui.SliderFloat("float", ref f, 0.0f, 1.0f, null, 1f);
+ ImGui.ColorEdit3("clear color", ref clear_color);
+ if (ImGui.Button("Test Window")) show_test_window = !show_test_window;
+ if (ImGui.Button("Another Window")) show_another_window = !show_another_window;
+ ImGui.Text(string.Format("Application average {0:F3} ms/frame ({1:F1} FPS)", 1000f / ImGui.GetIO().Framerate, ImGui.GetIO().Framerate));
+
+ ImGui.InputText("Text input", _textBuffer, 100, InputTextFlags.Default, null);
+
+ ImGui.Text("Texture sample");
+ ImGui.Image(_imGuiTexture, new Num.Vector2(300, 150), Num.Vector2.Zero, Num.Vector2.One, Num.Vector4.One, Num.Vector4.One); // Here, the previously loaded texture is used
+ }
+
+ // 2. Show another simple window, this time using an explicit Begin/End pair
+ if (show_another_window)
+ {
+ ImGui.SetNextWindowSize(new Num.Vector2(200, 100), Condition.FirstUseEver);
+ ImGui.BeginWindow("Another Window", ref show_another_window, WindowFlags.Default);
+ ImGui.Text("Hello");
+ ImGui.EndWindow();
+ }
+
+ // 3. Show the ImGui test window. Most of the sample code is in ImGui.ShowTestWindow()
+ if (show_test_window)
+ {
+ ImGui.SetNextWindowPos(new Num.Vector2(650, 20), Condition.FirstUseEver);
+ ImGuiNative.igShowDemoWindow(ref show_test_window);
+ }
+ }
+
+ private static Stream GenerateImage(int width, int height)
+ {
+ var stream = new MemoryStream();
+ var random = new Random(42);
+
+ var bmp = new System.Drawing.Bitmap(width, height);
+ var graphics = System.Drawing.Graphics.FromImage(bmp);
+ graphics.Clear(System.Drawing.Color.Black);
+
+ for (int i = 0; i < 100; i++)
+ {
+ var size = random.Next(10, 50);
+ var pen = new System.Drawing.Pen(System.Drawing.Color.FromArgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255)), random.Next(1, 4));
+
+ graphics.DrawEllipse(pen, random.Next(0, width), random.Next(0, height), size, size);
+ }
+
+ bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
+
+ stream.Position = 0;
+
+ return stream;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ImGui.NET.sln b/src/ImGui.NET.sln
index 770d4ff..1a34b50 100644
--- a/src/ImGui.NET.sln
+++ b/src/ImGui.NET.sln
@@ -6,6 +6,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImGui.NET", "ImGui.NET\ImGu
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImGui.NET.SampleProgram", "ImGui.NET.SampleProgram\ImGui.NET.SampleProgram.csproj", "{D6F62D30-7A37-43A1-BD5B-BE9A3D6F964C}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImGui.NET.SampleProgram.XNA", "ImGui.NET.SampleProgram.XNA\ImGui.NET.SampleProgram.XNA.csproj", "{3024336E-9A19-475F-A95D-60A60C0B1C0D}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -40,6 +42,18 @@ Global
{D6F62D30-7A37-43A1-BD5B-BE9A3D6F964C}.Release|x64.Build.0 = Release|Any CPU
{D6F62D30-7A37-43A1-BD5B-BE9A3D6F964C}.Release|x86.ActiveCfg = Release|Any CPU
{D6F62D30-7A37-43A1-BD5B-BE9A3D6F964C}.Release|x86.Build.0 = Release|Any CPU
+ {3024336E-9A19-475F-A95D-60A60C0B1C0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3024336E-9A19-475F-A95D-60A60C0B1C0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3024336E-9A19-475F-A95D-60A60C0B1C0D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3024336E-9A19-475F-A95D-60A60C0B1C0D}.Debug|x64.Build.0 = Debug|Any CPU
+ {3024336E-9A19-475F-A95D-60A60C0B1C0D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3024336E-9A19-475F-A95D-60A60C0B1C0D}.Debug|x86.Build.0 = Debug|Any CPU
+ {3024336E-9A19-475F-A95D-60A60C0B1C0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3024336E-9A19-475F-A95D-60A60C0B1C0D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3024336E-9A19-475F-A95D-60A60C0B1C0D}.Release|x64.ActiveCfg = Release|Any CPU
+ {3024336E-9A19-475F-A95D-60A60C0B1C0D}.Release|x64.Build.0 = Release|Any CPU
+ {3024336E-9A19-475F-A95D-60A60C0B1C0D}.Release|x86.ActiveCfg = Release|Any CPU
+ {3024336E-9A19-475F-A95D-60A60C0B1C0D}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/ImGui.NET/IO.cs b/src/ImGui.NET/IO.cs
index 546ad3f..774586d 100644
--- a/src/ImGui.NET/IO.cs
+++ b/src/ImGui.NET/IO.cs
@@ -121,6 +121,15 @@ namespace ImGuiNET
set { _nativePtr->KeyAlt = value ? (byte)1 : (byte)0; }
}
+ ///
+ /// Keyboard modifier pressed: Cmd/Super/Windows
+ ///
+ public bool SuperPressed
+ {
+ get { return _nativePtr->KeySuper == 1; }
+ set { _nativePtr->KeySuper = value ? (byte)1 : (byte)0; }
+ }
+
public bool WantCaptureMouse
{
get { return _nativePtr->WantCaptureMouse == 1; }