We have an image like:
We have 4 coordinates top:10, bottom:10, left:10, right:10 we have resi开发者_如何学编程ze to values like newWidth:100, newHeight:35 we have some SDL_Rect Sprite
which was generated from some SDL_Surface *button
how to performe on that Sprite such resize transformations?
So how to inplement 9-slice scaling in SDL?
I've made a demo project performing 9 slice rendering using c and sdl-2 here: https://github.com/cxong/sdl2-9-slice
Take a look at the render()
function and copy it if you like - it's permissively licensed.
The key is to use the srcrect
and dstrect
parameters of SDL_RenderCopy()
- the former is which part of the source texture to render, the latter which part of the destination (render target) to render into.
For 9 slice, the corners are copied as-is; for the middle parts, depending on how you want to render - stretched or repeated - the srcrect
will be the same, but dstrect
will stretch or repeat.
Another thing is that SDL does not do texture repeating (yet). So if you want to render as repeat mode, you need to use a loop.
Here's the function in case the project dies:
int render(
SDL_Renderer *renderer, SDL_Surface *s, SDL_Texture *t,
int x, int y, int top, int bottom, int left, int right, int w, int h,
bool repeat)
{
const int srcX[] = {0, left, s->w - right};
const int srcY[] = {0, top, s->h - bottom};
const int srcW[] = {left, s->w - right - left, right};
const int srcH[] = {top, s->h - bottom - top, bottom};
const int dstX[] = {x, x + left, x + w - right, x + w};
const int dstY[] = {y, y + top, y + h - bottom, y + h};
const int dstW[] = {left, w - right - left, right};
const int dstH[] = {top, h - bottom - top, bottom};
SDL_Rect src;
SDL_Rect dst;
for (int i = 0; i < 3; i++)
{
src.x = srcX[i];
src.w = srcW[i];
dst.w = repeat ? srcW[i] : dstW[i];
for (dst.x = dstX[i]; dst.x < dstX[i + 1]; dst.x += dst.w)
{
if (dst.x + dst.w > dstX[i + 1])
{
src.w = dst.w = dstX[i + 1] - dst.x;
}
for (int j = 0; j < 3; j++)
{
src.y = srcY[j];
src.h = srcH[j];
dst.h = repeat ? srcH[j] : dstH[j];
for (dst.y = dstY[j]; dst.y < dstY[j + 1]; dst.y += dst.h)
{
if (dst.y + dst.h > dstY[j + 1])
{
src.h = dst.h = dstY[j + 1] - dst.y;
}
const int res = SDL_RenderCopy(renderer, t, &src, &dst);
if (res != 0)
{
return res;
}
}
}
}
}
return 0;
}
精彩评论