Skip to main content
GameDev.net gamedev.net
🔒 Locked

Texture reloading when toggling fullscreen, SDL+OpenGL

Started by stenny Dec 28, 2009 at 9:08 PM 13 replies 8.8k views
Original Post
stenny
stenny
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
idinev
idinev
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 :)
Zakwayda
Zakwayda
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?
Zakwayda
Zakwayda
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.)
idinev
idinev
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)
Zakwayda
Zakwayda
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).
szecs
szecs
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.
stenny
stenny
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
Zakwayda
Zakwayda
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).
szecs
szecs
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.
Zakwayda
Zakwayda
Quote:
Original post by szecs
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.
Assuming you're responding to the OP, he's using SDL, which (at least currently) always destroys and recreates the OpenGL context when the video mode is reset (whether or not the host system actually requires it). I think the question wasn't so much, 'Why is my context being lost?', but rather, 'Why aren't I seeing anything after the context is recreated?'.
swiftcoder
swiftcoder
Quote:
Original post by jyk
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.
So switch to something like SFML, which has pretty decent platform coverage, and does support fullscreen/windowed toggling out of the box.
Quote:
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.
I broached this issue with the SDL developers back in 2004, and it comes up with alarming regularity on the various mailing lists and forums before and since. Given that SDL has had an explicit API to toggle fullscreen mode since the very beginning, and it is still only supported on X11, I find promises of 1.3 a little lacking...
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
stenny
stenny
Quote:
Original post by jyk
I think the question wasn't so much, 'Why is my context being lost?', but rather, 'Why aren't I seeing anything after the context is recreated?'.

Yup.

Anyway, I think you're right jyk. Deleting the OpenGL Resources before 'losing' isn't a bad idea anyway. If SDL ever fixes this issue, that doesn't mean the OpenGL context will never ever get 'lost' again. Having a simple reloadTextures() in such a case doesn't hurt.

Also, SFML looks promising. I'll look into that :)
- 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
Yann L
Yann L
Quote:
Original post by stenny
If SDL ever fixes this issue, that doesn't mean the OpenGL context will never ever get 'lost' again. Having a simple reloadTextures() in such a case doesn't hurt.

OpenGL will never 'lose' the context on its own. Never. If it happens, then it's either a driver bug (which is very unlikely to slip through quality control at NV & co, due to it breaking 99% of all OpenGL applications out there) or a bug of the framework (SDL in this case). There's no need for a texture reload function in normal OpenGL operation.

Quote:
Original post by swiftcoder
I broached this issue with the SDL developers back in 2004, and it comes up with alarming regularity on the various mailing lists and forums before and since. Given that SDL has had an explicit API to toggle fullscreen mode since the very beginning, and it is still only supported on X11, I find promises of 1.3 a little lacking...

I find it absolutely ludicrous that SDL still behaves in this idiotic way. As you said, it's been an issue for years now. You'd think that fixing this would be topmost priority. Didn't it also destroy the context everytime you simply resized a window ? Has that been fixed ?
Zakwayda
Zakwayda
Quote:
You'd think that fixing this would be topmost priority. Didn't it also destroy the context everytime you simply resized a window ? Has that been fixed ?
I think the 'destroy context on resize' problem has been fixed (I haven't used that feature though, so I can't say for sure). As for destroying the context on video reset, this has been discussed on the SDL forums recently, I believe for possible inclusion in SDL 1.3. I'm not sure what the status of these revisions is though.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.