Sdl 1.3:如何实现简单的scale-9-grid来调整图像大小?

发布于 2024-11-17 04:33:31 字数 306 浏览 3 评论 0原文

我们有一个像这样的图像:

在此处输入图像描述

我们有 4 个坐标 top:10、bottom:10、left:10、 right:10 我们已将大小调整为 newWidth:100、newHeight:35 等值,我们有一些 SDL_Rect Sprite,它是由某些 SDL_Surface *button 生成的对该 Sprite 执行此类调整大小转换?

那么如何在SDL中实现9切片缩放呢?

We have an image like:

enter image description here

We have 4 coordinates top:10, bottom:10, left:10, right:10 we have resize 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

想念有你 2024-11-24 04:33:31

我制作了一个演示项目,使用 此处:<一href="https://github.com/cxong/sdl2-9-slice" rel="nofollow noreferrer">https://github.com/cxong/sdl2-9-slice

screenshot

查看 render() 函数并根据需要复制它 - 它已获得许可。

关键是使用 < 的 srcrectdstrect 参数code>SDL_RenderCopy() - 前者是要渲染源纹理的哪一部分,后者是要渲染到目标(渲染目标)的哪一部分。

对于 9 切片,角点按原样复制;对于中间部分,根据您想要的渲染方式(拉伸或重复),srcrect 将是相同的,但 dstrect 将拉伸或重复。

另一件事是,SDL 还没有进行纹理重复。所以如果你想渲染为重复模式,你需要使用循环。

这是项目终止时的函数:

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;
}

I've made a demo project performing 9 slice rendering using and here: https://github.com/cxong/sdl2-9-slice

screenshot

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文