View Full Version : Frame Rate Droppage

14-08-2003, 03:43 PM
I'm writing a 2d asteroids clone. Nothing fancy, its the first game I actually plan on finishing. I'm not using TSprites just the DXImageList.Draw functions at the moment. Picture this, I have an asteroid, an explosion and a ship, wizzing about 60 fps no problems. However when I add the "Laser Beam" (I feel like Dr. Evil now) or the "Shields" my framerate drops (to about 55 with the laser beam and about 30 with the shields). These are both using DrawRotateAlpha's but if I change them to plain on DrawRotate's I get the same frame droppage.

I've listed out the on screen items below, what functions I'm using to draw them and their sizes. If anyone could shed some light on the situation I'd be very gratefull.

Asteroid: DrawRotate
64x64, 4096bytes

Explosion: Draw
194x129 Image (6 64x64 frames), 25284bytes

Ship: DrawRotate
64 x 192 (3 64x64 frames), 12288 bytes

EnergyBar Outline: Draw
21 x 176, 4224 bytes

EnergyBar: StretchDraw (stretch height from 1 to 176)
21 x 176, 4224 bytes

Laser: DrawRotateAlpha
5 x 192, 1536bytes

Shields: DrawRotateAlpha (this is drawn over the SHIP)
96 x 96, 9216 bytes

14-08-2003, 07:56 PM
It could be a number of things. But without seeing the code, I can't really say for sure what it is. I'm guessing, the problem is in your drawing routine. Perhaps you are doing something like this?

if (key = vk_space) then dxdraw1.surface.draw(x,y, yourBeam... etc)

This will effectively draw a beam (or the shield for that matter) over and over again, while you are pressing the spacebar. This is of course not what you want, because you may end up with 10 beams instead of just 1.

Instead try this:

if (key = vk_space) and (shooting = false) then shooting := true;

//then in your drawing procedure draw the beam
if (shooting) then dxdraw1.surface.draw(x,y, yourBeam... etc)
Of course you should set shooting to false at some point again.

But, like I said, I''m only guessing here, perhaps your problem is of a very different nature.

Btw, I noticed you are using stretchdraw to display the energybar. I'm not sure how you have done it, but I imagine it may look a bit weird (unless it's made of just one color).
Perhaps you might be interested in this way....

Form1.DXDraw1.surface.Draw(10,30,rect(0,0,decrease ThisValueForTheEffect, 20),energybar,false);

Anway, I hope it helped a bit.

14-08-2003, 09:52 PM
It's already working pretty close to the way you suggested. My ship "Object" has a "laser" property. In the drawing section I'm checking this variable and drawing the laser if need be. It's nice to know I'm on the right lines with *something* at least.

Things are just getting wierder however.
I discovered the slow down at work when I was doing a little after hours games programming. My pc at work is a celeron running at 1.5Mhz I think. Strange thing is, when I take this program home and run it here on my Athlon xp+ (running at 1.7Mhz, and this pc has a much better Graphics card) it runs like a dog, putting out 30 frames per second even if I don't touch the controls.

The code ain't real easy to read, I'm a bit too ashamed to post it here (:oops:) , I've decided to got back to the drawing board, do a few tutorials from here and there and see if I notice any glaring mistakes in my code that way.

As a side note, I've noticed that you don't use the DelphiX animation and do it yourself. Any reason behind this, have you found it to slow?

Cheers for the help

P.s. regarding the energy bar (it's a yellow to red gradient from top to bottom), seeing as it was more informative than anything else and I couldn't be bothered working out how to take a piece of my graphic so I went for the stretch option. It's looks pretty funky luckily enough but I was wondering how to take a chunk of a graphic so that code snippit definately helps.

14-08-2003, 10:12 PM
It couldn't be because I'm using Bitmaps instead of Dibs could it?

14-08-2003, 11:14 PM
You aren't using the Canvas anywhere are you? I made that fault in the past as well, for drawing my text. Only a few months after giving up on the project because the framerate was to low, I found out that using the Canvas and after you are done Canvas.Release, takes a real bite out of your framerate. So that might be your problem...

15-08-2003, 08:00 AM
I am using the canvas but only with a few TextOuts. You know, framerate and a few other variables. I gave it a go and commented it all out but I still got the lag.

I didn't have any problems when I was using 640x480 and 32x32 sprites but I recently upped it to 1024x768 and 64x64 sprites (which are all 255 colours). I'm just presuming that other people have wrote games working with this res and this size sprites without the whole thing coming to a standstill? I mean theres only 4 or 5 images being drawn on the screen, whats gonna happan when that number goes to 10 or 20+

15-08-2003, 02:58 PM
DrawRotate and DrawRotateAlpha using software acceleration.
You can try:
set propety editor-doSystemMemory=True

15-08-2003, 06:54 PM
DelphiX -IS- outdated. If you want high resolutions, lots of pixels and blinding graphics, dump it. You are WAY better of using a 3D engine (which uses DX3D/OpenGL, I don't care) which can use hardware acceleration. DelphiX hardly uses any hardware, so using a screensize of approx 2.5 times your old resolution, also slows your program down 2.5 times.

Oh, and what is VSync set to? For best speed you'd like it to be Off (DXDraw.Options I think it is?)...

15-08-2003, 08:17 PM
doSystemMemory didn't make much difference at all. But thanks for the effort.

I changed DXDraw.doWaitVBlank (it was the nearest thing I could find) and hey presto straight back up to 60fps. So that is all fantastic., if anyone could explain what thats all about that would be great.

I can accept that DelphiX is outdated, but it's so darn easy to use. I'm do this as a hobby not a career so something that lets me produce poor-ish results sooner, rather than fantastic results after a huge steep learning curve is going to be a winner for me. Don't get me wrong, using the Delphi SDL libraries is on my todo list, but game code using those libraries looks exactly like C++ code, just in Pascal whereas DelphiX code looks like a delphi app.

Surely your not telling me that there is no way of creating high resolution games with prerendered sprites without resorting to 3D? What about games like Diablo?

Anywayz, thanks alot for your help, I really appreciate it. Now you've sorted my problem out and I can get back to having fun, and if you can point me at some good non-delphiX tutorials (maybe some with a little 2D in there to keep me sweet) I'll be sure to have a go.



15-08-2003, 08:20 PM
I disagree, you are definitely NOT better of with a 3D engine!
Surely it may look all nice and fancy, but when I see people asking questions about how to draw a rectangle on the screen (no offence intended) do you really think they can handle a 3D engine?

DelphiX may be outdated yes, but so is my geforce 2! And even I still use both every now and then.
True, it may not be the fastest lib in the world, but it sure is a great way to learn the basics. And ok, it won't do all the cool fx you see in your 3D engine, but you could also ask yourself the question if it's really needed? Command & Conquer didn't use them either you know!

15-08-2003, 08:47 PM
Resorting to vsinc, may seem nice, but can leave some strange artifacts on the screen as well. Be carefull with that option!

Creating high resolution (1024x768) games is of course possible. In fact, some time ago, I was working on something that could display 1500 images (like in tiles) on the screen and still maintaining an average framerate of 50.

Note that for a game at that resolution it (only?) takes 768 tiles to fill the entire screen!

17-08-2003, 08:59 AM
Make sure you have SystemMemory property set to false on each indivdual image in your image lists. My current project was running around 30fps and doubled after setting all the images in the lists to false. It's easy to do with DXGEdit if you use DXGs, which I would suggest anyway. But using Alpha with delphix is painfully slow, regardless. I would avoid using it if posible.

18-08-2003, 07:39 AM
Funny you should say that. When I set the images to systemmemory = False I lose about 10 frames per second.

13-10-2003, 07:25 PM
I use UnDelphiX (which is mostly the same as DelphiX, but, as far as I recall, with optimized headers and little more) and my frame rate is mostly constant. It drops heavily if I do something wrong (like Sining and Cosing in every loop :> or just using DrawSub or DrawRotate which I definetly suggest not to use if there are any other possibilities - it slows down machine), but mostly its constant 75 (AMD 1600XP 256 DDRAM m/b 266 GF4Ti4200 Golden ed. 128 Mb 5400 HDD) in every resolution or colour setting (8, 16 bits). Its acctually rather weird, 'cuz other people with not so good video have 85 fps and more while others have 50 and less..once I had bug - it showed just 5 fps, then I reinstalled videodrivers and 75 were back again.
Again, I suggest you check your code for every Strech or Rotate Draws, because I have encountered a very notificable slow-down when using them. And your game sounds not so complicated to have frame-rate lower than blank DirectX mode screen. ( OK, two or three fps could be bearable.) Maybe re-think every part of code? Cant anywhere be done any optimizations?
And again - this all is just my damn opinion.

14-10-2003, 08:32 AM
Kamaz, it looks like your game encountered v-synch. In short, DirectX is waiting until a monitor refresh starts before drawing the next frame, so it can only run as quickly as the monitor refresh rate (in your case, 75Hz, i.e., 75 updates per second). Other people will have different monitor refresh rates, so their game runs differently but at consistent speed. Your game is probably capable of running at hundreds of frames per second, but it's just obeying the speed limit in a way ;).

I don't get why people worry about the FPS once it's over 60. Unless it hurts the physics (which it shouldn't) then anything above 60 is utterly playable. It's the discrepency between FPS (i.e., having it jump all over the place) that makes games seem jerky.

So anyway, look out for the following "magic" values: 60, 70, 72, 75, 85, 100, 120. These are typical monitor refresh rates. If your game gets one of those values as its FPS then you can disable v-synch (somewhere in the DelphiX options probably - have a look around, since I've never used DelphiX). Also, if your game only gets exactly half of one of the above values then you may also be affected by v-synch, but your game main loop is taking _slightly_ too long and you're only catching every other monitor refresh, hence half the rate. In either case, disabling v-synch will make your game run faster (but may introduce a visual artifact, "tearing", if you scroll quickly - but that's mostly in first person 3d games when turning).

Your frame rate probably dropped to ~5 FPS before as you undoubtedly use an nVidia chipset. Relatively recent nVidia drivers have screwed up DDraw performance for whatever reason - I waited a good few versions but they didn't seem to care enough to fix it. Hence, I'm with ATI now (and a happy customer, plug plug). You can temporarily fix that issue by rolling back to an older driver release (I can't remember when this issue first arose) or by disabling hardware acceleration in the DirectX/DDraw control panel (which is a bit of a rubbish solution). I don't know whether nVidia have un-screwed-up this screw-up of theirs yet.

To the OP: any translucency effects will be implemented on the CPU rather than hardware because DDraw doesn't provide for alpha-blending, unfortunately. This means that translucency is typically a _big_ speed hit compared to other stuff - scaling can be done on hardware (dunno if it is on DelphiX, but I'd be surprised if it wasn't), as can rotation (but, I believe, _only_ on hardware - no software support, so maybe DelphiX took a safe route and emulated it in software). The DrawRotateAlpha will almost certainly be implemented in software.

If you switch to a 2d-in-3d package then you'll get a big speed boost for rotation and alpha blending (a big, big, BIG speed boost). The trick, though, is finding one with the features of DelphiX.

It is probably possible to hand-optimise the alpha-blending functions inside DelphiX if you really wanted to (maybe to include MMX and such) - the question is, can you be bothered? If yes, then have a look at www.optimalcode.com for the fast alpha blending examples (dunno where - somewhere on that site, honest), or see if you can dig up Mike Lischke's alpha blending code in his virtual treeview (is that the one with source? Can't remember).

Keep in mind that reading from video memory is slooooooow with a capital "very". If you're manipulating surfaces by locking them and changing pixels (likely to be done for the alpha functions, and maybe the rotate ones - check the DelphiX source) then you want to use system memory. This means slower drawing-to-final-destination but much quicker pixel fiddling.

14-10-2003, 08:37 AM
What the hell happened to the optimalcode site?! :shock: Bloody domain squatters?! Trying going to http://www.archive.org and typing in http://www.optimalcode.com in there to find the alpha blending examples, if they're still around...

Sigh, another useful resources bites the dust. I'm tempted to contact the guy who ran that site (Robert Lee?) to find out what the heck happened.

14-10-2003, 09:00 AM
Gosh, thnx for the tip, Ali-Monster - now I feel like seeing/knowing the Highest Truth. Damn, of course it is so. Everything seems just understandable and clear now..