Sign in to follow this  

Rendering Optimizations

This topic is 4777 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

I need some tips on how to make the rendering of quads faster using Direct 3D. I already have it sorted by textures. Would it be faster to send only visible quads to DrawPrimitive, or does it already cull and clip automatically the quads that can't be seen? What is the fastest way to render in Direct 3D?

Share this post


Link to post
Share on other sites
Have you tried ID3DXSprite? This interface is *very* optimized for textured quad rendering. It batch renders all of the textures together, so the lowest number of Draw*Primitive*() calls is made. This is probably the biggest speed increase, since Draw*Primitive*() is a very expensive function.

On the other hand, it's also really easy to use - much easier than manually creating vertex buffers and managing them.

Share this post


Link to post
Share on other sites
When it makes a call to draw primitive does it still use triangles? Does Direct 3D have anything that can render a quad without using triangles, and without using D3DXSprite? Rendering as a square or rectangle would be even more efficient than using triangles.

Share this post


Link to post
Share on other sites
You must try to make the few state changes that you can. You have to sort the primitives by textures, and also reorder the vertex in order to make less DrawPrimitive calls.

Share this post


Link to post
Share on other sites
So basically, I should just use Direct Draw instead. Can Direct Draw be as fast as Direct 3D? I know Direct 3D accesses the hardware, but will it make that huge of a difference? On another note, if I sort the vertices to render them as triangle strips, or use wrap textures will that make a difference in speed?

Share this post


Link to post
Share on other sites
Nope, quads are not a primitive in DirectX (they are in OpenGL I think?). Direct3D is going to be faster than DirectDraw. How are you batching the textures together? Are you creating one big vertex buffer for each texture and calling DrawPrimitive once for that? If you're only calling SetTexture once and then calling DrawPrimitive 100 times per texture, then it is very unoptimized. You need to add all of those quads together in a buffer, if they share the same texture, as triangle lists.

DirectX does cull vertices that aren't in view, but why throw 1,000,000 vertices through the pipe if you know they aren't in view? In other words, if you have a lot of vertices and a large world and are only viewing a small part, you need to use some sort of visible set algorithm (such as quadtrees) to determine what is possibly visible, then you could cull it further right down to the mark by using frustrum culling. If you're just using RHW quads specifically, then you use a simplified version of frustrum culling. You know what quads are on the screen by the fact that you have to specify transformed vertices, so you end up only drawing the ones you want in the first place.

What exactly are you wanting to do? Maybe some background on what you need to draw will let us help you optimize.

Chris

Share this post


Link to post
Share on other sites
You will still want some sort of geometry removal. Though DX does this for you (it is called clipping), it is done triangle by triangle, so it is slower than removing entire objects and such.

Triangles are the only 2D primitive that current hardware supports. Though OpenGL supports quads, it still has to break them up into tris for you.

Share this post


Link to post
Share on other sites
I created a single vertex buffer which contains all the geometry for a single cell. Then I called SetTexture once per texture and had it call DrawPrimitive to render all primitives with that texture. I also have an if statement that won't even call those two if there are no primitives to draw for that texture.

I'm making a 2D(with 3D aspects) game that is made up of mostly quads. I was just wondering if there was a better way of doing this since triangles wouldn't be an optimal answer in this special case. I'm curious about which rendering methods are the fastest in Direct 3D, and how could they possibly be optimized?

Is calling SetTexture and DrawPrimitive(with no vertices) more expensive than an if statement?

Would using a vertex buffer for all visible triangles, and making on the fly changes of the vertex buffer, and textured primitive counts still be faster than just rendering? The first one would take a moment, but after that it could make less changes each cycle, but would it still be faster?

[Edited by - BEHOLDER192875 on November 14, 2004 11:10:45 AM]

Share this post


Link to post
Share on other sites
In my experience an easy way to improve speed in DirectX (and probably in OpenGL, etc) is the following:

When you have a lot of surfaces with the same texture, instead of
rendering with DrawPrimitive each one, try to make a single surface that contains all the vertexes of the surfaces and render with a single DrawPrimitive call. Of cource you must use TRIANGLE_LISTs, not TRIANGLE_FUN or TRIANGLE_STRIP.
I mean: instead of calling DrawPrimitive 100 times to render 100 triangles each time it's much more faster to call DrawPrimitive once and render 10000 triangles in a single call.

Share this post


Link to post
Share on other sites
Quote:
Original post by BEHOLDER192875
I'm making a 2D(with 3D aspects) game that is made up of mostly quads. I was just wondering if there was a better way of doing this since triangles wouldn't be an optimal answer in this special case. I'm curious about which rendering methods are the fastest in Direct 3D, and how could they possibly be optimized?


Triangle list would be the best as you are going to batch sprites together. Don't worry about having a extra 2 vertices, you'll run out of fillrate before you hit a geometry processing limit.

Quote:

Is calling SetTexture and DrawPrimitive(with no vertices) more expensive than an if statement?


Definitely. By a long shot, even if D3D ignores them (assuming your condition isn't ridiculously expensive).

Quote:

Would using a vertex buffer for all visible triangles, and making on the fly changes of the vertex buffer, and textured primitive counts still be faster than just rendering? The first one would take a moment, but after that it could make less changes each cycle, but would it still be faster?


You'd have to use vertex buffers (or rather a single buffer) correctly for optimal use, which would mean re-creating your visible vertices each frame. I haven't tried this but I would think it is probably the best solution since most sprites would have some change every frame (either movement or animation).

Make sure you have the same number of DrawPrimitive (or probably better to use DrawIndexedPrimitive) calls as you have different textures - no more.

Share this post


Link to post
Share on other sites
Well, I like to know exactly how things work. Besides, creating a good algorithm like this helps simplify stuff I'll be doing later. What if I didn't want an exact rectangle? How about a trapezoid? Can ID3DXSprite create trapezoids? Creating this will also allow me to use the textured primitive counting for later purposes. The idea was to create the most open ended code possible, and make it as fast as ID3DXSprite.

Share this post


Link to post
Share on other sites

This topic is 4777 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