【问题标题】:SDL Toggling Fullscreen reveals frameSDL 切换全屏显示帧
【发布时间】:2011-12-03 12:31:05
【问题描述】:

在将全屏 SDL 应用程序切换到窗口并返回时遇到问题:

SDL_SetVideoMode( (int)screenSize.x, (int)screenSize.y, 32, SDL_NOFRAME | SDL_FULLSCREEN | SDL_OPENGL );
// now upload all active textures back into the GPU

// toggle from fullscreen to windowed
SDL_SetVideoMode( (int)screenSize.x, (int)screenSize.y, 32, SDL_OPENGL );

这里的问题是“SDL_NOFRAME”标志似乎不起作用 - 我实际上在全屏应用中看到了一个框架!

注意:“框架”是指标题栏上带有应用程序名称的 Windows 窗口框架,以及最小化、恢复和关闭按钮。

如果我直接以全屏或窗口模式启动应用程序,一切正常,只是切换不起作用。如果我对窗口模式和全屏模式都使用 SDL_NOFRAME,它会按预期工作,但这不是我想要的。

编辑: 可以在此处阅读此功能的文档: http://www.libsdl.org/cgi/docwiki.cgi/SDL_SetVideoMode

从全屏 -> 窗口化 -> 全屏,错误如上。 从窗口->全屏, 结果略有不同,我看到的是黑条而不是框架...

【问题讨论】:

    标签: c++ sdl


    【解决方案1】:

    您使用的是哪个版本的 SDL?我认为它是 SDL-1.2.14 并尝试使用该版本进行以下操作:

    #include "SDL.h"
    
    int main(int argc, char *argv[])
    {
        SDL_Init(SDL_INIT_VIDEO);
    
        SDL_Surface *screen;
    #if 1
        screen = SDL_SetVideoMode(640, 480, 32, SDL_OPENGL);
        SDL_Delay(2000);
        screen = SDL_SetVideoMode(640, 480, 32, SDL_OPENGL | SDL_FULLSCREEN);
        SDL_Delay(5000);
        screen = SDL_SetVideoMode(640, 480, 32, SDL_OPENGL);
        SDL_Delay(5000);
    #else
        screen = SDL_SetVideoMode(640, 480, 32, SDL_OPENGL | SDL_FULLSCREEN);
        SDL_Delay(2000);
        screen = SDL_SetVideoMode(640, 480, 32, SDL_OPENGL);
        SDL_Delay(5000);
        screen = SDL_SetVideoMode(640, 480, 32, SDL_OPENGL | SDL_FULLSCREEN);
        SDL_Delay(5000);
    #endif
    
        SDL_Quit();
        return 0;
    }
    

    根据预处理器标志集,代码会从窗口化到全屏并返回或相反。

    我没有在全屏模式下获得窗口框架,而省略 SDL_FULLSCREEN 时有一个窗口框架。我还将SDL_SetVideoMode 的返回值分配给一个变量,因为这可能会改变。当切换到全屏窗口时,可能仍会显示您处于窗口模式时碰巧显示的屏幕内容。在全屏模式下,我看到了位于屏幕左上角的 SDL_app 窗口。您必须清空屏幕以确保只显示您自己的东西。

    还有一个SDL_WM_ToggleFullscreen 函数。它不适用于 Windows,但文档的链接包含有关如何以可移植方式处理切换窗口/全屏的示例。 SDL 文档中的代码示例如下所示:

    /* Anyone may copy and alter this fragment of pseudo-code and use it however they wish */
    #include "SDL.h" /* The only library needed to do this */
    
    Uint32 flags = SDL_SWSURFACE; /* Start with whatever flags you prefer */
    SDL_Surface *screen = SDL_SetVideoMode(640, 480, 32, flags); /* Start with whatever settings you prefer */
    
    /* -- Portable Fullscreen Toggling --
    As of SDL 1.2.10, if width and height are both 0, SDL_SetVideoMode will use the
    width and height of the current video mode (or the desktop mode, if no mode has been set).
    Use 0 for Height, Width, and Color Depth to keep the current values. */
    
    flags = screen->flags; /* Save the current flags in case toggling fails */
    screen = SDL_SetVideoMode(0, 0, 0, screen->flags ^ SDL_FULLSCREEN); /*Toggles FullScreen Mode */
    if(screen == NULL) screen = SDL_SetVideoMode(0, 0, 0, flags); /* If toggle FullScreen failed, then switch back */
    if(screen == NULL) exit(1); /* If you can't switch back for some reason, then epic fail */
    

    该示例没有提及在切换窗口模式时使用SDL_OPENGL 标志会发生什么。我担心 OpenGL 上下文可能会被破坏并重新创建,这意味着您必须在切换时重新初始化 OpenGL 并重新加载所有纹理和几何图形 窗口模式。

    编辑:

    我能够确认,OpenGL 上下文在切换显示模式后被破坏:

    创建显示列表

    GLuint list = glGenLists(1);
    glNewList(list, GL_COMPILE);
    glBegin(GL_LINES);
    glVertex2f(0.0f, 0.0f);
    glVertex2f(1.0f, 1.0f);
    glEnd();
    glEndList();
    

    并调用它

    glClear(GL_COLOR_BUFFER_BIT);
    glCallList(list);
    

    工作。在SDL_SetVideoMode 调用同一个列表后,没有任何东西可以绘制。

    【讨论】:

    • 您好 Trenki,感谢您的回复。我确实在使用 SDL 1.2.14,并且在调整大小并重新加载所有纹理/几何图形后,我正在重新初始化 OpenGL 上下文。我也在清除 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);每一帧,所以应该只显示我的东西!
    • 好吧,这有点奇怪,但是当我改变我对 setvideomode 的调用以使前 3 个参数为空时,它似乎可以工作了!
    猜你喜欢
    • 2017-08-31
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-03
    • 1970-01-01
    相关资源
    最近更新 更多