The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
SDL transparent primary surface (main window) ?
meuchel


Joined: 23 Jul 2014
Posts: 6
Hi,
is it possible to have a transparent background in the main window with SDL2?
So that if the SDL main window is running in foreground its still possible to see whats going on in the windows of the background programs.

Thx
Pat
meuchel


Joined: 23 Jul 2014
Posts: 6
no one knows?

I found this GL sample to manage transparent background which works but I have no idea how to adapt this with SDL2.
https://gist.github.com/je-so/903479

I tried the following in the render function:
Instead of SDL_RenderClear(mRenderer) I've added

// Create an OpenGL context associated with the window.
SDL_GLContext glcontext = SDL_GL_CreateContext(mWindow);
// now you can make GL calls.
glClearColor( 0.7, 0.7, 0.7, 0.7) ; // light gray bg
glClear(GL_COLOR_BUFFER_BIT);
// Once finished with OpenGL functions, the SDL_GLContext can be deleted.
SDL_GL_DeleteContext(glcontext);
... and finally
SDL_RenderPresent(mRenderer);

In principle it works, the bg will be shown light gray but unfortunatly solid instead of transparent.
What I missed (couldn't archive it from the sample)?
Above GL stuff seems nothing other than SDL_SetRenderDrawColor(renderer, 0xC0, 0xC, 0xC, 127) which also didn't helped to make it transparent.
I assume that there is maybe a OS dependent hack neecessary e.g. in SDL_X11window.c ?
I use to get it to work with Ubuntu 14.04 LTS.
Any help would be fine. Sad
meuchel


Joined: 23 Jul 2014
Posts: 6
I thought I would find here SDL specialists with a solution... Wink

Because I got no answer I solved it myself with help of regular SDL_CreateWindowFrom and share it with you.
Its not perfect but it works for me under Ubuntu.
It works only with GL. Another bad thing is that the window doesn't post SDL events.
On the fly I couldn't find a solution to manage this.
Maybe someone other can tell how this can be done.
Meanwhile below you will find too how to handle X events.

Add this variables to your App class or whereever
Code:
Window        mXWindow;
Display*      mXDisplay;

Here is the custom SDL create window function with transparent background.
Code:
SDL_Window* App::SDL_CreateTransparentWindow(const char* title, int x, int y, int w, int h)
{
    /*Window mXWindow;*/
    /*Display*/ mXDisplay = XOpenDisplay(0);
    const char* xserver = getenv("DISPLAY");

    if (mXDisplay == 0)
    {
        printf("Could not establish a connection to X-server '%s'\n", xserver );
        exit(1) ;
    }

    // query Visual for "TrueColor" and 32 bits depth (RGBA)
    XVisualInfo visualinfo;
    XMatchVisualInfo(mXDisplay, DefaultScreen(mXDisplay), 32, TrueColor, &visualinfo);

    // create window
    GC gc;
    XSetWindowAttributes attr;
    attr.colormap   = XCreateColormap(mXDisplay, DefaultRootWindow(mXDisplay), visualinfo.visual, AllocNone);
    attr.event_mask = ExposureMask | KeyPressMask;
    attr.background_pixmap = None;
    attr.border_pixel = 0;

    mXWindow = XCreateWindow(mXDisplay, DefaultRootWindow(mXDisplay),
                        x, y, w, h, // x,y,width,height : are possibly opverwriteen by window manager
                        0,
                        visualinfo.depth,
                        InputOutput,
                        visualinfo.visual,
                        CWColormap|CWEventMask|CWBackPixmap|CWBorderPixel,
                        &attr);
    gc = XCreateGC(mXDisplay, mXWindow, 0, 0);

    // set title bar name of window
    XStoreName(mXDisplay, mXWindow, title);

    // say window manager which position we would prefer
    XSizeHints sizehints ;
    sizehints.flags = PPosition | PSize;
    sizehints.x     = x ;  sizehints.y = y;
    sizehints.width = w ; sizehints.height = h;
    XSetWMNormalHints(mXDisplay, mXWindow, &sizehints);

    // Switch On >> If user pressed close key let window manager only send notification >>
    Atom wm_delete_window = XInternAtom(mXDisplay, "WM_DELETE_WINDOW", 0);
    XSetWMProtocols(mXDisplay, mXWindow, &wm_delete_window, 1);

    // create OpenGL context
    GLXContext glcontext = glXCreateContext(mXDisplay, &visualinfo, 0, True) ;

    if (!glcontext)
    {
        printf("X11 server '%s' does not support OpenGL\n", xserver ) ;
        return false;
    }

    glXMakeCurrent(mXDisplay, mXWindow, glcontext);

    // now let the window appear to the userSDL_WINDOWPOS_U
    XMapWindow(mXDisplay, mXWindow);
    glXSwapBuffers(mXDisplay, mXWindow);

    SDL_Window* sdl_window = SDL_CreateWindowFrom((void*)mXWindow);

    SDL_Delay(30);

    return sdl_window;
}

SDL_CreateTransparentWindow can be used as usual
Code:
...
   if (NULL == (mWindow=SDL_CreateTransparentWindow("My SDL App with transparent background", 100, 50, WindowWidth, WindowHeight)))
    {
      LogError("Unable to create SDL Window: %s\n", SDL_GetError());
      return false;
   }

   if (NULL == (mRenderer=SDL_CreateRenderer(mWindow, -1, /*SDL_RENDERER_SOFTWARE*/SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC)))
   {
      LogError("Unable to create renderer: %s\n", SDL_GetError());
      return false;
    }
...

Add this to the beginning of your render procedure to clear the transparent background.
You can place your drawing objects as usual. Also blending your objects is still working.
Code:
void App:Render() {
SDL_SetRenderDrawColor(mRenderer, 0, 0, 0, 0);
SDL_RenderClear(mRenderer);
...

Event handler
Code:
void App::OnEvent()
{
    if (XPending(mXDisplay) > 0)
    {
        // process event
        XEvent event ;
        XNextEvent(mXDisplay, &event) ;

        switch(event.type)
        {  // see 'man XAnyEvent' for a list of available events
        case ClientMessage:
            // check if the client message was send by window manager to indicate user wants to close the window
            if ( event.xclient.message_type  == XInternAtom(mXDisplay, "WM_PROTOCOLS", 1)
                && event.xclient.data.l[0]  == XInternAtom(mXDisplay, "WM_DELETE_WINDOW", 1))
            {
                printf("Event WM_PROTOCOLS\n");
            }
            break;
        case KeyPress:
            if (XLookupKeysym(&event.xkey, 0) == XK_Escape)
            {
                printf("Event KeyPress Escape\n");
            }
            break ;
        default:
            // do nothing
            break ;
        }
    }
}

Add finally following to your cleanup procedure
Code:
...
   if (mXDisplay && mXWindow)
   {
        XDestroyWindow(mXDisplay, mXWindow);
        mXWindow = 0;
        if (mXDisplay)
        {
            XCloseDisplay(mXDisplay);
            mXDisplay = NULL;
        }
    }
...
SDL transparent primary surface (main window) ?
Iván José Dasilva Fr...
Guest

I know that this comes a bit late, but maybe this can help you, meuchel.


I was making a 'clone' of Pong and I was asked to make it for a terminal window, so I decided to use ncurses. As I wanted to manage the keyboard events with SDL, I need an SDL window that received the events. In order to receive them, the window needs to have the focus, but I wanted it to be 'transparent', so this is what I used.


I have this window (which is the one I use for menus):


  window = SDL_CreateWindow("Poing!", 100, 100, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);


and when I want it to be 'transparent', I use this:


  SDL_DestroyWindow(window);
  window = SDL_CreateWindow("", 0, 0, 100, 0, SDL_WINDOW_BORDERLESS);


I know this can looks horrible to someone with more experience in SDL than me (that's not too difficult Razz), but it worked to me.


Greetings.
Alpha-blended overlay widgets (transparent window)
Egal


Joined: 26 Aug 2015
Posts: 1
Hi there,

I found an interesting feature for SDL2: alpha-blended overlay widgets, see links for examples:

http://www.getlazarus.org/forums/viewtopic.php?t=40
http://www.getlazarus.org/forums/viewtopic.php?t=37

Anyways, the source is found at:

https://github.com/sysrpl/Cross.Codebot/tree/master/source

I am thinking about learning SDL2 and porting (maybe) the win32/win64 portion.

-Egal