Sign in to follow this  
Clueless

Toggling fullscreen, OpenGL

Recommended Posts

Hello all, I think I read some time ago that it is possible to toggle between windowed and fullscreen mode in a way that your registered textures are not gone after the process. I think I read that the enhanced NeHe basecode does it that way!? I wasn't able to figure out what happens in the case of a WM_TOGGLEFULLSCREEN there. Can anybody please briefly explain the important things to know about the process? I have a theory but I won't be able to test this for a while because I can't import textures yet. Still ... I'm writing the change_settings(...) function for the window now and need to know this. Guess this might be interesting for other beginners that work with the Nehe basecode, too. Is this correct: - The textures are deleted when the render context is closed? - I can kill the window without killing the renderContext? - I can call wglMakeCurrent(...,NULL); without calling wglDeleteContext(...); and assign the render context to a new window in a change_settings(...) function? Btw. is there no way of passing new styles to the window handle? Is there a reason why there is no API function like UpdateWindowEX(...)? I was kinda hoping there is a way to change the window settings without killing the window:
bool change_settings(Uint16 width, Uint16 height,
    Uint16 redBits, Uint16 greenBits, Uint16 blueBits, Uint16 alphaBits,
    bool fullscreen) {

    bool success = true;

    RECT rect = {0,0,(long)width,(long)height};
    g_rect = rect;

    ZeroMemory (&g_screenSettings, sizeof(DEVMODE));

    g_screenSettings.dmSize = sizeof(g_screenSettings);
    g_screenSettings.dmPelsWidth =  (long)width;
    g_screenSettings.dmPelsHeight = (long)height;
    g_screenSettings.dmBitsPerPel = redBits + greenBits + blueBits
        + alphaBits;
    g_screenSettings.dmFields = DM_BITSPERPEL |
                                DM_PELSWIDTH  |
                                DM_PELSHEIGHT;

    if ( fullscreen ) {
        g_extStyle = WS_EX_APPWINDOW | WS_EX_TOPMOST;
        g_style    = WS_POPUP;
        if ( ChangeDisplaySettings(&g_screenSettings,CDS_FULLSCREEN)
             != DISP_CHANGE_SUCCESSFUL ) {
            success = false;
        } else {
            /* somehow update the window style */
            g_bits = redBits + greenBits + blueBits + alphaBits;
            ShowCursor(FALSE);
        }
    } else {
        g_extStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
        g_style    = WS_OVERLAPPEDWINDOW;
        AdjustWindowRectEx(&g_rect,g_style,FALSE,g_extStyle);
        if ( ChangeDisplaySettings(NULL,0)
             != DISP_CHANGE_SUCCESSFUL ) {
            success = false;
        } else {
            /* somehow update the window style */
            g_bits = redBits + greenBits + blueBits + alphaBits;
            ShowCursor(TRUE);
        }
    }

    return success;
}

Share this post


Link to post
Share on other sites
You don't need to destroy the window/context and re-create them to change the screen mode. What you need to do is change the window properties and call the ChangeDisplaySettings() function.

To change the window properties you use SetWindowLong() and GetWindowLong(), you get the current flags using GetWindowLong() then bitwise OR (I think) the properties with the returned ones. After this you set them back to the window with SetWindowLong(). You would also need to call SetWindowPos() to let the window know the properties were changed.

I don't have my code here but this should help:
SetWindowLong (MSDN)

Share this post


Link to post
Share on other sites
Nah, can't figure it out. Once I use SetWindowPos(...) the fullscreen view is messed up.
Fullscreen mode is entered but the window is still visible as such. The mousepointer is shown ... but Cursor(FALSE) has been executed.

[edit]
Logfile updated
[/edit]

I hope somebody has done this before and can help ...


bool change_settings(Uint16 width, Uint16 height,
Uint16 redBits, Uint16 greenBits, Uint16 blueBits, Uint16 alphaBits,
bool fullscreen) {

#if defined( DD_LOGGING )
LOG << "Updating the window!<br />" << ENDL;
g_pLog->flush("Updating Window");
#endif

bool success = true;

RECT rect = {0,0,(long)width,(long)height};
g_rect = rect;

ZeroMemory (&g_screenSettings, sizeof(DEVMODE));

g_screenSettings.dmSize = sizeof(g_screenSettings);
g_screenSettings.dmPelsWidth = (long)width;
g_screenSettings.dmPelsHeight = (long)height;
g_screenSettings.dmBitsPerPel = redBits + greenBits + blueBits
+ alphaBits;
g_screenSettings.dmFields = DM_BITSPERPEL |
DM_PELSWIDTH |
DM_PELSHEIGHT;

if ( fullscreen ) {
g_extStyle = WS_EX_APPWINDOW;
g_style = WS_POPUP;
if (g_windowHandle) {
#if defined( DD_LOGGING )
LOG << "Window handle exists, fullscreen mode!<br />" << ENDL;
g_pLog->flush("Initializing Window");
#endif
g_style |= GetWindowLong(g_windowHandle, GWL_STYLE);
g_extStyle |= GetWindowLong(g_windowHandle, GWL_EXSTYLE);
SetWindowLong(g_windowHandle, GWL_EXSTYLE, g_extStyle);
SetWindowLong(g_windowHandle, GWL_STYLE, g_style);
}
if ( ChangeDisplaySettings(&g_screenSettings,CDS_FULLSCREEN)
!= DISP_CHANGE_SUCCESSFUL ) {
g_windowHandle = NULL;
success = false;
#if defined( DD_LOGGING )
LOG << "Error while changing the displaysettings!<br />" << ENDL;
g_pLog->flush("Updating", debug::FlushError);
#endif
} else {
g_bits = redBits + greenBits + blueBits + alphaBits;
ShowCursor(FALSE);
#if defined( DD_LOGGING )
LOG << "Successfully changed the displaysettings!<br />" << ENDL;
g_pLog->flush("Updating");
#endif
}
} else {
g_extStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
g_style = WS_OVERLAPPEDWINDOW;
if (g_windowHandle) {
#if defined( DD_LOGGING )
LOG << "Window handle exists! Windowed mode<br />" << ENDL;
g_pLog->flush("Initializing Window");
#endif
g_style |= GetWindowLong(g_windowHandle, GWL_STYLE);
g_extStyle |= GetWindowLong(g_windowHandle, GWL_EXSTYLE);
SetWindowLong(g_windowHandle, GWL_EXSTYLE, g_extStyle );
SetWindowLong(g_windowHandle, GWL_STYLE, g_style );
}
AdjustWindowRectEx(&g_rect,g_style,FALSE,g_extStyle);
if ( ChangeDisplaySettings(NULL,0)
!= DISP_CHANGE_SUCCESSFUL ) {
g_windowHandle = NULL;
success = false;
#if defined( DD_LOGGING )
LOG << "Error while changing the displaysettings!<br />" << ENDL;
g_pLog->flush("Updating", debug::FlushError);
#endif
} else {
g_bits = redBits + greenBits + blueBits + alphaBits;
ShowCursor(TRUE);
#if defined( DD_LOGGING )
LOG << "Successfully changed the displaysettings!<br />"
<< "Should now show cursor!<br />" << ENDL;
g_pLog->flush("Updating");
#endif
SetWindowPos(g_windowHandle,HWND_TOPMOST,
0, 0,
g_rect.right-g_rect.left, g_rect.bottom-g_rect.top,
SWP_SHOWWINDOW);
}
}

return success;
}





Logfile - Begin

Begin
Logging Started!

Initializing Window
Creating window in Windowed mode!

Updating Window
Updating the window!

Updating
Successfully changed the displaysettings!
Should now show cursor!

Initialized Window
- Successfully done!

Updating Window
Updating the window!

Updating Window
Window handle exists, fullscreen mode!

Updating
Successfully changed the displaysettings!

Uninitializing Window
Just killed the window!


Logfile - End

[Edited by - Clueless on May 18, 2006 6:03:55 PM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this