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

Author Topic: OpenGL context after window create/recreate  (Read 3281 times)

0 Members and 1 Guest are viewing this topic.

memidex

  • Newbie
  • *
  • Posts: 4
    • View Profile
OpenGL context after window create/recreate
« on: August 30, 2012, 01:47:18 am »
OpenGL has always caused problems when changing between video modes (on Windows), as evidenced by the threads on this and various other forums. To be exact, the OpenGL context and all associated resources were lost. Now, it seems that Laurent has worked on this issue in SFML. I believe he mentioned that a shared context is created that keeps certain OpenGL resources around, even if the window is recreated. While this is great, it unfortunately does not apply to states. For example, it seems that vertex array objects loose all of their state. (See the attached code for a short example.)

So I was wondering: Is there any way to find out what will stick around and what will be lost after recreating a window (other than trial and error)?

[attachment deleted by admin]
« Last Edit: August 30, 2012, 02:24:33 am by memidex »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: OpenGL context after window create/recreate
« Reply #1 on: August 30, 2012, 09:51:34 am »
Resources objects are kept (textures, VBOs, shaders, ...) and states are lost, since those are specific to each context.
Laurent Gomila - SFML developer

memidex

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: OpenGL context after window create/recreate
« Reply #2 on: August 30, 2012, 02:05:08 pm »
Thank you for the quick answer, that makes sense. In the example code I posted, I am not really changing the video mode (i.e. not using sf::Style::Fullscreen). Rather than that, I resize the window to the current desktop resolution and I hide the border (i.e. using sf::Style::None). Resizing should not destroy the context, since you can drag the window border and everything stays fine. But it seems that changing the window style does, or at least using the only exposed method that allows doing so (sf::Window::create). I assume it is not possible to create a method that allows changing the style without destroying the context?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: OpenGL context after window create/recreate
« Reply #3 on: August 30, 2012, 02:14:51 pm »
Window::create recreates the window and its context. Indeed, you'd need a Window::setStyle function in order to change the style without loosing the context.

Out of curiosity, why do you want to change the style of the window after creating it?
Laurent Gomila - SFML developer

memidex

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: OpenGL context after window create/recreate
« Reply #4 on: August 30, 2012, 03:03:52 pm »
Some people have suggested that you should not change the actual video resolution (i.e. use fullscreen exclusive mode) in modern OpenGL applications. Personally, I am also not too fond of the flickering etc. that goes on during such a transition.

The commonly suggested alternative is to render to an OpenGL framebuffer of the desired size and stretch it to the real screen resolution. That is what I am trying to implement. However, when entering this "light" fullscreen mode, it would be nice to hide the window border. I am wondering if this could be done without losing the context.
« Last Edit: August 30, 2012, 03:06:16 pm by memidex »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: OpenGL context after window create/recreate
« Reply #5 on: August 30, 2012, 05:33:21 pm »
Ok, I see. This can probably be done but is not supported yet.
Laurent Gomila - SFML developer

memidex

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: OpenGL context after window create/recreate
« Reply #6 on: August 31, 2012, 02:36:03 am »
You are right, it can be done. It is actually quite trivial on Windows (the majority is just window style conversion between SFML and WINAPI, which I copied from WindowImplWin32):

void setStyle(sf::Window& window, sf::Uint32 style)
{
    HWND handle = window.getSystemHandle();
    DWORD win32Style = WS_VISIBLE;

    if (style == sf::Style::None)
    {
        win32Style |= WS_POPUP;
    }
    else
    {
        if (style & sf::Style::Titlebar) win32Style |= WS_CAPTION | WS_MINIMIZEBOX;
        if (style & sf::Style::Resize)   win32Style |= WS_THICKFRAME | WS_MAXIMIZEBOX;
        if (style & sf::Style::Close)    win32Style |= WS_SYSMENU;
    }

    SetWindowLongPtr(handle, GWL_STYLE, win32Style);

    // Force changes to take effect
    SetWindowPos(handle, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME);
}

Combined with sf::Window::setPosition/setSize it works just like desired: very fast, no loss of OpenGL context.
« Last Edit: August 31, 2012, 02:43:01 am by memidex »