D3D10 Sprites are insane.

I'm trying to draw a single sprite to the screen. I have a window created (640,480) and the texture loaded in properly. The sprite drawing uses the code below in a Render() function. When run, the sprite does show up but is either tiny when scaling is not applied or skewed when scaling is applied. I know i'm messing up the scaling value, i'm just confused on what the formula should be for calculating it. Right now, i'm using example code from DXUT.cpp which says the scale should be (windowx/textureWidth) and (windowy/textureHeight). This gets the sprite close, but the result is skewed.

Could someone please take a look at the code below and see if you see any glaring issues? Thanks.

Render()

{

// clear the target buffer

pD3DDevice->ClearRenderTargetView(pRenderTargetView, D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f));

if (gSpriteBatch != NULL)

{

D3D10_VIEWPORT VPs [D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];

UINT cVPs = 1;

ID3D10Device* pd3dDevice = NULL;

gSpriteBatch->GetDevice( &pD3DDevice );

pD3DDevice->RSGetViewports(&cVPs, VPs);

D3DXMATRIXA16 matProjection;

D3DXMatrixOrthoOffCenterLH(&matProjection, (FLOAT)VPs[0].TopLeftX, (FLOAT)(VPs[0].TopLeftX + VPs[0].Width), (FLOAT)VPs[0].TopLeftY, (FLOAT)(VPs[0].TopLeftY + VPs[0].Height), 0.1f, 10);

HRESULT hr = gSpriteBatch->SetProjectionTransform(&matProjection);

gSpriteBatch->Begin(D3DX10_SPRITE_SORT_TEXTURE);

D3DXMATRIXA16 matTranslation;

D3DXMATRIXA16 matScaling;

float scaleX = 640/32;

float scaleY = 480/32;

D3DXMatrixScaling( &matScaling, scaleX, scaleY, 1.0f );

D3DXMatrixTranslation( &matTranslation, 32,480-32,0.1f);

D3DX10_SPRITE Sprite;

Sprite.matWorld = matScaling*matTranslation;

Sprite.pTexture = gSpriteTextureRV;

Sprite.TexCoord.x = (float)0.0f;

Sprite.TexCoord.y = (float)0.0f;

Sprite.TexSize.x = (float)1.0f;

Sprite.TexSize.y = (float)1.0f;

Sprite.TextureIndex = 0;

Sprite.ColorModulate = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);

gSpriteBatch->DrawSpritesBuffered(&Sprite, 1);

gSpriteBatch->Flush();

gSpriteBatch->End();

}

// display the next item in the swap chain

pSwapChain->Present(0, 0);

}

[4929 byte] By [nekoWendy] at [2008-2-24]
# 1

If I understand your code right your sprite is 32*32 pixels but I am not sure how big you want it on the screen? The formula you use is for the case you want to fill your single sprite the whole screen. Do you want this?

RalfKornmann at 2007-9-4 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Direct3D 10...
# 2
I want the sprite to be 32x32 on screen. I don't want any scaling really. I want to treat the screen like a 2D environment of 640x480. If I remove scaling completely, the the sprite becomes this dot a single pixel wide. The formula for scaling ends up making the sprite almost it's intended size on screen but is wider than it is tall giving it a squished appearance. It doesn't fill the screen.

Thanks.

nekoWendy at 2007-9-4 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Direct3D 10...
# 3

Sorry I should have read your code more careful.

Your projection matrix looks strange. In the case you want to use sprites with screen coordinates you should create a full screen orthogonal projection matrix.

D3DXMATRIXA16 matProjection;

D3DXMatrixOrthoOffCenterLH(&matProjection, 0.0f, screenWidth, 0.0f, screenHeight, 0.1f, 10);

gSpriteBatch->SetProjectionTransform(&matProjection);

As the “default” sprite has a size of 1 you need to scale to the number of pixels you want to see on the screen.

D3DXMATRIXA16 matScaling;

D3DXMatrixScaling( &matScaling, 32, 32, 1.0f );

The next step is to translate the sprite to the right position

D3DXMATRIXA16 matTranslation;

D3DXMatrixTranslation( &matTranslation, x, screenHeight-y, vPos.z );

Multiply the two matrices together will get you the world matrix for the sprite.

Sprite.matWorld = matScaling*matTranslation;

I am not on my vista system right now therefore it’s not tested but it should work.

RalfKornmann at 2007-9-4 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Direct3D 10...
# 4
I changed the scaling value to be the width and height of the sprite and it scaled correctly. I did notice that the translation position was still off. Finally, I realized that the system was using the center of the sprite (width/2, height/2) as the position instead of the top-left corner. Sprites just don't seem as intuitive as they used to :)

Thanks for your help!

nekoWendy at 2007-9-4 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Direct3D 10...