SDL_PollEvent似乎阻止窗口表面更新 [英] SDL_PollEvent seems to prevent window surface from updating
问题描述
我目前正在浏览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屋!