1
\$\begingroup\$

I'm making a simple game in C# and i'm trying to slice my UI images into 9 smaller rectangles, so the image doesn't get stretched when drawing to different resolutions, but i'm having lots of problems with my code.

I have the following method for slicing an image:

public RectangleF[] SliceRectangle (RectangleF rectangle, float LeftPadding, float RightPadding, float TopPadding, float BottomPadding)
{
    var x = rectangle.X;
    var y = rectangle.Y;
    var w = rectangle.Width;
    var h = rectangle.Height;

    var middleWidth = w - LeftPadding - RightPadding;
    var middleHeight = h - TopPadding - BottomPadding;
    var bottomY = y + h - BottomPadding;
    var rightX = x + w - RightPadding;
    var leftX = x + LeftPadding;
    var topY = y + TopPadding;

    var patches = new RectangleF[]
    {
        new RectangleF(x,      y,        LeftPadding,  TopPadding),      // top left
        new RectangleF(leftX,  y,        middleWidth,  TopPadding),      // top middle
        new RectangleF(rightX, y,        RightPadding, TopPadding),      // top right

        new RectangleF(x,      topY,     LeftPadding,  middleHeight),    // left middle
        new RectangleF(leftX,  topY,     middleWidth,  middleHeight),    // middle
        new RectangleF(rightX, topY,     RightPadding, middleHeight),    // right middle

        new RectangleF(x,      bottomY,  LeftPadding,  BottomPadding),   // bottom left
        new RectangleF(leftX,  bottomY,  middleWidth,  BottomPadding),   // bottom middle
        new RectangleF(rightX, bottomY,  RightPadding, BottomPadding)    // bottom right
    };

    return patches;
}

And then i draw the sliced image like this:

public void Render (Graphics graphics)
{
    sprite.rectangle = new RectangleF(0, 0, 512, 512);

    var destination_slices = sprite.SliceRectangle(rectangle: sprite.rectangle, left: 32, right: 480, top: 32, bottom: 480);
    var source_slices = sprite.SliceRectangle(rectangle: new RectangleF(0, 0, sprite.texture.Width, sprite.texture.Height), left: 32, right: 224, top: 16, bottom: 48);

    for (int i = 0; i < source_slices.Length; i++)
    {
        graphics.DrawImage(sprite.texture, destination_slices[i], source_slices[i], GraphicsUnit.Pixel);
        Debug.Log(source_slices[i]);
    }
}

Here is the result that is printed by the "Render" method:

Top left:   X = 0,   Y = 0,  Width = 32,  Height = 16
Top middle: X = 32,  Y = 0,  Width = 192, Height = 16
Top right:  X = 224, Y = 0,  Width = 32,  Height = 16

Middle left:  X = 0,   Y = 16, Width = 32,  Height = 32
Middle:       X = 32,  Y = 16, Width = 192, Height = 32
Middle Right: X = 224, Y = 16, Width = 32,  Height = 32

Bottom left:   X = 0,   Y = 48, Width = 32,  Height = 16
Bottom middle: X = 32,  Y = 48, Width = 192, Height = 16
Bottom right:  X = 224, Y = 48, Width = 32,  Height = 16

Now, the problem is that this method is producing completely wrong results:

  • When changing the rectangle values, the slices gets scaled incorectly.
  • The image slices are not sized correctly and some parts of the image are missing, specially when changing the padding values.
  • I believe the padding is what is making the slices draw incorrectly, so i would like to know what values they should have.

Some specifications:

  • The size of the image i'm drawing is 256 by 64 pixels.
  • The area i want to draw the image is 512 by 512 pixels.

I tried lots of different values and combinations, but could not make this method work, so i'm hoping someone here tests the code and help me find a solution to this problem.

Thanks in advance!

\$\endgroup\$
11
  • 1
    \$\begingroup\$ Not an answer (I cannot make the time right now!), but I solve a similar problem with a dedicated struct for a 9slice. It takes outer dimensions and margins and turns them into 16 points, which are then used by the renderer to create the 9 quads (rects in your case) to actually draw. github.com/htmlcoderexe/3DGame/blob/… The code that uses this data structure is in RenderFrame inside GFXUtility in the same folder, you can follow it from there. \$\endgroup\$ Commented Sep 14, 2021 at 14:06
  • 1
    \$\begingroup\$ What are the parameters passed to the region rectangles constructor? Are those the direct padding values? Is the result you've shared for the destination or the source? What is source_patch? \$\endgroup\$ Commented Sep 14, 2021 at 16:47
  • 1
    \$\begingroup\$ Then why right: 224? If your source image is 256 pixels wide, and left padding is 32 pixels, and right padding is 224, there would be no texture left for the middle piece? Yet this is not what your results show, so it's not clear if the provided code actually produces the output shown. \$\endgroup\$ Commented Sep 14, 2021 at 17:04
  • 1
    \$\begingroup\$ Then your previous comment isn't true, as the right value is not the direct padding size, but instead coordinates that you (assumedly?) calculate the actual padding values from. \$\endgroup\$ Commented Sep 14, 2021 at 17:28
  • 1
    \$\begingroup\$ Okay, and how do you calculate those padding values? Since the region only gets those coordinates and no size, how does TextureRegion know that RightPadding should be 32 pixels, as all it gets is 224? \$\endgroup\$ Commented Sep 14, 2021 at 18:08

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.