Sign in to follow this  
Maxamor

[MDX] Sprite transformations, Sprite.draw()

Recommended Posts

Maxamor    361
Hi all. I'm working on a 2.5d action/platform games in MDX 9, using the newest SDK available, which I believe was from April. Anyhow, here's my current problem. I want to be able to reverse my sprites horizontally by modifying the scale matrix in this way:
public void flipH() {
    scaleMatrix.M11 = -scaleMatrix.M11;
}
I have seen this done in tutorials, and it makes sense to me to do this. I used to use the Sprite.draw2d() method, but since I have read that it's only there for backwards compatibility, and it is recommended to use the Sprite.draw() method, I'm trying to use Sprite.draw(). My problem lies in the correct transformation matrix. It seems no matter what order I multiply them in, something goes wrong. Most of the time, if I flip it horizontally, it flips the entire sprite layer over (0,0) and then draw, which makes all the sprites go offscreen. I had previously thought I had a solution to this by center the sprite, applying scale/rotation, and then applying the translation. Is this recommended? How have you worked around this? My searches on Google hav led me to try a few different things, but I have yet to find the right way to do it without negatively affecting scale, rotation, or location on the screen. If you need more info, I can post some more code.

Share this post


Link to post
Share on other sites
MasterWorks    496
I don't know if this will help you or not, but I flip my (custom) sprite class by swapping the appropriate members of the (tu,tv) texture coordinates. Each quad has four texture coordinates (tu1,tv1,tu2,tv2) To flip horizontally, just swap tu1 and tu2, etc.

Share this post


Link to post
Share on other sites
Maxamor    361
That does help, but to simplify my original question, is there a specific order to multiply the three matricies (scale, rotation, translation) in, and if so, which is the correct order?

Share this post


Link to post
Share on other sites
Rotation and Scaling must be done before you transform since it scales and rotates about the origin. So I'm 90% sure it has to be scale/rotate->transform for what you want.

Edit: This only works if your sprites are untransformed to start with, which it looks like yours are not.

Share this post


Link to post
Share on other sites
Maxamor    361
This can be marked solved. I have solved my problem!

I think that the documentation for the Direct3D.Sprite class is inclear.
public void Draw(Texture, Rectangle, Vector3, Vector3, Color);
The "center" parameter's description: "A Vector3 structure that identifies the center of the sprite. A value of (0,0,0) indicates the upper-left corner." I was under the assumption that "(0,0,0)" meant the upper left-hand corner of my viewport.

The "center" oarameter is actually relative to the sprite object only. So, (0,0,0) actually means the upper left-hand corner of the sprite's source rectangle.

So, if your sprite's source rectangle is 32x32 pixles, and you want the pivot in the middle, (16, 16, 0) is what your center parameter should be.

I also found the correct way to multiply my matricies, and the order is "opposite of the order you want to apply them."

Here's my fixed up code:

public void Draw()
{
// Apply any transformation we may have and then draw.
Sprite.Transform = rotationMatrix * scaleMatrix * positionMatrix;
Sprite.Draw(Texture, SourceRectangle, Pivot, Vector3.Empty, tintColor);
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this