mirror of https://github.com/encounter/SDL.git
Added line drawing using Bresenham's line algorithm (thanks @rtrussell!)
This commit is contained in:
parent
fe3a33a092
commit
9f56faeedc
|
@ -2782,13 +2782,129 @@ SDL_RenderDrawLineF(SDL_Renderer * renderer, float x1, float y1, float x2, float
|
||||||
return SDL_RenderDrawLinesF(renderer, points, 2);
|
return SDL_RenderDrawLinesF(renderer, points, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int plotLineLow(SDL_Renderer *renderer, float x0, float y0, float x1, float y1)
|
||||||
|
{
|
||||||
|
int retval = 0;
|
||||||
|
float dx = x1 - x0;
|
||||||
|
float dy = y1 - y0;
|
||||||
|
int yi = 1;
|
||||||
|
float x, y, D;
|
||||||
|
int count = (x1 - x0 + 1);
|
||||||
|
SDL_bool isstack;
|
||||||
|
SDL_FPoint *points = SDL_small_alloc(SDL_FPoint, count, &isstack);
|
||||||
|
SDL_FPoint *tmp = points;
|
||||||
|
|
||||||
|
if (dy < 0) {
|
||||||
|
yi = -1;
|
||||||
|
dy = -dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
D = (2 * dy) - dx;
|
||||||
|
y = y0;
|
||||||
|
for (x = x0; x <= x1; ++x) {
|
||||||
|
tmp->x = x;
|
||||||
|
tmp->y = y;
|
||||||
|
tmp++;
|
||||||
|
if (D > 0) {
|
||||||
|
y += yi;
|
||||||
|
D += 2 * (dy - dx);
|
||||||
|
} else {
|
||||||
|
D += 2*dy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
|
||||||
|
retval = RenderDrawPointsWithRectsF(renderer, points, count);
|
||||||
|
} else {
|
||||||
|
retval = QueueCmdDrawPoints(renderer, points, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_small_free(points, isstack);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int plotLineHigh(SDL_Renderer *renderer, float x0, float y0, float x1, float y1)
|
||||||
|
{
|
||||||
|
int retval = 0;
|
||||||
|
float dx = x1 - x0;
|
||||||
|
float dy = y1 - y0;
|
||||||
|
int xi = 1;
|
||||||
|
float x, y, D;
|
||||||
|
int count = (y1 - y0 + 1);
|
||||||
|
SDL_bool isstack;
|
||||||
|
SDL_FPoint *points = SDL_small_alloc(SDL_FPoint, count, &isstack);
|
||||||
|
SDL_FPoint *tmp = points;
|
||||||
|
|
||||||
|
if (dx < 0) {
|
||||||
|
xi = -1;
|
||||||
|
dx = -dx;
|
||||||
|
}
|
||||||
|
|
||||||
|
D = (2 * dx) - dy;
|
||||||
|
x = x0;
|
||||||
|
for (y = y0; y <= y1; ++y) {
|
||||||
|
tmp->x = x;
|
||||||
|
tmp->y = y;
|
||||||
|
tmp++;
|
||||||
|
if (D > 0) {
|
||||||
|
x += xi;
|
||||||
|
D += 2 * (dx - dy);
|
||||||
|
} else {
|
||||||
|
D += 2*dx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
|
||||||
|
retval = RenderDrawPointsWithRectsF(renderer, points, count);
|
||||||
|
} else {
|
||||||
|
retval = QueueCmdDrawPoints(renderer, points, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_small_free(points, isstack);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int plotLineBresenham(SDL_Renderer *renderer, float x0, float y0, float x1, float y1)
|
||||||
|
{
|
||||||
|
if (SDL_fabs(y1 - y0) < SDL_fabs(x1 - x0)) {
|
||||||
|
if (x0 > x1) {
|
||||||
|
return plotLineLow(renderer, x1, y1, x0, y0);
|
||||||
|
} else {
|
||||||
|
return plotLineLow(renderer, x0, y0, x1, y1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (y0 > y1) {
|
||||||
|
return plotLineHigh(renderer, x1, y1, x0, y0);
|
||||||
|
} else {
|
||||||
|
return plotLineHigh(renderer, x0, y0, x1, y1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
RenderDrawLinesWithPointsF(SDL_Renderer * renderer,
|
||||||
|
const SDL_FPoint * points, const int count)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < count-1; ++i, ++points) {
|
||||||
|
retval += plotLineBresenham(renderer, points[0].x, points[0].y, points[1].x, points[1].y);
|
||||||
|
}
|
||||||
|
if (retval < 0) {
|
||||||
|
retval = -1;
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
RenderDrawLinesWithRectsF(SDL_Renderer * renderer,
|
RenderDrawLinesWithRectsF(SDL_Renderer * renderer,
|
||||||
const SDL_FPoint * points, const int count)
|
const SDL_FPoint * points, const int count)
|
||||||
{
|
{
|
||||||
SDL_FRect *frect;
|
SDL_FRect *frect;
|
||||||
SDL_FRect *frects;
|
SDL_FRect *frects;
|
||||||
SDL_FPoint fpoints[2];
|
|
||||||
int i, nrects = 0;
|
int i, nrects = 0;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
SDL_bool isstack;
|
SDL_bool isstack;
|
||||||
|
@ -2818,12 +2934,7 @@ RenderDrawLinesWithRectsF(SDL_Renderer * renderer,
|
||||||
frect->w = (maxX - minX + 1) * renderer->scale.x;
|
frect->w = (maxX - minX + 1) * renderer->scale.x;
|
||||||
frect->h = renderer->scale.y;
|
frect->h = renderer->scale.y;
|
||||||
} else {
|
} else {
|
||||||
/* FIXME: We can't use a rect for this line... */
|
retval += RenderDrawLinesWithPointsF(renderer, &points[i], 2);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2886,6 +2997,7 @@ SDL_RenderDrawLinesF(SDL_Renderer * renderer,
|
||||||
const SDL_FPoint * points, int count)
|
const SDL_FPoint * points, int count)
|
||||||
{
|
{
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
int use_renderpoints;
|
||||||
int use_rendergeometry;
|
int use_rendergeometry;
|
||||||
|
|
||||||
CHECK_RENDERER_MAGIC(renderer, -1);
|
CHECK_RENDERER_MAGIC(renderer, -1);
|
||||||
|
@ -2904,9 +3016,12 @@ SDL_RenderDrawLinesF(SDL_Renderer * renderer,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
use_renderpoints = 1;
|
||||||
use_rendergeometry = 1;
|
use_rendergeometry = 1;
|
||||||
|
|
||||||
if (use_rendergeometry) {
|
if (use_renderpoints) {
|
||||||
|
retval = RenderDrawLinesWithPointsF(renderer, points, count);
|
||||||
|
} else if (use_rendergeometry) {
|
||||||
SDL_bool isstack1;
|
SDL_bool isstack1;
|
||||||
SDL_bool isstack2;
|
SDL_bool isstack2;
|
||||||
const float scale_x = renderer->scale.x;
|
const float scale_x = renderer->scale.x;
|
||||||
|
|
Loading…
Reference in New Issue