#6 Autoload textures after OpenGL context re-creation

open
Matthias Baas
None
5
2010-05-16
2010-04-08
Alex
No

My previous patch (2977469 - Resize capability for viewer.py) introduced the following problem: on Windows, when using textured objects,
the texture disappears after resizing the window. On Linux, the same textures work fine.

It seems to be a Pygame/SDL problem, since some implementations (especially the Win32 one) destroy and recreate the OpenGL context when resizing
the window. After this, all the textures and display lists used in OpenGL code will have to be reloaded.

Here are some links with discussions on this problem:

http://www.gamedev.net/community/forums/topic.asp?topic_id=556486
http://lists.libsdl.org/pipermail/sdl-libsdl.org/2009-October/072897.html
http://bugzilla.libsdl.org/show_bug.cgi?id=40

This fix tests whether the texture is still valid, using glIsTexture(...) in glmaterial.cpp.
If it is not, it means OpenGL context was recreated, and a texture reload is scheduled automatically.

Therefore, user programs do not have to worry about OpenGL context recreation and should work unmodified.

If cgkit uses textures or display lists in other places, a similar fix should be applied.

Regards,
Alex

Discussion

  • Alex
    Alex
    2010-04-08

    Autoload textures after OpenGL context re-creation

     
  • Matthias Baas
    Matthias Baas
    2010-05-03

    Right, it does happen on OSX as well.

    I'm a bit hesitant to apply this patch though and I am rather tempted to revert the previous patch that introduced the resize feature. I have never seen this happen in other GUI toolkits, so this seems to be a genuine bug in SDL and should actually be fixed there. The OpenGL drawing code is not specific to a particular toolkit (you could just as well use it with PyQt, wxWidgets, etc.) which is why I don't like the idea of adding "hacks" to work around bugs in SDL. The other thing, as you said, is that anybody using display lists or other stuff that is tied to a context has to be aware of this and always check if the resource is still there or not. People can write their own OpenGL drawing code in custom geometry, so they would have to be aware of this problem (which I doubt they are).

    How essential is that resizing functionality for your current application? If this is enabled, would it be an option to listen to the resize event and update textures manually (for example, by setting their name again)?

    Another "fix" might be switching to a different toolkit or adding the ability that the viewer could be used not only with pygame but also with other toolkits (whatever the user has installed). Support for a tablet or space mouse might be a bit tricky though....

     
  • Alex
    Alex
    2010-05-04

    It may be either a bug, or a limitation in Win32 OpenGL. You are right, hacks are ugly, but I don't think the problem will be fixed in SDL soon (see the discussion links from patch description).

    My users were very happy when I added the resize capability to the application, so I would like to keep it.

    Also, while experimenting with smaller cgkit programs, I often maximize the viewer window, and other times resize it to about 300x100 to see the console in parallel.

    My suggestion is to mark the resize feature as EXPERIMENTAL for now, and use a command line switch (e.g. -R, --resize).
    When it will work without hacking, we could let it enabled by default.

    Btw, my application is here:

    http://alexdu.github.com/robot-sandbox/

    I'm using it for the robotics laboratory classes, and for now, only the Windows version works out of the box.

    I just found another fix, which seems to be a bit more elegant:

    http://www.cegui.org.uk/wiki/index.php/Using_CEGUI_with_SDL_and_OpenGL#Change_of_window_size

    case SDL_VIDEORESIZE:
    renderer->grabTextures();
    //your resize code here, including the SDL_SetVideoMode call
    renderer->restoreTextures();
    renderer->setDisplaySize(CEGUI::Size(e.resize.w, e.resize.h));
    break;

    So we could implement grabTextures and restoreTextures in viewer.py, and this should cover also the custom OpenGL drawing code. If you agree to this solution, I could try to create a new patch.

    Alex

     
  • Matthias Baas
    Matthias Baas
    2010-05-16

    A solution that responds to the resize event looks nicer to me as it works on the topmost level (the viewer application) and not on the bottommost one (the rendering code).
    I have just pushed a small modification to the viewer that "dirties" all texture objects when a resize occurs. It iterates over all the texture objects in the scene and sets their name again which will mark them as dirty and during the next redraw the texture objects get recreated.
    Let me know if this works for you (it does here on OSX with demo4.py).
    If other code ever needs to be informed as well, we could also emit a cgkit event that other components could connect to. But so far, I think the texture objects are the only resources that get destroyed.

    Cheers,

    - Matthias -

     
  • Matthias Baas
    Matthias Baas
    2010-05-16

    • assigned_to: nobody --> mbaas