Skip to main content
GameDev.net gamedev.net
🔒 Locked

In-Depth Direct3D Question

Started by eSam Jan 23, 2007 at 1:10 PM 4 replies 750+ views
Original Post
eSam
eSam
What would be the best scenario to process a game/demo objects that render themselves. An object is assumed to have a think() and present() think() does logical and math calc. and render() uses d3d to render the object based on the think() results. Hence think() comes first. 1) Scenario: For each object: ProcessObject: Think() Render() 2) Scenario: For each object: Think() For each object: Render() The 2nd approach delays the rendering or the GPU usage till the CPU almost finishes everything. I guess there we can minimize (or exactly have one) Direct3D Present call. And we can utilize the CPU time for the next frame when the GPU is still busy. What do you think? What if there's PlaySound()? Thanks.
cobru
cobru
The first approach you suggest indicates that an object always has to 'Think()' before it gets render... I don't think that's the case for a tipical game/demo (which implies decoupling 'thinking' from the 'presenting').

Also, I don't see why the first approach implies several D3D Present() calls, you present a scene once it's rendered, you don't present each object in turn (or do you?)

I would go for a scene graph (so that I could group objects based on their properties, for example if 5 objects use the same texture/shaders, seems to me like a good idea to render them one after another, so that you don't switch textures/shaders), for the rendering part at least.

and.. PlaySound()... why do you think that if there is a PlaySound() something changes in your game loop ?
Q: How many programmers does it take to write a nice piece of software?A: MORE.
jbarcz1
jbarcz1

You dont ever want to have more than one Present() call during a frame. In either approach, you want to make sure that Present() isn't called until after all of the rendering is done.

As to the design question, Issuing rendering calls requires CPU time in and of itself, so there is no reduction in your CPU workload if you go with the second option, but it will probably better utilize the GPU. Remember that your frames are not presented immediately, the GPU driver may buffer up frames before it renders and presents them. If you issue all of the rendering at once, you give the driver more freedom to chunk away on your previous frame while you're running the think()ing for the next frame.

Another thing to think about is multi-pass rendering algorithms. If you want to do something like shadow mapping in your scene, you're going to need to have all the think()ing done in advance so that you can render all of your things into the shadow map before the main rendering pass.
Joshua Barczak3D Application Research GroupAMD
eSam
eSam
First let me correct my mistake. Sorry. I meant the BeginScene & EndScene that would be called more than once.

This is an abstract question regardless of what rendering techniques are used, multipass, shaders, or whatever...

Issuing CPU calls goes through the CPU of course, but there's a point when the GPU is the only one involved, and that's the case after every DrawPrimitive, then when it returns it's either the GPU could finish rendering quickly with no lagging behind the CPU OR the GPU still needs some time, microseconds or millisecond i dunno.

The idea is that CPU always finishes first when exit from any D3D call, generally, unless there's no GPU/Acceleration.

It's a bit complex question as I made it clear in the title. And maybe we need to consider multicore CPUs but that is left later, lets focus on a single core CPU, then we can move to true threading.

sirob
sirob
This topic is much, much more complicated than you think, but still would probably have very little impact on how the game performs.

One thing you should note, is that in most cases, you can't start drawing an object before you've finished updating all objects. What happens if a collision occurs? You'd then need to undraw the object (which is practically impossible), or force it into that position, causing weird stuff for other objects.

A solution you could use is to draw first, then update each object as you go along. This would work, but is probably a bit useless, since the time it takes to iterate through your objects isn't usually an issue.

Add to that the fact that if you do any culling, you wouldn't need to go through every object to render, but would need to go through them all to update, and you end up with a pretty complex issue.

All in all, this really depends on what exactly you're doing. Theres no one-solution-that's-best.

Hope this helps.
Sirob Yes.» - status: Work-O-Rama.
eSam
eSam
Lets focus on GPU/CPU utilization area. Regardless of what objects are being culled or whi9ch one collide with whatever, the provided loops assume everything is resolved from physics to visibility, so it's a pure logical presentation of the problem. Even that can apply to OpenGL, but I want here to consider D3D as the rendering API.

My question is complicated enough, you are right. And it maybe I could not express what I really want.

Topic Locked

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

Sign in to reply to this topic.