Speed issues

Started by
15 comments, last by d_prodigy 22 years, 9 months ago
Im developing an isometric tile engine for an RTS game and it runs terribly slow(Spec: 200MHz, 64MB, 2MB VRAM). I dont expect it to run very fast with my crappy video-card but when i run other RTS games like Age of Empires II the speed is perfectly accebtable. I have clocked different parts of the program and located the problem to the Blt-function: lpddsMapView->Blt(&rMapCoords[x][y],lpddsBasicTileSet[iTileNr], NULL, DDBLT_WAIT | DDBLT_KEYSRC, NULL); This function is repeated x*y times and stores the part of the map that will be seen onscreen. Then it is blitted to the backbuffert(this reduces the number of blitts heavily when the user doesnt scroll much). Is there any other(faster) way to do this? The source codes ive looked at all use a variant of this method(and BltFast). Thanks in advance.
Advertisement
Hello,



1. Try not to draw anything that is not on screen, even running a plain loop with nothing inside 10k times every frame will slow down your program considerably

2. As Blt() does resizing automatically, make sure that source and target rectangles are exactly the same size, because resizing the picture will cause a big slowdown.

3. Try to put all bitmaps in video or all bitmaps in system memory



asd_de
For comparison, you might want to try BMDXCtls. It''s a 2-D DirectDraw tile engine written in VC++. I know this runs acceptably fast on many computers, so you can see how fast your code runs compared to this. It''s open source and is available as part of The Scrolling Game Development Kit. To download just the BMDXCtls source code, you''ll want to visit the File List.

Of course since it''s open source, you could also change it and see what effect certain changes have, and see how it works. I did use BltFast in this engine.

If you need a program that *uses* the tile engine (and can''t make a test program for it in VB or something, using the included help file), just download the Scrolling Game Development Kit itself. It installs BMDXCtls.dll as part of its install (it will un-install it during the un-install also). Anything that switches to full screen mode uses BMDXCtls. It also appears that the sample "Maze" game is still available out there at http://members.nbci.com/win32realm/codecity/directx/bmdxctls/ if you want a smaller sample program that uses BMDXCtls.

"All you need to do to learn circular logic is learn circular logic"
"All you need to do to learn circular logic is learn circular logic"
You might want to go with a dirty rectangle scheme,which will eliminate redundtant overdraw of unchanged areas. It was nessecary for any type of 2d game back when cards were alot more limited. However it has fallen out of favor, as of late. Basically you somehow much keep a record of changes to the screen. Of course if the screen is scrolling you will have to blt the whole thing, however if you noticed games like AOE the screen isnt scrolling most of the time. It''s usually fixed. So a simple method divide up the 2ndry buffer into an evenly grided rectangle. When you blt to this 2nd buffer mark down the rectangles which have been touched by the blt rect. Do this for all the blts. Once done coallate the dirty rectangles if need be, that is try to elminiate multiple blt overheads of many small areas if you can group them without too much redundancy. Once that''s done blt those rects which only have changed to screen. You should get about 2x speed increase using this system, as most of the screen isn''t changing, also as you increase resolution the benifits become even greater as amount of info you have to pass using a single fullscreen blt increases faster than the blt overhead of the diry rect system, which stays pretty much constant.

Good Luck

-ddn
As i was reading your post again it seems that you might be redrawing the entire screen irrespective of any changes to the buffer. The dirty rectangle method will still work for you but you''ll have to add an addition to it.

You''ll need to implement a history buffer for each of the rects and run through the blt cycle 2 times. The first is to collect a blt history for each rect (dont draw anything on this cycle). Compare that to the old blt history if they are the same, nothing has change and avoid blting any tiles into that area. For those rects which have change queue up all unique blts and blt them in order (this is where you actually draw stuff to the 2ndary buffer). Then draw the dirty rects. This should get you savings on the tile by tile blts as well as the 2ndary to screen blts.

Good Luck

-ddn
Don''t use blt. Use bltfast and do your own clipping.

That should speed it up considerably.

Ben
http://therabbithole.redback.inficad.com
KalvinB - That''s not always the case. On my machine, I ran a test using blt vs. bltfast. BltFast showed a loss of 3~4 fps for large numbers of blits.
Yep, blt is the big bottleneck.

Worst of all this function seems to be at the mercy of the vid driver''s particular fancy ... let me explain a bit more to make myself clearer.

I wrote an iso engine in ddraw using blt, thinking that things were cool since I was getting *ok* fps on my system which is fairly modest (PII-350/Diamond viper 550) assuming the majority of other setups would run my app better. I did a few driver switches and found my app could lose a lot of ground, my frame rate halved sometimes. Then I ran tests on 10 or so other boxes all better than mine. I got frame rates ranging from *1* frame a second up to more than *40* fps, running the same .exe

IMO - If you want smooth scrolling at 600 * 480 * 8 or above *don''t* use blt - in fact I''d even go so far as to say avoid 2d, cards/drivers just don''t want to know about it.

KalvinB : The advice to use bltfast and clip yourself, the same advice you gave me. What exactly are you suggesting ? On the fly creation of custom surfaces ? On the fly data manipulation of existing surfaces ?

El Duderino
Thanks for all the help.

As long as I dont scroll I now have an acceptable speed.
But as soon as I scroll, the entire buffer must be re-blitted.
This takes more than 500ms and practically makes it unscrollable.

Anyone know how to effectively do this(scroll)?
By the way, I dont use "smooth scrolling". I scroll tile by tile to keep up the speed(in vain obviously :-).

asd_de: You say I should either put everything in the video-memory or the system-memory, why? I dont have enough VRAM to hold more than one of the surfaces, should I explicitly put it in systemmemory? Does that give better performance?
One way you might want to think about is - use bltfast and cover up the frayed tile edges with a frame. This way you don''t need clipping and can use bltfast. Might be significantly faster (probably will be). This method obviously looks better if you have smaller size tiles. Or if you have larger tiles maybe cover the frayed edges with other parts of the gui.

Yeah it sounds like a pissweak cop-out but done tastefully it can look ok. This is ok for tile by tile scrolling but for smooth scrolling it won''t work.

El Duderino

This topic is closed to new replies.

Advertisement