Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: SFML: Transparent Window Background?  (Read 13170 times)

0 Members and 1 Guest are viewing this topic.

6Peppered9

  • Newbie
  • *
  • Posts: 9
    • View Profile
SFML: Transparent Window Background?
« on: October 31, 2018, 01:02:32 am »
Hello,

I have a normal window with SFML (C ++) and I want to render the background of the window (not its content) transparent, e.g. can change the alpha channel.

Since the rendering of the window is the window manager's task and I do not have a direct way to change the window properties directly via SFML, I go back to X11 and tried the following:

https://github.com/texus/TransparentWindows/blob/master/Transparent.cpp

I'm not really familiar with the Xlib.

The problem is that I use the above method to make the entire window transparent (including the contents of the window).

Does anyone know a way to make only the background of the window transparent? I would be very happy about code examples. ?

Thank you.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11007
    • View Profile
    • development blog
    • Email
Re: SFML: Transparent Window Background?
« Reply #1 on: October 31, 2018, 07:50:55 am »
If you just want to get rid of the decorations, you can use sf::Style::None
Otherwise you need to be more specific with what you mean by transparent window but not the content.

Btw I removed your double post and moved your thread into the help section. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

6Peppered9

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: SFML: Transparent Window Background?
« Reply #2 on: October 31, 2018, 04:20:20 pm »
I want exactly this:


I want to set the background transparency of my window exactly like the transparency in the gnome terminal settings.
« Last Edit: October 31, 2018, 04:22:01 pm by 6Peppered9 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11007
    • View Profile
    • development blog
    • Email
Re: SFML: Transparent Window Background?
« Reply #3 on: October 31, 2018, 05:35:25 pm »
So you just want to change the opacity to not be fully transparent, but semi-transparent. The repository you linked already provides a variable to set the opacity.

Change the opacity variable in the Transparent.cpp to whatever opacity you want.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

6Peppered9

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: SFML: Transparent Window Background?
« Reply #4 on: October 31, 2018, 08:29:36 pm »
Yes, but with the method i posted, i change the opacity of the entire window including the topbar and everything  in the window (buttons, ...)

it looks like this:


but i want only to change the background opacity. The window frame (including title, close button, ...) should be displayed normally

texus

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • TGUI
    • Email
Re: SFML: Transparent Window Background?
« Reply #5 on: November 01, 2018, 01:40:39 pm »
Do you only need it for linux? I hacked some code together that seems to work (for both the case where only the background has to be transparent and the case where the entire contents has to be transparent).


The downside is that it required a modification in SFML:
diff --git a/src/SFML/Window/Unix/WindowImplX11.cpp b/src/SFML/Window/Unix/WindowImplX11.cpp
index da697505..abbdd00e 100644
--- a/src/SFML/Window/Unix/WindowImplX11.cpp
+++ b/src/SFML/Window/Unix/WindowImplX11.cpp
@@ -573,13 +573,17 @@ m_lastInputTime  (0)
     int height = mode.height;
 
     // Choose the visual according to the context settings
-    XVisualInfo visualInfo = ContextType::selectBestVisual(m_display, mode.bitsPerPixel, settings);
+    //XVisualInfo visualInfo = ContextType::selectBestVisual(m_display, mode.bitsPerPixel, settings);
+
+    XVisualInfo visualInfo;
+    XMatchVisualInfo(m_display, m_screen, 32, TrueColor, &visualInfo);
 
     // Define the window attributes
     XSetWindowAttributes attributes;
     attributes.colormap = XCreateColormap(m_display, DefaultRootWindow(m_display), visualInfo.visual, AllocNone);
     attributes.event_mask = eventMask;
     attributes.override_redirect = (m_fullscreen && !ewmhSupported()) ? True : False;
+    attributes.border_pixel = 0;
 
     m_window = XCreateWindow(m_display,
                              DefaultRootWindow(m_display),
@@ -589,7 +593,7 @@ m_lastInputTime  (0)
                              visualInfo.depth,
                              InputOutput,
                              visualInfo.visual,
-                             CWEventMask | CWOverrideRedirect | CWColormap,
+                             CWEventMask | CWOverrideRedirect | CWColormap | CWBorderPixel,
                              &attributes);
 
     if (!m_window)
 

After that the following code should give the result shown in the images above:
#include <SFML/Graphics.hpp>

// Comment this define to only make the background transparent and keep all other things drawn to the window opaque
#define TRANSPARENT_DRAWING

const unsigned char backgroundOpacity = 150;

int main(int argc, char* argv[])
{
    sf::Image backgroundImage;
    backgroundImage.loadFromFile("image.png");

    sf::RenderWindow window(sf::VideoMode(backgroundImage.getSize().x, backgroundImage.getSize().y, 32), "Transparent Window");
    window.setPosition(sf::Vector2i((sf::VideoMode::getDesktopMode().width - backgroundImage.getSize().x) / 2,
                                    (sf::VideoMode::getDesktopMode().height - backgroundImage.getSize().y) / 2));

    sf::Texture backgroundTexture;
    sf::Sprite backgroundSprite;
    backgroundTexture.loadFromImage(backgroundImage);
    backgroundSprite.setTexture(backgroundTexture);

#ifdef TRANSPARENT_DRAWING
    sf::RenderTexture renderTexture;
    renderTexture.create(backgroundImage.getSize().x, backgroundImage.getSize().y, 32);
#endif

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed || (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape))
                window.close();
        }

#ifdef TRANSPARENT_DRAWING
        renderTexture.clear(sf::Color::Transparent);
        renderTexture.draw(backgroundSprite);
        renderTexture.display();

        sf::Sprite renderTextureSprite(renderTexture.getTexture());
        renderTextureSprite.setColor({255, 255, 255, backgroundOpacity});
       
        window.clear({0, 0, 0, backgroundOpacity});
        window.draw(renderTextureSprite);
        window.display();
#else
        window.clear({0, 0, 0, backgroundOpacity});
        window.draw(backgroundSprite);
        window.display();
#endif
    }
   
    return 0;
}
TGUI: C++ SFML GUI

Torrunt

  • Newbie
  • *
  • Posts: 16
    • View Profile
    • Torrunt
Re: SFML: Transparent Window Background?
« Reply #6 on: November 13, 2018, 11:13:35 am »
I manged to do this for Windows using DwmEnableBlurBehindWindow, which is a Desktop Window Manager API function.

You can see it in use here:
https://github.com/Torrunt/vimage/blob/master/vimage/Source/ImageViewer.cs#L109

That's using C# but you should be able to do it with C++ as well:
https://docs.microsoft.com/en-us/windows/desktop/api/dwmapi/nf-dwmapi-dwmenableblurbehindwindow

Then when you clear your window during you draw call, clear it with a colour that has some transparency.