Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Added interfaces for batch drawing of points, lines and rects:
Browse files Browse the repository at this point in the history
    SDL_DrawPoints()
    SDL_BlendPoints()
    SDL_BlendLines()
    SDL_DrawLines()
    SDL_FillRects()
    SDL_BlendRects()
    SDL_RenderPoints()
    SDL_RenderLines()
    SDL_RenderRects()
Renamed SDL_RenderFill() to SDL_RenderRect()
  • Loading branch information
slouken committed Dec 9, 2009
1 parent 56a5b64 commit b48296c
Show file tree
Hide file tree
Showing 26 changed files with 1,192 additions and 523 deletions.
2 changes: 2 additions & 0 deletions include/SDL_compat.h
Expand Up @@ -350,6 +350,8 @@ extern DECLSPEC int SDLCALL SDL_EnableKeyRepeat(int delay, int interval);
extern DECLSPEC void SDLCALL SDL_GetKeyRepeat(int *delay, int *interval);
extern DECLSPEC int SDLCALL SDL_EnableUNICODE(int enable);

#define SDL_RenderFill SDL_RenderRect

/*@}*//*Compatibility*/

/* Ends C function definitions when using C++ */
Expand Down
22 changes: 22 additions & 0 deletions include/SDL_rect.h
Expand Up @@ -42,6 +42,17 @@ extern "C" {
/* *INDENT-ON* */
#endif

/**
* \brief The structure that defines a point
*
* \sa SDL_EnclosePoints
*/
typedef struct
{
int x;
int y;
} SDL_Point;

/**
* \brief A rectangle, with the origin at the upper left.
*
Expand All @@ -50,6 +61,7 @@ extern "C" {
* \sa SDL_HasIntersection
* \sa SDL_IntersectRect
* \sa SDL_UnionRect
* \sa SDL_EnclosePoints
*/
typedef struct SDL_Rect
{
Expand Down Expand Up @@ -92,6 +104,16 @@ extern DECLSPEC void SDLCALL SDL_UnionRect(const SDL_Rect * A,
const SDL_Rect * B,
SDL_Rect * result);

/**
* \brief Calculate a minimal rectangle enclosing a set of points
*
* \return SDL_TRUE if any points were within the clipping rect
*/
extern DECLSPEC SDL_bool SDLCALL SDL_EnclosePoints(const SDL_Point * points,
int count,
const SDL_Rect * clip,
SDL_Rect * result);

/**
* \brief Calculate the intersection of a rectangle and line segment.
*
Expand Down
39 changes: 24 additions & 15 deletions include/SDL_surface.h
Expand Up @@ -405,6 +405,8 @@ extern DECLSPEC int SDLCALL SDL_ConvertPixels(int width, int height,
*/
extern DECLSPEC int SDLCALL SDL_DrawPoint
(SDL_Surface * dst, int x, int y, Uint32 color);
extern DECLSPEC int SDLCALL SDL_DrawPoints
(SDL_Surface * dst, const SDL_Point * points, int count, Uint32 color);

/**
* Blends a point with an RGBA value.
Expand All @@ -415,8 +417,11 @@ extern DECLSPEC int SDLCALL SDL_DrawPoint
* \return 0 on success, or -1 on error.
*/
extern DECLSPEC int SDLCALL SDL_BlendPoint
(SDL_Surface * dst, int x, int y, int blendMode,
Uint8 r, Uint8 g, Uint8 b, Uint8 a);
(SDL_Surface * dst, int x, int y,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
extern DECLSPEC int SDLCALL SDL_BlendPoints
(SDL_Surface * dst, const SDL_Point * points, int count,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);

/**
* Draws a line with \c color.
Expand All @@ -428,45 +433,49 @@ extern DECLSPEC int SDLCALL SDL_BlendPoint
*/
extern DECLSPEC int SDLCALL SDL_DrawLine
(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color);
extern DECLSPEC int SDLCALL SDL_DrawLines
(SDL_Surface * dst, const SDL_Point * points, int count, Uint32 color);

/**
* Blends an RGBA value along a line.
*
* \return 0 on success, or -1 on error.
*/
extern DECLSPEC int SDLCALL SDL_BlendLine
(SDL_Surface * dst, int x1, int y1, int x2, int y2, int blendMode,
Uint8 r, Uint8 g, Uint8 b, Uint8 a);
(SDL_Surface * dst, int x1, int y1, int x2, int y2,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
extern DECLSPEC int SDLCALL SDL_BlendLines
(SDL_Surface * dst, const SDL_Point * points, int count,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);

/**
* Performs a fast fill of the given rectangle with \c color.
*
* The given rectangle is clipped to the destination surface clip area
* and the final fill rectangle is saved in the passed in pointer.
*
* If \c dstrect is NULL, the whole surface will be filled with \c color.
* If \c rect is NULL, the whole surface will be filled with \c color.
*
* The color should be a pixel of the format used by the surface, and
* can be generated by the SDL_MapRGB() function.
*
* \return 0 on success, or -1 on error.
*/
extern DECLSPEC int SDLCALL SDL_FillRect
(SDL_Surface * dst, SDL_Rect * dstrect, Uint32 color);
(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color);
extern DECLSPEC int SDLCALL SDL_FillRects
(SDL_Surface * dst, const SDL_Rect ** rects, int count, Uint32 color);

/**
* Blends an RGBA value into the given rectangle.
*
* The given rectangle is clipped to the destination surface clip area
* and the final fill rectangle is saved in the passed in pointer.
*
* If \c dstrect is NULL, the whole surface will be filled with \c color.
* If \c rect is NULL, the whole surface will be filled with \c color.
*
* \return This function returns 0 on success, or -1 on error.
*/
extern DECLSPEC int SDLCALL SDL_BlendRect
(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode, Uint8 r, Uint8 g,
Uint8 b, Uint8 a);
(SDL_Surface * dst, const SDL_Rect * rect,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
extern DECLSPEC int SDLCALL SDL_BlendRects
(SDL_Surface * dst, const SDL_Rect ** rects, int count,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);

/**
* Performs a fast blit from the source surface to the destination surface.
Expand Down
34 changes: 33 additions & 1 deletion include/SDL_video.h
Expand Up @@ -1147,6 +1147,17 @@ extern DECLSPEC int SDLCALL SDL_GetRenderDrawBlendMode(int *blendMode);
*/
extern DECLSPEC int SDLCALL SDL_RenderPoint(int x, int y);

/**
* \brief Draw some number of points on the current rendering target.
*
* \param points The points to draw
* \param count The number of points to draw
*
* \return 0 on success, or -1 if there is no rendering context current.
*/
extern DECLSPEC int SDLCALL SDL_RenderPoints(const SDL_Point * points,
int count);

/**
* \brief Draw a line on the current rendering target.
*
Expand All @@ -1159,6 +1170,17 @@ extern DECLSPEC int SDLCALL SDL_RenderPoint(int x, int y);
*/
extern DECLSPEC int SDLCALL SDL_RenderLine(int x1, int y1, int x2, int y2);

/**
* \brief Draw a series of connected lines on the current rendering target.
*
* \param points The points along the lines
* \param count The number of points, drawing count-1 lines
*
* \return 0 on success, or -1 if there is no rendering context current.
*/
extern DECLSPEC int SDLCALL SDL_RenderLines(const SDL_Point * points,
int count);

/**
* \brief Fill the current rendering target with the drawing color.
*
Expand All @@ -1167,7 +1189,17 @@ extern DECLSPEC int SDLCALL SDL_RenderLine(int x1, int y1, int x2, int y2);
*
* \return 0 on success, or -1 if there is no rendering context current.
*/
extern DECLSPEC int SDLCALL SDL_RenderFill(const SDL_Rect * rect);
extern DECLSPEC int SDLCALL SDL_RenderRect(const SDL_Rect * rect);

/**
* \brief Fill some number of rectangles in the current rendering target with the drawing color.
*
* \param rects A pointer to an array of destination rectangles.
* \param count The number of rectangles.
*
* \return 0 on success, or -1 if there is no rendering context current.
*/
extern DECLSPEC int SDLCALL SDL_RenderRects(const SDL_Rect ** rect, int count);

/**
* \brief Copy a portion of the texture to the current rendering target.
Expand Down
99 changes: 89 additions & 10 deletions src/video/SDL_blendline.c
Expand Up @@ -195,8 +195,6 @@ int
SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
SDL_PixelFormat *fmt = dst->format;

/* This function doesn't work on surfaces < 8 bpp */
if (dst->format->BitsPerPixel < 8) {
SDL_SetError("SDL_BlendLine(): Unsupported surface format");
Expand All @@ -209,32 +207,31 @@ SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2,
}


if ((blendMode == SDL_BLENDMODE_BLEND)
|| (blendMode == SDL_BLENDMODE_ADD)) {
if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
r = DRAW_MUL(r, a);
g = DRAW_MUL(g, a);
b = DRAW_MUL(b, a);
}

switch (fmt->BitsPerPixel) {
switch (dst->format->BitsPerPixel) {
case 15:
switch (fmt->Rmask) {
switch (dst->format->Rmask) {
case 0x7C00:
return SDL_BlendLine_RGB555(dst, x1, y1, x2, y2, blendMode, r, g,
b, a);
}
break;
case 16:
switch (fmt->Rmask) {
switch (dst->format->Rmask) {
case 0xF800:
return SDL_BlendLine_RGB565(dst, x1, y1, x2, y2, blendMode, r, g,
b, a);
}
break;
case 32:
switch (fmt->Rmask) {
switch (dst->format->Rmask) {
case 0x00FF0000:
if (!fmt->Amask) {
if (!dst->format->Amask) {
return SDL_BlendLine_RGB888(dst, x1, y1, x2, y2, blendMode, r,
g, b, a);
} else {
Expand All @@ -243,15 +240,97 @@ SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2,
}
break;
}
break;
default:
break;
}

if (!fmt->Amask) {
if (!dst->format->Amask) {
return SDL_BlendLine_RGB(dst, x1, y1, x2, y2, blendMode, r, g, b, a);
} else {
return SDL_BlendLine_RGBA(dst, x1, y1, x2, y2, blendMode, r, g, b, a);
}
}

int
SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
int i;
int x1, y1;
int x2, y2;
int (*func)(SDL_Surface * dst, int x1, int y1, int x2, int y2,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
int status = 0;

if (!dst) {
SDL_SetError("Passed NULL destination surface");
return -1;
}

/* This function doesn't work on surfaces < 8 bpp */
if (dst->format->BitsPerPixel < 8) {
SDL_SetError("SDL_BlendLines(): Unsupported surface format");
return -1;
}

if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
r = DRAW_MUL(r, a);
g = DRAW_MUL(g, a);
b = DRAW_MUL(b, a);
}

/* FIXME: Does this function pointer slow things down significantly? */
switch (dst->format->BitsPerPixel) {
case 15:
switch (dst->format->Rmask) {
case 0x7C00:
func = SDL_BlendLine_RGB555;
}
break;
case 16:
switch (dst->format->Rmask) {
case 0xF800:
func = SDL_BlendLine_RGB565;
}
break;
case 32:
switch (dst->format->Rmask) {
case 0x00FF0000:
if (!dst->format->Amask) {
func = SDL_BlendLine_RGB888;
} else {
func = SDL_BlendLine_ARGB8888;
}
break;
}
default:
break;
}

if (!func) {
if (!dst->format->Amask) {
func = SDL_BlendLine_RGB;
} else {
func = SDL_BlendLine_RGBA;
}
}

for (i = 1; i < count; ++i) {
x1 = points[i-1].x;
y1 = points[i-1].y;
x2 = points[i].x;
y2 = points[i].y;

/* Perform clipping */
/* FIXME: We don't actually want to clip, as it may change line slope */
if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
continue;
}

status = func(dst, x1, y1, x2, y2, blendMode, r, g, b, a);
}
return status;
}

/* vi: set ts=4 sw=4 expandtab: */

0 comments on commit b48296c

Please sign in to comment.