February 26, 2005

Sprite.Draw2D Scaling Issue

If you've used Managed Direct3D's Sprite.Draw2D class to render sprites out and tried to scale the sprites, you may have noticed that it applies the scale *after* the shift for position. Needless to say, this is a bad thing, as it causes the sprites to shift up and to the left by odd amounts if scaling down, and down and to the right if scaling up.

To fix the problem, you need to multiply the x and y positions of your sprites by the texture width divided by the the new height.

    Private Sprites As New Queue

Private Structure Sprite_Type
Dim tex As Texture
Dim x, y, width, height As Integer
Dim c As Color
End Structure

Public Sub Draw_Sprites()
If Sprites.Count = 0 Then Return
Dim s As New Sprite(VideoDevice)

While Sprites.Count > 0
Dim sp As Sprite_Type = DirectCast(Sprites.Dequeue, Sprite_Type)
Dim xmult As Single = sp.tex.GetSurfaceLevel(0).Description.Width / sp.width
Dim ymult As Single = sp.tex.GetSurfaceLevel(0).Description.Height / sp.height
s.Draw2D(sp.tex, Rectangle.Empty, New Rectangle(sp.x, sp.y, sp.width, sp.height), New Point(0, 0), 0, New Point(sp.x * xmult, sp.y * ymult), sp.c)
End While

End Sub

I know that my code isn't following the .NET Framework Naming Guidelines. This is merely a test app that I'm throwing together to make sure that I can work out my rendering issues before I go full-bore into my next project.


Dan said...

Thank you thank you! I've spent hours this morning trying to figure this out!

I managed to fix it with your code example but I'm still not sure what's happening. Would it be possible to give more details if you can still remember?

The texture itself is stored as a power of two image - no matter what the filesize is that it's loaded from.

You can use the destination rectangle parameter to squash it back to the dimensions you wished for. The problem comes with the position . . . I don't really understand this bit - is it still rendering using the co-ordinates of the power of 2 texture?

This bit confuses me :D I wish I had a better head for maths!

Michael Russell said...

What is the problem you are having?

SarahC said...

Thank you!

I wonder - I'm just starting out with DX today, and I don't know where the Matrix scaling would appear in the code you posted?

Michael Russell said...


The third parameter is the destination rectangle: the area on the screen that it's going to draw it.