C++ 混合(本机托管)+sdl + opengl & c# winforms
C++ hybrid (native managed) +sdl + opengl & c# winforms
我正在开发一个交互式渲染软件,在用 C++ 编写的 sdl 中使用 opengl。
项目不断发展,我想有一个 HIM/GUI 来操纵我的渲染引擎。
所以我开始搜索一些 easy/fast HIM 编码方法来做到这一点。
最后我决定使用 winforms 和 c# 来创建 HIM,因为它提供了一种轻松设计和编码 HIM 的方法。
起初我开始使用本机和托管 C++ 创建混合 dll。好的。
在我尝试在 c# 应用程序中使用此 dll 之后。好的。
现在我的目标是:在 winforms 应用程序中插入 opengl 渲染。
我的问题是:
- 我可以将 SDLcontext/SDLwindows(C++) 绑定到 winforms 对象吗?
- 我可以将 c# 位图绑定到我的 dll 中的字节数组吗? (旨在通过dll更新它的像素)
- 如果可以:我是否必须调用一个函数来在像素更改时刷新我的 GUI (winforms)?
- 您认为放弃 SDL 并仅使用 winforms 来完成此类工作会很有趣吗?
- 有什么建议吗?
编辑:添加有关我的调查的信息
感谢 Lawrence Kok,我继续我的研究。
所以我尝试将我的 SDL windows 绑定到面板表单
private void LaunchEngine(string str)
{
unsafe
{
byte[] bytes = Encoding.ASCII.GetBytes(str);
sbyte[] sbyt = (sbyte[])(Array)bytes;
fixed (sbyte* p = sbyt)
{
// Engine is a managed class that bridge my c++ to c#
// all it's function are static
Engine.LOAD_CONTENT_FROM_FILE(p);
Engine.PRINTCONFIGURATION();
if (Engine.LOAD_ENGINE_DATA() && Engine.INITIALISE_ENGINE_DATA())
{
// Bind attempt here
_SdlWindowHandle = Engine.GETHANDLE();
SetWindowPos(_SdlWindowHandle, this.Handle, 0, 0, 0, 0, (SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_SHOWWINDOW));
// Make the SDL Window the child of our Panel
SetParent(_SdlWindowHandle, m_SdlPanel.Handle);
ShowWindow(_SdlWindowHandle, ShowWindowCommand.SW_SHOWNORMAL);
// In futur i will put this loop in another thread
// but for now I'm trying to validate my prototype
for (; ; )
{
Engine.UPDATE_ENGINE_DATA();
Engine.DRAW_ENGINE_DATA();
}
}
}
}
实际上,更改我的sdl windows的父级,关闭它,我的引擎是运行,但我的面板是完全空白的。
我想我在这里遗漏了一些东西,但我不知道是什么。
这是我如何获得 SDL window 句柄(来自 SDL2)
// coming from c++ native library
// and represent by Engine.GETHANDLE();
// from managed c++ lib
HWND SDLWindowManager::GetHandle()
{
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
/*if (SDL_GetWMInfo(&info) < 0)
return 0;*/
SDL_GetWindowWMInfo(_mainWindow, &info);
return info.info.win.window;
}
编辑:问题已解决
我忘记将面板添加到 winforms 控件中:
public Form1()
{
InitializeComponent();
m_SdlPanel = new Panel();
m_SdlPanel.Size = new Size(512, 512);
m_SdlPanel.Location = new Point(0, 0);
Controls.Add(m_SdlPanel);
}
鉴于您的目标平台是 Windows,有一种非常简单的方法可以将您的 opengl 渲染插入到您的 windows 表单应用程序中。你可以简单地用你最喜欢的选择包、sdl、sfml、纯 winapi 代码制作一个 window。当你获取到有问题的window的句柄时,只需更改window的样式,使其成为子window,并将其作为window的子window您的 window 选择。至于父 window,我喜欢做的是为此目的对特殊面板类型控件进行子类化。
之后您就可以正常使用控件的组合了。只有空域问题可能会影响演示文稿(https://msdn.microsoft.com/en-us/library/aa970688%28v=vs.110%29.aspx)。
我正在开发一个交互式渲染软件,在用 C++ 编写的 sdl 中使用 opengl。 项目不断发展,我想有一个 HIM/GUI 来操纵我的渲染引擎。
所以我开始搜索一些 easy/fast HIM 编码方法来做到这一点。 最后我决定使用 winforms 和 c# 来创建 HIM,因为它提供了一种轻松设计和编码 HIM 的方法。
起初我开始使用本机和托管 C++ 创建混合 dll。好的。 在我尝试在 c# 应用程序中使用此 dll 之后。好的。
现在我的目标是:在 winforms 应用程序中插入 opengl 渲染。
我的问题是:
- 我可以将 SDLcontext/SDLwindows(C++) 绑定到 winforms 对象吗?
- 我可以将 c# 位图绑定到我的 dll 中的字节数组吗? (旨在通过dll更新它的像素)
- 如果可以:我是否必须调用一个函数来在像素更改时刷新我的 GUI (winforms)?
- 您认为放弃 SDL 并仅使用 winforms 来完成此类工作会很有趣吗?
- 有什么建议吗?
编辑:添加有关我的调查的信息
感谢 Lawrence Kok,我继续我的研究。
所以我尝试将我的 SDL windows 绑定到面板表单
private void LaunchEngine(string str)
{
unsafe
{
byte[] bytes = Encoding.ASCII.GetBytes(str);
sbyte[] sbyt = (sbyte[])(Array)bytes;
fixed (sbyte* p = sbyt)
{
// Engine is a managed class that bridge my c++ to c#
// all it's function are static
Engine.LOAD_CONTENT_FROM_FILE(p);
Engine.PRINTCONFIGURATION();
if (Engine.LOAD_ENGINE_DATA() && Engine.INITIALISE_ENGINE_DATA())
{
// Bind attempt here
_SdlWindowHandle = Engine.GETHANDLE();
SetWindowPos(_SdlWindowHandle, this.Handle, 0, 0, 0, 0, (SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_SHOWWINDOW));
// Make the SDL Window the child of our Panel
SetParent(_SdlWindowHandle, m_SdlPanel.Handle);
ShowWindow(_SdlWindowHandle, ShowWindowCommand.SW_SHOWNORMAL);
// In futur i will put this loop in another thread
// but for now I'm trying to validate my prototype
for (; ; )
{
Engine.UPDATE_ENGINE_DATA();
Engine.DRAW_ENGINE_DATA();
}
}
}
}
实际上,更改我的sdl windows的父级,关闭它,我的引擎是运行,但我的面板是完全空白的。
我想我在这里遗漏了一些东西,但我不知道是什么。
这是我如何获得 SDL window 句柄(来自 SDL2)
// coming from c++ native library
// and represent by Engine.GETHANDLE();
// from managed c++ lib
HWND SDLWindowManager::GetHandle()
{
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
/*if (SDL_GetWMInfo(&info) < 0)
return 0;*/
SDL_GetWindowWMInfo(_mainWindow, &info);
return info.info.win.window;
}
编辑:问题已解决
我忘记将面板添加到 winforms 控件中:
public Form1()
{
InitializeComponent();
m_SdlPanel = new Panel();
m_SdlPanel.Size = new Size(512, 512);
m_SdlPanel.Location = new Point(0, 0);
Controls.Add(m_SdlPanel);
}
鉴于您的目标平台是 Windows,有一种非常简单的方法可以将您的 opengl 渲染插入到您的 windows 表单应用程序中。你可以简单地用你最喜欢的选择包、sdl、sfml、纯 winapi 代码制作一个 window。当你获取到有问题的window的句柄时,只需更改window的样式,使其成为子window,并将其作为window的子window您的 window 选择。至于父 window,我喜欢做的是为此目的对特殊面板类型控件进行子类化。
之后您就可以正常使用控件的组合了。只有空域问题可能会影响演示文稿(https://msdn.microsoft.com/en-us/library/aa970688%28v=vs.110%29.aspx)。