I'm trying to understand transformation matrices. Suppose I use the camera from this StackOverflow answer, this is how my view matrix would look:

Matrix.Identity *
Matrix.CreateTranslation(-Position.X, -Position.Y, 0) *
Matrix.CreateRotationZ(Rotation) *
Matrix.CreateTranslation(Scale, Scale, 0) *
Matrix.CreateScale(new Vector3(Scale, Scale, Scale));

How'd I calculate my World and Projection matrices then?


Well, if you want to use it for 2D games (assuming from the tags), you only need a Transform matrix to apply to the SpriteBatch, you don't need World and Projection matrices.

So, when you're drawing an object that should be drawn inside your game world (e.g. the main player), you use the following Begin method from SpriteBatch (XNA 4.0, replace the other parameters by what you need):

spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, effect, camera.Transform);
Draw the world objects like walls, players, weapons, etc.

This will apply the camera's effect to the drawing, simulating a camera within your world.

For other visual elements that are not part of the world (like the HUD with player health, etc.), you just use the regular Begin method (without the camera's matrix as a parameter) to draw it, because you don't really want them to move all around the screen when the camera moves, you want them to be static.

The way the camera works is that it applies a translation matrix going in the opposite direction of where you want your camera to be (it explains the negative signs in Matrix.CreateTranslation(-Position.X, -Position.Y, 0) to simulate a camera moving inside a world. In fact, what you're really doing is that you're moving the world around so that the camera's view is represented by the game's window.

So, say you want your camera to move to the right by 20 pixels, you want to move your whole world to the left by 20 pixels to give the user the feeling that they moved to the right. This is achieved by applying the camera's matrix to all the world objects, to sort of move them around.

The same goes for scaling and rotation, you move the world around when you're drawing them to give a feeling of change.

|improve this answer|||||
  • \$\begingroup\$ I know, but I need to calculate those matrices anyway - for another purpose. How would I do that? \$\endgroup\$ – Alon Gubkin Oct 17 '11 at 22:19
  • \$\begingroup\$ Hum, from this link: forums.create.msdn.com/forums/p/72388/441565.aspx it seems like you can't with SpriteBatch (and explains that SpriteBatch does the job for you). Could you give the reasons about why you'd want to do that? \$\endgroup\$ – Jesse Emond Oct 17 '11 at 22:25
  • \$\begingroup\$ What does SpriteBatch related to Matrix calculation? I just want to calculate the projection and world matrices, not use them with SpriteBatch or something. \$\endgroup\$ – Alon Gubkin Oct 17 '11 at 22:44
  • \$\begingroup\$ And a simple world = Matrix.Identity and projection = Matrix.CreatePerspectiveFieldOfView(/*...*/) won't do? \$\endgroup\$ – Jesse Emond Oct 17 '11 at 22:50
  • \$\begingroup\$ How to use Matrix.CreatePerspectiveFieldOfView for the view matrix I wrote in the question? \$\endgroup\$ – Alon Gubkin Oct 17 '11 at 23:02

The world Translation affect object in your world, so usually it will be a simple Translation. But if you want scale, rotation, ... is done this way;

Matrix World = Matrix.CreateTranslation(-origin,0) * MatrixCreateRotationZ(angle) * Matrix.CreateScale(scale) * Matrix.CreateTranslation(Position,0); 

The View Matrix is the Camera matrix, i usually use:

Matrix.CreateTranslation(-Position.X, -Position.Y, 0) * Matrix.CreateRotationZ(Rotation) * Matrix.CreateScale(Scale) * Matrix.CreateTranslation(Viewport.Center.X, Viewport.Center.Y,0);

This is the projection Matrix used by SpriteBatch (source)

Matrix projection = Matrix.CreateOrthographicOffCenter(0, viewport.Width, viewport.Height, 0, 0, 1);
Matrix halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0);   

projection = halfPixelOffset * projection;

The final transform is: World * View * Projection.

|improve this answer|||||

Your Answer

