DirectDraw Speed

Started by
4 comments, last by Kaptain Kangaroo 22 years, 7 months ago
I have a program which blits 1 fullscreen background image, and 30 tiles. Now, on a 500Mhz machine with a voodoo 3, it only performs 30fps MAXIMUM. What is the problem? Why is it so slow?
Advertisement
1. Make sure all surfaces are allocated in local video memory.

2. Make sure there are no Lock() or GetDC() calls, particularly on any surfaces referred to in the blits. If you really need to do it, double (or more) buffer the surface you Lock/GetDC on so that the lock doesn''t stall the blit.

3. 8bit, 16bit or 32bit surfaces are faster than 24bit.

4. If you are syncronising your Flip to VSYNC, then that will limit your maximum speed to a lower multiple of the refresh rate - if your card refreshes at 60Hz and your game runs at 59Hz, the frame rate you''ll get will be 30Hz. Try it in windowed mode or with VSYNC turned off (you may need to adjust the display settings too as drivers usually allow users to force VSYNC on)

--
Simon O''''Connor
Creative Asylum Ltd
www.creative-asylum.com

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Thanks. Turning off the VSYNC made things zoom! I didn''t think that would be the problem, heh.

Now, the problem I am having now is that if I run it on my friend''s machine with VSYNC off, it flickers like crazy. This leads me to believe that I need to have VYSNC on for it to work properly on other machines. But in that case, won''t I carry on getting frame rates like 30FPS on other people''s machines? That''s no good! What is the solution?
Tutorial time... (hard to explain + the influence of lots of strong French lager isn''t helping )

Display technology has evolved from television, and so is quite similar. A picture on a TV/monitor is made from a number of lines (scanlines). Although a picture looks complete it is really drawn line by line. It takes 1/60th of a second to draw all the scanlines in a 60Hz (60fps) display.
Some of the scanlines in a display aren''t visible - some are used by things such as teletext (look for white dots just above the picture on dodgy TVs). Above those is the "vertical blanking gap", a non-visible area on all displays.

If the picture in video memory remains the same for the complete 1/60th of a second, then it will be drawn perfectly.

If you update the bottom half of the display at the time where the monitor is drawing the top half you will get a "tear" - because the top half represents the previous frame and the bottom half represents the current frame. They are out of synchronisation.

Doing a Flip with a wait for VSYNC forces the graphics chip to wait until the current scanline (the drawing line) is in the vertical blanking gap. This wait is what forces the overall app speed down.

If you don''t wait for VSYNC you''ll get tearing - thats jus the way things work...

One thing which can help in some circumstances is to triple buffer - if you''re using pure DirectDraw try setting the number of back buffers to 2.

In our games we use synchronised display by default (rock solid but potentially slower), but allow the user to change the behaviour to non-synced and/or triple buffered (i.e. tears and flickers) if they want to. It''s just an unfortunate caveat of graphics programming you have to live with.

--
Simon O''''Connor
Creative Asylum Ltd
www.creative-asylum.com

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Actually, there''s a simpler answer. When you use Flip() with the DDFLIP_WAIT flag, it automatically waits for a VSYNC before doing it. If you do a WaitForVerticalBlank() right before you do the Flip() using this flag, you''re actually waiting for 2 VSYNCS before the flip occurs, which halves your locked framerate. So, if you''re locking your framerate at 60fps, your game will only run at 30.
Solution: Don''t use WaitForVerticalBlank()

Paradigm Shift 2000
I wasn''t calling WaitForVeticalRetrace(), but thanks anyway.

A thought crossed my mind, what if I was to force the screenmode to 60hz refresh rate, I could use that as mmy frame limiter. Can anybody see any problems with doing this?


I did try it, but if I call IDirectDraw4->SetDisplayMode(640, 480, 16, 60, 0); (with 60 as my refresh rate) it doesn''t work. What values should I suse?

This topic is closed to new replies.

Advertisement