Sign in to follow this  

Fastest way to render 2D sprites

This topic is 4530 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So, what's the fastest way to render 2D sprites? I've been using the D3DXSprite interface to render my sprites in my game engine. Performance wise it seems ok, I get speeds of 30-60fps with hundreds of sprites and a full screen redraw. But I've read that batching up all of my sprites and then making one call to render them would be the fastest but I take it this is not using the D3DXSprite interface. I want to stick with DirectX8 because it provides a little more end user compatbility compared to DirectX9. But if someone has experience with both Dx8,Dx9's D3DXSprite interface, I'd love to hear about the speed differences between the 2 versions? Thanks..

Share this post


Link to post
Share on other sites
ID3DXSprite does batching automatically, HOWEVER, it require you to flush when you change textures etc.

The fastest way is as you said, batch as far as possible (by texture and states), and for all solid quads (sprites) you draw front-to-back, then you draw all transparent sprites back-to-front. (using your own or someone elses 2d engine using Direct3D)

I'm guessing that using a custom pixelshader and vertexshader you could crank it up even more as to only process minimal amount of instructions, but I would say, if you perform the previous step you should have plenty of power for any game that is built with any sense in mind on most of the graphics cards available today.

Using static buffers for static content (e.g., map tiles) could likely improve the speed by a small factor, however, can also decrease the performance due to excessive texture changing etc, trial and error.

EDIT: it's said that the ID3DXSprite for DX9 is much better than it was back in DX8.

Share this post


Link to post
Share on other sites
Hi,

Well, I didn't ever tried the dx8 sprites, and I use an own sprite class for dx9 rendering instead of the D3DXSprite. maybe, batching could make your code faster, but I don't really think so, as you mentioned hundreds of sprites (which are, if you do them with two triangles) are not that much vertices, and not that much draw calls. I would suggest measuring with NVPerfHUD. Try the 2x2 texture option. If it speeds up, then consider making your textures smaller, and/or using DXTn compression for your textures. (This DNTn thing gave me almost 2x FPS increase in some cases on some hardware). So, before trying anything, use compressed DDS textures, then do some measuring. I think batching is not the way for you, but you can try of course (I did).

kp

Share this post


Link to post
Share on other sites
From your description, you probably don't have a problem - ID3DXSpite will be optimized, so I wouldn't worry about it being slow unless you see particular evidence that it's a bottleneck in your software...



I use my own implementation of sprites, so I can't answer w.r.t. to the actual interfaces.

But I will say that you need to be quite sure that your new implementation is significantly different to the D3DX version if you expect a noticeable speed increase.

By this I mean that if you were to re-implement ID3DXSprite using pretty much the same methodology you're unlikely to beat the hand-tuned and tested Microsoft code [smile]

However, if you change one of the mechanics (such as storing all resources together to aid batching) then you might well get a speed-up for the simple reason that you're taking advantage of a "special case" in your system.

A similar example of this is that I wrote my own text rasterizer that took advantage of the fact the text was (mostly) static... it's an order of magnitude faster than using the D3DX text rendering, but I reckon that's only because I'm taking advantage of my knowledge of the way it's being used and chagned the mechanics accordingly...

hth
Jack

Share this post


Link to post
Share on other sites
Quote:
Original post by Rebooted
D3DX text is quite slow because it uses GDI functions, so you can beat it with your own code. ID3DXSprite however, is probably as fast as you can get.


No, since the june (i think) 2004 D3DX Text is based on textured quads (with the option to use D3DXSprites to improve performance) rather than GDI

Share this post


Link to post
Share on other sites
Would anyone like to code a simple sprite test challange? It would be cool if several coders coded a sprite test to see who's render loop is rendering the most sprites, at the highest fps. :)

800x600x32 screen, 2000 32x32 sprites, all moving in pong fashion around the screen, with rotation and scaling, etc. Any takers? Perhaps we could all use the same texture? I could code a DirectX8 version using VB6 and the D3DXSprite interface for comparison???

DirectX 8 or 9 only. We could all use Fraps.com utility for fps reporting so no cheating. :) LOL...

Share this post


Link to post
Share on other sites
Quote:
Original post by 2dcoder
Would anyone like to code a simple sprite test challange? It would be cool if several coders coded a sprite test to see who's render loop is rendering the most sprites, at the highest fps. :)

800x600x32 screen, 2000 32x32 sprites, all moving in pong fashion around the screen, with rotation and scaling, etc. Any takers? Perhaps we could all use the same texture? I could code a DirectX8 version using VB6 and the D3DXSprite interface for comparison???

DirectX 8 or 9 only. We could all use Fraps.com utility for fps reporting so no cheating. :) LOL...


Actually, i've just implemented a simple sprite demo (no demo.. sorry) where i pushed around 250 888 sprites at 30fps in 1024 * 768 * D3DFMT_X8R8G8B8, and YES, those were textured sprites...

Share this post


Link to post
Share on other sites
Quote:
Original post by Metus
No, since the june (i think) 2004 D3DX Text is based on textured quads (with the option to use D3DXSprites to improve performance) rather than GDI


It has always been as far as I believe, HOWEVER, what he was referring to was the generation of the texture, which is done using GDI calls, and could be quite slow for generating the texture.

Share this post


Link to post
Share on other sites
"where i pushed around 250 888 sprites at 30fps in 1024 * 768 * D3DFMT_X8R8G8B8, and YES, those were textured sprites..."

250,888 sprites????? On what hardware? I would love to run that demo on my test box. Would you consider releasing that as a demo? Puhlease!! LOL...

Share this post


Link to post
Share on other sites
i'm using DirectDraw 7 in my game. Direct-X 8 doesn't have Direct Draw and seemed to me to be some 2D/3D hybrid, so i stuck with DX7. i might be wrong about that tho. is DX8 better than DX7? as fasr as speed goes. i don't need any crazy effects or addded fluff.

also, if someone has never had DX7 on their comp (for example if it's a brand new PC) and only has had 8 or 9, would they then have to install DX7? would that overwrite their DX8 or 9? i'm kinda confused about this.

Share this post


Link to post
Share on other sites
DDraw is still available in DX8/DX9, but it will not be updated from version 7 anymore. Anything from DX8 on is 3d only. On most drivers DDraw will be implemented using the 3d acceleration anyway.

If you've got DX8 or DX9 installed you also got DX7 and all the older DX stuff installed.

Share this post


Link to post
Share on other sites
DirectDraw is in microsofts eyes deprecated and is not supported anymore... Also, going over to DirectX9 and using 3D for 2D will most likely speed things up for you as you can then use the power of todays cards with blending, scewing, rotation, and pure acceleration.

So, do continue to use DirectDraw if you've already begun. But going over to Direct3D (and ID3DXSprite if you wish) is a step that one should take if granted the time, I would even further recommend you to build your own "ID3DXSprite"-class using quads, which allows you to achieve powerful effects and power even in 2D, but if using DirectDraw, you will most certainly be happy with ID3DXSprite.

Share this post


Link to post
Share on other sites
Interesting. I myself have only recently started work on a d3dxsprite based 2d engine (more as a learning experience than anything). I was previously doing a being, draw, end loop for every sprite in my engine before I realised that the you actually need just one sprite object, which can have multiple draw calls on it.

i.e, you have 1 D3DXSprite object, and you have a collection of graphic objects that consist of nothing more than a texture and a rectangle (to indicate part of the texture to draw from). Then when you want to render:

1) D3DXSprite begin
2) D3DXSprite draw with graphicObject rectangle and texture (and any other property that sprite draw requires)
3) repeat step 2 as necessary with as many graphic objects that are required (note you may want to sort by transparent/opaque and front/back order beforehand).
4) D3DXSprite end

The above is a rough represenation of events as far as batching goes. But I take it this is how it goes since it seems to work fine here. The point to note is that all your draws are batched up till you hit the end call whereupon everything is pushed to the renderer in a batch. So to answer the OT, I think batching would be the way to go purely because it makes sense! :)

Share this post


Link to post
Share on other sites
"i.e, you have 1 D3DXSprite object, and you have a collection of graphic objects that consist of nothing more than a texture and a rectangle (to indicate part of the texture to draw from)..."

Yah, I got that from the get go, thanks. I'm using DX8 and I don't know if it's as optimized and batch ready as the DX9 version is, anyone know?

I'll check back later and throw together a simple sprite demo, and perhaps some of you can download it and run it and report how many sprites at what fps it's running at on your hardware. ;)

Share this post


Link to post
Share on other sites
http://64.151.99.9/spritetest.zip (100k zip)

A simple sprite demo (exe) that renders 2000 sprites using the D3DXSprite interface in DirectX8. Windows XP, VB6 runtimes (already on most machines)

Steady 30fps reporting using Fraps.com
HP Pavillion Celeron 2.93 ghz
Onboard Intel Extreme Graphics

If you get faster or slower results, could you please post your system specs along with graphics card? And ofcourse if anyone can write a demo that renders the 2000 sprites faster, that would cool to compare, especially using the DirectX9 D3DSprite interface to see if it's faster than the DirectX8 version.

If you do write a demo for comparison, please use the following guideline:
800x600x32
32x32 sprite (use the included texture)
Scaling goes from half size to full size. (.5 to 1)
Sprite alpha is initialized with random values ranging from no transparency to half transparency.

Thanks!

Share this post


Link to post
Share on other sites
256x256 is just a standard texture size, when using the D3DXSprite interface you point to a region inside a texture for the sprite area. I guess I could have used a smaller texture size, but it really shouldn't matter at least not for this test.

On my system (Intel Extreme Onboard Graphics) 30fps for the 2000 32x32 sprites is not bad, actually I'm getting around 35fps when I turn off my virus checkers. So 30-35 is the average speed on my system for this test.

Share this post


Link to post
Share on other sites
"85-90 fps on a P4 3.2Ghz with a GeForce 4200Ti graphics card."

Thanks for running the demo, much appreciated!

hmm... this is obviously 2-3 times faster compared to my system, but I'd still like to see how a DX9 D3DXSprite system would compare to the DX8 system, and then ultimately a Quad/Batched system that doesn't use the D3DXSprite interface.

Share this post


Link to post
Share on other sites
Quote:
Original post by 2dcoder
"where i pushed around 250 888 sprites at 30fps in 1024 * 768 * D3DFMT_X8R8G8B8, and YES, those were textured sprites..."

250,888 sprites????? On what hardware? I would love to run that demo on my test box. Would you consider releasing that as a demo? Puhlease!! LOL...


It was on my A64 2.8Ghz, 1Gb of ram and an nVidia GF6600GT

Share this post


Link to post
Share on other sites
Metus, I've been researching DirectX sprite rendering the past few days, and that number seems almost impossible. Even a non alpha Direct Draw engine would be hard pressed to pump 250,000 sprites at 30fps. So until I see an actual demo from you I'm just a little skeptical. ;)

Share this post


Link to post
Share on other sites
hmm.. perhaps i have to review my code.. but i was just curious for one of my game project ( a tiled-based multilayer game ) so i quickly hacked this thing together:

resolution: 1024 * 768
spritesize: 8 * 8
layers 10

1024 / 8 * 768 / 8 = 128 * 96 = 12288 sprites per layer * 10 layers = 122880 tiles per 10 layers.

soo.. it was my mistake.. on 122880 sprites there are twice the amount of polygons.. that is wat nvPerfHud reports :P

so the correct number of sprites are 122 800

Share this post


Link to post
Share on other sites
Even 122800 8x8 sprites at 30fps in 32bit color seems unlikely. ;) And if you were drawing 10 layers, then to get the full 122800 sprites on screen at one time EVERY tile in EVERY layer would have to be filled. Perhaps you had a few (thousand or so) empty tiles? ;)

Share this post


Link to post
Share on other sites

This topic is 4530 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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