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);

    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.


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);

    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);
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – House
    Jul 2 '13 at 0:10
  • \$\begingroup\$ 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. \$\endgroup\$
    – MahanGM
    Jul 2 '13 at 0:14
  • \$\begingroup\$ @Byte56, Thanks for the advice. I'll go for it. \$\endgroup\$
    – MahanGM
    Jul 2 '13 at 0:20
  • 2
    \$\begingroup\$ @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. \$\endgroup\$ Jul 2 '13 at 0:21
  • \$\begingroup\$ @NathanReed, Thank you for identity matrix reminder. I'll go look for some information about setting camera in DirectX. \$\endgroup\$
    – MahanGM
    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.

  • \$\begingroup\$ 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. \$\endgroup\$
    – MahanGM
    Jul 2 '13 at 8:21
  • \$\begingroup\$ I tried this, but nothing happened. \$\endgroup\$
    – MahanGM
    Jul 2 '13 at 8:41
  • \$\begingroup\$ @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. \$\endgroup\$ Jul 2 '13 at 17:47
  • \$\begingroup\$ 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. \$\endgroup\$
    – MahanGM
    Jul 2 '13 at 19:27
  • \$\begingroup\$ @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. \$\endgroup\$ Jul 2 '13 at 20:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.