Skip to main content
gamedev.net
🔒 Locked

DirectX slow

Started by gerbenvv 15 replies 1.7k views
Original Post
gerbenvv
gerbenvv
Hi, I was working with Directdraw 7 to do my 2d game, but it seemed very slow to me. So i decided to go to direct3D 8, but after all it's not much faster, while i thought 3d technics were faster nowadays. Maybe it's my video-card (ATI RADEON 7000)? Is it true that 3d technics are faster? Or is it just my video-card which needs to be updated? Gerben VV
while (!asleep()) { sheep++;}
dave
dave
HAPPY BIRTHDAY!

Umm, what exactly are you trying to do in DirectX?

ace
gerbenvv
gerbenvv
Tnx, i'm just drawing tiles and sprites to the screen, using the textured quads. first 16 x 12 = 192 tiles, then for about 20 sprites.
while (!asleep()) { sheep++;}
dave
dave
Right then, some things to look out for:

- Turn on D3D Debugging, this will throw debug info at you.
- How are you rendering the sprites? DIP()?
- Creating vertex buffers on the fly?

ace
gerbenvv
gerbenvv
Um, I don't know how to enable D3D Debugging, i'm using the borland compiler.
I'm rendering my sprites, like here http://www.gamedev.net/reference/articles/article1972.asp
What is DIP?

I first get a pointer to the vertex buffer, then apply a texture, then write the coordinates into it and show it.
while (!asleep()) { sheep++;}
dave
dave
Hi,

Typical Solution
----------------

Assuming your scene is static, ie no texture changes on the fly for an object and it isn't moving, you would do this:

- ...process your quads however you want to, be it a quad manager or whatever.
- Sort the quads by material, this might just be a texture.
- Build a list of render batches, so you render in batches by texture.
- According to the batches you have created, fill one static vertex buffer and one static index buffer.
- Iterate through the batches you created, setting the all the render/texturestage/samplerstage states and call DP or DIP

DP - DrawPrimitive(), this is used when you have created only a vertex buffer and the vertices in the vertex buffer are the triangles exactly.
DIP - DrawIndexedPrimitive(), this is used when you have a vertex buffer with all the DIFFERENT vertices in it and have an index buffer which contains integers indexing into the vertex buffer, the index buffer describes the triangles exactly. This is faster.

To enable Direct3D in DEBUG mode go to your control panel and there should be a DirectX icon, if you have installed the DirectX 9 SDK. Look at the Direct3D tab in here.

Hope that helps a few things, if not i'll go into more detail.

ace
jollyjeffers
jollyjeffers
See the link in my signiture for a guide to "DirectX Debugging" - it'll cover the stuff that Ace mentioned...

DIP -> DrawIndexedPrimitive(). It's one of the ways you can render geometry using both index buffers and vertex buffers.

If you're following the code in that article, you're using "DP" - DrawPrimitive().

Regarding that article - it's a good place to start, but from a cursory scan of the code presented it doesn't seem to be the most efficient code [smile]

One thing I notice, in it's BlitD3D function is that it locks/writes/unlocks the buffer every single time you want to draw something. Resource modification can be a necessary evil, but the best performing code avoids it where possible [smile]

It comes down to a key thing: Do you need to animate/change your tiles? Once loaded, do they ever move around at all? If not, create the geometry ONCE in a SINGLE large vertex buffer and then render directly from that - with no resource modification.

If you do need to change your positions/whatever then there are a few tricks to try and get better performance. For example, making sure that the VB is created with the right usage flags (D3DUSAGE_DYNAMIC or D3DUSAGE_WRITEONLY) and that when you lock it you attempt to do so with flags such as D3DLOCK_DISCARD..

As a general note - despite similarities, don't treat Direct3D as if it were DirectDraw with different syntax [smile] Sure, it might work, but you'll only get the best performance (and use of features) if you write your Direct3D applications as though they were just that - Direct3D applications...

The point being that it might be worth your effort (if you're planning on sticking with D3D) to learn some of the background/principles and "best practices" type stuff.

hth
Jack
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ |
Jaywalk
Jaywalk
Happy birthday!

I should think D3D on your card should be pretty fast, but you should be aware that there are some things that can slow Direct3D down quite severely. Firstly, the make sure you use hardware and not the reference device, because reference is really slow. Secondly, DrawPrimitiveUP is also slow, so use vertex buffers instead. Thirdly, reuse vertex buffers - don't create and destroy them each frame. Fourth, instead of having a tiny 4-vertex vertex buffer for each sprite, try have one huge buffer to store all the sprites at once. Also, you get a speed boost if you make your buffers "write-only" - I doubt you'll want to read from them.

You might consider learning OpenGL for this game you're making. While it's not necessarily faster than DirectX (the best-case performance of each is roughly equal, depending on the drivers you're using), it's far easier to get OpenGL to perform well. You can just draw your sprites on-the-fly without having to worry about vertex buffers. The only real catch to OpenGL is initialising it (if you're not using SDL or GLUT or something similar, in which case you don't need to worry).
gerbenvv
gerbenvv
sorting the sprites by texture is a problem, cause sprites overlap each other sometimes. I do a depth sorting on the sprites.
while (!asleep()) { sheep++;}
gerbenvv
gerbenvv
actually, i've never tried openGL, so that could be a solution. In my 2d game you have sprites at different z values. I now use a sort on their z values and draw them in that order, is this a good thing or could it be done faster? (I think when i use the vertex z thing the sprites will be smaller according to their z values)
while (!asleep()) { sheep++;}
dave
dave
Well when you are rendering in 2D the Z has little impact unless you are doing a depth sort. Since the vertices map directly to screen coordinates the quads won't get smaller.

Why is sorting by texture a problem?, not sure i understand.

ace
gerbenvv
gerbenvv
Can somebody give me an example code to setup indexed vertex buffer and sorting sprites by texture and writing them?

What's happening with sprites who have the same z anyway?
while (!asleep()) { sheep++;}
dave
dave
Well, like i said in another post the Z barely matters. In 2D it is the order in which you draw the sprites that determine which comes out on top.

gerbenvv
gerbenvv
Yeah, but if i'm gonna sort the sprites on texture i can't sort them on z too.
while (!asleep()) { sheep++;}
jeffason
jeffason
i've written several mini 2d games using directx with no performance issues. one of which was in fact an rpg.
gerbenvv
gerbenvv
Can somebody give me an example code to setup indexed vertex buffer and sorting sprites by texture and writing them, plz? (Or links to good tuts)

while (!asleep()) { sheep++;}
Calin
Calin
MSDN has a good explanation on how Index Buffers work here. 32Bits also has a tutorial on using Index Buffers (Look for the terrain tutorial). 32Bits.

[Edited by - Calin on October 21, 2005 11:26:16 AM]
My project`s facebook page is “DreamLand Page”

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.