Texture reloading when toggling fullscreen, SDL+OpenGL

Started by
13 comments, last by Zakwayda 14 years, 3 months ago
Dear reader, Today I decided to tackle the problem of reloading my textures whenever the OpenGL context gets lost and recovered (for example when SDL switches to fullscreen or windowed -> a new window is created). However, this seems to be harder than I reckoned, because I can't get it to work. Whenever I switch to fullscreen, the simple textured GL_QUADS I render every frame disappears, and when switching back to windowed mode, it doesn't come back. Before asking any other questions; when I don't texture the quad (but just glColor3f() it), and then switch to fullscreen, the quad disappears just as well. This isn't supposed to happen right? As far as I know, I need to reload textures because they allocate memory internal to OpenGL, but a simple glBegin(GL_QUADS) - glEnd() structure does not right? Can anyone point me to the right direction and take a guess as to why my vertices disappear? Oh, and if it's any help: I clear the screen with a colour determined by the mouse position (so it changes whenever I move with my cursor). This works before I switch to fullscreen, but does so too in fullscreen mode and after switching back. I also glEnable(GL_TEXTURE_2D); after (re)setting up SDL's video mode, so that can't be it either. Thank you for reading (and hopefully replying) - Stijn Frishert
What do I expect? A young man's quest to defeat an evil sorceror while discovering the truth of his origins. A plucky youngster attended by her brutish guardian. A powerful artifact which has been broken into a small number of artifactlets distributed around the world.What do I want? Fewer damn cliches. - Sneftel
Advertisement
This is a problem only DX has. OpenGL always internally keeps copies of all objects in SysRAM. There's no concept of "lost context" in GL. But "a new window is created" means that your context stays intact in the previous window. Make SDL or whatever not recreate the window, it's pointless. If it can't be fixed, then ditch SDL and spend a few minutes in writing your own windowing :)
Quote:Today I decided to tackle the problem of reloading my textures whenever the OpenGL context gets lost and recovered (for example when SDL switches to fullscreen or windowed -> a new window is created). However, this seems to be harder than I reckoned, because I can't get it to work. Whenever I switch to fullscreen, the simple textured GL_QUADS I render every frame disappears, and when switching back to windowed mode, it doesn't come back.

Before asking any other questions; when I don't texture the quad (but just glColor3f() it), and then switch to fullscreen, the quad disappears just as well. This isn't supposed to happen right? As far as I know, I need to reload textures because they allocate memory internal to OpenGL, but a simple glBegin(GL_QUADS) - glEnd() structure does not right? Can anyone point me to the right direction and take a guess as to why my vertices disappear?

Oh, and if it's any help: I clear the screen with a colour determined by the mouse position (so it changes whenever I move with my cursor). This works before I switch to fullscreen, but does so too in fullscreen mode and after switching back. I also glEnable(GL_TEXTURE_2D); after (re)setting up SDL's video mode, so that can't be it either.
The first thing to check would probably be your OpenGL state setup. When the OpenGL context is lost and recreated, the entire OpenGL state is reset to its default; this includes render states, transform matrices, etc. Once the context has been recreated, you'll need to repeat whatever setup work you did at startup; if you miss anything crucial (such as setting up the projection matrix), you may not get the results you expect after the reset.

You are right that textures need to be re-uploaded to OpenGL after the context is recreated; this also holds for other volatile resources that may reside in video memory or in OpenGL-managed system memory, such as VBOs or display lists. Code such as glBegin()/End() blocks, on the other hand, simply issue commands and will be unaffected (aside from being dependent on the overall OpenGL state, of course).

What OS are you developing on? Windows? Also, if I may ask, are you only losing the context on windowed<->fullscreen switches? Or are you losing the context in other situations as well?
Quote:This is a problem only DX has. OpenGL always internally keeps copies of all objects in SysRAM. There's no concept of "lost context" in GL. But "a new window is created" means that your context stays intact in the previous window. Make SDL or whatever not recreate the window, it's pointless. If it can't be fixed, then ditch SDL and spend a few minutes in writing your own windowing :)
I think ditching SDL because of this behavior might be a little shortsighted; especially if you're targeting multiple OSs/platforms, writing your own windowing and events code (and making it 'play nice' with each OS) will likely take more than a few minutes, I would think. Also, for what it's worth, there's been some discussion on the SDL forums of trying to address this problem in SDL 1.3.

As for the context never being lost in Windows, I've read that as well, but even with very simple programs (i.e. rendering a single textured triangle) I've had problems with the app crashing sometimes when you alt-tab in and out of fullscreen mode. In other places I've read that you're not supposed to render to the context when the app doesn't have focus, but I haven't been able to confirm this. (I'm not sure if any of this relates to the OP's problem, but it's something I've been curious about.)
I've been coding GL stuff for years without relying on stuff like SDL (I don't need cross-platforming), and gpu-resets never ever crashed my code or made it misbehave. Neither did unfocusing/hiding the window. All GL state was automatically and transparently restored for me. Have I been lucky for a change? (I doubt it)
Quote:I've been coding GL stuff for years without relying on stuff like SDL (I don't need cross-platforming)
Sure, it's a different situation if you have no need for cross-platform support.
Quote:and gpu-resets never ever crashed my code or made it misbehave. Neither did unfocusing/hiding the window. All GL state was automatically and transparently restored for me. Have I been lucky for a change? (I doubt it)
Maybe the problem I'm seeing is specific to SDL or to my particular hardware configuration (I have a fairly old Intel video card).
I setup the window for my own, and don't have problems with alt-tabbing. I simply don't render, when focus is lost (because it's a fullscreen app, so it's pointless to do anything when not having focus). I simply set ChangeDisplaySettings, ShowWindow, SetForegroundWindow when handling alt-tabbing.

I'm sure it has some kind of equivalent in SDL.
Thanks for replying, idinev, jyk and szecs! I solved the problem, thanks to you guys. It lay indeed in the not resetting of the OpenGL state correctly after switching.

Quote:original post by jyk:
You are right that textures need to be re-uploaded to OpenGL after the context is recreated; this also holds for other volatile resources that may reside in video memory or in OpenGL-managed system memory, such as VBOs or display lists. Code such as glBegin()/End() blocks, on the other hand, simply issue commands and will be unaffected (aside from being dependent on the overall OpenGL state, of course).

What OS are you developing on? Windows? Also, if I may ask, are you only losing the context on windowed<->fullscreen switches? Or are you losing the context in other situations as well?

Yeap, it was indeed the OpenGL state. Now for another important question though: Should I glDeleteTextures() all my textures before switching fullscreen<->windowed? I wouldn't want any allocated and unrefered to memory internal to OpenGL hanging around.

I'm developing for Windows, right now. Not necessarily into cross-platform, I just happen to like the SDL+OpenGL combination (however, if porting to e.g. OSX would work out, why wouldn't I?). As far as I know, I only lose the context when switching from windowed to fullscreen switches and vice versa. Alt-tabbing works perfectly well, if that's what you're asking.

Again, thanks for helping out,
- Stijn
What do I expect? A young man's quest to defeat an evil sorceror while discovering the truth of his origins. A plucky youngster attended by her brutish guardian. A powerful artifact which has been broken into a small number of artifactlets distributed around the world.What do I want? Fewer damn cliches. - Sneftel
Quote:Should I glDeleteTextures() all my textures before switching fullscreen<->windowed? I wouldn't want any allocated and unrefered to memory internal to OpenGL hanging around.
I think textures and other similar resources are released/destroyed with the context, but I don't know this for sure (I always delete such resources explicitly before recreating the context, just to be sure).
Maybe you should post your initialization code.

I may be wrong, but maybe you are trying to set a fullscreen mode, which isn't supported. Maybe just 24 bit instead of 32, or something like that, so maybe that's the reason your context is getting lost.
But that may be totally wrong.

Lot of "maybe"s for a post.

This topic is closed to new replies.

Advertisement