【问题标题】:SDL_PollEvent seems to prevent window surface from updatingSDL_PollEvent 似乎阻止窗口表面更新
【发布时间】:2016-10-18 16:34:35
【问题描述】:

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

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

此循环无法更新窗口:

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 );
}

这个循环成功地用加载的图像更新了窗口:

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 );
}

【问题讨论】:

  • 你是在声明e吗?某处有SDL_Event e; 吗?
  • 您还在正确的线程中调用 SDL_PollEvent 吗?来自文档:“由于此函数隐式调用 SDL_PumpEvents(),因此您只能在设置视频模式的线程中调用此函数。” wiki.libsdl.org/SDL_PollEvent
  • 是的,除了我上面展示的代码外,其余代码与教程中使用的代码相同,可以从页面下载。
  • 另外,这不是SDL_Event 无法正常工作的问题,它可以很好地接收事件,如果我愿意,我可以处理它们。而且本教程中没有多线程代码,因此 SDL 的边缘情况在这里应该不是问题。问题是我似乎无法在不影响图像是否成功显示在窗口中的情况下包含SDL_Event
  • @oldmanmike 可能存在使窗口表面无效的调整大小事件。在事件循环之后但在 blitting 之前获取窗口表面。

标签: c++ sdl sdl-2


【解决方案1】:

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

在其他世界中,窗口表面不能保证在某些事件之后持续存在,因此理论上刷新事件队列可以使表面无效。在绘制之前,您需要在刷新事件队列之后在每一帧上获取窗口表面:

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 );
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-27
    相关资源
    最近更新 更多