SDL中视频更新延迟显著

3

如果我没记错的话,我以前遇到过这个问题,但是我不记得我是怎么解决它的。

这是我的程序:

#include "SDL.h"

SDL_Surface *screen;
SDL_Event event;

int main(int argc,char *argv[])
{
    SDL_Init(SDL_INIT_VIDEO);
    atexit(SDL_Quit);
    screen = SDL_SetVideoMode(640,480,32,SDL_SWSURFACE);
    int x = 10,y = 10;
    while (1)
    {
        while (SDL_PollEvent(&event))
        {
            if (event.type == SDL_QUIT)
                exit(0);
        }
        int mx,my;
        Uint8 mstate = SDL_GetMouseState(&mx,&my);
        if (mstate & SDL_BUTTON(1)) x = mx,y = my;
        SDL_FillRect(screen,NULL,0);
        *(Uint32*)((Uint8*)screen->pixels+screen->pitch*y+x*sizeof(Uint32)) = 0xFFFFFFFF;
        SDL_UpdateRect(screen,0,0,0,0);
    }
}

当你按下鼠标左键时,黑色背景中会出现一个白色像素,并且它会移动到鼠标光标的位置。问题在于,这个像素在新位置出现之前需要花费相当一部分时间。这不仅仅是像素的问题。当我尝试移动程序窗口时,它也不会立即响应。如果我将函数printf放在while(SDL_PollEvent(&event))循环中的某个位置,它也不会立即响应。另一方面,如果我使用SDL_SetVideoMode做同样的事情,它会在事件发生时立即响应。 此外,只有当FPS和分辨率足够高时才会出现这种情况。如果我将视频模式设置为320x200而不是640x480,或者限制FPS,一切都会按时发生。 顺便说一下,我使用带有Mesa图形驱动程序的Ubuntu 11.10。 那么,这个问题是SDL还是其他软件的错误,还是我的问题?

它在我的电脑上(windows7)很好用。您尝试过双缓冲吗?您也不需要每次迭代都执行 SDL_FillRect(),只有当鼠标被点击时才需要执行(即使那时您也可以只更改单个像素)。 - jrok
1个回答

0

我的电脑(Windows7)上也可以正常运行,在while (1)内的执行时间不到1毫秒。

当您将视频模式设置为较低分辨率时,一切都按时发生的事实表明您的计算机资源不足和/或在Ubuntu 11.10 with Mesa graphics drivers上未经优化的功能。

您需要对每个函数使用的CPU时间进行分析,以找出瓶颈。

一些想法:

  • 将绘图/更新函数放置在if (mstate & SDL_BUTTON(1))
  • 更新更改的像素 -> SDL_UpdateRect(screen,x,y,1,1);
  • 将旧的白色像素更新为黑色,而不是填充整个屏幕。
  • 在while(1)循环结束之前添加SDL_Delay(10);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接