Embedding SDL2 into a child wxWindow

Do you have a typical platform dependent issue you're battling with ? Ask it here. Make sure you mention your platform, compiler, and wxWidgets version.
Post Reply
Fuujinn
In need of some credit
In need of some credit
Posts: 2
Joined: Mon Dec 28, 2020 5:28 am

Embedding SDL2 into a child wxWindow

Post by Fuujinn »

Hello everyone :)

I'm currently attempting to embed an SDL2 Window/Renderer inside a child wxWindow. After some digging around I managed to retrieve the X11 handle from that child wxWindow, and use it inside SDL_CreateWindowFrom(), and therefore also create a renderer via SDL_CreateRenderer().
The code compiles and executes without any crashes, the SDL window and renderer get created with no issues, however nothing is being rendered on the wxWindow child...

Here is a snippet of the code which shows the initialization of the wxWindow child with respect to a wxFrame parent (aka the top level window):

Code: Select all

PPU::PPU(wxFrame* parent, Memory* mem) : wxWindow(parent, wxID_ANY, wxPoint(0, 0), parent->GetSize())
{
    WXWidget widget = GetHandle();
#ifdef FUUGB_SYSTEM_LINUX
    GdkWindow* gdkWindow = gtk_widget_get_window(widget);
    XID x11Handle = GDK_WINDOW_XID(gdkWindow);
    sdlWindow = SDL_CreateWindowFrom((void*)x11Handle);
#endif
    if (sdlWindow == NULL) {
        wxPrintf("Error occured during SDL window creation: %s\n", SDL_GetError());
        SDL_Quit();
        wxExit();
    }

    renderer = SDL_GetRenderer(sdlWindow);

    if (renderer == NULL) {
        if (!(renderer = SDL_CreateRenderer(sdlWindow, -1, SDL_RENDERER_SOFTWARE))) {
            wxPrintf("Error occured during renderer creation: %s\n", SDL_GetError());
            SDL_Quit();
            wxExit();
        }
    }
 ...
Something that I noticed is that if I simply use the parent wxFrame instead, the rendering DOES occur...
Here is the code snippet which works (but is not desireable):

Code: Select all

PPU::PPU(wxFrame* parent, Memory* mem)
{
    WXWidget widget = parent->GetHandle();
#ifdef FUUGB_SYSTEM_LINUX
    GdkWindow* gdkWindow = gtk_widget_get_window(widget);
    XID x11Handle = GDK_WINDOW_XID(gdkWindow);
    sdlWindow = SDL_CreateWindowFrom((void*)x11Handle);
#endif
...
I'd prefer not using the parent wxFrame to render in, simply because SDL renders on top of the menubar... (I could simply tell SDL to start rendering at a hardcoded y offset, but that just seems like a band-aid solution...)

Would anyone know why the rendering is not occuring on the wxWindow child? I've debugged the program and it seems like everything is running fine on the SDL2 side, so i'm suspecting i'm missing a crucial call from the wxWidgets library side...

Here are the details of my environment:

wxWidgets 3.0.5 with GTK+-3.0
Ubuntu 20.04 LTS
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Embedding SDL2 into a child wxWindow

Post by doublemax »

Code: Select all

PPU::PPU(wxFrame* parent, Memory* mem) : wxWindow(parent, wxID_ANY, wxPoint(0, 0), parent->GetSize())
Did you confirm that parent->GetSize() returns valid values at this point? Try a hard-coded size for testing.

Try setting a different background color for this window, so you can see if it's actually visible.
Use the source, Luke!
Fuujinn
In need of some credit
In need of some credit
Posts: 2
Joined: Mon Dec 28, 2020 5:28 am

Re: Embedding SDL2 into a child wxWindow

Post by Fuujinn »

Found the issue, and its a total face palm moment. #-o

The wxWindow child was being initialized and added to the parent wxFrame AFTER the initial call to wxFrame->Show()...

Changed the code to now add the wxWindow child to the wxFrame parent BEFORE the call to wxFrame->Show() and it works flawlessly!
doublemax wrote: Mon Dec 28, 2020 9:48 am

Code: Select all

PPU::PPU(wxFrame* parent, Memory* mem) : wxWindow(parent, wxID_ANY, wxPoint(0, 0), parent->GetSize())
Did you confirm that parent->GetSize() returns valid values at this point? Try a hard-coded size for testing.

Try setting a different background color for this window, so you can see if it's actually visible.
Yup, I am getting valid dimensions from the call to GetSize(). One thing that is odd though is that calling SetBackgroundColor() with those iterations of the code did work, but SDL was not able to render to it if it was added after the initial Show() call...

Thank you for the insights :D
Post Reply