Sign in to follow this  
pyphehe

ID3DXSprite & SetRenderState ??

Recommended Posts

Hi~ I meet some problems about ID3DXSprite. Yesterday i changed my SDK to Apr2006, i found the ID3DXSprite interface changed a lot (the version of my SDK was very old ), and i can't make it work well now. My code looks like this: pDev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 0, 0); pDev->BeginScene(); Spr->Begin(D3DXSPRITE_ALPHABLEND)// This method has no parameter before, Now i use D3DXSPRITE_ALPHABLEND, am i right? pDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); pDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); Spr->Draw(...)// Here i want to render something fade in or fade off pDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); pDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); Spr->Draw(...)//Here i want to render some flames Spr->End(); pDev->EndScene(); pDev->Present(NULL, NULL, NULL, NULL); this code worked very well before (with old sdk), but it seems that i can't SetRenderState() between Begin() and End() now(whit the new sdk). What's wrong?

Share this post


Link to post
Share on other sites
ID3DXSprite has been changed quite a bit. The good news is these changes bring with them a good performance increase, and the interface is now much much faster.

What's happening in your code is that the Sprite interface is batching up your draw calls into a single batch. What this means is that they are not actually drawn when you call Draw. They are instead put in a line of stuff to be drawn. When you call End(), the interface actually does the drawing.

This batching provides a significant speed increase, but it does mean that all the draws taking place in a single batch need to use the same renderstates.

You have two options:
1) Call Sprite->Flush() before each time you change a renderstate. This would eliminate batching, and you will suffer a performance penalty, but this is likely an easy modification to code, so it would require very little work.
2) Split your drawing into two batchs:
first draw all the sprites that use normal blending, call End, and then call Begin again, and draw all the sprites that use additive blending. This would likely be faster, but might require some changes to your code.

Hope this helps.

Share this post


Link to post
Share on other sites
You are right. Some time back (with DX9 if I'm not mistaken) ID3DXSprite was changed to enforce a state block on the device when ID3DXSprite::Begin() is called. This means that the device's state can't be altered until the state block is lifted.

To cancel this you can set the necessary states manually plus the ones you like and then supply the D3DXSPRITE_DONOTMODIFY_RENDERSTATE flag to ID3DXSprite::Begin() before drawing. For a full list of the states that are normally applied by ID3DXSprite::Begin() check out the link.

I ran in to the same problem earlier when I was trying to use a pixel shader in conjunction with ID3DXSprite.

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