Search code examples
c#xnaspritescalingtexture2d

Scaling a Texture2D in XNA


I have a 160 x 80 button in a window with resolution of 1280 x 720. I draw it as followed(I paraphrase a bit here):

currentwindowwidth = 1280;
// The scale in this instance would be 1.0f
scale = currentwindowwidth / 1280f;
b.position = new Vector2(640, 650) * scale;
b.origin = new Vector2(80, 40) * scale;
spriteBatch.Draw(b.texture, b.pos, null, Color.White, 0, b.ori, scale, SpriteEffects.None, 0);

When I draw the window at 1280 x 720, the button is drawn in the correct location and the button detection:

if (mousepos.X >= b.pos.X - b.ori.X && mousepos.X <= b.pos.X + b.ori.X)
{
    if (mousepos.Y >= b.pos.Y - b.ori.Y && mousepos.Y <= b.pos.Y + b.ori.Y)
    {
        HandleButton(b);
    }
}

works 100%. The button detects my mouse clicks to pixel perfect precision, and the texture2d is drawn faithfully to the detection box.

However, when I scale up to 1920 x 1080 (same aspect ratio), the button is drawn in the incorrect location:

currentwindowwidth = 1920;
// The scale would be 1.5f here
scale = currentwindowwidth / 1280f;
b.position = new Vector2(640, 650) * scale;
b.origin = new Vector2(80, 40) * scale;
spriteBatch.Draw(b.texture, b.pos, null, Color.White, 0, b.ori, scale, SpriteEffects.None, 0);

This will now give me a position vector of (960, 975) and an origin of (120, 60)(<-- which I find in the "Locals" tab in visual studio). After doing some calculations these are the correct values, and the button detection works exactly where I want it to work. HOWEVER the sprite is not drawn in the correct location, it is drawn (-60, -30) pixels offset from where it should be. When scaled up the button detection works in the correct location(840-1080, 915-1035) but the texture2d is drawn in the wrong place.

This happens as well when I scale the screen to another 16:9 resolution such as 1366 x 768, except not (-60, -30) off but proportionally (-8.0625, -4.03125) and (-30, -15) at 1600 x 900.

This effect is also witnessed when I use resolutions smaller than 1280 x 720 (854 x 480), but in the opposite direction (a positive offset vector instead of a negative one).

In every 16:9 resolution the button detection works as calculated, but when I scale the texture2d it is drawn in the incorrect place. My only guess is that the scale scale's the texture2d in ways I am not aware of.

If anybody else has any experience on the issue I would much appreciate it,

Ken


Solution

  • The origin parameter is specified in pixels from the top-left corner of the sprite texture. It gets applied before the sprite is scaled or positioned - you don't need to scale origin with the screen!

    Also, it may be worth considering passing a scaling matrix to SpriteBatch.Begin, to scale up your entire scene, instead of manually scaling and positioning every sprite.

    You will probably need to re-work your maths for figuring out the click-bounds in either case.

    Note that if you use a matrix for scaling your whole scene, that matrix can be inverted to go back from screen (client) coordinates to scene (world) coordinates.