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_SHOWN
和 SDL_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 );
}
我目前正在浏览 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_SHOWN
和 SDL_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 );
}