-
-
Save flibitijibibo/cf282bfccc1eaeb47550 to your computer and use it in GitHub Desktop.
#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 | |
} |
#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 | |
} |
@Goicox FNA is a reimplementation of XNA, so you can use the docs and tutorials for it. SDL2-CS is just a thin wrapper, the API is pretty much the same as the C version, so you can use the same docs.
Hello everyone,
// REMOVE:
Because it doesn't work for WinAPI. Only X11 works as well if you add child window in SDL2 Only FreeBSD and Linux are successful with child windows, And macOS and Windows won't work because they don't have child window inside SDl2.
That is why - It is bad news for Windows 10 and macOS ( I am not sure if NS_Panel pops up from child of SDL2 like X11. But I don't see that. ??? )
// UPDATE:
It is simple button clicks with scene switchers:
https://gist.github.com/DeafMan1983/86934b03b701de37a39acb0163ce391a
Enjoy and understand how do you switch scenes of screen of game app!
Thanks regards!
Where could I find more examples for using this library? Goicox