SDL2:如何正确切换全屏?

17

我在我的程序中遇到了退出全屏模式的问题。进入全屏模式是正确的,但尝试返回窗口模式会失败,唯一的效果是光标再次显示。

下面是能够重现此问题的MCVE/SSCCE代码:

void ToggleFullscreen(SDL_Window* Window) {
    Uint32 FullscreenFlag = SDL_WINDOW_FULLSCREEN;
    bool IsFullscreen = SDL_GetWindowFlags(Window) & FullscreenFlag;
    SDL_SetWindowFullscreen(Window, IsFullscreen ? 0 : FullscreenFlag);
    SDL_ShowCursor(IsFullscreen);
}

int main() {
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window* Window = SDL_CreateWindow("",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);

    bool Exit = false;
    for (SDL_Event Event; !Exit;) {
        SDL_WaitEvent(&Event);
        if (Event.type == SDL_KEYDOWN) {
            switch (Event.key.keysym.sym) {
                case SDLK_f: ToggleFullscreen(Window); break;
                case SDLK_q: Exit = true; break;
            }
        }
    }
    SDL_DestroyWindow(Window);
    SDL_Quit();
}

SDL_SetWindowFullscreen返回0,就像操作成功一样。我做错了什么?(我正在使用SDL 2.0.3和OS X 10.10.3。)

4个回答

8

似乎在v2.0.4分支中有一个修补程序可以解决这个漏洞。我想我只能等到它发布了。 - emlai

1
即使现在,SDL_SetWindowFullscreen 仍然存在问题。我尝试使用这个函数为我的视频播放器添加全屏功能。但是,在全屏和窗口模式之间切换时,它会随机崩溃。
我找到了一个临时解决方法,目前似乎可以正常工作。
SDL_DisplayMode dm;

if (SDL_GetDesktopDisplayMode(0, &dm))
{
    printf("Error getting desktop display mode\n");
    return -1;
}

if (SDL_PollEvent(&event))
{
    switch (event.type)
    {
        case SDL_KEYUP:
            switch (event.key.keysym.sym)
            {
                case SDLK_f:
                    SDL_RestoreWindow(screen); //Incase it's maximized...
                    SDL_SetWindowSize(screen, dm.w, dm.h + 10);
                    SDL_SetWindowPosition(screen, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
            }
            break;
    }
}

基本上是“假”全屏。它调整窗口大小,使客户区覆盖整个屏幕,并将最小化、最大化、退出按钮隐藏在屏幕外。
希望这可以帮助到您。

0

在SDL2中,这对我来说很好用(按下f可以切换开/关,按下q退出):

  SDL_Window* window = SDL_CreateWindow("Fullscreen demo", 0, 0, 640, 480, 0);
  SDL_Renderer* renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

  SDL_Event event;
  bool fullScreen = false;
  SDL_bool running = SDL_TRUE;

  while (running) {
    while (SDL_PollEvent(&event)) {
      switch (event.type) {
      case SDL_QUIT:
        running = SDL_FALSE;
        break;
      case SDL_KEYDOWN:
        if(event.key.keysym.scancode == SDL_SCANCODE_F){
          fullScreen = !fullScreen;
          if(fullScreen){
            SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
          }
          else{
            SDL_SetWindowFullscreen(window, 0);
          }
        }
        if(event.key.keysym.scancode == SDL_SCANCODE_Q){
          running = SDL_FALSE;
        }
        break;
      default: break;
      }
    }
    
    // drawing stuff here...
    
    // swap and display buffer
    SDL_RenderPresent(renderer);
  }


0

我知道这可能是五年后的事情,但我也遇到了同样的问题,我发现你的代码比必要的复杂得多。所以我想为任何来到这里的人添加一些内容:

//somewhere outside the loop
bool isFullScreen = true;

void toggleFullScreen(SDL_Window* window, bool currentState)
{
    isFullScreen = !currentState;

    SDL_SetWindowFullscreen(window, !currentState);
    SDL_ShowCursor(currentState);
}

只需要将 isFullscreen 放置在当前状态中,就可以使用按键事件来实现一个很好的切换。


2
SDL_SetWindowFullscreen 不接受布尔值,而是接受 SDL_WINDOW_FULLSCREEN、SDL_WINDOW_FULLSCREEN_DESKTOP 或 0。 - emlai
实际上,它确实需要一个布尔值。它需要一个1或0。当您传递SDL_WINDOW_FULLSCREEN时,这就是您所做的全部。因此,您可以只传递一个布尔值(true == 1,false == 0)。 - Lyingdutchman
我知道它能工作,因为我正在编写一个通用的SDL2窗口并使用它。请参考我的实现:https://github.com/LyingDutch/SDL2Window - Lyingdutchman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接