我目前正在浏览SDL2的Lazy Foo教程(我在Linux机器上这样做)我遇到了某种错误,其中在我的主循环中包含SDL_PollEvent
似乎阻止SDL_UpdateWindowSurface
实际更新。如果我将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 );
}
答案 0 :(得分:1)
SDL_GetWindowSurface documentation说This surface will be invalidated if the window is resized
。在初始窗口创建时会生成几个事件,例如SDL_WINDOWEVENT_SHOWN
和SDL_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 );
}