SDL provides 2D accelerated rendering including pixel points, rectangles and lines. Furthermore you can set device independent resolution and nearest pixel sampling. So you can use the resolution of the C64 (320 x 200) on a big window (1280 x 800) for example. The pixels are scaled accordingly.
But not always. If you draw a line then it's pixels are only scaled if that line ist either a horizontal or a vertical one. Sloped lines are rendered without pixel scaling.
That's because lines are rendered as rectangles internally:
Code:
static int
RenderDrawLinesWithRects(SDL_Renderer * renderer,
const SDL_Point * points, const int count)
{
SDL_FRect *frect;
SDL_FRect *frects;
SDL_FPoint fpoints[2];
int i, nrects = 0;
int retval = 0;
SDL_bool isstack;
frects = SDL_small_alloc(SDL_FRect, count-1, &isstack);
if (!frects) {
return SDL_OutOfMemory();
}
for (i = 0; i < count-1; ++i) {
if (points[i].x == points[i+1].x) {
const int minY = SDL_min(points[i].y, points[i+1].y);
const int maxY = SDL_max(points[i].y, points[i+1].y);
frect = &frects[nrects++];
frect->x = points[i].x * renderer->scale.x;
frect->y = minY * renderer->scale.y;
frect->w = renderer->scale.x;
frect->h = (maxY - minY + 1) * renderer->scale.y;
} else if (points[i].y == points[i+1].y) {
const int minX = SDL_min(points[i].x, points[i+1].x);
const int maxX = SDL_max(points[i].x, points[i+1].x);
frect = &frects[nrects++];
frect->x = minX * renderer->scale.x;
frect->y = points[i].y * renderer->scale.y;
frect->w = (maxX - minX + 1) * renderer->scale.x;
frect->h = renderer->scale.y;
} else {
/* FIXME: We can't use a rect for this line... */
fpoints[0].x = points[i].x * renderer->scale.x;
fpoints[0].y = points[i].y * renderer->scale.y;
fpoints[1].x = points[i+1].x * renderer->scale.x;
fpoints[1].y = points[i+1].y * renderer->scale.y;
retval += QueueCmdDrawLines(renderer, fpoints, 2);
}
}
retval += QueueCmdFillRects(renderer, frects, nrects);
SDL_small_free(frects, isstack);
if (retval < 0) {
retval = -1;
}
return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
}
Did you notice that FIXME? -- I wrote an additional procedure in order to draw sloped pixel lines. It makes use of that good old Bresenham algorithm. Also each line is devided into horizontal or vertical segments which can be rendered quite fast by SDL:
Code:
procedure SDL_RenderDrawLineSloped(renderer: PSDL_renderer; x1, y1, x2, y2: longint);
var
dx, dy, rx, ry: longint;
error, c: longint;
begin
dy := y2-y1;
if dy>=0 then ry := 1
else begin
dy := -dy;
ry := -1
end;
y2 := y1;
dx := x2-x1;
if dx>=0 then rx := 1
else begin
dx := -dx;
rx := -1
end;
x2 := x1;
{ slope is moderate (dy/dx <= 1) }
if dx>=dy then begin
error := dx shr 1;
for c := 0 to dx do begin
inc(x2, rx);
dec(error, dy);
if error<0 then begin
SDL_RenderDrawLine(renderer, x1, y1, x2-rx, y1);
x1 := x2;
inc(error, dx);
inc(y1, ry);
end;
end;
{ slope is very moderate (dy/dx <= 0.5) : complete line ending }
if dx>=dy+dy then SDL_RenderDrawLine(renderer, x1, y1, x2-rx, y1);
end
{ slope is steep (dy/dx > 1) }
else begin
error := dy shr 1;
for c := 0 to dy do begin
inc(y2, ry);
dec(error, dx);
if error<0 then begin
SDL_RenderDrawLine(renderer, x1, y1, x1, y2-ry);
y1 := y2;
inc(error, dy);
inc(x1, rx);
end;
end;
{ slope is very steep (dy/dx >= 2) : complete line ending }
if dy>=dx+dx then SDL_RenderDrawLine(renderer, x1, y1, x1, y2-ry);
end;
end;
Bookmarks