【问题标题】:Increasing Speed of per-pixel Access of SDL提高 SDL 的每像素访问速度
【发布时间】:2012-07-16 17:15:07
【问题描述】:

我开始制作康威生命游戏的 SDL 版本。我以前使用过 SDL,但从未直接访问像素。我编写了以下代码,它的执行速度非常慢。我尝试过使用 UpdateRect 而不是 Flip,两者之间没有区别。我用 SWSURFACE 初始化了 SDL。有什么我可以做的来改善它吗?我想到了解决方法(将 bmp 用于更大的像素等)。绘图数组是 640x480 的 Cell 对象,它只包含一个可以通过 getter/setter 访问的成员 'alive'。我要做的就是让鼠标有效地绘制像素。我需要使用 OpenGL 来执行此操作吗?我想澄清一下,我意识到现代硬件并不意味着每像素访问。但鉴于这是我需要的,我正在寻找解决方案。

while (quit == false)
    {
            int pX = 0;
            int pY = 0;
            bool did_set = false;
            if (SDL_PollEvent(&event))
            {
                    switch(event.type)
                    {
                            case SDL_MOUSEBUTTONDOWN:
                                    plot[event.button.y][event.button.x].setAlive(true);
                                    pX = event.button.x;
                                    pY = event.button.y;
                                    did_set = true;
                            break;
                            case SDL_QUIT:
                                    quit = true;
                            break;
                    }
            }

            if (did_set)
            {
                    SDL_LockSurface(screen);
                    Uint32 p = SDL_MapRGB(screen->format, 255,255,255);
                    putpixel(screen, pX, pY, p);
                    SDL_UnlockSurface(screen);
            }
            SDL_Flip(screen);
    }

【问题讨论】:

  • 将鼠标移动到容器中,并在一个地方完成所有绘图。即渲染()函数。此外,您正在进行的比较次数,if .. 的 switch 语句将您的代码分解为处理您需要的任何事件的函数或对象成员函数。并尽可能少地保持循环内的实际处理。执行所有这些操作,您应该会看到执行速度显着提高。目前使用您发布的代码,您在 while 循环的每次迭代中更新屏幕,而您真正需要做的就是更新屏幕
  • 在关键时刻,例如当鼠标移动时,以及当窗口需要重新绘制(调整大小、模糊等)时

标签: c++ sdl


【解决方案1】:

每个“帧”只处理一个事件。

尝试将SDL_PollEvent() if 更改为while

const Uint32 p = SDL_MapRGB(screen->format, 255,255,255);
while (quit == false)
{
    while (SDL_PollEvent(&event))
    {
        switch(event.type)
        {
        case SDL_MOUSEBUTTONDOWN:
            {
                int pX = event.button.x;
                int pY = event.button.y;
                plot[pY][pX].setAlive(true);
                SDL_LockSurface(screen);
                putpixel(screen, pX, pY, p);
                SDL_UnlockSurface(screen);
            }
            break;
        case SDL_QUIT:
            quit = true;
            break;
        }
    }

    SDL_Flip(screen);
}

【讨论】:

    【解决方案2】:

    您可能会在一帧中收到多个事件,但您一次只处理一个,然后等待下一帧。在几乎每个 SDL 示例代码中,您都会在 while 语句中看到 SDL_PollEvent

    此外,鼠标一次可以移动多个像素,因此您必须将整条线从旧位置绘制到新位置(例如使用 Bresenham 算法);此时你最好避免使用putpixel,因为当你实际上只是沿着列和线走时,它会进行整个乘法以获得内存中的位置(只需加法即可完成)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-11
      • 1970-01-01
      • 2012-06-15
      • 2023-03-10
      • 1970-01-01
      • 2017-10-15
      相关资源
      最近更新 更多