Sign in to follow this  
Harryu

ID3DXSprite problems

Recommended Posts

Harryu    174
i have recently been trying to scale my DirectX 9 sprites, but they never scale. i looked on MSDN, and found two ID3DXSprite interfaces, one that draws with scaling, the other does not. i can't see any difference between them, as you create them in the same way and stuff like that. this is the only difference i could find: here is the Create function for the one i am apparently using: HRESULT WINAPI D3DXCreateSprite( LPDIRECT3DDEVICE9 pDevice, LPD3DXSPRITE *ppSprite ); but this is the one i want to use: HRESULT D3DXCreateSprite( LPDIRECT3DDEVICE9 pDevice, LPD3DXSPRITE *ppSprite ); i have tried just using the scaling draw() function's parameters, but i get errors saying that the parameter's are wrong. this is because it is determined to use the OTHER sprite interface if anybody could tell me how to choose the interface i want, it would be very much appreciated. thanks in advance.

Share this post


Link to post
Share on other sites
PumpkinPieman    382
This is how I do it, I hope this helps.

bool cSprite::Draw(char depth)
{
if((m_graphics == NULL) || (m_graphics->GetSprite() == NULL) || (m_texture == NULL))
return false;


D3DXMATRIX mat;
D3DXMATRIX trans;
D3DXVECTOR3 tempcenter;
D3DXVECTOR3 temptranslation;
D3DXVECTOR3 tempscale;
D3DXQUATERNION temprotation;
LPRECT mask;
float AspectX = m_graphics->GetWidth() / m_view.x;
float AspectY = m_graphics->GetHeight() / m_view.y;

if(m_currentframe != NULL){
mask = &m_currentframe->texturemask;

temptranslation.x = (m_position.x + m_currentframe->position.x) * AspectX;
temptranslation.y = (m_position.y + m_currentframe->position.y) * AspectY;
temptranslation.z = (float)((depth / 0xFF) + (m_currentframe->depth / 0xFF) / 100.0f);

tempcenter.x = (m_center.x + m_currentframe->center.x) * AspectX;
tempcenter.y = (m_center.y + m_currentframe->center.y) * AspectY;
tempcenter.z = 0.0f;

tempscale.x = (m_scale.x + m_currentframe->scale.x) * AspectX;
tempscale.y = (m_scale.y + m_currentframe->scale.y) * AspectY;
tempscale.z = 0.0f;

D3DXQuaternionRotationYawPitchRoll(&temprotation, 0.0f, 0.0f, m_currentframe->rotation);
}else{
mask = &pSrcRect;

temptranslation.x = (m_position.x) * AspectX;
temptranslation.y = (m_position.y) * AspectY;
temptranslation.z = (float)(depth / 0xFF);

tempcenter.x = (m_center.x) * AspectX;
tempcenter.y = (m_center.y) * AspectY;
tempcenter.z = 0.0f;

tempscale.x = (m_scale.x) * AspectX;
tempscale.y = (m_scale.y) * AspectY;
tempscale.z = 0.0f;

D3DXQuaternionRotationYawPitchRoll(&temprotation, 0.0f, 0.0f, m_rotation);
}

D3DXMatrixTransformation(&mat, &tempcenter, NULL, &tempscale, &tempcenter, &temprotation, &temptranslation);

m_graphics->GetSprite()->SetTransform(&mat);
return SUCCEEDED(m_graphics->GetSprite()->Draw(m_texture->GetTexture(), mask, NULL, NULL, m_colour));
};

Share this post


Link to post
Share on other sites
SSJCORY    100
pumpkin pie man can u tell me how ur class initializes the sprite and texture. Every time i do it it doesnt work i guess when i'm passing the device to my init(IDirect3DDevice9 *device) it isnt valid or something can u show me how u do it.
thanks,
Cory

Share this post


Link to post
Share on other sites
PumpkinPieman    382
Quote:
Original post by SSJCORY
pumpkin pie man can u tell me how ur class initializes the sprite and texture. Every time i do it it doesnt work i guess when i'm passing the device to my init(IDirect3DDevice9 *device) it isnt valid or something can u show me how u do it.
thanks,
Cory

If you're interested in the code it's posted below. Basically what I did was make the sprite interface apart of the cGraphics, or my main graphics object. Since there only needs to be one sprite interface having duplicates of this is rather pointless.

The sprite class itself doesn't initialize any textures, it simply is a shell for a sprite. If I wanted to change the texture for the sprite, and the sprite was a static sprite without an animation. I would simply create a texture using cTexture and attach it to the sprite using SetTexture.

Quote:
Original post by Supernat02
Are they different versions of the sprite interface? What version of the SDK do you have installed and can you post some of the code?

Not that I'm aware of, there are from release to release but I'm currently working with Junes SDK so there is only one. (Don't forget that some of these interfaces change from release to release, so using a feburary sdk doc on a june machine may work but have suddle differences.)

Here's the sprite class, but the actual sprite interface is handled by my graphics class.

cSprite.h

class cSprite
{
protected:
LPGRAPHICS m_graphics;
cTexture* m_texture;
RECT pSrcRect;
D3DXVECTOR2 m_view;
D3DXVECTOR2 m_scale;
D3DXVECTOR2 m_position;
D3DXVECTOR2 m_center;
float m_rotation;
D3DCOLOR m_colour;

cSpriteAnimation* m_spriteani;
_sprframe* m_currentframe;
DWORD m_currenttime;

public:
cSprite();
~cSprite();

bool Create(LPGRAPHICS pGraphics, D3DXVECTOR2* pViewWindow );
void Free();

void Mask(long left, long top, long right, long bottom);
void Scale(float ScaleX, float ScaleY);
void Move(float PosX, float PosY);
void Center(float CenterX, float CenterY);
void CenterMask();
void Rotate(float radians);
void Colour(uint8 Red, uint8 Green, uint8 Blue, uint8 Alpha);

bool SetTexture(cTexture* texture);
void SetFrame(_sprframe* frame);

void SetAnimation(cSpriteAnimation* sprani);
bool SetAction(const char* action);

void operator= (cSpriteAnimation* sprani);

void Update(DWORD timeoffset);
bool Draw(char depth = 0);

float GetXScale();
float GetYScale();
float GetXPos();
float GetYPos();
float GetXCenter();
float GetYCenter();
float GetRotation();
DWORD GetColour();

};






cSprite.cpp

cSprite::cSprite()
: m_graphics(NULL)
, m_texture(NULL)
, m_view(D3DXVECTOR2(640.0f, 480.0f))
, m_scale(D3DXVECTOR2(1.0f, 1.0f))
, m_position(D3DXVECTOR2(0.0f, 0.0f))
, m_center(D3DXVECTOR2(0.0f, 0.0f))
, m_rotation(0.0f)
, m_colour(0xFFFFFFFF)
, m_spriteani(NULL)
, m_currentframe(NULL)
{
ZeroMemory(&pSrcRect, sizeof(RECT));
};
cSprite::~cSprite()
{
Free();
};

bool cSprite::Create(LPGRAPHICS pGraphics, D3DXVECTOR2* pViewWindow)
{
Free();
if(pGraphics == NULL)
return false;

m_graphics = pGraphics;

if(pViewWindow != NULL)
m_view = (*pViewWindow);
else{
m_view.x = (float)m_graphics->GetWidth();
m_view.y = (float)m_graphics->GetHeight();
}

return true;
};

void cSprite::Free()
{
m_graphics = NULL;
m_texture = NULL;
m_spriteani = NULL;
m_currentframe = NULL;
};

void cSprite::Mask(long left, long top, long right, long bottom)
{
SetRect(&pSrcRect,left,top,right,bottom);
};
void cSprite::Scale(float ScaleX, float ScaleY)
{
m_scale.x = ScaleX;
m_scale.y = ScaleY;
};

void cSprite::Move(float PosX, float PosY)
{
m_position.x = PosX;
m_position.y = PosY;
};

void cSprite::Center(float CenterX, float CenterY)
{
m_center.x = CenterX;
m_center.y = CenterY;
};

void cSprite::CenterMask()
{
m_center.x = (float)(pSrcRect.right - pSrcRect.left) / 2;
m_center.y = (float)(pSrcRect.bottom - pSrcRect.top) / 2;
};

void cSprite::Rotate(float radians)
{
m_rotation = radians;
};

void cSprite::Colour(uint8 Red, uint8 Green, uint8 Blue, uint8 Alpha)
{
m_colour = (((Alpha & 0xff)<<24) | ((Red & 0xff)<<16) | ((Green & 0xff)<<8) | (Blue & 0xff));
};

bool cSprite::SetTexture(cTexture* texture){
if(texture == NULL)
return false;

m_texture = texture;

SetRect(&pSrcRect,0,0,texture->GetWidth(),texture->GetHeight());
return true;
};

void cSprite::SetFrame(_sprframe* frame)
{
m_currentframe = frame;
};

void cSprite::SetAnimation(cSpriteAnimation* sprani)
{
m_spriteani = sprani;
};

bool cSprite::SetAction(const char* action)
{
if(m_spriteani == NULL)
return false;

return m_spriteani->SetAction(this, action);
};

void cSprite::operator= (cSpriteAnimation* sprani)
{
m_spriteani = sprani;
};

void cSprite::Update(DWORD timeoffset)
{
if(m_currentframe == NULL)
return;

m_currenttime += timeoffset;

while(m_currenttime >= m_currentframe->duration){
m_currenttime -= m_currentframe->duration;
m_currentframe = m_currentframe->next;
}
};

bool cSprite::Draw(char depth)
{
if((m_graphics == NULL) || (m_graphics->GetSprite() == NULL) || (m_texture == NULL))
return false;


D3DXMATRIX mat;
D3DXMATRIX trans;
D3DXVECTOR3 tempcenter;
D3DXVECTOR3 temptranslation;
D3DXVECTOR3 tempscale;
D3DXQUATERNION temprotation;
LPRECT mask;
float AspectX = m_graphics->GetWidth() / m_view.x;
float AspectY = m_graphics->GetHeight() / m_view.y;

if(m_currentframe != NULL){
mask = &m_currentframe->texturemask;

temptranslation.x = (m_position.x + m_currentframe->position.x) * AspectX;
temptranslation.y = (m_position.y + m_currentframe->position.y) * AspectY;
temptranslation.z = (float)((depth / 0xFF) + (m_currentframe->depth / 0xFF) / 100.0f);

tempcenter.x = (m_center.x + m_currentframe->center.x) * AspectX;
tempcenter.y = (m_center.y + m_currentframe->center.y) * AspectY;
tempcenter.z = 0.0f;

tempscale.x = (m_scale.x + m_currentframe->scale.x) * AspectX;
tempscale.y = (m_scale.y + m_currentframe->scale.y) * AspectY;
tempscale.z = 0.0f;

D3DXQuaternionRotationYawPitchRoll(&temprotation, 0.0f, 0.0f, m_currentframe->rotation);
}else{
mask = &pSrcRect;

temptranslation.x = (m_position.x) * AspectX;
temptranslation.y = (m_position.y) * AspectY;
temptranslation.z = (float)(depth / 0xFF);

tempcenter.x = (m_center.x) * AspectX;
tempcenter.y = (m_center.y) * AspectY;
tempcenter.z = 0.0f;

tempscale.x = (m_scale.x) * AspectX;
tempscale.y = (m_scale.y) * AspectY;
tempscale.z = 0.0f;

D3DXQuaternionRotationYawPitchRoll(&temprotation, 0.0f, 0.0f, m_rotation);
}

D3DXMatrixTransformation(&mat, &tempcenter, NULL, &tempscale, &tempcenter, &temprotation, &temptranslation);

m_graphics->GetSprite()->SetTransform(&mat);
return SUCCEEDED(m_graphics->GetSprite()->Draw(m_texture->GetTexture(), mask, NULL, NULL, m_colour));
};

float cSprite::GetXScale()
{
return m_scale.x;
};

float cSprite::GetYScale()
{
return m_scale.y;
};

float cSprite::GetXPos()
{
return m_position.x;
};

float cSprite::GetYPos()
{
return m_position.y;
};

float cSprite::GetXCenter()
{
return m_center.x;
};

float cSprite::GetYCenter()
{
return m_center.y;
};

float cSprite::GetRotation()
{
return m_rotation;
};

DWORD cSprite::GetColour()
{
return m_colour;
};







cGraphics::Init

//LPDIRECT3DDEVICE9 m_device;
//LPD3DXSPRITE m_sprite;

if(FAILED(D3DXCreateSprite(m_device, &m_sprite))){
Kill();
return false;
};







cTexture.h

class cTexture : public cResource
{
protected:
LPGRAPHICS graphics;
LPDIRECT3DTEXTURE9 texture;

long m_width;
long m_height;

public:
cTexture();
~cTexture();

LPDIRECT3DTEXTURE9 GetTexture();

bool Load(LPGRAPHICS pGraphics, LPCSTR p_Filename, D3DCOLOR Colour = NULL, D3DFORMAT Format = D3DFMT_UNKNOWN, PALETTEENTRY* pPalette = NULL);
void Free();

long GetWidth();
long GetHeight();
};






cTexture.cpp

// *************************************************
// Class: cTexture
// Info: Handles texture loading
// *************************************************


cTexture::cTexture():
graphics(NULL),
texture(NULL),
m_width(0),
m_height(0)
{

}

cTexture::~cTexture()
{
Free();
}

LPDIRECT3DTEXTURE9 cTexture::GetTexture()
{
return texture;
};

bool cTexture::Load(LPGRAPHICS pGraphics, LPCSTR p_Filename, D3DCOLOR Colour, D3DFORMAT Format, PALETTEENTRY* pPalette)
{
Free();

if((graphics = pGraphics) == NULL)
return false;
if(graphics->GetDevice() == NULL)
return false;
if(texture != NULL)
return false;

HRESULT hr;
if(Colour == NULL){
hr = D3DXCreateTextureFromFile(pGraphics->GetDevice(), p_Filename, &texture);
}else{
hr = D3DXCreateTextureFromFileEx(pGraphics->GetDevice(), p_Filename,
D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0,
Format, D3DPOOL_MANAGED, D3DX_FILTER_TRIANGLE,
D3DX_FILTER_TRIANGLE, Colour, NULL,
NULL, &texture);
}
if(SUCCEEDED(hr))
{
D3DSURFACE_DESC d3dsd;
if(FAILED(texture->GetLevelDesc(0, &d3dsd)))
{
Free();
return false;
}
m_width = d3dsd.Width;
m_height = d3dsd.Height;

return true;
}
return false;
};

void cTexture::Free()
{
releaseCOM(texture);
};

long cTexture::GetWidth()
{
return m_width;
};

long cTexture::GetHeight()
{
return m_height;
};







This code was just cut and pasted from my current project (2D Engine), I'm actually hoping to come back to this code and fix it up a bit.

Share this post


Link to post
Share on other sites
Harryu    174
i ended up not using the scaling built in to one of the Draw functions, but just using a matrix and calling SetTransform.

works perfectly!

Share this post


Link to post
Share on other sites
jflanglois    1020
By the by, there are different versions of D3DX, and thusly, ID3DXSprite. I think the draw method changed in the February release of DX9, or sometime around there... The scale parameter was removed, I suppose to make the interface more consistent because you use matrix transforms to rotate and translate, so why not scale as well Err, wait, it wasn't a scale parameter. Well, in any case, the draw method did change, and perhaps you went to an archive in MSDN.

hth.

jfl.

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