Sign in to follow this  
dhanji

ID3DXSprite and billboarding

Recommended Posts

Hi, here is my code to render a 2D quad somewhere in worldspace:
	D3DXQUATERNION qt;

	//WorldView are concatenated 
	sprite3D->SetWorldViewLH(&matWorldView, &matIdentity);
	sprite3D->Begin(D3DXSPRITE_ALPHABLEND|D3DXSPRITE_SORT_DEPTH_FRONTTOBACK);
			
	D3DXQuaternionRotationYawPitchRoll(&qt, st.yaw, st.pitch, st.roll);
	D3DXMatrixAffineTransformation(&mat, scale.x, &D3DXVECTOR3(0,0,0), &qt, &st.position);
	D3DXMatrixMultiply(&mat, &mat, &matWorldView);

	sprite3D->SetTransform(&mat);
	sprite3D->Draw(st.resource->GetTexture(), st.clipRect, NULL, NULL, st.color);
	sprite3D->End();


st is a struct containing info about the location/size/rotation of a sprite. But what this does is to display a "bent" sprite on the top left of my screen following the camera around. By comparison if I replace the sprite3D->Draw with a call to device->SetTransform(..WORLD, &mat) and a generic quad vertex buffer (device->DrawPrimitive) it draws perfectly. IF I remove the multiplying the affine transform matrix by matWorldView my sprite disappears altogether. Any ideas? thanks.

Share this post


Link to post
Share on other sites
I dont understand why you're rendering quads in world space the way you are. You mentioned billboarding but it looks like you're setting their rotation yourself? I don't have access to the docs on the computer I'm on but isn't the flag for billboards D3DXSPRITE_BILLBOARD or something like that?

Anyhow, here's how I render quads in world space.


HRESULT DXEngine::DrawSprite( D3DXMATRIX matWorld, LPDIRECT3DTEXTURE9 pSrcTexture,
RECT *pSrcRect, DWORD dwFlags )
{

D3DXVECTOR3 trans(0,0,0), rcenter(0,0,0);

// Define the center of the texture. For rotation, and drawing at the center.
if(pSrcRect) {
rcenter.x = ((float)(pSrcRect->right - pSrcRect->left) / 2);
rcenter.y =((float)(pSrcRect->bottom - pSrcRect->top) / 2);
}

m_pd3dxSprite->SetTransform( &matWorld );
m_pd3dxSprite->Begin( D3DXSPRITE_OBJECTSPACE );

m_pd3dxSprite->Draw(m_pTexShip, pSrcRect, &rcenter, NULL, 0xFFFFFFFF );
m_pd3dxSprite->End();

return S_OK;

}




Mine aren't billboards because my camera is stationary, though. I'd have to look at your code more to understand exaclty what you're going for, but your method looks a little overcomplicated to me at first glance. In all fairness mine sets up the matrix somewhere else not shown here, but even so that's done with D3DXMatrixRotationYawPitchRoll D3DXMatrixTranslate and D3DXMatrixScaling and is pretty straight forward.

Share this post


Link to post
Share on other sites
well enabling or disabling D3DXSPRITE_BILLBOARD simply adjusts the rotation to face the camera. I have tried it both ways and nothing shows up. how should it matter whether I rotate them myself or get the sprite interface to do it.

D3DXMatrixAffineTransformation is just a concatenation of YPR, scaling and translation as you use them with individual matrices. I use quaternions to prevent gimbal lock. It is very simple, I just use a struct to hold the values rather than take them into the function from the matworld that you generate elsewhere.
My main question is why should that transform matrix work with a quad from a vertexbuffer and not the ID3DXSprite interface?

Though from your code you give me an idea with the D3DXSPRITE_OBJECTSPACE flag, which could be it...
thanks for your response.

Share this post


Link to post
Share on other sites
Hi,

You should try to write sprite3D->SetWorldViewLH(&matWorld, &matView); instead of sprite3D->SetWorldViewLH(&matWorldView, &matIdentity); maybe it can solve some problems.

For the rest of the code, I don't see any problem, although I don't do it the same way :
I use SetTransform only to scale a particle. To move it, I use the 4th parameter of ID3DXSprite::Draw() (i'm using billboard, so I don't care about the rotation)


.:: Paic Citron ::.

Share this post


Link to post
Share on other sites
Hi I managed to fix it by setting the OBJECTSPACE flag which preserves the worldview matrices from the device state.


Quote:

You should try to write sprite3D->SetWorldViewLH(&matWorld, &matView); instead of sprite3D->SetWorldViewLH(&matWorldView, &matIdentity); maybe it can solve some problems.


As I said I concatenated the world and view matrices and set view to identity. It works fine for a textured quad, so I was wondering why it dint work here.
But thanks very much for your help.

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