整体思路
- 创建 OpenGL 窗体
- 获取 OpenGL 窗体 句柄
- 将 OpenGL 窗体 嵌入 Winform Panel 控件中
定义 OpenGL 窗体
public partial class MainForm : Form
{
private static IWindow? _window;
public MainForm()
{
InitializeComponent();
}
}
创建 OpenGL 窗体
设置创建时参数,并绑定窗体 Load 事件
private void Create_OpenGL_Window()
{
WindowOptions options = WindowOptions.Default with
{
Size = new Vector2D<int>(panel_render.Width, panel_render.Height),
Title = "My first Silk.NET application!"
};
_window = Window.Create(options);
_window.Load += OpenGL_Window_Load;
_window.Run();
}
public void OpenGL_Window_Load()
{
if (_window != null)
{
// 将 OpenGL 窗口嵌入 Panel
EmbedGlfwWindowIntoPanel(_window, panel_render.Handle);
}
}
将 OpenGL 窗体 嵌入 Winform Panel 控件中
// 将 OpenGL 窗口嵌入 Panel
private void EmbedGlfwWindowIntoPanel(IWindow glWindow, IntPtr panelHandle)
{
string windowTitle = glWindow.Title;
IntPtr hwnd = Win32.FindWindow(null, windowTitle);
//IntPtr hwnd = glWindow.Handle;
if (hwnd != IntPtr.Zero)
{
Win32.SetParent(hwnd, panelHandle);
Win32.SetWindowLong(hwnd, Win32.GWL_STYLE, Win32.WS_VISIBLE | Win32.WS_CHILD);
Win32.MoveWindow(hwnd, 0, 0, panel_render.Width, panel_render.Height, true);
}
else
{
MessageBox.Show("Failed to find GLFW window handle.");
}
}
// Win32 API 互操作
public static class Win32
{
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll")]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
public const int GWL_STYLE = -16;
public const int WS_CHILD = 0x40000000;
public const int WS_VISIBLE = 0x10000000;
}
posted on
浙公网安备 33010602011771号