]> git.itanic.dy.fi Git - sdl-planets/commitdiff
draw_planet: Draw circular planets
authorTimo Kokkonen <kaapeli@itanic.dy.fi>
Sat, 20 Mar 2010 11:51:40 +0000 (13:51 +0200)
committerTimo Kokkonen <kaapeli@itanic.dy.fi>
Sat, 20 Mar 2010 11:51:40 +0000 (13:51 +0200)
This looks better than square planets, doh...

Signed-off-by: Timo Kokkonen <kaapeli@itanic.dy.fi>
planet.c

index e6716adec5c92383af13224ccaaa863d09a0f83c..9e44e099e623c831ee41d0da54319b1ad10032b4 100644 (file)
--- a/planet.c
+++ b/planet.c
@@ -40,7 +40,8 @@ void draw_planet(SDL_Surface *screen, struct planet *p,
                 const struct camera *cam)
 {
        struct vector pos;
-       int radius = p->radius * cam->zoom;
+       float radius = p->radius * cam->zoom;
+       float r2 = radius * radius;
        int x, x_start, y, x_end, y_end;
 
        vector_sub(&p->pos, &cam->pos, &pos);
@@ -48,15 +49,35 @@ void draw_planet(SDL_Surface *screen, struct planet *p,
        pos.x += screen->w / 2;
        pos.y += screen->h / 2;
 
-       x_start = MAX(pos.x - radius, 0);
        y = MAX(pos.y - radius, 0);
 
-       x_end = MIN(pos.x + radius + 1, screen->w);
-       y_end = MIN(pos.y + radius + 1, screen->h);
-
-       for (; y < y_end; y++)
-               for (x = x_start; x < x_end; x++)
-                       putpixel(screen, x, y, p->r, p->g, p->b);
+       if (radius * 2 <= 1 ) {
+               if (pos.x >= 0 && pos.x < screen->w &&
+                   pos.y >= 0 && pos.y < screen->h)
+                       putpixel(screen, (int)pos.x, (int)pos.y,
+                                p->r, p->g, p->b);
+               return;
+       }
+
+       for (; y < MIN(pos.y + radius, screen->h); y++) {
+               int offset;
+               unsigned char *buf = screen->pixels;
+               float y2 = (y - pos.y);
+
+               y2 = sqrt(r2 - y2 * y2);
+               x_start = pos.x - y2;
+               x_end = pos.x + y2;
+               x_start = MAX(0, x_start);
+               x_end = MIN(x_end, screen->w);
+
+               offset = y * screen->pitch + x_start * 4;
+               for (x = x_start; x < x_end; x++) {
+                       buf[offset++] = p->b;
+                       buf[offset++] = p->g;
+                       buf[offset++] = p->r;
+                       offset++;
+               }
+       }
 }
 
 int gravitize_planets(struct planet *a, struct planet *b, const double time)