English 中文(简体)
DirectX: Game loop order, draw first and then handle input?
原标题:

I was just reading through the DirectX documentation and encountered something interesting in the page for IDirect3DDevice9::BeginScene :

To enable maximal parallelism between the CPU and the graphics accelerator, it is advantageous to call IDirect3DDevice9::EndScene as far ahead of calling present as possible.

I ve been accustomed to writing my game loop to handle input and such, then draw. Do I have it backwards? Maybe the game loop should be more like this: (semi-pseudocode, obviously)

while(running) {
    d3ddev->Clear(...);
    d3ddev->BeginScene();
    // draw things
    d3ddev->EndScene();

    // handle input
    // do any other processing
    // play sounds, etc.

    d3ddev->Present(NULL, NULL, NULL, NULL);
}

According to that sentence of the documentation, this loop would "enable maximal parallelism".

Is this commonly done? Are there any downsides to ordering the game loop like this? I see no real problem with it after the first iteration... And I know the best way to know the actual speed increase of something like this is to actually benchmark it, but has anyone else already tried this and can you attest to any actual speed increase?

最佳回答

Since I always felt that it was "awkward" to draw-before-sim, I tended to push the draws until after the update but also after the "present" call. E.g.

while True:
   Simulate()
   FlipBuffers()
   Render()

While on the first frame you re flipping nothing (and you need to set up things so that the first flip does indeed flip to a known state), this always struck me as a bit nicer than putting the Render() first, even though the order of operations are the same once you re under way.

问题回答

The short answer is yes, this is how it s commonly done. Take a look at the following presentation on the game loop in God of War III on the PS3:

http://www.tilander.org/aurora/comp/gdc2009_Tilander_Filippov_SPU.pdf

If you re running a double buffered game at 30 fps, the input lag will be 1 / 30 ~= 0.033 seconds which is way to small to be detected by a human (for comparison, any reaction time under 0.1 seconds on 100 metres is considered to be a false start).

Its worth noting that on nearly all PC hardware BeginScene and EndScene do nothing. In fact the driver buffers up all the draw commands and then when you call present it may not even begin drawing. They commonly buffer up several frames of draw commands to smooth out frame rate. Usually the driver does things based around the present call.

This can cause input lag when frame rate isn t particularly high.

I d wager if you did your rendering immediately before the present you d notice no difference to the loop you give above. Of course on some odd bits of hardware this may then cause issues so, in general, you are best off looping as you suggest above.





相关问题
Prerequisite for learning directx

I am from .net C# background and I want to learn DirectX. I have knowledge of C++ but I am fairly new to graphic world. I am little confused about how to start learning directx, should I start ...

How to programmatically disable the auto-focus of a webcam?

I am trying to do computer vision using a webcam (the model is Hercules Dualpix). I know it is not the ideal camera to use, but I have no choice here. The problem is the auto-focus makes it hard/...

Making an object orbit a fixed point in directx?

I am trying to make a very simple object rotate around a fixed point in 3dspace. Basically my object is created from a single D3DXVECTOR3, which indicates the current position of the object, ...

3d Alternative for D3DXSPRITE for billboarding

I am looking to billboard a sun image in my 3d world (directx 9). Creating a D3DXSPRITE is great in some cases, but it is only a 2d object and can not exist in my "world" as a 3d object. What is ...

热门标签