-
-
Save dterracino/5676eb2c0ea124ea3dacc0eabf6a981d to your computer and use it in GitHub Desktop.
Example to hook up an SDL2 window to a Panel for use in a System.Windows.Forms window
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#region License | |
/* FNA GameWindow for System.Windows.Forms Example | |
* Written by Ethan "flibitijibibo" Lee | |
* http://www.flibitijibibo.com/ | |
* | |
* Released under public domain. | |
* No warranty implied; use at your own risk. | |
*/ | |
#endregion | |
#region Using Statements | |
using System; | |
using System.Threading; | |
using System.Runtime.InteropServices; | |
/* Bad awful Win32 Stuff */ | |
using System.Drawing; | |
using System.Windows.Forms; | |
using Point = System.Drawing.Point; | |
/* Good nice FNA Stuff */ | |
using SDL2; | |
using Microsoft.Xna.Framework; | |
using Color = Microsoft.Xna.Framework.Color; | |
#endregion | |
public class FNAWindowExample : Form | |
{ | |
#region FNA Game | |
class ExampleGame : Game | |
{ | |
public Color ClearColor; | |
GraphicsDeviceManager graphics; | |
public ExampleGame() : base() | |
{ | |
graphics = new GraphicsDeviceManager(this); | |
graphics.PreferredBackBufferWidth = 640; | |
graphics.PreferredBackBufferHeight = 480; | |
ClearColor = new Color(255, 255, 255, 255); | |
} | |
protected override void Draw(GameTime gameTime) | |
{ | |
GraphicsDevice.Clear(ClearColor); | |
} | |
} | |
#endregion | |
#region Private FNA Window/Control Variables | |
// These are the variables you care about. | |
private static ExampleGame game; | |
private Panel gamePanel; | |
private bool windowAttached = false; | |
#endregion | |
#region Private Variables | |
private Random random = new Random(); | |
#endregion | |
#region WinAPI Entry Points | |
[DllImport("user32.dll")] | |
private static extern IntPtr SetWindowPos( | |
IntPtr handle, | |
IntPtr handleAfter, | |
int x, | |
int y, | |
int cx, | |
int cy, | |
uint flags | |
); | |
[DllImport("user32.dll")] | |
private static extern IntPtr SetParent(IntPtr child, IntPtr newParent); | |
[DllImport("user32.dll")] | |
private static extern IntPtr ShowWindow(IntPtr handle, int command); | |
#endregion | |
#region Form Constructor | |
public FNAWindowExample() | |
{ | |
// This is what we're going to attach the SDL2 window to | |
gamePanel = new Panel(); | |
gamePanel.Size = new Size(640, 480); | |
gamePanel.Location = new Point(80, 10); | |
// Make the WinForms window | |
Size = new Size(800, 600); | |
FormClosing += new FormClosingEventHandler(WindowClosing); | |
Button button = new Button(); | |
button.Text = "Whatever"; | |
button.Location = new Point( | |
(Size.Width / 2) - (button.Size.Width / 2), | |
gamePanel.Location.Y + gamePanel.Size.Height + 10 | |
); | |
button.Click += new EventHandler(ClickedButton); | |
Controls.Add(button); | |
Controls.Add(gamePanel); | |
} | |
#endregion | |
#region Button Event Method | |
private void ClickedButton(object sender, EventArgs e) | |
{ | |
if (!windowAttached) | |
{ | |
// Make the Game, give it time to start up | |
new Thread(GameThread).Start(); | |
Thread.Sleep(1000); | |
// Get the Win32 HWND from the FNA window | |
SDL.SDL_SysWMinfo info = new SDL.SDL_SysWMinfo(); | |
SDL.SDL_GetWindowWMInfo(game.Window.Handle, ref info); | |
IntPtr winHandle = info.info.win.window; | |
// Move the SDL2 window to 0, 0 | |
game.Window.IsBorderlessEXT = true; | |
SetWindowPos( | |
winHandle, | |
Handle, | |
0, | |
0, | |
0, | |
0, | |
0x0401 // NOSIZE | SHOWWINDOW | |
); | |
// Attach the SDL2 window to the panel | |
SetParent(winHandle, gamePanel.Handle); | |
ShowWindow(winHandle, 1); // SHOWNORMAL | |
// We out. | |
windowAttached = true; | |
} | |
game.ClearColor = new Color( | |
(float) random.NextDouble(), | |
(float) random.NextDouble(), | |
(float) random.NextDouble(), | |
1.0f | |
); | |
} | |
#endregion | |
#region Window Close Method | |
private void WindowClosing(object sender, FormClosingEventArgs e) | |
{ | |
game.Exit(); | |
} | |
#endregion | |
#region Game Thread | |
// Run the Game in its own thread, to prevent GL ugliness | |
private static void GameThread() | |
{ | |
using (game = new ExampleGame()) | |
{ | |
game.Run(); | |
} | |
} | |
#endregion | |
#region Program Entry Point | |
[STAThread] | |
static void Main() | |
{ | |
Application.Run(new FNAWindowExample()); | |
} | |
#endregion | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#region License | |
/* SDL2 Window for System.Windows.Forms Example | |
* Written by Ethan "flibitijibibo" Lee | |
* http://www.flibitijibibo.com/ | |
* | |
* Released under public domain. | |
* No warranty implied; use at your own risk. | |
*/ | |
#endregion | |
#region Using Statements | |
using System; | |
using System.Drawing; | |
using System.Runtime.InteropServices; | |
using System.Windows.Forms; | |
using SDL2; | |
#endregion | |
public class SDL2WindowExample : Form | |
{ | |
#region Private SDL2 Window/Control Variables | |
// These are the variables you care about. | |
private Panel gamePanel; | |
private IntPtr gameWindow; // For FNA, this is Game.Window.Handle | |
#endregion | |
#region Private GL Variables | |
// IGNORE MEEEEE | |
private Random random; | |
private IntPtr glContext; | |
private delegate void Viewport(int x, int y, int width, int height); | |
private delegate void ClearColor(float r, float g, float b, float a); | |
private delegate void Clear(uint flags); | |
private Viewport glViewport; | |
private ClearColor glClearColor; | |
private Clear glClear; | |
#endregion | |
#region WinAPI Entry Points | |
[DllImport("user32.dll")] | |
private static extern IntPtr SetWindowPos( | |
IntPtr handle, | |
IntPtr handleAfter, | |
int x, | |
int y, | |
int cx, | |
int cy, | |
uint flags | |
); | |
[DllImport("user32.dll")] | |
private static extern IntPtr SetParent(IntPtr child, IntPtr newParent); | |
[DllImport("user32.dll")] | |
private static extern IntPtr ShowWindow(IntPtr handle, int command); | |
#endregion | |
#region Form Constructor | |
public SDL2WindowExample() | |
{ | |
// This is what we're going to attach the SDL2 window to | |
gamePanel = new Panel(); | |
gamePanel.Size = new Size(640, 480); | |
gamePanel.Location = new Point(80, 10); | |
// Make the WinForms window | |
Size = new Size(800, 600); | |
FormClosing += new FormClosingEventHandler(WindowClosing); | |
Button button = new Button(); | |
button.Text = "Whatever"; | |
button.Location = new Point( | |
(Size.Width / 2) - (button.Size.Width / 2), | |
gamePanel.Location.Y + gamePanel.Size.Height + 10 | |
); | |
button.Click += new EventHandler(ClickedButton); | |
Controls.Add(button); | |
Controls.Add(gamePanel); | |
// IGNORE MEEEEE | |
random = new Random(); | |
SDL.SDL_Init(SDL.SDL_INIT_VIDEO); | |
gameWindow = SDL.SDL_CreateWindow( | |
String.Empty, | |
0, | |
0, | |
gamePanel.Size.Width, | |
gamePanel.Size.Height, | |
SDL.SDL_WindowFlags.SDL_WINDOW_BORDERLESS | SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | |
); | |
glContext = SDL.SDL_GL_CreateContext(gameWindow); | |
glViewport = (Viewport) Marshal.GetDelegateForFunctionPointer( | |
SDL.SDL_GL_GetProcAddress("glViewport"), | |
typeof(Viewport) | |
); | |
glClearColor = (ClearColor) Marshal.GetDelegateForFunctionPointer( | |
SDL.SDL_GL_GetProcAddress("glClearColor"), | |
typeof(ClearColor) | |
); | |
glClear = (Clear) Marshal.GetDelegateForFunctionPointer( | |
SDL.SDL_GL_GetProcAddress("glClear"), | |
typeof(Clear) | |
); | |
glViewport(0, 0, gamePanel.Size.Width, gamePanel.Size.Height); | |
glClearColor(1.0f, 0.0f, 0.0f, 1.0f); | |
glClear(0x4000); | |
SDL.SDL_GL_SwapWindow(gameWindow); | |
// Get the Win32 HWND from the SDL2 window | |
SDL.SDL_SysWMinfo info = new SDL.SDL_SysWMinfo(); | |
SDL.SDL_GetWindowWMInfo(gameWindow, ref info); | |
IntPtr winHandle = info.info.win.window; | |
// Move the SDL2 window to 0, 0 | |
SetWindowPos( | |
winHandle, | |
Handle, | |
0, | |
0, | |
0, | |
0, | |
0x0401 // NOSIZE | SHOWWINDOW | |
); | |
// Attach the SDL2 window to the panel | |
SetParent(winHandle, gamePanel.Handle); | |
ShowWindow(winHandle, 1); // SHOWNORMAL | |
} | |
#endregion | |
#region Button Event Method | |
private void ClickedButton(object sender, EventArgs e) | |
{ | |
glClearColor( | |
(float) random.NextDouble(), | |
(float) random.NextDouble(), | |
(float) random.NextDouble(), | |
1.0f | |
); | |
glClear(0x4000); // GL_COLOR_BUFFER_BIT | |
SDL.SDL_GL_SwapWindow(gameWindow); | |
} | |
#endregion | |
#region Window Close Method | |
private void WindowClosing(object sender, FormClosingEventArgs e) | |
{ | |
glClear = null; | |
glClearColor = null; | |
glViewport = null; | |
SDL.SDL_GL_DeleteContext(glContext); | |
glContext = IntPtr.Zero; | |
SDL.SDL_DestroyWindow(gameWindow); | |
gameWindow = IntPtr.Zero; | |
SDL.SDL_Quit(); | |
} | |
#endregion | |
#region Program Entry Point | |
[STAThread] | |
static void Main() | |
{ | |
Application.Run(new SDL2WindowExample()); | |
} | |
#endregion | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment