c++ SDL2函数用于绘制实心圆

hfwmuf9z  于 2023-02-06  发布在  其他
关注(0)|答案(2)|浏览(254)

我正在寻找一个函数,绘制一个填充圆使用SDL2而不使用渲染器在所有。我目前有这个:

void Circle(int center_x, int center_y, int radius, SDL_Color color) {
  eraseOldCircle();

  uint32_t *pixels = (uint32_t *) windowSurface->pixels;
  SDL_PixelFormat *windowFormat = windowSurface->format;
  SDL_LockSurface(windowSurface); // Lock surface for direct pixel access capability

  int radiussqrd = radius * radius;

  for(int x=center_x-radius; x<=center_x+radius; x++) {
    int dx = center_x - x;
    for(int y=center_y-radius; y<=center_y+radius; y++) {
      int dy = center_y - y;
      if((dy * dy + dx * dx) <= radiussqrd) {
        pixels[(y * WIDTH + x)] = SDL_MapRGB(windowFormat, color.r, color.g, color.b);
      }
    }
  }

  SDL_UnlockSurface(windowSurface);
  SDL_UpdateWindowSurface(window);
}

它改编自我在这里找到的另一个函数,它在调用eraseOldCircle后直接将像素绘制到windowSurface(这将游戏的背景图像放回到圆圈的先前位置,有效地将其从那里擦除。)但对于我所需要的来说,它仍然太慢(可能是数学?)。使用直接像素访问画圆的最快方法是什么?我需要它的高速,这样我就可以在2D游戏中使用它。我还没有能够找到任何东西,直到现在,我看到的所有内容都使用SDL_Renderer,但我绝对不应该使用它。
下面是eraseOldCircle(),如果它有帮助的话:

void eraseOldCircle() {
  //Calculate previous position of ball
  SDL_Rect pos = {circlePosition.x-(radius+steps), circlePosition.y-(radius+steps), radius*radius, radius*2+steps};
  SDL_BlitSurface(backgroundImage, &pos, windowSurface, &pos);
}
eivgtgni

eivgtgni1#

我不太清楚如何处理表面和内存管理等问题,但如果这有帮助的话,这里有一个使用SDL_Renderer的版本,它运行得非常快:

void draw_circle(SDL_Renderer *renderer, int x, int y, int radius, SDL_Color color)
{
    SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
    for (int w = 0; w < radius * 2; w++)
    {
        for (int h = 0; h < radius * 2; h++)
        {
            int dx = radius - w; // horizontal offset
            int dy = radius - h; // vertical offset
            if ((dx*dx + dy*dy) <= (radius * radius))
            {
                SDL_RenderDrawPoint(renderer, x + dx, y + dy);
            }
        }
    }
}
e4yzc0pl

e4yzc0pl2#

如果你画了很多圆圈,我猜SDL_UpdateWindowSurface是你花时间最多的地方。

SDL_LockSurface
  // erase and draw all circles (possibly >1000)
  SDL_UnlockSurface
  SDL_UpdateWindowSurface

你可以稍微优化一下你的画圆代码,但是它可能已经足够快了。我也认为SDL_Renderer可能已经足够快了。
The documentation for SDL_UpdateWindowSurface说它会把曲面复制到屏幕上,你只需要每帧做一次。

相关问题