Last active
October 22, 2019 14:51
-
-
Save aleksas/06d6c300d1f01cea5f96cd7b3d8e6a76 to your computer and use it in GitHub Desktop.
C# SDL2 Panel control wrapping SDL2 window. Based on this snippet: https://gist.github.com/flibitijibibo/cf282bfccc1eaeb47550.
This file contains hidden or 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
| using SDL2; | |
| using System; | |
| using System.ComponentModel; | |
| using System.Runtime.InteropServices; | |
| using System.Windows.Forms; | |
| namespace DesktopApp1 | |
| { | |
| class SDL2Panel : Panel | |
| { | |
| #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", SetLastError = true)] | |
| public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); | |
| [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 Private Variables | |
| 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 Private SDL2 Window/Control Handles | |
| private IntPtr gameWindow; | |
| private IntPtr winHandle; | |
| #endregion | |
| private bool InDesignerMode | |
| { | |
| get | |
| { | |
| return LicenseManager.UsageMode == LicenseUsageMode.Designtime || DesignMode; | |
| } | |
| } | |
| private void InitializeSDLWindow() | |
| { | |
| if (!InDesignerMode) | |
| { | |
| SDL.SDL_Init(SDL.SDL_INIT_VIDEO); | |
| gameWindow = SDL.SDL_CreateWindow( | |
| String.Empty, | |
| 0, | |
| 0, | |
| Size.Width, | |
| Size.Height, | |
| SDL.SDL_WindowFlags.SDL_WINDOW_BORDERLESS | SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL// | SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE | |
| ); | |
| 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, Size.Width, 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); | |
| 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, Handle); | |
| ShowWindow(winHandle, 1); // SHOWNORMAL | |
| } | |
| } | |
| private void SDL2Panel_Resize1(object sender, EventArgs e) | |
| { | |
| throw new NotImplementedException(); | |
| } | |
| public SDL2Panel() | |
| { | |
| HandleDestroyed += SDL2Panel_HandleDestroyed; | |
| Resize += SDL2Panel_Resize; | |
| InitializeSDLWindow(); | |
| } | |
| public void ReandomColor() | |
| { | |
| var random = new Random(); | |
| glClearColor( | |
| (float)random.NextDouble(), | |
| (float)random.NextDouble(), | |
| (float)random.NextDouble(), | |
| 1.0f | |
| ); | |
| glClear(0x4000); // GL_COLOR_BUFFER_BIT | |
| SDL.SDL_GL_SwapWindow(gameWindow); | |
| } | |
| private void SDL2Panel_Resize(object sender, EventArgs e) | |
| { | |
| if (!InDesignerMode) | |
| { | |
| SDL.SDL_SetWindowSize(gameWindow, Size.Width, Size.Height); | |
| MoveWindow(winHandle, 0, 0, Size.Width, Size.Height, true); | |
| glViewport(0, 0, Size.Width, Size.Height); | |
| glClear(0x4000); // GL_COLOR_BUFFER_BIT | |
| SDL.SDL_GL_SwapWindow(gameWindow); | |
| } | |
| } | |
| private void SDL2Panel_HandleDestroyed(object sender, EventArgs e) | |
| { | |
| if (!InDesignerMode) | |
| { | |
| glClear = null; | |
| glClearColor = null; | |
| glViewport = null; | |
| SetParent(winHandle, IntPtr.Zero); | |
| SDL.SDL_GL_DeleteContext(glContext); | |
| glContext = IntPtr.Zero; | |
| SDL.SDL_DestroyWindow(gameWindow); | |
| gameWindow = IntPtr.Zero; | |
| SDL.SDL_Quit(); | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment