Reputation: 3740
So I know there are a few questions/answers regarding building a 2D Camera for XNA however people seem to just be happy posting their code without explanation. I'm looking for more of an explanation of what I'm doing wrong.
First off, I understand the whole World -> View - > Projection - > Screen transformation.
My goal is to have a camera object that is centered in the center of the viewport and that when the camera's position moves up it correlates to moving up in the viewport and when it moves to the right it correlates moving right in the viewport.
I'm having difficulty implementing that functionality because the Y value of the viewport is inverted.
//In Camera Class
private void UpdateViewTransform()
{
//My thinking here was that I would create a projection matrix to center the camera and then flip the Y axis appropriately
Matrix proj = Matrix.CreateTranslation(new Vector3(_viewport.Width * 0.5f, _viewport.Height * 0.5f, 0)) *
Matrix.CreateScale(new Vector3(1f, -1f, 1f));
//Here is the camera Matrix. I have to give the Inverse of this matrix to the Spritebatch I believe since I want to go from World Coordinates to Camera Coordinates
_viewMatrix = Matrix.CreateRotationZ(_rotation) *
Matrix.CreateScale(new Vector3(_zoom, _zoom, 1.0f)) *
Matrix.CreateTranslation(_position.X, _position.Y, 0.0f);
_viewMatrix = proj * _viewMatrix;
}
Can someone help me understand how I can build my view transformation to pass into the SpriteBatch so that I achieve what I'm looking for.
EDIT
This as a transformation seems to work however I am unsure why. Can someone perhaps break it down for me in understanding:
Matrix proj = Matrix.CreateTranslation(new Vector3(_viewport.Width * 0.5f, _viewport.Height * 0.5f, 0));
_viewMatrix = Matrix.CreateRotationZ(_rotation) *
Matrix.CreateScale(new Vector3(_zoom, _zoom, 1.0f)) *
Matrix.CreateTranslation(-1 * _position.X, _position.Y, 0.0f);
_viewMatrix = proj * _viewMatrix;
I've built a raytracer before so I should understand your understanding, my confusion lies with the fact it's 2D and that SpriteBatch is hiding what it's doing from me. Thanks! Farid
Upvotes: 1
Views: 1549
Reputation: 2058
I've fought with XNA a lot trying to get it to be like other engines I have worked with before... my reccomendation, it isn't worth it... Just go with the XNA standards and use the Matrix helper methods for creating your Perspective / Viewport matrices.
Upvotes: 1
Reputation: 3740
So after just thinking logically, I was able to deduce the proper transformation. I'll outline the steps here incase anyone wants the real breakdown:
It is important to understand what is a Camera Transformation or View Transformation. A View Transformation is normally what is needed to go from Coordinates relative to your Camera to World-Space coordinates. The inverse of the View Transformation would then make a world coordinate relative to your Camera!
Creating a View Matrix
Now the inverse of the matrix will do World Coordinate -> View Cordinates.
I also chose to center my camera in the center of the screen, so I included a pre-appended translation.
Matrix proj = Matrix.CreateTranslation(new Vector3(_viewport.Width * 0.5f, _viewport.Height * 0.5f, 0));
_viewMatrix = Matrix.CreateRotationZ(moveComponent.Rotation) *
Matrix.CreateTranslation(moveComponent.Position.X, -1 * moveComponent.Position.Y, 0.0f) *
Matrix.CreateScale(new Vector3(zoomComponent.Zoom, zoomComponent.Zoom, 1.0f));
_viewMatrix = proj * Matrix.Invert(_viewMatrix);
Upvotes: 0
Reputation: 27215
If you flip everything on the Y axis with your scale matrix, that means you are flipping the models that SpriteBatch
is drawing (textured quads). This means you also have to change your winding-order (ie: backface culling is interpreting that you are drawing the backs of the triangles facing the camera, so it culls them, so you have to change the rule that it uses).
By default, SpriteBatch
uses RasterizerState.CullCounterClockwise
. When you call SpriteBatch.Begin
you need to pass in RasterizerState.CullClockwise
instead.
And, of course, Begin
is where you pass in your transformation matrix.
I haven't carefully checked your matrix operations - although I have a suspicion that the order is incorrect. I recommend you create a very simple testing app and build up your transformations one at a time.
Upvotes: 2