[SDL] "Perfect" circles

xEsk PiV xeskuu.sdl at gmail.com
Thu Nov 9 09:25:21 PST 2006


Hello,

First, thank you to all for your answars! I'm so glad :)

Second, I made this example to show you how I see the results (I build
it on Windows, my main computer where I work is broken...).

http://img73.imageshack.us/img73/2516/demo01lf8.png
http://img490.imageshack.us/img490/3441/demo02js5.png

Bye and have a nice day! :D

xEsk.

---------

Source code:

#include <math.h>
#include <SDL/SDL.h>

float pre_cos[360];
float pre_sin[360];
bool is_pre_cos_sin_init = false;

const float PI = 3.14159265358979323846;

float RadToDeg(float rad) { return rad * 180 / PI; }
float DegToRad(float deg) { return deg * PI / 180; }

void init_pre_math()
{
 for(int i = 0; i <= 360; i++)
 {
   pre_cos[i] = cos(DegToRad(i));
   pre_sin[i] = sin(DegToRad(i));
 }

 is_pre_cos_sin_init = true;
}

SDL_Rect advance(SDL_Rect pos, float angle, int units)
{
 if (!is_pre_cos_sin_init) init_pre_math();

 int ang = static_cast<int>(-angle);
 ang = (ang < 0) ? (ang % 360) + 360: ang % 360;

 pos.x = pos.x + static_cast<Sint16>(units * pre_cos[ang]);
 pos.y = pos.y + static_cast<Sint16>(units * pre_sin[ang]);

 return pos;
}

/*
  This function is a modification of
    "int _putPixelAlpha(SDL_Surface * surface, Sint16 x, Sint16 y,
Uint32 color, Uint8 alpha);"

  extracted from:
    SDL_gfxPrimitives.h - Graphics primitives for SDL surfaces

    LGPL (c) A. Schiffler
*/

/* Defines for pixel clipping tests (SDL_gfxPrimitives) */

#define clip_xmin(surface) surface->clip_rect.x
#define clip_xmax(surface) surface->clip_rect.x+surface->clip_rect.w-1
#define clip_ymin(surface) surface->clip_rect.y
#define clip_ymax(surface) surface->clip_rect.y+surface->clip_rect.h-1

bool putPixel(SDL_Surface* dst, Sint16 x, Sint16 y, Uint32 color,
const Uint8 alpha)
{
  /* Lock the surface */
  if (SDL_MUSTLOCK(dst))
    if (SDL_LockSurface(dst) < 0)
      return false;

  Uint32 R, G, B, A = 0;
  Uint32 Rmask = dst->format->Rmask,
         Gmask = dst->format->Gmask,
         Bmask = dst->format->Bmask,
         Amask = dst->format->Amask;

  /* First Check if this new pixel is in the surface */
  if (x >= clip_xmin(dst) && x <= clip_xmax(dst) && y >=
clip_ymin(dst) && y <= clip_ymax(dst))
  {
    if (alpha == 255)
      *((Uint16 *)dst->pixels + y * dst->pitch / 2 + x) = color;
    else
    {
      Uint16* pixel = (Uint16*)dst->pixels + y* dst->pitch / 2 + x;
      Uint32 dc = *pixel;

      R = ((dc & Rmask) + (((color & Rmask) - (dc & Rmask)) * alpha >>
8)) & Rmask;
      G = ((dc & Gmask) + (((color & Gmask) - (dc & Gmask)) * alpha >>
8)) & Gmask;
      B = ((dc & Bmask) + (((color & Bmask) - (dc & Bmask)) * alpha >>
8)) & Bmask;

      if (Amask)
        A = ((dc & Amask) + (((color & Amask) - (dc & Amask)) * alpha
>> 8)) & Amask;

      *pixel = R | G | B | A;
    }
    return true;
  }

  /* Unlock the surface */
  if (SDL_MUSTLOCK(dst))
    SDL_UnlockSurface(dst);

  return true;
}

int main (int argc, char *argv[]){
    /* Initialize SDL */
    SDL_Init (SDL_INIT_VIDEO);
    atexit (SDL_Quit);

    /* Set 640x480 16-bits video mode */
    SDL_Surface *screen = SDL_SetVideoMode (320, 250, 16,
SDL_SWSURFACE | SDL_DOUBLEBUF);
    /* white screen */
    SDL_FillRect(screen, NULL, SDL_MapRGB (screen->format, 255, 255, 255));

    SDL_Rect position;
    position.x = 160;
    position.y = 240;

    /* example: */
    for (int n = 0; n < 360; n++)
    {
      position = advance(position, n, 3);
      putPixel(screen, position.x, position.y, 0, 255);
    }
    /* Make sure everything is displayed on screen */
    SDL_Flip(screen);

    /* main loop */
    int done = 0;
    while (!done)
    {
      SDL_Event event;
      /* Check for events */
      while (SDL_PollEvent (&event))
      {
        switch (event.type)
        {
          case SDL_KEYDOWN:
            break;
          case SDL_QUIT:
            done = 1;
            break;
          default:
            break;
        }
      }
    }
    return 0;
}




More information about the SDL mailing list