![]() |
|
This thread is locked; no one can reply to it.
![]() ![]() |
1
2
|
Game runs slow on slower computers |
konedima
Member #6,241
September 2005
|
I know the title sounds obvious, but just read. My game runs fine on my computer (Athlon 64 3000+/1GB RAM/GF7600GT) but not on an old computer I have lying around (an old Celeron 850mhz/256mb/integrated graphics dog). Obviously games shouldn't work as well on that, but my game is just 2d graphics with not too much happening on screen at any one time (during gameplay it's only 7-17 sprites being double buffered), so maybe someone could look over my code and tell me if I've done anything particuarly wrong (since this is my first game in C++/Allegro, I'm not exactly too sure on everything. My game is War Pong HD, the homepage is http://warpong.sourceforge.net. The source code is available there. War Pong HD! Every time you don't download it, a kitten of hope dies in my heart. Please, save the imaginary kittens. |
Kris Asick
Member #1,424
July 2001
|
set_color_depth(32); if (set_gfx_mode(GFX_AUTODETECT_FULLSCREEN,1024,768,0,0)!=0) { There's the cause of your slowdowns right there. Switching to 16-bit colour will almost double the framerate. Switching to 8-bit if you can will double it again. (Provided you don't make too many calls to makecol().) Also, 1024x768 is a very high resolution to be doing non-accelerated doubled-buffered graphics at. It may only be 2D, but if it's the CPU that has to handle the drawing then an over 2 GHz difference in processor speed is going to have a big effect on gameplay. If you've ever played Mechwarrior II back in the days of DOS you would know that it had a 1024x768 mode. Even on a 600 Mhz computer I once tried that on it only ran at a framerate of about 8. Without hardware acceleration you need to be careful how much data you're trying to push at any one time. 32-bit colour, 1024x768, and double buffered graphics all together are going to kill the framerate on older computers. --- Kris Asick (Gemini) --- Kris Asick (Gemini) |
Richard Phipps
Member #1,632
November 2001
![]() |
For a non-scrolling pong game use a Dirty Rectangle system for a big speedup and still run at 1024 x 768 in 32 bit colour. |
James Stanley
Member #7,275
May 2006
![]() |
Quote: an old Celeron 850mhz/256mb/integrated graphics dog
Dog? |
konedima
Member #6,241
September 2005
|
Kris: I seem to recall I was having some problems with 16 bit colour, but if I recall, it was a problem I've long since fixed but not changed back. Richard: WTF is dirty rectangle? James: How many computers do you have? War Pong HD! Every time you don't download it, a kitten of hope dies in my heart. Please, save the imaginary kittens. |
spellcaster
Member #1,493
September 2001
![]() |
A dirty rectangle system only updates rects on the screen that have changed since the last update. So, instead of updating the complete screen, you'd only update small parts of it. -- |
konedima
Member #6,241
September 2005
|
Most of the screen is actively being changed (what with bullets flying around and such), so dirty rectangle is probably out of the question. Still, could someone please provide either an example or a link to one so I can keep it in mind for the future? War Pong HD! Every time you don't download it, a kitten of hope dies in my heart. Please, save the imaginary kittens. |
james_lohr
Member #1,947
February 2002
|
Quote: Most of the screen is actively being changed (what with bullets flying around and such), so dirty rectangle is probably out of the question. I doubt it. Unless they are extremely large bullets, or there are hundreds of them, you'll still benifit hugely by using dirty rectangles. Suppose you've got 20 bullets each of size 32x32: 32x32*20 / 1024x768 = 3% of the screen. However there are few things more boring than a game with a static non-scrolling background.
|
konedima
Member #6,241
September 2005
|
Alright, maybe dirty rectangle would help (most bullets is 10, 8x8, equals an inconprehisibly small percentage). Still, that's not telling me how to do it. Secondly, what's wrong with a nice static background? I don't want to detract from the main action. Also I was able to fix my 16 bit graphics issue (which I mentioned at the top of the thread and extensively in http://www.allegro.cc/forums/thread/589766 - read that if you don't know what I'm talking about). To put it bluntly, it wasn't displaying my 16 bit bitmaps at 16 bit colour, but if either of them was another bit depth it would work. I'm now using PNGs, and when I set it 16 bit colour, it wasn't displaying my nice PNGs (which surprised me, because they're 24 bit). It's fixed though: the problem was my double buffering. I was using:buffer = create_bitmap(1024,768); which didn't work. I change it to:buffer = create_bitmap_ex(16,1024,768); and it magically works. War Pong HD! Every time you don't download it, a kitten of hope dies in my heart. Please, save the imaginary kittens. |
Richard Phipps
Member #1,632
November 2001
![]() |
There are different types of Dirty Rectangle Systems, the Allegro demo uses one as an option too. I think I even posted a simple one on this forums some years ago. Do a search on these forums and I'm sure you'll find plenty of info.. |
spellcaster
Member #1,493
September 2001
![]() |
Another, but not so popular method would be to actually think about the concept. Then you could show us how you'd implement it and we might be able to learn something from you. A DRS is really pretty simple. Keep a list of all areas that need to be updated and update only these areas instead of the whole screen. -- |
Jonatan Hedborg
Member #4,886
July 2004
![]() |
Of course, optimizing these areas (merging to reduce overdraw / function calls) etc is non-trivial, but also not really vital (profile!)
|
BAF
Member #2,981
December 2002
![]() |
Quote:
Dog?
That just means your laptop, your brothers laptop, and two of your computers suck then. |
Kris Asick
Member #1,424
July 2001
|
The simplest way to implement dirty rectangles for your game would probably be: 1. Eliminate the buffer. Do all drawing directly to the screen. (This will mean that all drawing to the screen has to be done at once between an acquire_screen() and release_screen() pair unless you store everything into video bitmaps. (Which would be faster but has an added complication of having to restore all video bitmaps if there's a task switch.)) 2. All sprites must store their previous positions from the last frame. This is because you only ever redraw sprites which have moved. (Or animated.) 3. You never clear the screen. You simply clear any area you're about to draw to. (IE: If you're about to draw a paddle in a new position, you blit the section of the background the paddle was previously over to the screen, then blit the new position of the paddle immediately afterwards.) For instance, for drawing any sprite you would have the following mock code: blit(bg_bitmap,screen,sprite.prev_x,sprite.prev_y,sprite.prev_x,sprite.prev_y,sprite.h,sprite.w); draw_sprite(screen,sprite.bitmap,sprite.x,sprite.y); You could probably convert that into a special function to make such drawing simpler. The buffer is the big performance hit with the screen resolution and colour depth you're using. Eliminating it eliminates not one but TWO full-screen blits every frame. That's a lot of CPU power you're getting back! --- Kris Asick (Gemini) --- Kris Asick (Gemini) |
konedima
Member #6,241
September 2005
|
The problem with not double buffering is that the graphics flicker horribly, and double buffering is the best way I know of to fix it. At least I looking through my code I found an unnecessary clear running on the buffer (unnecessary because I draw the background each frame anyway). Also, I'm just not following you on the dirty rectangles code you put there. Could you please simplify it a bit? War Pong HD! Every time you don't download it, a kitten of hope dies in my heart. Please, save the imaginary kittens. |
spellcaster
Member #1,493
September 2001
![]() |
Ok, we simplify. You have double buffer keeping list of changed regions helps Nah, but seriously: All you do is instead of blitting the complete buffer, you only blit changed parts of the buffer. Since this will be even faster than blitting the complete buffer, you get all benefits without drawbacks. If you don't want to keep a list, try this (it's not quite as good, but should be easy to implement): Your screen is 1024x768 Whenever you draw something mark the quad you're drawing in as "dirty". This way you can keep a simple array to keep track of the dirty parts. Another option: -- |
BAF
Member #2,981
December 2002
![]() |
Quote: Eliminating it eliminates not one but TWO full-screen blits every frame. How does it remove two full-screen blits? |
spellcaster
Member #1,493
September 2001
![]() |
Because both the backbuffer and the screen will only be updated as needed. with the DRS he'll be updating only what's needed. -- |
BAF
Member #2,981
December 2002
![]() |
Blitting the buffer to the screen is only one full-screen blit though. |
konedima
Member #6,241
September 2005
|
For some reason your explanation made me blissfully more aware. I just fear that it could get complicated with the logo and scores (just use ifs to determine if a part I need to redraw lies in one of those areas, right?). Anyway, I did figure out how to dirty rectangle the paddles (as long as it's acceptable practice that it redraws the whole column, not just around where the paddle actually is). War Pong HD! Every time you don't download it, a kitten of hope dies in my heart. Please, save the imaginary kittens. |
Jonatan Hedborg
Member #4,886
July 2004
![]() |
Does it make the gameplay acceptable? First "clear" all the areas that objects were at last frame by blitting the background image over them, then draw the objects at their current positions.
|
konedima
Member #6,241
September 2005
|
I don't need to track the previous positions of the objects (at least, I don't think I need to). Everything except the ball moves at a constant rate (and the ball has variables to track its speed), so I can just calculate the previous position. War Pong HD! Every time you don't download it, a kitten of hope dies in my heart. Please, save the imaginary kittens. |
Kris Asick
Member #1,424
July 2001
|
Quote: I don't need to track the previous positions of the objects (at least, I don't think I need to). Everything except the ball moves at a constant rate (and the ball has variables to track its speed), so I can just calculate the previous position. Something you're going to learn about programming: The more memory you use, the faster things go. IE: When given the choice between making new variables to track something and calculating it every frame, make the new variables to save yourself the CPU time of recalculating. The reason for tracking previous coordinates with the method I described is because you only want to redraw things that have moved since the last frame. If it doesn't move, you don't redraw it, because that's what makes it flicker without a buffer. The method I've described is actually used in a lot of much older games. Back before the 386 processor was invented redrawing the entire screen each frame could take forever. (This is why side scrollers weren't common, or would only scroll fixed amounts when reaching the edge of the screen.) Plus, it would take a lot of memory to store a buffer, and without extended memory every byte made a difference! --- Kris Asick (Gemini) --- Kris Asick (Gemini) |
spellcaster
Member #1,493
September 2001
![]() |
Quote: Blitting the buffer to the screen is only one full-screen blit though. Yep. And blitting the fullscreen bgImage to the backbuffer is the 2nd. (Well, actually it's the first, and bliting the backbuffer is the 2nd). -- |
Richard Phipps
Member #1,632
November 2001
![]() |
From my experience, if you use a Dirty Rectangle System for a breakout game you can have smooth 60 fps action at 1280 x 960 in 32 bit colour on a PII 300mhz PC. |
|
1
2
|