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

Author Topic: How to have a transparent RenderWindow (on Windows 7)  (Read 5875 times)

0 Members and 1 Guest are viewing this topic.

tbop

  • Newbie
  • *
  • Posts: 34
    • View Profile
How to have a transparent RenderWindow (on Windows 7)
« on: June 17, 2013, 12:50:23 pm »
Hi there,


I've to render a transparent layered openGL windows but since I'll only be drawing 2d stuffs such as lines, polygons, circles and all I'd like to pre-render everything on a RenderTexture so that it eases me the task (I'll be only using drawLine, drawCircle instead of the tricky openGL's set of methods).
Then I just want to get the Sfml::Texture out of it and draw it as it is on my layered window by using openGL.


How could I do this conversion properly?
Should I be drawing quads?


Cheers!
« Last Edit: June 17, 2013, 03:03:36 pm by tbop »

tbop

  • Newbie
  • *
  • Posts: 34
    • View Profile
The question could be put the other way around and be: How can I create a layered openGL window context with SFML but it turns out to be quite impossible as far as my research's shown.... isn't it?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
SFML cannot create a transparent window, you'll need OS-specific functions. But apart from that, the rest is quite easy to implement.
Laurent Gomila - SFML developer

tbop

  • Newbie
  • *
  • Posts: 34
    • View Profile
Hi Laurent,


Thanks for the quick answer!

So what would be the strategy then? Keeping a RenderTexture without any openGl context, drawing on top of it, getting the raw image buffer behind and drawing it as an openGL texture?

Or is there any chance to create a RenderWindow but to alter some of its inherent properties afterward depending on some OS-specific functions?


Cheers!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Yes, use the getSystemHandle() function and then do whatever you want with the returned handle.
Laurent Gomila - SFML developer

tbop

  • Newbie
  • *
  • Posts: 34
    • View Profile
Great!


Sorry I guess it's kind of recurrent question but I wasn't convinced with what I'd found on Google and I wanted to make sure not to go in a totally silly direction.


Cheers!

tbop

  • Newbie
  • *
  • Posts: 34
    • View Profile
Re: How to have a transparent RenderWindow
« Reply #6 on: June 17, 2013, 02:54:57 pm »
Wait up! :D

I was sure it's not going to be as easy as I thought.

It seems the code I was using needs to set another kind of pixel format
http://www.jose.it-berater.org/smfforum/index.php?topic=2844.0 (see part 3)

If I do this after creating the RenderWindow and getting its inner WindowHandle, SetPixelFormat will return me an error 2000 which is "the pixel format is invalid".
Well I'm sure the pixel format is valid since the code is working in case I don't draw on the RenderWindow but just with the former full-native code.
I guess the problem is that the openGL is again already created through SFML and that I've no chance to change the pixel format once the openGL context's been created.

Am I right?
What would be a good workaround here according to you (guys)?

Here's the culprit!

bool InitGL()
{
        // Even though we aren't going to be rendering the scene to the window
        // we still need to create a dummy rendering context in order to load the
        // pbuffer extensions and to create our pbuffer.

        PIXELFORMATDESCRIPTOR pfd = {0};

        // Don't bother with anything fancy here. This is just a dummy rendering
        // context so just ask for the bare minimum.
        pfd.nSize = sizeof(pfd);
        pfd.nVersion = 1;
        pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI;
        pfd.iPixelType = PFD_TYPE_RGBA;
        pfd.cColorBits = 24;
        pfd.cDepthBits = 32;
        pfd.iLayerType = PFD_MAIN_PLANE;

        if (!(g_hDC = GetDC(g_hWnd)))
                return false;

        int pf = ChoosePixelFormat(g_hDC, &pfd);

        if (!SetPixelFormat(g_hDC, pf, &pfd))
                return false;

        if (!(g_hRC = wglCreateContext(g_hDC)))
                return false;

        if (!wglMakeCurrent(g_hDC, g_hRC))
                return false;

        if (!InitGLExtensions())
                return false;

        if (!InitPBuffer())
                return false;

        // Deactivate the dummy rendering context now that the pbuffer is created.
        wglMakeCurrent(g_hDC, 0);
        ReleaseDC(g_hWnd, g_hDC);
        g_hDC = 0;

        // We are only doing off-screen rendering. So activate our pbuffer once.
        wglMakeCurrent(g_hPBufferDC, g_hPBufferRC);

        glEnable(GL_DEPTH_TEST);
        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);
        glEnable(GL_TEXTURE_2D);

        // Create and bind the texture to the pbuffer's rendering context.
        InitCheckerPatternTexture();
        glBindTexture(GL_TEXTURE_2D, g_textureId);

        return true;
}


Cheers!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: How to have a transparent RenderWindow (on Windows 7)
« Reply #7 on: June 17, 2013, 03:18:13 pm »
To be clear: you just need the PFD_SUPPORT_GDI flag to have everything working? Have you tried to add it directly to the source code of SFML (and recompile it)?
Laurent Gomila - SFML developer

tbop

  • Newbie
  • *
  • Posts: 34
    • View Profile
Re: How to have a transparent RenderWindow (on Windows 7)
« Reply #8 on: June 17, 2013, 03:52:12 pm »
Quote
you just need the PFD_SUPPORT_GDI flag to have everything working?

No clue! I'm just following the tutorial I've found. I must confess this pixel-format-thingy part is a trifle out of my knowledge.

Hum ok but I didn't really want to hack into SFML for that indeed.... I'd rather like to keep with an unaltered version of the library.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: How to have a transparent RenderWindow (on Windows 7)
« Reply #9 on: June 17, 2013, 04:02:41 pm »
It was just a quick test, so that if it was indeed all you need, maybe I could add it to SFML directly for the next version.
Laurent Gomila - SFML developer

tbop

  • Newbie
  • *
  • Posts: 34
    • View Profile
Re: How to have a transparent RenderWindow (on Windows 7)
« Reply #10 on: June 17, 2013, 05:55:07 pm »
Ok I've checked the original code in WglContext but I wouldn't think the problem is here, except the support GDI but I don't need GDI here.

So basically I've managed to draw everything but no matter what I just can't get rid of the black background.

Although I'm doing everything like here:
http://www.jose.it-berater.org/smfforum/index.php?topic=2844.0


The code right above with the pixel format and all is outdated. I'm no longer using it.


Here's how I alter the window (and it seems to work as expected:
        HWND hWnd = window.getSystemHandle ();
        if (!SetWindowLongPtr (hWnd, GWL_EXSTYLE, WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW | WS_EX_TOPMOST))
                return 0;

        if (!SetWindowLongPtr (hWnd, GWL_STYLE, WS_POPUP | WS_VISIBLE))
                return 0;

Here is what I initialize after creating RenderWindow:

BOOL initSC()
{
        glEnable(GL_ALPHA_TEST);        
        glEnable(GL_DEPTH_TEST);        
        glEnable(GL_COLOR_MATERIAL);

        glEnable(GL_LIGHTING);          
        glEnable(GL_LIGHT0);            

        glEnable(GL_BLEND);            
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glClearColor(0, 0, 0, 0);

        return 0;
}

Do you understand which part fails when it comes to applying pure alpha blending over the top of the screen output here?
« Last Edit: June 17, 2013, 06:26:36 pm by tbop »

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 878
    • View Profile
Re: How to have a transparent RenderWindow (on Windows 7)
« Reply #11 on: June 17, 2013, 06:18:17 pm »
It was just a quick test, so that if it was indeed all you need, maybe I could add it to SFML directly for the next version.
Not sure whether there's some downside in setting this other than it being mutually exclusive with PFD_SUPPORT_DOUBLEBUFFER. Either way, it looks like some thing for backwards compatibility, nothing that should be used just in case you might want it some time later.