Sign in to follow this  
Pedigree_D

Texture Management

Recommended Posts

Hi guys, Im having problems with how to handle textures in DirectX. Im trying to find the most efficient way to manage IDirect3DDTexture9 pointers. Im using sprites and currently im putting together a framework to which i can create games without having to code window creation, direct3d initialization etc over and over. When it comes the textures im wondering whether to have a class that encapsulates sprite and texture creation...

typedef D3DXVECTOR3 VECTOR;

class SPRITE
{
public:
   SPRITE();
   ~SPRITE();

   void LoadTexture(const char* filename);
   HRESULT DrawSprite(VECTOR* pos, int frame);

private:
   ID3DXSprite* sprite;
   IDirect3DTexture9* tex;

};

// Used as:
// SPRITE character;
VECTOR pos(100.0f, 100.0f, 0.0f);
// character.LoadTexture("test.png");
// character.DrawSprite(&pos, 1);


Above is what i would assume it would look like of the top of my head. Now, would it be ideal this way or would it be best to have the ID3DXSprite pointer in with the rendering code as it has to be created once with D3DXCreareSprite() and pass it to the constructor of a SPRITE object?? I have been advised to use a list of IDirect3DTexture9 pointers by other people but the problem i have with this is searching for the specific texture you want to draw. How would you guys do it?? Thanks

Share this post


Link to post
Share on other sites
Don't fully understand your question, but I hope this helps. This is the SPRITE class I made:

VECTOR nVector(float X, float Y); // new vector

class SPRITE {
public:
float x, y;
SPRITE() {
D3DXCreateSprite(_dev, &sprite);
}
void LoadTexture(const char* Path) {
D3DXCreateTextureFromFile(_dev, Path, &tex);
}
void Draw(VECTOR Position, VECTOR Center, COLOR Color) {
_dev->BeginScene();
sprite->Begin(D3DXSPRITE_ALPHABLEND);
sprite->Draw(tex, NULL, &D3DXVECTOR3(Center.x, Center.y, 0),
&D3DXVECTOR3(Position.x, Position.y, 0),
D3DCOLOR_XRGB(Color.R, Color.G, Color.B));
sprite->End();
_dev->EndScene();
_dev->Present(NULL, NULL, NULL, NULL);
x=Position.x;
y=Position.y;
}
void Draw() {
_dev->BeginScene();
sprite->Begin(D3DXSPRITE_ALPHABLEND);
sprite->Draw(tex, NULL, &D3DXVECTOR3(0, 0, 0),
&D3DXVECTOR3(x, y, 0),
D3DCOLOR_XRGB(255, 255, 255));
sprite->End();
_dev->EndScene();
_dev->Present(NULL, NULL, NULL, NULL);
}
void Release() {
if (sprite)
this->sprite->Release();
sprite=0;
if (tex)
this->tex->Release();
tex=0;
}
private:
LPD3DXSPRITE sprite;
LPDIRECT3DTEXTURE9 tex;
};


Note: LPD3DXSPRITE is the same as ID3DXSprite* and LPDIRECT3DTEXTURE9 is the same as IDirect3DTexture9*. _dev is the global LPDIRECT3DDEVICE9 I use.

Share this post


Link to post
Share on other sites
Ideally you have a single ID3DXSprite object and run all rendering through that. MUCH more efficient than having each Sprite object own a ID3DXSprite of it's own.


-Nate S.

Share this post


Link to post
Share on other sites
Hi,

Here's the implementation of my Sprite class.
I'm managing all the elements over only one sprite.


typedef struct _SPRITE_ELEMENT
{
LPDIRECT3DTEXTURE9 Texture;
D3DXMATRIX TransformationMatrix;
std::string Name;
} SPRITE_ELEMENT;

typedef std::vector <SPRITE_ELEMENT> CSpriteVector;

class CSprite
{
CSprite () {m_pSprite = NULL;};
CSprite (LPDIRECT3DDEVICE9 pDev) {D3DXCreateSprite (pDev, &m_pSprite);}
~CSprite() {if (m_pSprite) m_pSprite->Release();}

SPRITE_ELEMENT* Sprite (std::string name); //returns the element "name"
SPRITE_EMEMENT* Sprite (UINT i); //returns (i)th element
HRESULT Begin (DWORD options = 0)
{
if (!m_pSprite) return E_FAIL;
return m_pSprite->Begin (options);
}
HRESULT End ()
{
if (!m_pSprite) return E_FAIL;
return m_pSprite->End ();
}
HRESULT Draw (UINT i) //draws only (i)th element
{
if (m_pSprite == NULL) return E_FAIL;

if (Sprite (i) == NULL) return E_FAIL;

m_pSprite->SetTransform (&Sprite(i)->TransformationMatrix);
m_pSprite->Draw (Sprite(i)->Texture, NULL, NULL, NULL, 0xFFFFFFFF);
//passing three NULLs because we use transformation matrix
}
HRESULT Draw (); //draws all the elements with a for() loop

LPD3DXSPRITE m_pSprite;
CSpriteVector m_vSpriteArray;
};



You can build a transformation matrix by using D3DXTransformation2D () function.

Hope this helps.

[Edited by - programci_84 on June 21, 2009 4:09:11 PM]

Share this post


Link to post
Share on other sites
You don't want your sprite class to load up the texture itself. If you got 20 of the same sprites then you have 20 copies of the the texture in memory. You should have some kind of texture manager class that handles the actual loading into memory and when another sprite is created it just gets a pointer to the original instead of loading another into memory. As for drawing, your render function should take a pointer to a previously created ID3DXSprite and use that to render instead of every sprite having its own. Each sprite calling its own Begin()/End() is going to slow things down.

Little pseudo code:


class Sprite
{
public:
Sprite(Vec2 pos, IDirect3DTexture9 *tex) : m_pos(pos), m_tex(tex) {};

Draw(ID3DXSprite *sprite) {sprite->Draw(m_tex,...,m_pos....);};
private:
Vec2 m_pos;
IDirect3DTexture9 *m_tex;
};

Share this post


Link to post
Share on other sites
Wow, thanks for all the replies. Sorry i wasn't as quick with me response i've been having some issues with my laptop, seems Vista has decided my copy isn't genuine when it was pre-installed when i bought it?? Anyway, programci_84, that was what i was thinking of myself. The only problem i had was searching for the element in the vector i wish to draw by name. I use STL vector to handle my states but i haven't really plunged into the depths of vectors. Anyone have any good resources on the standard template library??

Thanks

Share this post


Link to post
Share on other sites
Hi,

Quote:
The only problem i had was searching for the element in the vector i wish to draw by name.

It's quite simple. You know there's a Name member in my SPRITE_ELEMENT declaration. Here's the snippet how I get the element called "Name":

SPRITE_ELEMENT* Sprite (std::string Name)
{
for (UINT i = 0; i < m_vSpriteArray.size(); i++)
{
if (m_vSpriteArray[i].Name == Name)
return &m_vSpriteArray[i];
}

return NULL;
}


Also, here's an STL tutorial page. This is a Linux related website but this is not important for you.
http://www.yolinux.com/TUTORIALS/LinuxTutorialC++STL.html

Hope this helps.
Rohat.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this