From 611403dd0eaf15ebf0a1010962a916979461f9cf Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 8 Mar 2020 21:02:40 -0700 Subject: [PATCH] Clarified that the clip rectangle is defined relative to the viewport, and added a clip test to testviewport.c --- include/SDL_render.h | 4 +- test/testviewport.c | 94 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 80 insertions(+), 18 deletions(-) diff --git a/include/SDL_render.h b/include/SDL_render.h index 6d0e6962f..f26fb7e5f 100644 --- a/include/SDL_render.h +++ b/include/SDL_render.h @@ -618,8 +618,8 @@ extern DECLSPEC void SDLCALL SDL_RenderGetViewport(SDL_Renderer * renderer, * \brief Set the clip rectangle for the current target. * * \param renderer The renderer for which clip rectangle should be set. - * \param rect A pointer to the rectangle to set as the clip rectangle, or - * NULL to disable clipping. + * \param rect A pointer to the rectangle to set as the clip rectangle, + * relative to the viewport, or NULL to disable clipping. * * \return 0 on success, or -1 on error * diff --git a/test/testviewport.c b/test/testviewport.c index 13a5df728..fc44fe1b6 100644 --- a/test/testviewport.c +++ b/test/testviewport.c @@ -25,12 +25,14 @@ static SDLTest_CommonState *state; -SDL_Rect viewport; -int done, j; -SDL_bool use_target = SDL_FALSE; +static SDL_Rect viewport; +static int done, j; +static SDL_bool use_target = SDL_FALSE; #ifdef __EMSCRIPTEN__ -Uint32 wait_start; +static Uint32 wait_start; #endif +static SDL_Texture *sprite; +static int sprite_w, sprite_h; /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ static void @@ -40,6 +42,55 @@ quit(int rc) exit(rc); } +int +LoadSprite(char *file, SDL_Renderer *renderer) +{ + SDL_Surface *temp; + + /* Load the sprite image */ + temp = SDL_LoadBMP(file); + if (temp == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", file, SDL_GetError()); + return (-1); + } + sprite_w = temp->w; + sprite_h = temp->h; + + /* Set transparent pixel as the pixel at (0,0) */ + if (temp->format->palette) { + SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels); + } else { + switch (temp->format->BitsPerPixel) { + case 15: + SDL_SetColorKey(temp, SDL_TRUE, + (*(Uint16 *) temp->pixels) & 0x00007FFF); + break; + case 16: + SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels); + break; + case 24: + SDL_SetColorKey(temp, SDL_TRUE, + (*(Uint32 *) temp->pixels) & 0x00FFFFFF); + break; + case 32: + SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels); + break; + } + } + + /* Create textures from the image */ + sprite = SDL_CreateTextureFromSurface(renderer, temp); + if (!sprite) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); + SDL_FreeSurface(temp); + return (-1); + } + SDL_FreeSurface(temp); + + /* We're ready to roll. :) */ + return (0); +} + void DrawOnViewport(SDL_Renderer * renderer, SDL_Rect viewport) { @@ -53,11 +104,11 @@ DrawOnViewport(SDL_Renderer * renderer, SDL_Rect viewport) SDL_RenderClear(renderer); /* Test inside points */ - SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xF, 0xFF); - SDL_RenderDrawPoint(renderer, viewport.h/2 + 10, viewport.w/2); - SDL_RenderDrawPoint(renderer, viewport.h/2 - 10, viewport.w/2); - SDL_RenderDrawPoint(renderer, viewport.h/2 , viewport.w/2 - 10); - SDL_RenderDrawPoint(renderer, viewport.h/2 , viewport.w/2 + 10); + SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0x00, 0xFF); + SDL_RenderDrawPoint(renderer, viewport.h/2 + 20, viewport.w/2); + SDL_RenderDrawPoint(renderer, viewport.h/2 - 20, viewport.w/2); + SDL_RenderDrawPoint(renderer, viewport.h/2 , viewport.w/2 - 20); + SDL_RenderDrawPoint(renderer, viewport.h/2 , viewport.w/2 + 20); /* Test horizontal and vertical lines */ SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF); @@ -68,17 +119,15 @@ DrawOnViewport(SDL_Renderer * renderer, SDL_Rect viewport) /* Test diagonal lines */ SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0xFF, 0xFF); - SDL_RenderDrawLine(renderer, 0, 0, - viewport.w-1, viewport.h-1); - SDL_RenderDrawLine(renderer, viewport.w-1, 0, - 0, viewport.h-1); + SDL_RenderDrawLine(renderer, 0, 0, viewport.w-1, viewport.h-1); + SDL_RenderDrawLine(renderer, viewport.w-1, 0, 0, viewport.h-1); /* Test outside points */ - SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xF, 0xFF); + SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0x00, 0xFF); SDL_RenderDrawPoint(renderer, viewport.h/2 + viewport.h, viewport.w/2); SDL_RenderDrawPoint(renderer, viewport.h/2 - viewport.h, viewport.w/2); - SDL_RenderDrawPoint(renderer, viewport.h/2 , viewport.w/2 - viewport.w); - SDL_RenderDrawPoint(renderer, viewport.h/2 , viewport.w/2 + viewport.w); + SDL_RenderDrawPoint(renderer, viewport.h/2, viewport.w/2 - viewport.w); + SDL_RenderDrawPoint(renderer, viewport.h/2, viewport.w/2 + viewport.w); /* Add a box at the top */ rect.w = 8; @@ -86,6 +135,14 @@ DrawOnViewport(SDL_Renderer * renderer, SDL_Rect viewport) rect.x = (viewport.w - rect.w) / 2; rect.y = 0; SDL_RenderFillRect(renderer, &rect); + + /* Add a clip rect and fill it with the sprite */ + SDL_QueryTexture(sprite, NULL, NULL, &rect.w, &rect.h); + rect.x = (viewport.w - rect.w) / 2; + rect.y = (viewport.h - rect.h) / 2; + SDL_RenderSetClipRect(renderer, &rect); + SDL_RenderCopy(renderer, sprite, NULL, &rect); + SDL_RenderSetClipRect(renderer, NULL); } void @@ -149,6 +206,7 @@ main(int argc, char *argv[]) return 1; } + for (i = 1; i < argc;) { int consumed; @@ -171,6 +229,10 @@ main(int argc, char *argv[]) quit(2); } + if (LoadSprite("icon.bmp", state->renderers[0]) < 0) { + quit(2); + } + if (use_target) { int w, h;