DirectX 2D with/without matrices

F69b3a361c26467022ed3c31589d2bfa
0
gardon 101 Aug 27, 2006 at 21:56

So I finally figured out how to do the DirectX sprite interface things. The only question now is: do I use matrices from directX to store positions of my objects, and have my projection and view matrices set to static default values so I’m only looking down on the world….

or

should I have just regular x and y position coordinates for each object, and have my camera class change values based on the player position (centered on the player) so that each object can just be tested on whether or not both coordinates are inside the camera window. That way they will only be rendered if seen.

JAason

3 Replies

Please log in or register to post a reply.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 168 Aug 28, 2006 at 00:26

Both approaches are mathematically equivalent, so it’s really up to which approach you feel most comfortable with. Personally I would go for moving the camera with a matrix, and drawing each object at its location within the world. That’s the usual method and lets the GPU do the calculations instead of the CPU. Note however that you can (and should) do clipping based on the viewing window in either case, not just the second one.

F69b3a361c26467022ed3c31589d2bfa
0
gardon 101 Aug 28, 2006 at 01:54

Ok, thanks.

One more question if you’re up for it. I’ve researched the ID3DXSprite interface, and noticed that I could use it to load sprites/textures to use ingame.

My question lies in the fact that the D3DXSprite interf. has functions that work with drawing, etc., which includes the CreateTextureFromFile() function. This loads a IDirect3DTexture9 interface, and loads an image into it.

How can I load many sprites with that interface? Is there an easier way to do it besides consistently initializing texture9 interfaces? That seems like a lot for a game with animation fo rmany different characters, objects, and landscapes.

Jason

Ee906479c962cf1e11012954cb4a689f
0
B_rand___n 101 Aug 28, 2006 at 04:49

You are correct in your assumption that loading many sprites from different files would be memory intensive. That is why you want to use a sprite atlas. A sprite atlas is a texture that has a lot of different sprites on it, usually ones depicting frames of an animation.

Now how do you use this?

The ID3DXSprite has a Draw(..) function:

HRESULT Draw(
  LPDIRECT3DTEXTURE9 pTexture,
  CONST RECT * pSrcRect,
  CONST D3DXVECTOR3 * pCenter,
  CONST D3DXVECTOR3 * pPosition,
  D3DCOLOR Color
);

The second parameter is the key here! Say you have a 256x128 sprite atlas texture. Construct a RECT that encompasses a single frame on that texture.

For example, the sprites are 25x30 (note, not a power of 2! only the texture has to be a power of 2!!! :D) Well, the first frame would be the rect (0,0,25,30) and if the second frame was horizontally adjacent to the first, then it would be (25,0,50,30) (note that we are moving to the right and not down, if we added to the Y values then we’d be moving across the diagonal of the atlas!)

So how does this work?

RECT rFirstFrame, rSecondFrame;
ID3DXSprite * sSprite;   // or LPD3DXSPRITE sSprite;

SetRect(&rFirstFrame,0,0,25,30);
SetRect(&rSecondFrame,25,0,50,30);

//Put it where we want it on the X, Y 
D3DXVECTOR3 screenPos;
screenPos.x = (float)nX; screenPos.y = (float)nY; screenPos.z = 0.0f;

// (assume we have initialized it)

// here's a handy macro for doing the alpha 0..255
#define ALPHA(a)    ((a << 24)|0xFFFFFF)

sSprite->Draw(pTextureWePreviouslyCreated, &rFirstFrame, NULL, &screenPos, ALPHA(255));

// then after a Present() and delay (and a Clear() ) you can do:

sSprite->Draw(pTextureWePreviouslyCreated, &rSecondFrame, NULL, &screenPos, ALPHA(255));

Congratulations! You now have a two frame animation going on using the same texture! I hope you have understood what I tried to relate.

Brandon