Sign in to follow this  
PhiberOptic

Resize ID3DXSprite

Recommended Posts

I thought I should write some simple gui stuff with the D3DXSprite(9.0) class. It seem to work, but I have no clue how I should handle the size of the sprites. There is always a possibility to scale them with a matrix, but I want to decide more like "this sprite should have x pixels with and y pixels height". I don't know where it gets it size from when just drawing it, but all pictures seem to be way to big (~2x the size of the texture).. Why?

Share this post


Link to post
Share on other sites
What resolution are you running under?

It's very simple to calculate the matrix scale using the number of pixels tall or wide that you want the sprite:

NewScale = DesiredWidth / ImageWidth;

You'll also have to unscale the position of the image to use D3DXSprite. It's very strange in the way it deals with things. Whatever transforms you apply to the matrix always effect the position as well. So inverse the matrix state and apply it to the position before sending it to the sprite class.

Share this post


Link to post
Share on other sites
Here is how I do it.


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
Quote:
Original post by Jiia
What resolution are you running under?


640x480 for the windowapp, does that matter??

Quote:

It's very simple to calculate the matrix scale using the number of pixels tall or wide that you want the sprite:

NewScale = DesiredWidth / ImageWidth;

You'll also have to unscale the position of the image to use D3DXSprite. It's very strange in the way it deals with things. Whatever transforms you apply to the matrix always effect the position as well. So inverse the matrix state and apply it to the position before sending it to the sprite class.


I got it scaling and the position is correct.. I think.. but why this strange way to do it? I mean, by base the sprite on the size of the texture and force you to store the texture size manually to scale it back?

Share this post


Link to post
Share on other sites
Quote:
Original post by PhiberOptic
Quote:
Original post by Jiia
What resolution are you running under?


640x480 for the windowapp, does that matter??

I was just trying to understand why your sprites are twice as big as they should be. I've never seen that happen. Are you sure your back buffer is the same size as the window client area size?

Quote:
I got it scaling and the position is correct.. I think.. but why this strange way to do it? I mean, by base the sprite on the size of the texture and force you to store the texture size manually to scale it back?

Because you can specify a position in the matrix that you send to ID3DXSprite. That position should be transformed. It seems like it would be useful to have a "screen space" position that doesn't get transformed. You can also send a position when you draw, and for some reason, ID3DXSprite transforms it with the matrix. Seems useless to me.

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