Added SDL_RenderTextureTiled()
This commit is contained in:
parent
9e55ee9391
commit
198caa54a1
6 changed files with 385 additions and 71 deletions
|
@ -1843,6 +1843,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_RenderFillRects(SDL_Renderer *renderer, cons
|
||||||
* \since This function is available since SDL 3.0.0.
|
* \since This function is available since SDL 3.0.0.
|
||||||
*
|
*
|
||||||
* \sa SDL_RenderTextureRotated
|
* \sa SDL_RenderTextureRotated
|
||||||
|
* \sa SDL_RenderTextureTiled
|
||||||
*/
|
*/
|
||||||
extern SDL_DECLSPEC int SDLCALL SDL_RenderTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FRect *srcrect, const SDL_FRect *dstrect);
|
extern SDL_DECLSPEC int SDLCALL SDL_RenderTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FRect *srcrect, const SDL_FRect *dstrect);
|
||||||
|
|
||||||
|
@ -1875,6 +1876,28 @@ extern SDL_DECLSPEC int SDLCALL SDL_RenderTextureRotated(SDL_Renderer *renderer,
|
||||||
const double angle, const SDL_FPoint *center,
|
const double angle, const SDL_FPoint *center,
|
||||||
const SDL_FlipMode flip);
|
const SDL_FlipMode flip);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tile a portion of the texture to the current rendering target at subpixel
|
||||||
|
* precision.
|
||||||
|
*
|
||||||
|
* The pixels in `srcrect` will be repeated as many times as needed to completely fill `dstrect`.
|
||||||
|
*
|
||||||
|
* \param renderer the renderer which should copy parts of a texture.
|
||||||
|
* \param texture the source texture.
|
||||||
|
* \param srcrect a pointer to the source rectangle, or NULL for the entire
|
||||||
|
* texture.
|
||||||
|
* \param scale the scale used to transform srcrect into the destination rectangle, e.g. a 32x32 texture with a scale of 2 would fill 64x64 tiles.
|
||||||
|
* \param dstrect a pointer to the destination rectangle, or NULL for the
|
||||||
|
* entire rendering target.
|
||||||
|
* \returns 0 on success or a negative error code on failure; call
|
||||||
|
* SDL_GetError() for more information.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.0.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_RenderTexture
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC int SDLCALL SDL_RenderTextureTiled(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FRect *srcrect, float scale, const SDL_FRect *dstrect);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a list of triangles, optionally using a texture and indices into the
|
* Render a list of triangles, optionally using a texture and indices into the
|
||||||
* vertex array Color and alpha modulation is done per vertex
|
* vertex array Color and alpha modulation is done per vertex
|
||||||
|
|
|
@ -664,6 +664,7 @@ SDL3_0.0.0 {
|
||||||
SDL_RenderRects;
|
SDL_RenderRects;
|
||||||
SDL_RenderTexture;
|
SDL_RenderTexture;
|
||||||
SDL_RenderTextureRotated;
|
SDL_RenderTextureRotated;
|
||||||
|
SDL_RenderTextureTiled;
|
||||||
SDL_RenderViewportSet;
|
SDL_RenderViewportSet;
|
||||||
SDL_ReportAssertion;
|
SDL_ReportAssertion;
|
||||||
SDL_RequestAndroidPermission;
|
SDL_RequestAndroidPermission;
|
||||||
|
|
|
@ -689,6 +689,7 @@
|
||||||
#define SDL_RenderRects SDL_RenderRects_REAL
|
#define SDL_RenderRects SDL_RenderRects_REAL
|
||||||
#define SDL_RenderTexture SDL_RenderTexture_REAL
|
#define SDL_RenderTexture SDL_RenderTexture_REAL
|
||||||
#define SDL_RenderTextureRotated SDL_RenderTextureRotated_REAL
|
#define SDL_RenderTextureRotated SDL_RenderTextureRotated_REAL
|
||||||
|
#define SDL_RenderTextureTiled SDL_RenderTextureTiled_REAL
|
||||||
#define SDL_RenderViewportSet SDL_RenderViewportSet_REAL
|
#define SDL_RenderViewportSet SDL_RenderViewportSet_REAL
|
||||||
#define SDL_ReportAssertion SDL_ReportAssertion_REAL
|
#define SDL_ReportAssertion SDL_ReportAssertion_REAL
|
||||||
#define SDL_RequestAndroidPermission SDL_RequestAndroidPermission_REAL
|
#define SDL_RequestAndroidPermission SDL_RequestAndroidPermission_REAL
|
||||||
|
|
|
@ -700,6 +700,7 @@ SDL_DYNAPI_PROC(int,SDL_RenderRect,(SDL_Renderer *a, const SDL_FRect *b),(a,b),r
|
||||||
SDL_DYNAPI_PROC(int,SDL_RenderRects,(SDL_Renderer *a, const SDL_FRect *b, int c),(a,b,c),return)
|
SDL_DYNAPI_PROC(int,SDL_RenderRects,(SDL_Renderer *a, const SDL_FRect *b, int c),(a,b,c),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_RenderTexture,(SDL_Renderer *a, SDL_Texture *b, const SDL_FRect *c, const SDL_FRect *d),(a,b,c,d),return)
|
SDL_DYNAPI_PROC(int,SDL_RenderTexture,(SDL_Renderer *a, SDL_Texture *b, const SDL_FRect *c, const SDL_FRect *d),(a,b,c,d),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_RenderTextureRotated,(SDL_Renderer *a, SDL_Texture *b, const SDL_FRect *c, const SDL_FRect *d, const double e, const SDL_FPoint *f, const SDL_FlipMode g),(a,b,c,d,e,f,g),return)
|
SDL_DYNAPI_PROC(int,SDL_RenderTextureRotated,(SDL_Renderer *a, SDL_Texture *b, const SDL_FRect *c, const SDL_FRect *d, const double e, const SDL_FPoint *f, const SDL_FlipMode g),(a,b,c,d,e,f,g),return)
|
||||||
|
SDL_DYNAPI_PROC(int,SDL_RenderTextureTiled,(SDL_Renderer *a, SDL_Texture *b, const SDL_FRect *c, float d, const SDL_FRect *e),(a,b,c,d,e),return)
|
||||||
SDL_DYNAPI_PROC(SDL_bool,SDL_RenderViewportSet,(SDL_Renderer *a),(a),return)
|
SDL_DYNAPI_PROC(SDL_bool,SDL_RenderViewportSet,(SDL_Renderer *a),(a),return)
|
||||||
SDL_DYNAPI_PROC(SDL_AssertState,SDL_ReportAssertion,(SDL_AssertData *a, const char *b, const char *c, int d),(a,b,c,d),return)
|
SDL_DYNAPI_PROC(SDL_AssertState,SDL_ReportAssertion,(SDL_AssertData *a, const char *b, const char *c, int d),(a,b,c,d),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_RequestAndroidPermission,(const char *a, SDL_RequestAndroidPermissionCallback b, void *c),(a,b,c),return)
|
SDL_DYNAPI_PROC(int,SDL_RequestAndroidPermission,(const char *a, SDL_RequestAndroidPermissionCallback b, void *c),(a,b,c),return)
|
||||||
|
|
|
@ -3729,52 +3729,10 @@ int SDL_RenderFillRects(SDL_Renderer *renderer, const SDL_FRect *rects, int coun
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_RenderTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FRect *srcrect, const SDL_FRect *dstrect)
|
static int SDL_RenderTextureInternal(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FRect *srcrect, const SDL_FRect *dstrect)
|
||||||
{
|
{
|
||||||
SDL_FRect real_srcrect;
|
|
||||||
SDL_FRect real_dstrect;
|
|
||||||
int retval;
|
int retval;
|
||||||
int use_rendergeometry;
|
SDL_bool use_rendergeometry = (!renderer->QueueCopy);
|
||||||
|
|
||||||
CHECK_RENDERER_MAGIC(renderer, -1);
|
|
||||||
CHECK_TEXTURE_MAGIC(texture, -1);
|
|
||||||
|
|
||||||
if (renderer != texture->renderer) {
|
|
||||||
return SDL_SetError("Texture was not created with this renderer");
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DONT_DRAW_WHILE_HIDDEN
|
|
||||||
/* Don't draw while we're hidden */
|
|
||||||
if (renderer->hidden) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
use_rendergeometry = (!renderer->QueueCopy);
|
|
||||||
|
|
||||||
real_srcrect.x = 0.0f;
|
|
||||||
real_srcrect.y = 0.0f;
|
|
||||||
real_srcrect.w = (float)texture->w;
|
|
||||||
real_srcrect.h = (float)texture->h;
|
|
||||||
if (srcrect) {
|
|
||||||
if (!SDL_GetRectIntersectionFloat(srcrect, &real_srcrect, &real_srcrect)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GetRenderViewportSize(renderer, &real_dstrect);
|
|
||||||
if (dstrect) {
|
|
||||||
if (!SDL_HasRectIntersectionFloat(dstrect, &real_dstrect)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
real_dstrect = *dstrect;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (texture->native) {
|
|
||||||
texture = texture->native;
|
|
||||||
}
|
|
||||||
|
|
||||||
texture->last_command_generation = renderer->render_command_generation;
|
|
||||||
|
|
||||||
if (use_rendergeometry) {
|
if (use_rendergeometry) {
|
||||||
float xy[8];
|
float xy[8];
|
||||||
|
@ -3788,15 +3746,15 @@ int SDL_RenderTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FR
|
||||||
float minu, minv, maxu, maxv;
|
float minu, minv, maxu, maxv;
|
||||||
float minx, miny, maxx, maxy;
|
float minx, miny, maxx, maxy;
|
||||||
|
|
||||||
minu = real_srcrect.x / texture->w;
|
minu = srcrect->x / texture->w;
|
||||||
minv = real_srcrect.y / texture->h;
|
minv = srcrect->y / texture->h;
|
||||||
maxu = (real_srcrect.x + real_srcrect.w) / texture->w;
|
maxu = (srcrect->x + srcrect->w) / texture->w;
|
||||||
maxv = (real_srcrect.y + real_srcrect.h) / texture->h;
|
maxv = (srcrect->y + srcrect->h) / texture->h;
|
||||||
|
|
||||||
minx = real_dstrect.x;
|
minx = dstrect->x;
|
||||||
miny = real_dstrect.y;
|
miny = dstrect->y;
|
||||||
maxx = real_dstrect.x + real_dstrect.w;
|
maxx = dstrect->x + dstrect->w;
|
||||||
maxy = real_dstrect.y + real_dstrect.h;
|
maxy = dstrect->y + dstrect->h;
|
||||||
|
|
||||||
uv[0] = minu;
|
uv[0] = minu;
|
||||||
uv[1] = minv;
|
uv[1] = minv;
|
||||||
|
@ -3823,17 +3781,64 @@ int SDL_RenderTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FR
|
||||||
renderer->view->scale.x,
|
renderer->view->scale.x,
|
||||||
renderer->view->scale.y, SDL_TEXTURE_ADDRESS_CLAMP);
|
renderer->view->scale.y, SDL_TEXTURE_ADDRESS_CLAMP);
|
||||||
} else {
|
} else {
|
||||||
|
SDL_FRect rect;
|
||||||
|
|
||||||
real_dstrect.x *= renderer->view->scale.x;
|
rect.x = dstrect->x * renderer->view->scale.x;
|
||||||
real_dstrect.y *= renderer->view->scale.y;
|
rect.y = dstrect->y * renderer->view->scale.y;
|
||||||
real_dstrect.w *= renderer->view->scale.x;
|
rect.w = dstrect->w * renderer->view->scale.x;
|
||||||
real_dstrect.h *= renderer->view->scale.y;
|
rect.h = dstrect->h * renderer->view->scale.y;
|
||||||
|
|
||||||
retval = QueueCmdCopy(renderer, texture, &real_srcrect, &real_dstrect);
|
retval = QueueCmdCopy(renderer, texture, srcrect, &rect);
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SDL_RenderTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FRect *srcrect, const SDL_FRect *dstrect)
|
||||||
|
{
|
||||||
|
SDL_FRect real_srcrect;
|
||||||
|
SDL_FRect real_dstrect;
|
||||||
|
|
||||||
|
CHECK_RENDERER_MAGIC(renderer, -1);
|
||||||
|
CHECK_TEXTURE_MAGIC(texture, -1);
|
||||||
|
|
||||||
|
if (renderer != texture->renderer) {
|
||||||
|
return SDL_SetError("Texture was not created with this renderer");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DONT_DRAW_WHILE_HIDDEN
|
||||||
|
/* Don't draw while we're hidden */
|
||||||
|
if (renderer->hidden) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
real_srcrect.x = 0.0f;
|
||||||
|
real_srcrect.y = 0.0f;
|
||||||
|
real_srcrect.w = (float)texture->w;
|
||||||
|
real_srcrect.h = (float)texture->h;
|
||||||
|
if (srcrect) {
|
||||||
|
if (!SDL_GetRectIntersectionFloat(srcrect, &real_srcrect, &real_srcrect)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GetRenderViewportSize(renderer, &real_dstrect);
|
||||||
|
if (dstrect) {
|
||||||
|
if (!SDL_HasRectIntersectionFloat(dstrect, &real_dstrect)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
real_dstrect = *dstrect;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture->native) {
|
||||||
|
texture = texture->native;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture->last_command_generation = renderer->render_command_generation;
|
||||||
|
|
||||||
|
return SDL_RenderTextureInternal(renderer, texture, &real_srcrect, &real_dstrect);
|
||||||
|
}
|
||||||
|
|
||||||
int SDL_RenderTextureRotated(SDL_Renderer *renderer, SDL_Texture *texture,
|
int SDL_RenderTextureRotated(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||||
const SDL_FRect *srcrect, const SDL_FRect *dstrect,
|
const SDL_FRect *srcrect, const SDL_FRect *dstrect,
|
||||||
const double angle, const SDL_FPoint *center, const SDL_FlipMode flip)
|
const double angle, const SDL_FPoint *center, const SDL_FlipMode flip)
|
||||||
|
@ -3989,6 +3994,172 @@ int SDL_RenderTextureRotated(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int SDL_RenderTextureTiled_Wrap(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FRect *srcrect, float scale, const SDL_FRect *dstrect)
|
||||||
|
{
|
||||||
|
float xy[8];
|
||||||
|
const int xy_stride = 2 * sizeof(float);
|
||||||
|
float uv[8];
|
||||||
|
const int uv_stride = 2 * sizeof(float);
|
||||||
|
const int num_vertices = 4;
|
||||||
|
const int *indices = renderer->rect_index_order;
|
||||||
|
const int num_indices = 6;
|
||||||
|
const int size_indices = 4;
|
||||||
|
float minu, minv, maxu, maxv;
|
||||||
|
float minx, miny, maxx, maxy;
|
||||||
|
|
||||||
|
minu = 0.0f;
|
||||||
|
minv = 0.0f;
|
||||||
|
maxu = dstrect->w / (srcrect->w * scale);
|
||||||
|
maxv = dstrect->h / (srcrect->h * scale);
|
||||||
|
|
||||||
|
minx = dstrect->x;
|
||||||
|
miny = dstrect->y;
|
||||||
|
maxx = dstrect->x + dstrect->w;
|
||||||
|
maxy = dstrect->y + dstrect->h;
|
||||||
|
|
||||||
|
uv[0] = minu;
|
||||||
|
uv[1] = minv;
|
||||||
|
uv[2] = maxu;
|
||||||
|
uv[3] = minv;
|
||||||
|
uv[4] = maxu;
|
||||||
|
uv[5] = maxv;
|
||||||
|
uv[6] = minu;
|
||||||
|
uv[7] = maxv;
|
||||||
|
|
||||||
|
xy[0] = minx;
|
||||||
|
xy[1] = miny;
|
||||||
|
xy[2] = maxx;
|
||||||
|
xy[3] = miny;
|
||||||
|
xy[4] = maxx;
|
||||||
|
xy[5] = maxy;
|
||||||
|
xy[6] = minx;
|
||||||
|
xy[7] = maxy;
|
||||||
|
|
||||||
|
return QueueCmdGeometry(renderer, texture,
|
||||||
|
xy, xy_stride, &texture->color, 0 /* color_stride */, uv, uv_stride,
|
||||||
|
num_vertices,
|
||||||
|
indices, num_indices, size_indices,
|
||||||
|
renderer->view->scale.x,
|
||||||
|
renderer->view->scale.y, SDL_TEXTURE_ADDRESS_WRAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int SDL_RenderTextureTiled_Iterate(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FRect *srcrect, float scale, const SDL_FRect *dstrect)
|
||||||
|
{
|
||||||
|
float tile_width = srcrect->w * scale;
|
||||||
|
float tile_height = srcrect->h * scale;
|
||||||
|
float float_rows, float_cols;
|
||||||
|
float remaining_w = SDL_modff(dstrect->w / tile_width, &float_cols);
|
||||||
|
float remaining_h = SDL_modff(dstrect->h / tile_height, &float_rows);
|
||||||
|
float remaining_src_w = remaining_w * srcrect->w;
|
||||||
|
float remaining_src_h = remaining_h * srcrect->h;
|
||||||
|
float remaining_dst_w = remaining_w * tile_width;
|
||||||
|
float remaining_dst_h = remaining_h * tile_height;
|
||||||
|
int rows = (int)float_rows;
|
||||||
|
int cols = (int)float_cols;
|
||||||
|
SDL_FRect curr_src, curr_dst;
|
||||||
|
|
||||||
|
SDL_copyp(&curr_src, srcrect);
|
||||||
|
curr_dst.y = dstrect->y;
|
||||||
|
curr_dst.w = tile_width;
|
||||||
|
curr_dst.h = tile_height;
|
||||||
|
for (int y = 0; y < rows; ++y) {
|
||||||
|
curr_dst.x = dstrect->x;
|
||||||
|
for (int x = 0; x < cols; ++x) {
|
||||||
|
if (SDL_RenderTextureInternal(renderer, texture, &curr_src, &curr_dst) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
curr_dst.x += curr_dst.w;
|
||||||
|
}
|
||||||
|
if (remaining_dst_w > 0.0f) {
|
||||||
|
curr_src.w = remaining_src_w;
|
||||||
|
curr_dst.w = remaining_dst_w;
|
||||||
|
if (SDL_RenderTextureInternal(renderer, texture, &curr_src, &curr_dst) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
curr_src.w = srcrect->w;
|
||||||
|
curr_dst.w = tile_width;
|
||||||
|
}
|
||||||
|
curr_dst.y += curr_dst.h;
|
||||||
|
}
|
||||||
|
if (remaining_dst_h > 0.0f) {
|
||||||
|
curr_src.h = remaining_src_h;
|
||||||
|
curr_dst.h = remaining_dst_h;
|
||||||
|
curr_dst.x = dstrect->x;
|
||||||
|
for (int x = 0; x < cols; ++x) {
|
||||||
|
if (SDL_RenderTextureInternal(renderer, texture, &curr_src, &curr_dst) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
curr_dst.x += curr_dst.w;
|
||||||
|
}
|
||||||
|
if (remaining_dst_w > 0.0f) {
|
||||||
|
curr_src.w = remaining_src_w;
|
||||||
|
curr_dst.w = remaining_dst_w;
|
||||||
|
if (SDL_RenderTextureInternal(renderer, texture, &curr_src, &curr_dst) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SDL_RenderTextureTiled(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FRect *srcrect, float scale, const SDL_FRect *dstrect)
|
||||||
|
{
|
||||||
|
SDL_FRect real_srcrect;
|
||||||
|
SDL_FRect real_dstrect;
|
||||||
|
|
||||||
|
CHECK_RENDERER_MAGIC(renderer, -1);
|
||||||
|
CHECK_TEXTURE_MAGIC(texture, -1);
|
||||||
|
|
||||||
|
if (renderer != texture->renderer) {
|
||||||
|
return SDL_SetError("Texture was not created with this renderer");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scale <= 0.0f) {
|
||||||
|
return SDL_InvalidParamError("scale");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DONT_DRAW_WHILE_HIDDEN
|
||||||
|
/* Don't draw while we're hidden */
|
||||||
|
if (renderer->hidden) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
real_srcrect.x = 0.0f;
|
||||||
|
real_srcrect.y = 0.0f;
|
||||||
|
real_srcrect.w = (float)texture->w;
|
||||||
|
real_srcrect.h = (float)texture->h;
|
||||||
|
if (srcrect) {
|
||||||
|
if (!SDL_GetRectIntersectionFloat(srcrect, &real_srcrect, &real_srcrect)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GetRenderViewportSize(renderer, &real_dstrect);
|
||||||
|
if (dstrect) {
|
||||||
|
if (!SDL_HasRectIntersectionFloat(dstrect, &real_dstrect)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
real_dstrect = *dstrect;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture->native) {
|
||||||
|
texture = texture->native;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture->last_command_generation = renderer->render_command_generation;
|
||||||
|
|
||||||
|
// See if we can use geometry with repeating texture coordinates
|
||||||
|
if (!renderer->software &&
|
||||||
|
(!srcrect ||
|
||||||
|
(real_srcrect.x == 0.0f && real_srcrect.y == 0.0f &&
|
||||||
|
real_srcrect.w == (float)texture->w && real_srcrect.h == (float)texture->h))) {
|
||||||
|
return SDL_RenderTextureTiled_Wrap(renderer, texture, &real_srcrect, scale, &real_dstrect);
|
||||||
|
} else {
|
||||||
|
return SDL_RenderTextureTiled_Iterate(renderer, texture, &real_srcrect, scale, &real_dstrect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int SDL_RenderGeometry(SDL_Renderer *renderer,
|
int SDL_RenderGeometry(SDL_Renderer *renderer,
|
||||||
SDL_Texture *texture,
|
SDL_Texture *texture,
|
||||||
const SDL_Vertex *vertices, int num_vertices,
|
const SDL_Vertex *vertices, int num_vertices,
|
||||||
|
|
|
@ -36,6 +36,7 @@ static SDL_Renderer *renderer = NULL;
|
||||||
|
|
||||||
static int clearScreen(void);
|
static int clearScreen(void);
|
||||||
static void compare(SDL_Surface *reference, int allowable_error);
|
static void compare(SDL_Surface *reference, int allowable_error);
|
||||||
|
static void compare2x(SDL_Surface *reference, int allowable_error);
|
||||||
static SDL_Texture *loadTestFace(void);
|
static SDL_Texture *loadTestFace(void);
|
||||||
static int hasDrawColor(void);
|
static int hasDrawColor(void);
|
||||||
static int isSupported(int code);
|
static int isSupported(int code);
|
||||||
|
@ -292,6 +293,78 @@ static int render_testBlit(void *arg)
|
||||||
return TEST_COMPLETED;
|
return TEST_COMPLETED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests tiled blitting routines.
|
||||||
|
*/
|
||||||
|
static int render_testBlitTiled(void *arg)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
SDL_FRect rect;
|
||||||
|
SDL_Texture *tface;
|
||||||
|
SDL_Surface *referenceSurface = NULL;
|
||||||
|
SDL_Surface *referenceSurface2x = NULL;
|
||||||
|
|
||||||
|
/* Create face surface. */
|
||||||
|
tface = loadTestFace();
|
||||||
|
SDLTest_AssertCheck(tface != NULL, "Verify loadTestFace() result");
|
||||||
|
if (tface == NULL) {
|
||||||
|
return TEST_ABORTED;
|
||||||
|
}
|
||||||
|
SDL_SetTextureScaleMode(tface, SDL_SCALEMODE_NEAREST); /* So 2x scaling is pixel perfect */
|
||||||
|
|
||||||
|
/* Tiled blit - 1.0 scale */
|
||||||
|
{
|
||||||
|
/* Clear surface. */
|
||||||
|
clearScreen();
|
||||||
|
|
||||||
|
/* Tiled blit. */
|
||||||
|
rect.x = 0.0f;
|
||||||
|
rect.y = 0.0f;
|
||||||
|
rect.w = (float)TESTRENDER_SCREEN_W;
|
||||||
|
rect.h = (float)TESTRENDER_SCREEN_H;
|
||||||
|
ret = SDL_RenderTextureTiled(renderer, tface, NULL, 1.0f, &rect);
|
||||||
|
SDLTest_AssertCheck(ret == 0, "Validate results from call to SDL_RenderTextureTiled, expected: 0, got: %i", ret);
|
||||||
|
|
||||||
|
/* See if it's the same */
|
||||||
|
referenceSurface = SDLTest_ImageBlitTiled();
|
||||||
|
compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
|
||||||
|
|
||||||
|
/* Make current */
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tiled blit - 2.0 scale */
|
||||||
|
{
|
||||||
|
/* Clear surface. */
|
||||||
|
clearScreen();
|
||||||
|
|
||||||
|
/* Tiled blit. */
|
||||||
|
rect.x = 0.0f;
|
||||||
|
rect.y = 0.0f;
|
||||||
|
rect.w = (float)TESTRENDER_SCREEN_W * 2;
|
||||||
|
rect.h = (float)TESTRENDER_SCREEN_H * 2;
|
||||||
|
ret = SDL_RenderTextureTiled(renderer, tface, NULL, 2.0f, &rect);
|
||||||
|
SDLTest_AssertCheck(ret == 0, "Validate results from call to SDL_RenderTextureTiled, expected: 0, got: %i", ret);
|
||||||
|
|
||||||
|
/* See if it's the same */
|
||||||
|
referenceSurface2x = SDL_CreateSurface(referenceSurface->w * 2, referenceSurface->h * 2, referenceSurface->format);
|
||||||
|
SDL_BlitSurfaceScaled(referenceSurface, NULL, referenceSurface2x, NULL, SDL_SCALEMODE_NEAREST);
|
||||||
|
SDLTest_AssertCheck(ret == 0, "Validate results from call to SDL_BlitSurfaceScaled, expected: 0, got: %i", ret);
|
||||||
|
compare2x(referenceSurface2x, ALLOWABLE_ERROR_OPAQUE);
|
||||||
|
|
||||||
|
/* Make current */
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean up. */
|
||||||
|
SDL_DestroyTexture(tface);
|
||||||
|
SDL_DestroySurface(referenceSurface);
|
||||||
|
SDL_DestroySurface(referenceSurface2x);
|
||||||
|
referenceSurface = NULL;
|
||||||
|
|
||||||
|
return TEST_COMPLETED;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blits doing color tests.
|
* Blits doing color tests.
|
||||||
*
|
*
|
||||||
|
@ -1008,8 +1081,7 @@ loadTestFace(void)
|
||||||
* \sa SDL_CreateSurfaceFrom
|
* \sa SDL_CreateSurfaceFrom
|
||||||
* \sa SDL_DestroySurface
|
* \sa SDL_DestroySurface
|
||||||
*/
|
*/
|
||||||
static void
|
static void compare(SDL_Surface *referenceSurface, int allowable_error)
|
||||||
compare(SDL_Surface *referenceSurface, int allowable_error)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
SDL_Rect rect;
|
SDL_Rect rect;
|
||||||
|
@ -1041,6 +1113,38 @@ compare(SDL_Surface *referenceSurface, int allowable_error)
|
||||||
/* Clean up. */
|
/* Clean up. */
|
||||||
SDL_DestroySurface(testSurface);
|
SDL_DestroySurface(testSurface);
|
||||||
}
|
}
|
||||||
|
static void compare2x(SDL_Surface *referenceSurface, int allowable_error)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
SDL_Rect rect;
|
||||||
|
SDL_Surface *surface, *testSurface;
|
||||||
|
|
||||||
|
/* Explicitly specify the rect in case the window isn't the expected size... */
|
||||||
|
rect.x = 0;
|
||||||
|
rect.y = 0;
|
||||||
|
rect.w = TESTRENDER_SCREEN_W * 2;
|
||||||
|
rect.h = TESTRENDER_SCREEN_H * 2;
|
||||||
|
|
||||||
|
surface = SDL_RenderReadPixels(renderer, &rect);
|
||||||
|
if (!surface) {
|
||||||
|
SDLTest_AssertCheck(surface != NULL, "Validate result from SDL_RenderReadPixels, got NULL, %s", SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
testSurface = SDL_ConvertSurface(surface, RENDER_COMPARE_FORMAT);
|
||||||
|
SDL_DestroySurface(surface);
|
||||||
|
if (!testSurface) {
|
||||||
|
SDLTest_AssertCheck(testSurface != NULL, "Validate result from SDL_ConvertSurface, got NULL, %s", SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compare surface. */
|
||||||
|
ret = SDLTest_CompareSurfaces(testSurface, referenceSurface, allowable_error);
|
||||||
|
SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
|
||||||
|
|
||||||
|
/* Clean up. */
|
||||||
|
SDL_DestroySurface(testSurface);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the screen. Helper function.
|
* Clears the screen. Helper function.
|
||||||
|
@ -1182,39 +1286,43 @@ static int render_testUVWrapping(void *arg)
|
||||||
/* ================= Test References ================== */
|
/* ================= Test References ================== */
|
||||||
|
|
||||||
/* Render test cases */
|
/* Render test cases */
|
||||||
static const SDLTest_TestCaseReference renderTest1 = {
|
static const SDLTest_TestCaseReference renderTestGetNumRenderDrivers = {
|
||||||
(SDLTest_TestCaseFp)render_testGetNumRenderDrivers, "render_testGetNumRenderDrivers", "Tests call to SDL_GetNumRenderDrivers", TEST_ENABLED
|
(SDLTest_TestCaseFp)render_testGetNumRenderDrivers, "render_testGetNumRenderDrivers", "Tests call to SDL_GetNumRenderDrivers", TEST_ENABLED
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SDLTest_TestCaseReference renderTest2 = {
|
static const SDLTest_TestCaseReference renderTestPrimitives = {
|
||||||
(SDLTest_TestCaseFp)render_testPrimitives, "render_testPrimitives", "Tests rendering primitives", TEST_ENABLED
|
(SDLTest_TestCaseFp)render_testPrimitives, "render_testPrimitives", "Tests rendering primitives", TEST_ENABLED
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SDLTest_TestCaseReference renderTest3 = {
|
static const SDLTest_TestCaseReference renderTestPrimitivesWithViewport = {
|
||||||
(SDLTest_TestCaseFp)render_testPrimitivesWithViewport, "render_testPrimitivesWithViewport", "Tests rendering primitives within a viewport", TEST_ENABLED
|
(SDLTest_TestCaseFp)render_testPrimitivesWithViewport, "render_testPrimitivesWithViewport", "Tests rendering primitives within a viewport", TEST_ENABLED
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SDLTest_TestCaseReference renderTest4 = {
|
static const SDLTest_TestCaseReference renderTestBlit = {
|
||||||
(SDLTest_TestCaseFp)render_testBlit, "render_testBlit", "Tests blitting", TEST_ENABLED
|
(SDLTest_TestCaseFp)render_testBlit, "render_testBlit", "Tests blitting", TEST_ENABLED
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SDLTest_TestCaseReference renderTest5 = {
|
static const SDLTest_TestCaseReference renderTestBlitTiled = {
|
||||||
|
(SDLTest_TestCaseFp)render_testBlitTiled, "render_testBlitTiled", "Tests tiled blitting", TEST_ENABLED
|
||||||
|
};
|
||||||
|
|
||||||
|
static const SDLTest_TestCaseReference renderTestBlitColor = {
|
||||||
(SDLTest_TestCaseFp)render_testBlitColor, "render_testBlitColor", "Tests blitting with color", TEST_ENABLED
|
(SDLTest_TestCaseFp)render_testBlitColor, "render_testBlitColor", "Tests blitting with color", TEST_ENABLED
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SDLTest_TestCaseReference renderTest6 = {
|
static const SDLTest_TestCaseReference renderTestBlendModes = {
|
||||||
(SDLTest_TestCaseFp)render_testBlendModes, "render_testBlendModes", "Tests rendering blend modes", TEST_ENABLED
|
(SDLTest_TestCaseFp)render_testBlendModes, "render_testBlendModes", "Tests rendering blend modes", TEST_ENABLED
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SDLTest_TestCaseReference renderTest7 = {
|
static const SDLTest_TestCaseReference renderTestViewport = {
|
||||||
(SDLTest_TestCaseFp)render_testViewport, "render_testViewport", "Tests viewport", TEST_ENABLED
|
(SDLTest_TestCaseFp)render_testViewport, "render_testViewport", "Tests viewport", TEST_ENABLED
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SDLTest_TestCaseReference renderTest8 = {
|
static const SDLTest_TestCaseReference renderTestClipRect = {
|
||||||
(SDLTest_TestCaseFp)render_testClipRect, "render_testClipRect", "Tests clip rect", TEST_ENABLED
|
(SDLTest_TestCaseFp)render_testClipRect, "render_testClipRect", "Tests clip rect", TEST_ENABLED
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SDLTest_TestCaseReference renderTest9 = {
|
static const SDLTest_TestCaseReference renderTestLogicalSize = {
|
||||||
(SDLTest_TestCaseFp)render_testLogicalSize, "render_testLogicalSize", "Tests logical size", TEST_ENABLED
|
(SDLTest_TestCaseFp)render_testLogicalSize, "render_testLogicalSize", "Tests logical size", TEST_ENABLED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1224,9 +1332,18 @@ static const SDLTest_TestCaseReference renderTestUVWrapping = {
|
||||||
|
|
||||||
/* Sequence of Render test cases */
|
/* Sequence of Render test cases */
|
||||||
static const SDLTest_TestCaseReference *renderTests[] = {
|
static const SDLTest_TestCaseReference *renderTests[] = {
|
||||||
&renderTest1, &renderTest2, &renderTest3, &renderTest4,
|
&renderTestGetNumRenderDrivers,
|
||||||
&renderTest5, &renderTest6, &renderTest7, &renderTest8,
|
&renderTestPrimitives,
|
||||||
&renderTest9, &renderTestUVWrapping, NULL
|
&renderTestPrimitivesWithViewport,
|
||||||
|
&renderTestBlit,
|
||||||
|
&renderTestBlitTiled,
|
||||||
|
&renderTestBlitColor,
|
||||||
|
&renderTestBlendModes,
|
||||||
|
&renderTestViewport,
|
||||||
|
&renderTestClipRect,
|
||||||
|
&renderTestLogicalSize,
|
||||||
|
&renderTestUVWrapping,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Render test suite (global) */
|
/* Render test suite (global) */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue