diff --git a/include/SDL_polygon.h b/include/SDL_polygon.h new file mode 100644 --- /dev/null +++ b/include/SDL_polygon.h @@ -0,0 +1,65 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_polygon.h + * + * Header file for SDL_polygon definition and management functions. + */ + +#ifndef _SDL_polygon_h +#define _SDL_polygon_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_pixels.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/** + * \brief A polygon defined by 2 components. + * + * must be in triangles (GL_TRIANGLE_STRIP) + */ +typedef struct SDL_Polygon +{ + float *vertices; + int count; // the amount of vertices in the vertices array +} SDL_Polygon; + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_polygon_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/include/SDL_render.h b/include/SDL_render.h --- a/include/SDL_render.h +++ b/include/SDL_render.h @@ -42,16 +42,17 @@ * of the many good 3D engines. */ #ifndef _SDL_render_h #define _SDL_render_h #include "SDL_stdinc.h" #include "SDL_rect.h" +#include "SDL_polygon.h" #include "SDL_video.h" #include "begin_code.h" /* Set up for C function definitions, even when using C++ */ #ifdef __cplusplus /* *INDENT-OFF* */ extern "C" { /* *INDENT-ON* */ @@ -670,16 +671,26 @@ extern DECLSPEC int SDLCALL SDL_RenderFi * * \return 0 on success, or -1 on error */ extern DECLSPEC int SDLCALL SDL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count); /** + * \brief Fill a polygon on the current rendering target with the drawing color. + * + * \param polygon A pointer to the destination polygon + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderFillPolygon(SDL_Renderer * renderer, + const SDL_Polygon * polygon); + +/** * \brief Copy a portion of the texture to the current rendering target. * * \param texture The source texture. * \param srcrect A pointer to the source rectangle, or NULL for the entire * texture. * \param dstrect A pointer to the destination rectangle, or NULL for the * entire rendering target. * diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -1481,16 +1481,42 @@ SDL_RenderFillRects(SDL_Renderer * rende status = renderer->RenderFillRects(renderer, frects, count); SDL_stack_free(frects); return status; } int +SDL_RenderFillPolygon(SDL_Renderer * renderer, const SDL_Polygon * polygon) +{ + int i; + int status; + + CHECK_RENDERER_MAGIC(renderer, -1); + + if (!polygon) { + SDL_SetError("SDL_RenderDrawPolygon(): Passed NULL polygon"); + return -1; + } + if (polygon->count < 3) { + SDL_SetError("SDL_RenderDrawPolygon(): Invalid polygon count passed"); + return 0; + } + /* Don't draw while we're hidden */ + if (renderer->hidden) { + return 0; + } + + status = renderer->RenderFillPolygon(renderer, polygon); + + return status; +} + +int SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect) { SDL_Rect real_srcrect = { 0, 0, 0, 0 }; SDL_Rect real_dstrect = { 0, 0, 0, 0 }; SDL_FRect frect; CHECK_RENDERER_MAGIC(renderer, -1); diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h --- a/src/render/SDL_sysrender.h +++ b/src/render/SDL_sysrender.h @@ -95,16 +95,17 @@ struct SDL_Renderer int (*UpdateViewport) (SDL_Renderer * renderer); int (*RenderClear) (SDL_Renderer * renderer); int (*RenderDrawPoints) (SDL_Renderer * renderer, const SDL_FPoint * points, int count); int (*RenderDrawLines) (SDL_Renderer * renderer, const SDL_FPoint * points, int count); int (*RenderFillRects) (SDL_Renderer * renderer, const SDL_FRect * rects, int count); + int (*RenderFillPolygon) (SDL_Renderer * renderer, const SDL_Polygon * polygon); int (*RenderCopy) (SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect); int (*RenderCopyEx) (SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcquad, const SDL_FRect * dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip); int (*RenderReadPixels) (SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch); void (*RenderPresent) (SDL_Renderer * renderer); diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c --- a/src/render/opengl/SDL_render_gl.c +++ b/src/render/opengl/SDL_render_gl.c @@ -58,16 +58,17 @@ static int GL_SetRenderTarget(SDL_Render static int GL_UpdateViewport(SDL_Renderer * renderer); static int GL_RenderClear(SDL_Renderer * renderer); static int GL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, int count); static int GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count); static int GL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count); +static int GL_RenderFillPolygon(SDL_Renderer * renderer, const SDL_Polygon * polygon); static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect); static int GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip); static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch); static void GL_RenderPresent(SDL_Renderer * renderer); @@ -324,16 +325,17 @@ GL_CreateRenderer(SDL_Window * window, U renderer->LockTexture = GL_LockTexture; renderer->UnlockTexture = GL_UnlockTexture; renderer->SetRenderTarget = GL_SetRenderTarget; renderer->UpdateViewport = GL_UpdateViewport; renderer->RenderClear = GL_RenderClear; renderer->RenderDrawPoints = GL_RenderDrawPoints; renderer->RenderDrawLines = GL_RenderDrawLines; renderer->RenderFillRects = GL_RenderFillRects; + renderer->RenderFillPolygon = GL_RenderFillPolygon; renderer->RenderCopy = GL_RenderCopy; renderer->RenderCopyEx = GL_RenderCopyEx; renderer->RenderReadPixels = GL_RenderReadPixels; renderer->RenderPresent = GL_RenderPresent; renderer->DestroyTexture = GL_DestroyTexture; renderer->DestroyRenderer = GL_DestroyRenderer; renderer->GL_BindTexture = GL_BindTexture; renderer->GL_UnbindTexture = GL_UnbindTexture; @@ -971,16 +973,33 @@ GL_RenderFillRects(SDL_Renderer * render data->glRectf(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h); } GL_CheckError("", renderer); return 0; } +static int GL_RenderFillPolygon (SDL_Renderer * renderer, const SDL_Polygon * polygon) +{ + GL_RenderData *data = (GL_RenderData *) renderer->driverdata; + const float *v; + + GL_SetDrawingState(renderer); + + data->glBegin(GL_TRIANGLE_FAN); + for (v = polygon->vertices; v < polygon->vertices + polygon->count; v += 2) { + data->glVertex2f(v[0], v[1]); + } + data->glEnd(); + GL_CheckError("", renderer); + + return 0; +} + static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect) { GL_RenderData *data = (GL_RenderData *) renderer->driverdata; GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; GLfloat minx, miny, maxx, maxy; GLfloat minu, maxu, minv, maxv; diff --git a/src/render/opengles/SDL_render_gles.c b/src/render/opengles/SDL_render_gles.c --- a/src/render/opengles/SDL_render_gles.c +++ b/src/render/opengles/SDL_render_gles.c @@ -61,16 +61,17 @@ static int GLES_SetRenderTarget(SDL_Rend static int GLES_UpdateViewport(SDL_Renderer * renderer); static int GLES_RenderClear(SDL_Renderer * renderer); static int GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, int count); static int GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count); static int GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count); +static int GLES_RenderFillPolygon(SDL_Renderer * renderer, const SDL_Polygon * polygon); static int GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect); static int GLES_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip); static int GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch); @@ -303,16 +304,17 @@ GLES_CreateRenderer(SDL_Window * window, renderer->LockTexture = GLES_LockTexture; renderer->UnlockTexture = GLES_UnlockTexture; renderer->SetRenderTarget = GLES_SetRenderTarget; renderer->UpdateViewport = GLES_UpdateViewport; renderer->RenderClear = GLES_RenderClear; renderer->RenderDrawPoints = GLES_RenderDrawPoints; renderer->RenderDrawLines = GLES_RenderDrawLines; renderer->RenderFillRects = GLES_RenderFillRects; + renderer->RenderFillPolygon = GLES_RenderFillPolygon; renderer->RenderCopy = GLES_RenderCopy; renderer->RenderCopyEx = GLES_RenderCopyEx; renderer->RenderReadPixels = GLES_RenderReadPixels; renderer->RenderPresent = GLES_RenderPresent; renderer->DestroyTexture = GLES_DestroyTexture; renderer->DestroyRenderer = GLES_DestroyRenderer; renderer->GL_BindTexture = GLES_BindTexture; renderer->GL_UnbindTexture = GLES_UnbindTexture; @@ -795,16 +797,28 @@ GLES_RenderFillRects(SDL_Renderer * rend data->glVertexPointer(2, GL_FLOAT, 0, vertices); data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } return 0; } +static int GLES_RenderFillPolygon (SDL_Renderer * renderer, const SDL_Polygon * polygon) +{ + GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; + + GLES_SetDrawingState(renderer); + + data->glVertexPointer(2, GL_FLOAT, 0, polygon->vertices); + data->glDrawArrays(GL_TRIANGLE_FAN, 0, polygon->count / 2); + + return 0; +} + static int GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; GLfloat minx, miny, maxx, maxy; diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c --- a/src/render/opengles2/SDL_render_gles2.c +++ b/src/render/opengles2/SDL_render_gles2.c @@ -1160,16 +1160,36 @@ GLES2_RenderFillRects(SDL_Renderer *rend if (rdata->glGetError() != GL_NO_ERROR) { SDL_SetError("Failed to render lines"); return -1; } return 0; } +static int GLES2_RenderFillPolygon (SDL_Renderer * renderer, const SDL_Polygon * polygon) +{ + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; + + if (GLES2_SetDrawingState(renderer) < 0) { + return -1; + } + + rdata->glGetError(); + rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, polygon->vertices); + rdata->glDrawArrays(GL_TRIANGLE_FAN, 0, polygon->count / 2); + + if (rdata->glGetError() != GL_NO_ERROR) + { + SDL_SetError("Failed to render polygon"); + return -1; + } + return 0; +} + static int GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect) { GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; GLES2_ImageSource sourceType; SDL_BlendMode blendMode; @@ -1358,58 +1378,73 @@ GLES2_RenderCopyEx(SDL_Renderer *rendere { case SDL_PIXELFORMAT_ARGB8888: case SDL_PIXELFORMAT_RGB888: sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; break; case SDL_PIXELFORMAT_BGR888: sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; break; + default: + SDL_SetError("invalid texture format given"); + return -1; } break; case SDL_PIXELFORMAT_ARGB8888: switch (renderer->target->format) { case SDL_PIXELFORMAT_ABGR8888: case SDL_PIXELFORMAT_BGR888: sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; break; case SDL_PIXELFORMAT_RGB888: sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; break; + default: + SDL_SetError("invalid texture format given"); + return -1; } break; case SDL_PIXELFORMAT_BGR888: switch (renderer->target->format) { case SDL_PIXELFORMAT_ABGR8888: sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR; break; case SDL_PIXELFORMAT_ARGB8888: sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB; break; case SDL_PIXELFORMAT_RGB888: sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; break; + default: + SDL_SetError("invalid texture format given"); + return -1; } break; case SDL_PIXELFORMAT_RGB888: switch (renderer->target->format) { case SDL_PIXELFORMAT_ABGR8888: sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; break; case SDL_PIXELFORMAT_ARGB8888: sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR; break; case SDL_PIXELFORMAT_BGR888: sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; break; + default: + SDL_SetError("invalid texture format given"); + return -1; } break; + default: + SDL_SetError("invalid texture format given"); + return -1; } } else sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; // Texture formats match, use the non color mapping shader (even if the formats are not ABGR) } else { switch (texture->format) { case SDL_PIXELFORMAT_ABGR8888: @@ -1419,16 +1454,19 @@ GLES2_RenderCopyEx(SDL_Renderer *rendere sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; break; case SDL_PIXELFORMAT_BGR888: sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR; break; case SDL_PIXELFORMAT_RGB888: sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB; break; + default: + SDL_SetError("invalid texture format given"); + return -1; } } if (GLES2_SelectProgram(renderer, sourceType, blendMode) < 0) return -1; /* Select the target texture */ locTexture = rdata->current_program->uniform_locations[GLES2_UNIFORM_TEXTURE]; rdata->glGetError(); @@ -1734,16 +1772,17 @@ GLES2_CreateRenderer(SDL_Window *window, renderer->LockTexture = &GLES2_LockTexture; renderer->UnlockTexture = &GLES2_UnlockTexture; renderer->SetRenderTarget = &GLES2_SetRenderTarget; renderer->UpdateViewport = &GLES2_UpdateViewport; renderer->RenderClear = &GLES2_RenderClear; renderer->RenderDrawPoints = &GLES2_RenderDrawPoints; renderer->RenderDrawLines = &GLES2_RenderDrawLines; renderer->RenderFillRects = &GLES2_RenderFillRects; + renderer->RenderFillPolygon = &GLES2_RenderFillPolygon; renderer->RenderCopy = &GLES2_RenderCopy; renderer->RenderReadPixels = &GLES2_RenderReadPixels; renderer->RenderCopyEx = &GLES2_RenderCopyEx; renderer->RenderPresent = &GLES2_RenderPresent; renderer->DestroyTexture = &GLES2_DestroyTexture; renderer->DestroyRenderer = &GLES2_DestroyRenderer; renderer->GL_BindTexture = &GLES2_BindTexture; renderer->GL_UnbindTexture = &GLES2_UnbindTexture; diff --git a/src/render/software/SDL_render_sw.c b/src/render/software/SDL_render_sw.c --- a/src/render/software/SDL_render_sw.c +++ b/src/render/software/SDL_render_sw.c @@ -56,16 +56,17 @@ static int SW_SetRenderTarget(SDL_Render static int SW_UpdateViewport(SDL_Renderer * renderer); static int SW_RenderClear(SDL_Renderer * renderer); static int SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, int count); static int SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count); static int SW_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count); +static int SW_RenderFillPolygon(SDL_Renderer * renderer, const SDL_Polygon * polygon); static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect); static int SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect, const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip); static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch); static void SW_RenderPresent(SDL_Renderer * renderer); @@ -150,16 +151,17 @@ SW_CreateRendererForSurface(SDL_Surface renderer->LockTexture = SW_LockTexture; renderer->UnlockTexture = SW_UnlockTexture; renderer->SetRenderTarget = SW_SetRenderTarget; renderer->UpdateViewport = SW_UpdateViewport; renderer->RenderClear = SW_RenderClear; renderer->RenderDrawPoints = SW_RenderDrawPoints; renderer->RenderDrawLines = SW_RenderDrawLines; renderer->RenderFillRects = SW_RenderFillRects; + renderer->RenderFillPolygon = SW_RenderFillPolygon; renderer->RenderCopy = SW_RenderCopy; renderer->RenderCopyEx = SW_RenderCopyEx; renderer->RenderReadPixels = SW_RenderReadPixels; renderer->RenderPresent = SW_RenderPresent; renderer->DestroyTexture = SW_DestroyTexture; renderer->DestroyRenderer = SW_DestroyRenderer; renderer->info = SW_RenderDriver.info; renderer->driverdata = data; @@ -489,16 +491,21 @@ SW_RenderFillRects(SDL_Renderer * render renderer->r, renderer->g, renderer->b, renderer->a); } SDL_stack_free(final_rects); return status; } +static int SW_RenderFillPolygon (SDL_Renderer * renderer, const SDL_Polygon * polygon) +{ + return -1; +} + static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect) { SDL_Surface *surface = SW_ActivateRenderer(renderer); SDL_Surface *src = (SDL_Surface *) texture->driverdata; SDL_Rect final_rect;