Archived

This topic is now archived and is closed to further replies.

Eddie T Sehoo

Any other way to get a 2D sprite onscreen other than SetTexture?

Recommended Posts

Hi, I''m making a 2D game using Direct3D. Is there any other way to get a 2D sprite on the screen other than having to use SetTexture? In my game, my 2D sprites *must* be drawn in a specific algo-determined order.. So we basically have similar-texture sprites that sometimes are not drawn one after the other, hence eliminating the possibility of batching these sprites to save on SetTexture calls. I know that calls to setTexture are expensive (especially if its repeated maybe, 100-200 times in a scene) .So is there any other way to get my sprites onscreen? Will appreciate any help i can get. Thanks, Regards, Eddie

Share this post


Link to post
Share on other sites
are you batching the sprite textures in one single texture, like texture tiles? If the sprite don''t have texture coords repeated.

Share this post


Link to post
Share on other sites
SetTexture calls are not expensive, 100 calls per frame wont slow you down very much...

Share this post


Link to post
Share on other sites
Hi all
Thanks for the input. What I meant to say was that calls to *DrawPrimitive* will be expensive (when repeatedly called to render every quad in each frame). I can''t batch the triangles together because every quad uses a different texture. So I have to repeatedly call DrawPrimitive and SetTexture (as many as 1000 times per frame) ... DrawPrimitive is slow because nVidia says that if you''re sending small triangles to the card repeatedly, it''ll suffer a performance hit..

Anyway, I''m now left with another option : using the ID3DXSprite interface..
Do you think drawing 1000 different sprites in a frame using ID3DXSprite is faster performance wise? or making 1000 calls to DrawPrimitive & SetTexture?

Here''s the code for drawing a graphic using ID3DXSprite

LPD3DXSPRITE lpD3DSprite;
D3DXCreateSprite(g_lpD3DDevice, &lpD3DSprite);
lpD3DSprite->Begin();
D3DXVECTOR2 translation(80, 32);
lpD3DSprite->Draw(g_lpTextures[0], NULL, NULL, NULL, 0, &translation, 0xFFFFFFFF);
lpD3DSprite->End();
lpD3DSprite->Release();



Will appreciate any help. Thanks again!
Regards,
Eddie

Share this post


Link to post
Share on other sites
quote:
Original post by Eddie T Sehoo
Hi all
Thanks for the input. What I meant to say was that calls to *DrawPrimitive* will be expensive (when repeatedly called to render every quad in each frame). I can''t batch the triangles together because every quad uses a different texture.



yes, but do you NEED to have different textures for sprites? Can''t you put the sprites in one texture page and tile the sprites on the texture? Like in a font, it would be silly to have a texture for ''A'', a texture for ''B''... instead, they are all in one texture page. nothing prevents you to do the same for regular sprites, as long as they don''t need texture-repeat.

Share this post


Link to post
Share on other sites
quote:
Original post by Eddie T Sehoo
I'm making a 2D game using Direct3D. Is there any other way to get a 2D sprite on the screen other than having to use SetTexture? In my game, my 2D sprites *must* be drawn in a specific algo-determined order.. So we basically have similar-texture sprites that sometimes are not drawn one after the other, hence eliminating the possibility of batching these sprites to save on SetTexture calls.
quote:

What I meant to say was that calls to *DrawPrimitive* will be expensive (when repeatedly called to render every quad in each frame). I can't batch the triangles together because every quad uses a different texture. So I have to repeatedly call DrawPrimitive and SetTexture (as many as 1000 times per frame) ... DrawPrimitive is slow because nVidia says that if you're sending small triangles to the card repeatedly, it'll suffer a performance hit..


If you're worried about it not being fast enough why not test it with more than enough sprites for your game. If it's fast enough for you, great. By calling DrawPrimitive once per sprite you allow yourself the luxury of using matrix transformations on each sprite, which makes rotations/scaling painless. If you use texture transformations you can draw everything with 1 generic quad.

If it's not fast enough then here's a few suggestions:

-how come you need to draw your sprites in a certain order? Could you use the depth buffer and different z-coordinates instead?

-make 1 vertex buffer for all your sprites, and have a quad for each sprite. Do translation/rotation/scaling on the vertices for each sprite manually.

-if both the above are done you could draw hundreds of sprites with 1 call so long as they're on the same texture

[edited by - frankd on April 4, 2004 11:54:30 AM]

Share this post


Link to post
Share on other sites
Hi Frankd,
Thanks for your reply! I think you just solved my problem with your first suggestion :

"How come you need to draw your sprites in a certain order? Could you use the depth buffer and different z-coordinates instead?"

My game is a 2D isometric game... so basically there''s going to be a lot of overlapping graphics (eg: tree sprites overlapping objects, etc etc) . So I devised an algo to create a sort of ''draw queue'' , so that the sprites overlap correctly as required.. Thats why it was imperative that I stick to the queue drawing order.
The idea of using depth buffers didn''t really cross my mind.. until you suggested it.

Anyway, just a quick one of the depth buffers... Now, all my quads have to be drawn *without* any translation at all (ie I dont want the textures to be scaled in any way when the quads are put on different z coordinates) . Is there any way to do this? This practically means I just want to use the Z coordinate to order my tile drawing process, and not change depth perspective in any way.

Will appreciate all replies.Thanks again
Best regards,
Eddie

Share this post


Link to post
Share on other sites
check out the updated ID3DXSprite interface in the dx sdk summer update here

D3DXSPRITE_SORT_TEXTURE
D3DXSPRITE_SORT_DEPTH_FRONTTOBACK
D3DXSPRITE_SORT_DEPTH_BACKTOFRONT

Share this post


Link to post
Share on other sites
hi efoDay,
Thanks for the link! I didn''t know you could batch sprites using ID3DXSprite. This most certainly takes care of the problem, but in your opinion, is it faster batching sprites using ID3DXSprite or would I get along faster drawing sprites using the DrawPrimitive & settextures method?

Thanks again,
Regards,
Eddie

Share this post


Link to post
Share on other sites
Set the projection matrix to an orthographic projection (no depth scaling), you can use D3DXMatrixOrthoLH.

As for using ID3DXSprite, well it would save you the effort of implementing a sprite system, but it''s not doing anything more than calling SetTexture etc. itself. It''s not got access to some special technique that you can''t implement yourself. Also you may find it too restrictive for what you want to do.

Share this post


Link to post
Share on other sites