1
votes

I'm working on a interactive rendering software using opengl in sdl written in c++. The project evolving, I wanted to have a HIM/GUI to manipulate my rendering engine.

So I started to search some easy/fast HIM coding ways to do it. Finnaly I decided to use winforms and c# to create HIM, because its offer a way to design and code easily a HIM.

At first i started to create an hybrid dll with native and managed c++. OK. After I try to use this dll inside a c# application. OK.

Now my goal is: insert the opengl rendering inside the winforms application.

My questions are:

  • Can I bind my SDLcontext/SDLwindows(C++) to a winforms object?
  • Can I bind a c# bitmap to an array of byte from my dll ? (aim to update pixels of it by the dll)
    • if ok: do I have to call a function to refresh my GUI(winforms) on pixel change ?
  • Do you think it will be interesting to drop SDL and use only winforms for this kind of work ?
  • Any suggestion ?

EDIT: add information about my investigation

Thanks to Lawrence Kok I pursue my research.

So I tried to bind my SDL windows to a Panel form

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();
        }
      }
    }
  }

Actually, the change the parent of my sdl windows, close it, and my engine is running, but my panel is completely blank.

I think I'm missing something here but i can't figured what.

here is how i get the SDL window handle (from 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;
}

EDIT: problem solved

I forget to add the panel to winforms control:

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);
}
1
I don't know SDL, but you can definitely get a handle to a WinForms object, so you should be able to use the handle value in SDL. As for the bitmap, yes you can manipulate the pixels, there are several questions here on this topic.Lucas Trzesniewski

1 Answers

0
votes

Given that your target platform is Windows, there is a very easy way to insert your opengl rendering into your windows form application. You can simply make a window with your favorite package of choice, sdl, sfml, plain winapi code. When you obtain the handle of the window in question, just change the style of the window so that it becomes a child window, and put it as a child window of your window of choice. As for the parent window, what I like to do is subclass special panel-type control for this purpose.

After that you can just use the composition of the controls as normal. Only the airspace problems might influence the presentation (https://msdn.microsoft.com/en-us/library/aa970688%28v=vs.110%29.aspx).