SDL_PollEvent 似乎阻止了 window 表面更新

SDL_PollEvent seems to prevent window surface from updating

我目前正在浏览 SDL2 的 Lazy Foo 教程(我在 Linux 机器上执行此操作)并且我遇到了一些包含 SDL_PollEvent 的错误在我的主循环中似乎阻止 SDL_UpdateWindowSurface 实际更新。如果我离开 SDL_PollEvent 循环,加载的 bmp 会正确显示。但是,如果我包含 SDL_PollEvent 循环或什至调用 SDL_PollEvent,则 window 永远不会更新图像。其他一切似乎都工作正常,SDL_PollEvent 正在正确排队事件并且循环正确处理事件,但由于某种原因,包含 SDL_PollEvent 与将其排除在外之间存在视觉差异。

使用Lesson 03: Event driven programming提供的代码:

此循环无法更新 window:

while( !quit )
{
  //Handle events on queue
  while( SDL_PollEvent( &e ) != 0 )
  {
    //User requests quit
    if( e.type == SDL_QUIT )
    {
      quit = true;
    }
  }

  //Apply the image
  SDL_BlitSurface( gXOut, NULL, gScreenSurface, NULL );

  //Update the surface
  SDL_UpdateWindowSurface( gWindow );
}

此循环使用加载的图像成功更新 window:

while( !quit )
{

  //Apply the image
  SDL_BlitSurface( gXOut, NULL, gScreenSurface, NULL );

  //Update the surface
  SDL_UpdateWindowSurface( gWindow );
}

但它停止工作,包含对 SDL_PollEvent:

的单个调用
while( !quit )
{
  SDL_PollEvent(&e);

  //Apply the image
  SDL_BlitSurface( gXOut, NULL, gScreenSurface, NULL );

  //Update the surface
  SDL_UpdateWindowSurface( gWindow );
}

SDL_GetWindowSurface documentation 表示 This surface will be invalidated if the window is resized。在初始 window 创建时会生成多个事件,例如 SDL_WINDOWEVENT_SHOWNSDL_WINDOWEVENT_EXPOSED。虽然 window 未标记为用户可调整大小,但我想 window 经理仍然可以执行调整大小;您可能需要检查您的事件队列中放置了哪些事件(因为我无法重现您的问题 - 可能例如 window 特定于经理)。

换句话说,window surface 不能保证在某些事件发生后仍然存在,因此理论上刷新事件队列可以使 surface 无效。在绘制之前刷新事件队列后,您需要在每一帧上获得 window 表面:

while( !quit )
{
  // event loop here

  // get surface to draw on
  gScreenSurface = SDL_GetWindowSurface(gWindow);

  //Apply the image
  SDL_BlitSurface( gXOut, NULL, gScreenSurface, NULL );

  //Update the surface
  SDL_UpdateWindowSurface( gWindow );
}