Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Jofran

IDirect3DDevice8::Present and frame time

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

Hi, I know I''m not the first one to ask on frame time, but I''m trying to be accurate on this because I''m doing a 2D-game and every frame counts for smooth sprite-movement (by frame time I mean the exact time one single frame is visible to the user). What I have so far is a StopWatch-class that is called immediately after IDirect3DDevice8:resent. The returned time is then used to calculate movement for the next frame. That''s fine if the page-flip is not snyched with vertical refresh (looks jerky anyway). But here are the scenarios I have trouble with: 1. V-Sync with one back-buffer I found to get smoother results by not using the elapsed time but by constantly using the exact frame time (1 / refreshrate). The problem I have is to determine how many v-refresh cycles I missed to not slow the game down. The movement for the next frame has to be based on (v-cycles / refreshrate). But examining my StopWatch-time doesn''t neccessarily help, because the Present-method for the last frame might just have needed a little longer to return than for the previous frame. That would give me an elapsed time greater than (1 / refreshrate) but I actually didn''t miss that frame. If anybody is still reading and understanding my confusing words, please answer my question or try to explain it more precisely But it gets worse: 2. V-Sync with more than one back-buffer As far as I understand, a call to Present returns immediately if there are unrendered (or already shown) back-buffers available and somehow queues the frames to still show. But that means I don''t even nearly get to know when a v-refresh occurs (as opposed to working with one back-buffer). So what''s the most accurate way to deal with this situation? 3. Using presentation intervals like D3DPRESENT_INTERVAL_TWO I don''t expect this to be much different than using D3DPRESENT_INTERVAL_ONE, but my question is: if I''m using i.e. D3DPRESENT_INTERVAL_FOUR and I already missed five frames before calling Present, will the driver wait another four frames to display the back-buffer or will it be shown with the next v-refresh? If the later is the case, the driver must know how many v-cycles have occured since the last call to Present. Why isn''t that information exposed by DX8 (the solution to my above problems)? Maybe I see problems where there aren''t any, but I''d like to hear your approach to dealing with frame-time. Thanks for reading!

Share this post


Link to post
Share on other sites
Advertisement
I have no clue how to solve your problem, but you may want to look at d3dapp.cpp. It inserts some stuff into the render loop that allows your app to "single frame step." You might be able figure out what is going on by single frame stepping thru your program. . . it''ll show you what happens each frame.

Sorry for the vague answer.

DmGoober

Share this post


Link to post
Share on other sites
Hi there. I have been fondling around with smooth-scrolling-timing as well, and I came to the following conclusions:

- Calculating sub-pixel transformations (for example: position=time_passed/distance_per_millisecond) don''t give smooth scrolling as a result. ever. The human brain is a hard thing to trick. Since DirectDraw has no subpixel engine, the position will be rounded to whole pixels -> jerkyness...

- To get smooth scrolling, the loop should be locked to the refreshrate. Determine a multiplier of VSync (monitor''s refreshrate) the loop can keep up with. This should be an integer!!!

- Now, if every time the *multiplier* amount of VSyncs have passed, the object moves the same steady amount of -whole- pixels... ssSCHMOOoove scrolling!

Hope this helps,

CondorWitte

Share this post


Link to post
Share on other sites
Thanks. That''s what I''m trying to do but I don''t have a satisfying solution for determining the amount of vsyncs passed. Especially while having more than one back-buffer (see 2. in my original post).

Share this post


Link to post
Share on other sites
First, you need to know the time between 2 VSyncs. (1/refreshrate).

Then, count the time since the last loop. (preferably using the performance counter).

The amount of VSyncs will be the elapsed time divided by the time per VSync.

Offcourse, the moment in which the timestamp is made (the current time is read) is crucial.

Greetings, CondorWitte.

Share this post


Link to post
Share on other sites
After having finally updated my engine to DX8, I can give you some numbers to hopefully clarify my problem. My rendering loop traces three values: the total number of frames that have been rendered, the time that elapsed since the previous call to Present and the total time the program is running. The timestamps are retrieved by PerformanceCounters immediately after the call to Present. I ran my sample-program at 640x480 with a refresh-rate of 100Hz. Here''s the result:
After 100 frames were rendered, my program was running for exactly 0.998839 seconds. That makes me believe that I was able to provide a new frame every v-refresh. But the times that elapsed between the various Present-calls range from 0.007739 to 0.012261 seconds. This is close to my desired 0.01 seconds (1/refreshrate) per frame, but it is not enough to judge whether I missed a vrefresh or not.

Maybe now you can see why I don''t want to use the elapsed time: it''s just not constant although the frame-rate is. That will not give smooth scrolling as opposed to using 1/refreshrate.

Please state your opinion.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!