Recent

Author Topic: Creating a SDL child window on a form or panel control?  (Read 696 times)

sysrpl

  • Sr. Member
  • ****
  • Posts: 315
    • Get Lazarus
Creating a SDL child window on a form or panel control?
« on: July 03, 2022, 03:44:31 pm »
I am attempting to use SDL2 on Linux (gtk2 widgetset) to create an OpenGL window inside a child control. I got the idea or impression that this was possible using the SDL_CreateWindowFrom function of SDL2, but all execution stops when I call the function.

Here is a bit of code from my TEmbedWindow class that is attempting to wrap a control / SDL OpenGL together in a class.

Does anyone have any suggestions as to how to get this working? Currently when the line with SDL_CreateWindowFrom  is reached, my program just exits.

Thank you for any suggestions you might have.

Code: Pascal  [Select][+][-]
  1. function TEmbedWindow.Start: Boolean;
  2. var
  3.   W: TXID;
  4. begin
  5.   Result := False;
  6.   // FAssociate is a TWinControl and has a x windows handle
  7.   if FAssociate = nil then
  8.     Exit;
  9.   // I have also tried with just SDL_INIT_VIDEO or SDL_INIT_TIMER
  10.   if SDL_Init(SDL_INIT_EVERYTHING) < 0 then
  11.     Exit;
  12.   // Configure the OpenGL context request
  13.   SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
  14.   SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  15.   SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
  16.   SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
  17.   SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,      SDL_GL_CONTEXT_PROFILE_ES);
  18.   // This gets the x window handle from a gtk2 based control
  19.   W := GDK_WINDOW_XWINDOW(PGtkWidget(PtrUInt(FAssociate.Handle))^.window);
  20.   // This line stops all execution
  21.   FWindow := SDL_CreateWindowFrom(Pointer(W));
  22.   // The program exits from the line above
  23.   if FWindow = nil then
  24.     Exit;
  25.   FCtx := SDL_GL_CreateContext(FWindow);
  26.   if FCtx = nil then
  27.     Exit;
  28.   SDL_GL_MakeCurrent(FWindow, FCtx);
  29.   FStarted := LoadGL(SDL_GL_GetProcAddress);
  30.   Result := FStarted;
  31. end;
  32.  

hukka

  • New Member
  • *
  • Posts: 30
    • Github
Re: Creating a SDL child window on a form or panel control?
« Reply #1 on: July 03, 2022, 07:46:30 pm »
I haven't tried this on Linux, but on Windows I can successfully embed SDL2 into a TPanel with
Code: Pascal  [Select][+][-]
  1. SDL_CreateWindowFrom(Pointer(HostPanel.Handle));

Aistis

  • New Member
  • *
  • Posts: 10
Re: Creating a SDL child window on a form or panel control?
« Reply #2 on: February 12, 2024, 05:24:10 pm »
Sorry for bumping this thread. This was one of the first results I got when searching for this exact problem, and I want to share my findings that I manged to figure out during the last 24 hours.

I believe it's safe to assume that Windows and Linux draws things differently. As mentioned above, on Windows you could just pass a handle to a TPanel and it'd use it as an SDL window to draw things. However that's not the case for Linux.

From the (extremely little!) testing that I did, I found out that the (possibly) only way you can successfully draw onto a GTK form is by drawing to a TOpenGLControl from the LazOpenGLContext package.

Trying to draw to a TPanel (the Windows way) ends up in failure, as the program closes at the SDL_CreateWindowFrom function call with an error from X11 complaining about it being provided a bad window.

If I use additional function calls to get the correct pointer as mentioned in the 1st post (GDK_WINDOW_XWINDOW( PGtkWidget( PtrUInt( FAssociate.Handle ))^.window );), it does render to some controls, but the controls then repaint themselves to their default programmed look.

However, when passing the TOpenGLControl.Handle, said control gets used as an SDL window and you can actually draw to it.

Relevant units (don't forget to add LazOpenGLContext to your project's dependencies):
Code: Pascal  [Select][+][-]
  1. uses
  2.   {$IFDEF UNIX}
  3.   gtk2, gdk2x,
  4.   {$ENDIF}
  5.   OpenGLContext, SDL2;
  6.  
Relevant code:
Code: Pascal  [Select][+][-]
  1. var
  2.   OpenGLControl: TOpenGLControl;
  3.   sdlWindow1: PSDL_Window;
  4.  
  5. ...
  6.  
  7. {$IFDEF MSWINDOWS}
  8. sdlWindow1 := SDL_CreateWindowFrom(Pointer(OpenGLControl.Handle));
  9. {$ENDIF}
  10. {$IFDEF UNIX}
  11. sdlWindow1 := SDL_CreateWindowFrom(
  12.   Pointer(GDK_WINDOW_XWINDOW(
  13.     PGtkWidget(PtrUInt(OpenGLControl.Handle))^.window)
  14.   )
  15. );
  16. {$ENDIF}
  17.  

It works for me on Linux Mint (under X11), Windows, and I tried with a VM of a Debian install running Wayland too (image attached bellow).

I'm also attaching the demo project.
« Last Edit: February 12, 2024, 07:34:13 pm by Aistis »

Seenkao

  • Hero Member
  • *****
  • Posts: 549
    • New ZenGL.
Re: Creating a SDL child window on a form or panel control?
« Reply #3 on: February 12, 2024, 05:45:13 pm »
FWindow := SDL_CreateWindowFrom(@W);
???
Rus: Стремлюсь к созданию минимальных и достаточно быстрых приложений.

Eng: I strive to create applications that are minimal and reasonably fast.
Working on ZenGL

 

TinyPortal © 2005-2018