# How to set orthgraphic matrix for a 2d camera with zooming?

I'm using ID3DXSprite to draw my sprites and haven't set any kind of camera projection matrix. How to setup an orthographic projection matrix for camera in DirectX which it would be able to support zoom functionality?

    D3DXMATRIX orthographicMatrix;
D3DXMATRIX identityMatrix;

D3DXMatrixOrthoLH(&orthographicMatrix, nScreenWidth, nScreenHeight, 0.0f, 1.0f);
D3DXMatrixIdentity(&identityMatrix);

device->SetTransform(D3DTS_PROJECTION, &orthographicMatrix);
device->SetTransform(D3DTS_WORLD, &identityMatrix);
device->SetTransform(D3DTS_VIEW, &identityMatrix);


This code is for initial setup. Then, for zooming I multiply zoom factor in nScreenWidth and nScreenHeight.

UPDATE

This is going to work:

    D3DXMATRIX orthographicMatrix;
D3DXMATRIX identityMatrix;
D3DXMATRIX viewMatrix = D3DXMATRIX(
1,      0,      0,      0,
0,      1,      0,      0,
0,      0,      1,      0,
(FLOAT)(-(this->nScreenWidth / 2)), (FLOAT)(-(this->nScreenHeight / 2)),        0,      1
);

D3DXMatrixOrthoLH(&orthographicMatrix, (FLOAT)this->nScreenWidth, (FLOAT)-this->nScreenHeight, 0.0f, 1.0f);
D3DXMatrixIdentity(&identityMatrix);

this->p_device->SetTransform(D3DTS_PROJECTION, &orthographicMatrix);
this->p_device->SetTransform(D3DTS_WORLD, &identityMatrix);
this->p_device->SetTransform(D3DTS_VIEW, &viewMatrix);


And put D3DXSPRITE_OBJECTSPACE flag next to other flags when you use ID3DXSprite::Begin():

if(this->p_sprite->Begin(D3DXSPRITE_ALPHABLEND | ... | D3DXSPRITE_OBJECTSPACE) != D3D_OK) return 0;


For zoom functionality you can produce this matrix:

D3DXMatrixOrthoLH(&orthographicMatrix, this->nScreenWidth * this->dZoom, -this->nScreenHeight * this->dZoom, 0.0f, 1.0f);

• Typically you wouldn't scale each object, but you would instead change your perspective of the scene. That's done with the camera object. There shouldn't be any need to touch any of the objects in the world when zooming.
– House
Jul 2 '13 at 0:10
• Currently I'm applying a zoom factor multiplied in each object's scale factor to set sizes for my scaling matrix. I'm using ID3DXSprite to achieve this and I don't know how to change my perspective as you've mentioned. I'm not using orthographic view in my rendering pipeline. At least I don't remember that I've set something like this or not because there is none. Jul 2 '13 at 0:14
• @Byte56, Thanks for the advice. I'll go for it. Jul 2 '13 at 0:20
• @MahanGM If you haven't set a projection matrix then you're just implicitly using the identity matrix for projection. A simple way to zoom would be to just use an XY scaling matrix for the projection, rather than scaling every individual sprite and associated Box2D body. Presumably you need to do something similar for translation, unless you want to reset the position of every Box2D body when you move the camera. Jul 2 '13 at 0:21
• @NathanReed, Thank you for identity matrix reminder. I'll go look for some information about setting camera in DirectX. Jul 2 '13 at 0:24

Since you mentioned ID3DXSprite, I assume you're using Direct3D 9. In that case, you can set the projection matrix using

pDevice->SetTransform(D3DTS_PROJECTION, projMatrix);


The projMatrix for a 2D camera with zooming and translation could be constructed as follows:

s     0     0  0
0     s     0  0
0     0     1  0
-x*s  -y*s  0  1


where x, y is the camera position and s is the zoom factor. This is the result of a translation by -x, -y (centering the view on the camera position) followed by a 2D scale by s.

• How about using D3DXMatrixOrthoLH? Take a look at my code. If that's not going to work just say yep, and I'm going to use your matrix. Jul 2 '13 at 8:21
• I tried this, but nothing happened. Jul 2 '13 at 8:41
• @MahanGM Sure, D3DXMatrixOrthoLH should work (although it doesn't include translation). So the sprites don't zoom if you set the projection matrix before drawing the sprites? I wonder if ID3DXSprite ignores the matrices set on the device for some reason. You might try setting the matrix with ID3DXSprite::SetTransform instead and see if that gets you anywhere. Jul 2 '13 at 17:47
• The thing is, ID3DXSprite::SetTransform would change each sprite's perspective not the camera's. And currently I'm using D3DXMatrixTransformation2D to produce that matrix. I might go on using textured quads. Thanks for indications. Jul 2 '13 at 19:27
• @MahanGM Ahh, I looked at the docs again and found that you need to add the D3DXSPRITE_OBJECTSPACE flag when calling ID3DXSprite::Begin. Otherwise it indeed ignores the device world/view/projection matrices. Jul 2 '13 at 20:00