SDL_PollEvent似乎阻止窗口表面更新 [英] SDL_PollEvent seems to prevent window surface from updating

查看:54
本文介绍了SDL_PollEvent似乎阻止窗口表面更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

使用课程03:事件驱动的编程提供的代码:

此循环无法更新窗口:

  while(!quit){//处理队列中的事件while(SDL_PollEvent(& e)!= 0){//用户请求退出if(e.type == SDL_QUIT){quit = true;}}//套用图片SDL_BlitSurface(gXOut,NULL,gScreenSurface,NULL);//更新表面SDL_UpdateWindowSurface(gWindow);} 

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

  while(!quit){//套用图片SDL_BlitSurface(gXOut,NULL,gScreenSurface,NULL);//更新表面SDL_UpdateWindowSurface(gWindow);} 

但是它不再包含对 SDL_PollEvent 的单个调用:

  while(!quit){SDL_PollEvent(& e);//套用图片SDL_BlitSurface(gXOut,NULL,gScreenSurface,NULL);//更新表面SDL_UpdateWindowSurface(gWindow);} 

解决方案

SDL_GetWindowSurface文档如果调整窗口大小,该表面将无效.创建初始窗口时,会生成几个事件,例如 SDL_WINDOWEVENT_SHOWN SDL_WINDOWEVENT_EXPOSED .虽然未将窗口标记为用户可调整大小,但我认为窗口管理器仍具有执行调整大小的功能;您可能要检查事件队列中放置了哪些事件(由于我无法重现您的问题-例如特定于窗口管理器).

换句话说,不能保证某些事件后窗口表面会持续存在,因此从理论上讲,刷新事件队列会使表面无效.您需要在刷新事件队列之后在绘制之前在每一帧上获取窗口表面:

  while(!quit){//这里的事件循环//获取要绘制的表面gScreenSurface = SDL_GetWindowSurface(gWindow);//套用图片SDL_BlitSurface(gXOut,NULL,gScreenSurface,NULL);//更新表面SDL_UpdateWindowSurface(gWindow);} 

I'm currently walking through the Lazy Foo tutorials for SDL2 (I'm doing this on a Linux machine) and I'm encountering some kind of bug where the inclusion of SDL_PollEvent in my main loop seems to prevent SDL_UpdateWindowSurface from actually updating. If I leave the SDL_PollEvent loop out, the loaded bmp displays properly. However, if I include the SDL_PollEvent loop or even a call to SDL_PollEvent, then the window never gets updated with an image. Everything else seems to work fine, SDL_PollEvent is queuing events properly and the loop handles the events properly, but for some reason there's a visual discrepancy between the inclusion of SDL_PollEvent vs. leaving it out.

Using the code provided by Lesson 03: Event driven programming:

This loop fails to update the 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 );
}

This loop successfully updates the window with the loaded image:

while( !quit )
{

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

  //Update the surface
  SDL_UpdateWindowSurface( gWindow );
}

But it stops working with the inclusion of a single call to 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 says This surface will be invalidated if the window is resized. Upon initial window creation several events are generated, like SDL_WINDOWEVENT_SHOWN and SDL_WINDOWEVENT_EXPOSED. While window isn't marked as user-resizable, I suppose window manager still have an ability to perform resize; you may want to check which events are placed in your event queue (as I cannot reproduce your problem - may be e.g. window manager specific).

To put it in other worlds, window surface isn't guaranteed to persist after some events, so theoretically flushing event queue can invalidate surface. You need to get window surface after flushing event queue just before drawing, on each frame:

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

这篇关于SDL_PollEvent似乎阻止窗口表面更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆