[QUERY] How Do You Draw A Circle in SDL2? : SDL2

To draw a colour-filled rectangle in SDL, you can easily do it in 3 steps.

To draw a circle in SDL, there is no SDL_RenderDrawCircleI(int x, int y, radius)

Is there a reason for this?

I’ve attached the code, using the Midpoint Circle Algorithm, for drawing a circle for those who Googled their way here.

To draw a rectangle

SDL_Rect fillRect = { SCREEN_WIDTH / 4, SCREEN_HEIGHT / 4, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 };

SDL_SetRenderDrawColor( gRenderer, 0xFF, 0x00, 0x00, 0xFF );

SDL_RenderFillRect( gRenderer, &fillRect );

To draw a circle

void DrawCircle(SDL_Renderer* renderer, int32_t centreX, int32_t centreY, int32_t radius)
{
const int32_t diameter = (radius * 2);

int32_t x = (radius - 1);
int32_t y = 0;
int32_t tx = 1;
int32_t ty = 1;
int32_t error = (tx - diameter);

while (x >= y)
{
// Each of the following renders an octant of the circle
SDL_RenderDrawPoint(renderer, centreX + x, centreY - y);
SDL_RenderDrawPoint(renderer, centreX + x, centreY + y);
SDL_RenderDrawPoint(renderer, centreX - x, centreY - y);
SDL_RenderDrawPoint(renderer, centreX - x, centreY + y);
SDL_RenderDrawPoint(renderer, centreX + y, centreY - x);
SDL_RenderDrawPoint(renderer, centreX + y, centreY + x);
SDL_RenderDrawPoint(renderer, centreX - y, centreY - x);
SDL_RenderDrawPoint(renderer, centreX - y, centreY + x);

  if (error <= 0)
  {
  	++y;
  	error += ty;
  	ty += 2;
  }

  if (error > 0)
  {
  	--x;
  	tx += 2;
  	error += (tx - diameter);
  }

}
}

SDL uses 3D hardware to render squares (and just recently triangles) as a low-level base for you to create anything from. If you were coding graphics in Direct3D or OpenGL, you would still need to make your own circle code, which is more high-level. This is why.

It should be noted that using SDL_RenderDrawPoint is going to incur a severe performance penalty (at least on some backends). It would be better to coalesce the points and use SDL_RenderDrawPoints or even better (for a filled circle anyway) to rasterize the circle into lines and use SDL_DrawLines

The best performing method would be to convert the circle into a triangle fan and then draw it using SDL 2.0.17’s SDL_RenderGeometry()

That would only work for filled circles wouldn’t it? Otherwise it would look like a spoked wheel.

This seems like SDL is missing a basic function. How do you draw a basic shape like a circle? Code it yourself.

Out of curiosity, when you say “backend”, are you referring to servers or the desktop PC that developers work on?

How would you code it?

SDL2_gfx will draw circles, and a lot more besides. I’ve also extended it to provide improved support for drawing anti-aliased shapes. This demo was created using my extended version (with some wrapper code):

aagfxdem

This has nothing to do with “desktops” or “servers” I’m referring to the rendering backend (eg OpenGL or DirectX etc). I shouldn’t have even qualified it. Calling a function per pixel will always be slower than simply building a list of points.

Exactly the same way only instead of calling SDL_RenderDrawPoint for every pixel you instead insert into a preallocated array of SDL_Points and then call SDL_RenderDrawPoints at the end. For a filled circle just find the 2 end points of each line and call SDL_RenderDrawLines instead.

Beware that the ‘end point’ bug (which may have been fixed now, but is common in SDL2 releases still in use) makes the use of SDL_RenderDrawLine() problematical for drawing shapes, because you can’t be sure that exactly the pixels you want to be plotted will be. So for safety I still use SDL_RenderDrawPoints(), albeit that it is probably a little slower.

I’ll have to remember that and try it.