diff --git a/include/SDL_render.h b/include/SDL_render.h index 797274c07..1022f9c96 100644 --- a/include/SDL_render.h +++ b/include/SDL_render.h @@ -137,17 +137,6 @@ typedef struct SDL_Renderer SDL_Renderer; struct SDL_Texture; typedef struct SDL_Texture SDL_Texture; -/** - * \brief Vertex structure - */ -typedef struct SDL_Vertex -{ - SDL_FPoint position; /**< Vertex position, in SDL_Renderer coordinates */ - SDL_Color color; /**< Vertex color */ - SDL_FPoint tex_coord; /**< Normalized texture coordinates, if needed */ -} SDL_Vertex; - - /* Function prototypes */ /** @@ -1453,23 +1442,30 @@ extern DECLSPEC int SDLCALL SDL_RenderCopyExF(SDL_Renderer * renderer, const SDL_RendererFlip flip); /** - * \brief Render a list of triangles, optionally using a texture and indices into the vertex array + * \brief Render a list of triangles, optionally using a texture and indices into the vertex arrays * Color and alpha modulation is done per vertex (SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored). * * \param texture (optional) The SDL texture to use. - * \param vertices Vertices. + * \param xy Vertex positions + * \param xy_stride Byte size to move from one element to the next element + * \param color Vertex colors (as SDL_Color) + * \param color_stride Byte size to move from one element to the next element + * \param uv Vertex normalized texture coordinates + * \param uv_stride Byte size to move from one element to the next element * \param num_vertices Number of vertices. - * \param indices (optional) An array of integer indices into the 'vertices' array, if NULL all vertices will be rendered in sequential order. + * \param indices (optional) An array of indices into the 'vertices' arrays, if NULL all vertices will be rendered in sequential order. * \param num_indices Number of indices. - * - * \sa SDL_Vertex + * \param size_indice Indice size: 1 (byte), 2 (short), 4 (int) * * \return 0 on success, or -1 if the operation is not supported */ -extern DECLSPEC int SDLCALL SDL_RenderGeometry(SDL_Renderer *renderer, +extern DECLSPEC int SDLCALL SDL_RenderGeometryRaw(SDL_Renderer *renderer, SDL_Texture *texture, - SDL_Vertex *vertices, int num_vertices, - int *indices, int num_indices); + const float *xy, int xy_stride, + const int *color, int color_stride, + const float *uv, int uv_stride, + int num_vertices, + const void *indices, int num_indices, int size_indice); /** * Read pixels from the current rendering target to an array of pixels. diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 1175365f4..6a849c4fd 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -818,3 +818,4 @@ #define SDL_SetTextureUserData SDL_SetTextureUserData_REAL #define SDL_GetTextureUserData SDL_GetTextureUserData_REAL #define SDL_RenderGeometry SDL_RenderGeometry_REAL +#define SDL_RenderGeometryRaw SDL_RenderGeometryRaw_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 7c721f8cc..88ecb994a 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -883,3 +883,4 @@ SDL_DYNAPI_PROC(float,SDL_GameControllerGetSensorDataRate,(SDL_GameController *a SDL_DYNAPI_PROC(int,SDL_SetTextureUserData,(SDL_Texture *a, void *b),(a,b),return) SDL_DYNAPI_PROC(void*,SDL_GetTextureUserData,(SDL_Texture *a),(a),return) SDL_DYNAPI_PROC(int,SDL_RenderGeometry,(SDL_Renderer *a, SDL_Texture *b, SDL_Vertex *c, int d, int *e, int f),(a,b,c,d,e,f),return) +SDL_DYNAPI_PROC(int,SDL_RenderGeometryRaw,(SDL_Renderer *a, SDL_Texture *b, const float *c, int d, const int *e, int f, const float *g, int h, int i, const void *j, int k, int l),(a,b,c,d,e,f,g,h,i,j,k,l),return) diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 746bdf04d..d8c49ba49 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -564,7 +564,12 @@ QueueCmdCopyEx(SDL_Renderer *renderer, SDL_Texture * texture, static int QueueCmdGeometry(SDL_Renderer *renderer, SDL_Texture *texture, - SDL_Vertex *vertices, int num_vertices, int *indices, int num_indices, float scale_x, float scale_y) + const float *xy, int xy_stride, + const int *color, int color_stride, + const float *uv, int uv_stride, + int num_vertices, + const void *indices, int num_indices, int size_indice, + float scale_x, float scale_y) { SDL_RenderCommand *cmd; int retval = -1; @@ -574,7 +579,10 @@ QueueCmdGeometry(SDL_Renderer *renderer, SDL_Texture *texture, cmd = PrepQueueCmdDrawSolid(renderer, SDL_RENDERCMD_GEOMETRY); } if (cmd != NULL) { - retval = renderer->QueueGeometry(renderer, cmd, texture, vertices, num_vertices, indices, num_indices, scale_x, scale_y); + retval = renderer->QueueGeometry(renderer, cmd, texture, + xy, xy_stride, color, color_stride, uv, uv_stride, + num_vertices, indices, num_indices, size_indice, + scale_x, scale_y); if (retval < 0) { cmd->command = SDL_RENDERCMD_NO_OP; } @@ -3323,13 +3331,16 @@ SDL_RenderCopyExF(SDL_Renderer * renderer, SDL_Texture * texture, } int -SDL_RenderGeometry(SDL_Renderer *renderer, - SDL_Texture *texture, - SDL_Vertex *vertices, int num_vertices, - int *indices, int num_indices) +SDL_RenderGeometryRaw(SDL_Renderer *renderer, + SDL_Texture *texture, + const float *xy, int xy_stride, + const int *color, int color_stride, + const float *uv, int uv_stride, + int num_vertices, + const void *indices, int num_indices, int size_indice) { int i; - int retval; + int retval = 0; int count = indices ? num_indices : num_vertices; CHECK_RENDERER_MAGIC(renderer, -1); @@ -3346,14 +3357,30 @@ SDL_RenderGeometry(SDL_Renderer *renderer, } } - if (!vertices) { - return SDL_InvalidParamError("points"); + if (!xy) { + return SDL_InvalidParamError("xy"); + } + + if (!color) { + return SDL_InvalidParamError("color"); + } + + if (texture && !uv) { + return SDL_InvalidParamError("uv"); } if (count % 3 != 0) { return SDL_InvalidParamError(indices ? "num_indices" : "num_vertices"); } + if (indices) { + if (size_indice != 1 && size_indice != 2 && size_indice != 4) { + return SDL_InvalidParamError("size_indice"); + } + } else { + size_indice = 0; + } + /* Don't draw while we're hidden */ if (renderer->hidden) { return 0; @@ -3369,26 +3396,40 @@ SDL_RenderGeometry(SDL_Renderer *renderer, if (texture) { for (i = 0; i < num_vertices; ++i) { - if (vertices[i].tex_coord.x < 0.0f || vertices[i].tex_coord.y < 0.0f || vertices[i].tex_coord.x > 1.0f || vertices[i].tex_coord.y > 1.0f) { - return SDL_SetError("Values of 'vertices' out of bounds"); + const float *uv_ = (const float *)((const char*)uv + i * uv_stride); + float u = uv_[0]; + float v = uv_[1]; + if (u < 0.0f || v < 0.0f || u > 1.0f || v > 1.0f) { + return SDL_SetError("Values of 'uv' out of bounds %f %f at %d/%d", u, v, i, num_vertices); } } } if (indices) { for (i = 0; i < num_indices; ++i) { - if (indices[i] < 0 || indices[i] >= num_vertices) { + int j; + if (size_indice == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indice == 2) { + j = ((const Uint16 *)indices)[i]; + } else { + j = ((const Uint8 *)indices)[i]; + } + if (j < 0 || j >= num_vertices) { return SDL_SetError("Values of 'indices' out of bounds"); } } } - if (texture) { texture->last_command_generation = renderer->render_command_generation; } - retval = QueueCmdGeometry(renderer, texture, vertices, num_vertices, indices, num_indices, renderer->scale.x, renderer->scale.y); + retval = QueueCmdGeometry(renderer, texture, + xy, xy_stride, color, color_stride, uv, uv_stride, + num_vertices, + indices, num_indices, size_indice, + renderer->scale.x, renderer->scale.y); return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); } diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h index 1beb4b248..5c2add1f3 100644 --- a/src/render/SDL_sysrender.h +++ b/src/render/SDL_sysrender.h @@ -131,7 +131,9 @@ struct SDL_Renderer const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip); int (*QueueGeometry) (SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, - SDL_Vertex *vertices, int num_vertices, int *indices, int num_indices, float scale_x, float scale_y); + const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indice, + float scale_x, float scale_y); int (*RunCommandQueue) (SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize); int (*UpdateTexture) (SDL_Renderer * renderer, SDL_Texture * texture, diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c index cd531dc28..d9caf84b7 100644 --- a/src/render/opengl/SDL_render_gl.c +++ b/src/render/opengl/SDL_render_gl.c @@ -1054,7 +1054,9 @@ GL_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * te static int GL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, - SDL_Vertex *vertices, int num_vertices, int *indices, int num_indices, float scale_x, float scale_y) + const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indice, + float scale_x, float scale_y) { GL_TextureData *texturedata = NULL; int i; @@ -1074,19 +1076,32 @@ GL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *te cmd->data.draw.count = count; for (i = 0; i < count; i++) { - SDL_Vertex *v = &vertices[indices ? indices[i] : i]; + int j; + if (size_indice == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indice == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indice == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } - *(verts++) = v->position.x * scale_x; - *(verts++) = v->position.y * scale_y; + float *xy_ = (float *)((char*)xy + j * xy_stride); + SDL_Color col_ = *(SDL_Color *)((char*)color + j * color_stride); - *(verts++) = v->color.r * inv255f; - *(verts++) = v->color.g * inv255f; - *(verts++) = v->color.b * inv255f; - *(verts++) = v->color.a * inv255f; + *(verts++) = xy_[0] * scale_x; + *(verts++) = xy_[1] * scale_y; + + *(verts++) = col_.r * inv255f; + *(verts++) = col_.g * inv255f; + *(verts++) = col_.b * inv255f; + *(verts++) = col_.a * inv255f; if (texture) { - *(verts++) = v->tex_coord.x * texturedata->texw; - *(verts++) = v->tex_coord.y * texturedata->texh; + float *uv_ = (float *)((char*)uv + j * uv_stride); + *(verts++) = uv_[0] * texturedata->texw; + *(verts++) = uv_[1] * texturedata->texh; } } return 0; diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c index 775c0f4a8..6b997588b 100644 --- a/src/render/opengles2/SDL_render_gles2.c +++ b/src/render/opengles2/SDL_render_gles2.c @@ -960,7 +960,9 @@ GLES2_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * static int GLES2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, - SDL_Vertex *vertices, int num_vertices, int *indices, int num_indices, float scale_x, float scale_y) + const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indice, + float scale_x, float scale_y) { int i; const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888)); @@ -976,20 +978,35 @@ GLES2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture cmd->data.draw.count = count; for (i = 0; i < count; i++) { - SDL_Vertex *v = &vertices[indices ? indices[i] : i]; + int j; + if (size_indice == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indice == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indice == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } - *(verts++) = v->position.x * scale_x; - *(verts++) = v->position.y * scale_y; - *(verts++) = (colorswap ? v->color.b : v->color.r) * inv255f; - *(verts++) = v->color.g * inv255f; - *(verts++) = (colorswap ? v->color.r : v->color.b) * inv255f; - *(verts++) = v->color.a * inv255f; + float *xy_ = (float *)((char*)xy + j * xy_stride); + SDL_Color col_ = *(SDL_Color *)((char*)color + j * color_stride); + + *(verts++) = xy_[0] * scale_x; + *(verts++) = xy_[1] * scale_y; + + *(verts++) = (colorswap ? col_.b : col_.r) * inv255f; + *(verts++) = col_.g * inv255f; + *(verts++) = (colorswap ? col_.r : col_.b) * inv255f; + *(verts++) = col_.a * inv255f; if (texture) { - *(verts++) = v->tex_coord.x; - *(verts++) = v->tex_coord.y; + float *uv_ = (float *)((char*)uv + j * uv_stride); + *(verts++) = uv_[0]; + *(verts++) = uv_[1]; } } + return 0; } diff --git a/src/render/software/SDL_render_sw.c b/src/render/software/SDL_render_sw.c index fbc948ecf..0dcdc2adb 100644 --- a/src/render/software/SDL_render_sw.c +++ b/src/render/software/SDL_render_sw.c @@ -577,7 +577,9 @@ typedef struct GeometryCopyData static int SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, - SDL_Vertex *vertices, int num_vertices, int *indices, int num_indices, float scale_x, float scale_y) + const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indice, + float scale_x, float scale_y) { int i; int count = indices ? num_indices : num_vertices; @@ -594,16 +596,30 @@ SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *te if (texture) { GeometryCopyData *ptr = (GeometryCopyData *) verts; for (i = 0; i < count; i++) { - SDL_Vertex *v = &vertices[indices ? indices[i] : i]; + int j; + if (size_indice == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indice == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indice == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } - ptr->src.x = v->tex_coord.x * texture->w; - ptr->src.y = v->tex_coord.y * texture->h; + float *xy_ = (float *)((char*)xy + j * xy_stride); + SDL_Color col_ = *(SDL_Color *)((char*)color + j * color_stride); - ptr->dst.x = v->position.x * scale_x + renderer->viewport.x; - ptr->dst.y = v->position.y * scale_y + renderer->viewport.y; + float *uv_ = (float *)((char*)uv + j * uv_stride); + + ptr->src.x = uv_[0] * texture->w; + ptr->src.y = uv_[1] * texture->h; + + ptr->dst.x = xy_[0] * scale_x + renderer->viewport.x; + ptr->dst.y = xy_[1] * scale_y + renderer->viewport.y; trianglepoint_2_fixedpoint(&ptr->dst); - ptr->color = v->color; + ptr->color = col_; ptr++; } @@ -611,18 +627,29 @@ SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *te GeometryFillData *ptr = (GeometryFillData *) verts; for (i = 0; i < count; i++) { - SDL_Vertex *v = &vertices[indices ? indices[i] : i]; + int j; + if (size_indice == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indice == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indice == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } - ptr->dst.x = v->position.x * scale_x + renderer->viewport.x; - ptr->dst.y = v->position.y * scale_y + renderer->viewport.y; + float *xy_ = (float *)((char*)xy + j * xy_stride); + SDL_Color col_ = *(SDL_Color *)((char*)color + j * color_stride); + + ptr->dst.x = xy_[0] * scale_x + renderer->viewport.x; + ptr->dst.y = xy_[1] * scale_y + renderer->viewport.y; trianglepoint_2_fixedpoint(&ptr->dst); - ptr->color = v->color; + ptr->color = col_; ptr++; } } - return 0; } @@ -700,7 +727,7 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic } case SDL_RENDERCMD_SETCLIPRECT: { - drawstate.cliprect = cmd->data.cliprect.enabled ? &cmd->data.cliprect.rect : NULL; + drawstate.cliprect = cmd->data.cliprect.enabled ? &cmd->data.cliprect.rect : NULL; drawstate.surface_cliprect_dirty = SDL_TRUE; break; }