Jump to content
  • Advertisement
Sign in to follow this  
Fahrenheit451

OpenGL Persisting images across window/fullscreen switch

This topic is 4864 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone, What is the proper way to persist OpenGL images/textures and fonts across switches between fullscreen and window mode? Using one of the early NeHe lessons I have my image loading, font creation, and mesh initialisation in the InitGL() routine, and things survive the window destroy/recreate that is done in the switch because everything gets reloaded and recreated! This seems wasteful. Is there a better approach whereby I dont have to continually reload and rebind images, recreate fonts etc, when switching the window mode? I tried moving things out to a separate routine, and whilst my camera and mesh settings survive, the images and fonts do not. Any ideas on a better approach/methodology to not having to do all the reloading is appreciated. Thanks. F451 [Edited by - Fahrenheit451 on June 20, 2005 9:49:38 AM]

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Fahrenheit451
What is the proper way to persist OpenGL images/textures and fonts across switches between fullscreen and window mode? (..) They seem to need a valid rendering or device context.

Don't destroy/rebuild the window but 'physically' switch it between fullscreen and window mode:

DEVMODE m_devmode; // this will need to be filled with valid values
::ChangeDisplaySettings( &m_devmode, CDS_FULLSCREEN ); // for fullscreen
::ChangeDisplaySettings( NULL, 0 ); // for window mode


you'll also likely want to adjust the window style after the switch, so it has all proper borders in window mode and none in fullscreen. This can be done with:

LONG_PTR style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; // or whatever
::SetWindowLongPtr( hWnd, GWL_STYLE, style );
::SetWindowPos( hWnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );

Share this post


Link to post
Share on other sites
hmm. It kind of works. By just applying ChangeDisplaySettings() I get the desired effect of switching, but it looks odd. If I start off with a window, then switching full screen becomes a fullscreen *window* - ie. with borders, title etc. Just like hitting the maximize button top right. If I start off fullscreen, then it's correct and I get no borders, but switching down to a window gives me a window without borders! I guess there is something more sophisticated required than just a call to ChangeDisplaySettings().


if (fullscreen) {
DEVMODE dmScreenSettings; // Device Mode
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared
dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure
dmScreenSettings.dmPelsWidth = width; // Selected Screen Width
dmScreenSettings.dmPelsHeight = height; // Selected Screen Height
dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) {
// If The Mode Fails, Offer Two Options. Quit Or Use Windowed Mode.
if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) {
fullscreen=false;
} else {
// Pop Up A Message Box Letting User Know The Program Is Closing.
MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);
return false;
}
}
} else {
ChangeDisplaySettings(NULL,0);
}




[Edited by - Fahrenheit451 on June 22, 2005 7:03:31 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Fahrenheit451
I guess there is something more sophisticated required than just a call to ChangeDisplaySettings().

Yes. check the second part of my first reply, the one which starts with "you'll also likely want to adjust the window style after the switch, so it has all proper borders in window mode and none in fullscreen" -.^

( you set the window style with ::::SetWindowLongPtr() and then enforce the update with ::SetWindowPos() call)

Share this post


Link to post
Share on other sites
Yeah, I tried that. Copied them over from the original CreateGLWindow, but they do not have any effect when included in the code above. Let me do some googling for window style settings. Cheers.


// determine screen mode and process accordingly
if (fullscreen) {
dwExstyle=WS_EX_APPWINDOW;
dwstyle=WS_POPUP;
} else {
dwExstyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwstyle=WS_OVERLAPPEDWINDOW;
}

Share this post


Link to post
Share on other sites
Gah... forgot the ShowWindow(hWnd,SW_SHOW); call at the end of the routine :-( Works a treat. Thanks for the help.

[edit : The full routine for those interested. It doesnt include all style settings that are necessarily required, because some are already set in the original CreateGLWindow routine and therefore still in effect. This only sets those required for the toggle to take effect.]


// toggle between fullscreen and window mode
bool SwitchWindowMode(char* title, int width, int height, int bits, bool fullscreen)
{

DWORD dwStyle;

// setup fullscreen parameters
if (fullscreen) {
DEVMODE dmScreenSettings;
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
dmScreenSettings.dmSize=sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = width;
dmScreenSettings.dmPelsHeight = height;
dmScreenSettings.dmBitsPerPel = bits;
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) {
// If The Mode Fails, Offer Two Options. Quit Or Use Windowed Mode.
if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) {
fullscreen=FULLSCREEN;
} else {
// Pop Up A Message Box Letting User Know The Program Is Closing.
MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);
return false;
}
}
} else {
// revert to prior windows settings
ChangeDisplaySettings(NULL,0);
}

// set window style accordingly
if (fullscreen) {
dwStyle=WS_POPUP;
} else {
dwStyle=WS_OVERLAPPEDWINDOW;
}
SetWindowLongPtr( hWnd, GWL_STYLE, dwStyle );

// display our newly adjusted window
ShowWindow(hWnd,SW_SHOW);

return true;
}





[Edited by - Fahrenheit451 on June 22, 2005 8:56:46 AM]

Share this post


Link to post
Share on other sites
No worry, glad it helped ^^

You might want to add WS_CLIPSIBLINGS | WS_CLIPCHILDREN to dwstyle, for both the window and fullscreen modes. If nothing else it's going to come handy when you try to add extra controls on top of the main window...

[edit:

Quote:
It doesnt include all style settings that are necessarily required, because some are already set in the original CreateGLWindow routine and therefore still in effect. This only sets those required for the toggle to take effect

afraid this doesn't really work this way... ::SetWindow() effectively overwrites existing window style, so if you had, say, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN in the initialization routine ... and then use ::SetWindow() to apply WS_POPUP to your window ... the WS_CLIPCHILDREN is no more, WS_POPUP is all that remains.

One way to work around it would be to have the common styles stored in member variable of your window class, say:

LONG_PTR m_common_styles = WS_CLIPCHILDREN | WS_CLIPSIBLINGS

and then use this during mode switch to build the 'full' style variable:

LONG_PTR style = m_common_styles | WS_POPUP; ::SetWindowLongPtr( ... style );


[Edited by - tolaris on June 22, 2005 8:09:18 AM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!