Archived

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

suliman

bitblt way to slow! any idées on how to update screen?

Recommended Posts

Hi Im updating 800*600 pixels 32bits using windows bitblt. On any machine under 1.6GHz AMD, geforce 2 MX, the application cannot run without lag. Just the update consumes all CPU (I draw using CPU). The game is in 30FPS and contains no 3d /(thats way of my competence at the moment). Is there no way to do this faster? Do you really need such a fast computer just for blitting or am I just doing this badly? Whould be greatful for any suggestions.

Share this post


Link to post
Share on other sites
Are you talking about directx or something similar? What I do at the moment is drawing to memory and once every tick this memory gets "sent to the screen" updating the entire 800*600.

If I flip, wont I have difficulties accessing colordata already on the screen for multiply/add effects? My friend said something about that but i didnt quite get it...

Share this post


Link to post
Share on other sites
As a rule of thumb, blitting 2D graphics can quickly chew up the CPU because there''s little to no hardware acceleration you can take advantage of. Transluscy or other effects WILL kill your performance so fast your head''ll spin. It''s pretty sad but true: if you use a 2D API, you''ll have worse results than if you use a 3D API because you''re doing this in the software. Here are a few hints though.

1- "Precompile" everything, graphic-wise. If you have text windows à-la RPG and they''re all the same size, store an image of the whole window instead of the corners and sides to "build" it every frame. It takes more juice to draw a bunch of small images than it does to draw just one big images because of all the unecessary calls to your blitting function.

2- In SDL, make sure all of your surfaces are compatible with the display surface. Converting from 8bpp to 32bpp can cause one heck of a performance hit, especially if pretty much all of your resources are the wrong format.

3- Stay away from special effects unless you need them. It may be cool to have that fullscreen fireball spell go transluscent but your performance will be crap.

4- Try to avoid overdrawing. DirectDraw has some sort of reverse colorkeying function where you can blit only to a specified color (as opposed to blitting only from a color different from the specified one; color-keying). That aside, some careful planning can help avoid or reduce this.

5- Graphics may not be your bottleneck. Your algorithm may be a problem too. In an older project in VB, I used to draw a 3-layer tilebased map by looping through my map data and blitting the right tile. This meant I was also blitting a fully transparent tile for every place on my map where there wasn''t a tile. Adding a simple "if MapData(x,y,layer) then..." to my code dramatically sped things up.

6- Switch to a 3D API. OpenGL is very easy to use and can take as little as a weekend to set up and use for 2D. DirectX may take a little more effort, but is more flexible. I sugget OpenGL since the added flexibility is mainly towards 3D stuff. You''ll be able to use hardware acceleration fully then and it''ll run fast enough to be decent even on my PIII 650. ;P

Share this post


Link to post
Share on other sites
You should be getting better than 30fps, I would think. Have you tried using DrawDibSection() instead of BitBlt()?

Ultimately I would think this is limited by the speed of the AGP rather than your CPU speed.

Share this post


Link to post
Share on other sites
DrawDibSection seemes to not be included in win32 API. I found one reference when searching google, but that fuction called BitBlt.

So now im lost.

Share this post


Link to post
Share on other sites
Bitblt calls and windows graphical api are just naturally slow. On any machine the calls take awhile especially if there's a whole lot of them. Switch to a graphics api like DirectX or OpenGL and you'll see a massive speed increase.

"Life is a double edged sword, we always hope to strike though adversity with the shining side..."

jkettles16 of Venosoft

[edited by - jkettles16 on May 21, 2004 9:22:06 AM]

Share this post


Link to post
Share on other sites
Aaaargh, sorry, my bad. The API you want is not DrawDIBSection(), but StretchDIBits(). It''s standard Windows API, and according to this article on Animation in Win32 that I just found, it''s implemented in the video driver rather than through umpteen layers of virtual this and device-independant that.

Share this post


Link to post
Share on other sites
I did something like this before too..and I had no problems with windows bitblt..what i did..is...
HDC backbuffer;
HDC theScreen;

then every tick I would draw everything to the backbuffer..then with just *1* Bit block transfer..copy backbuffer to theScreen, and I could even make smooth animation and all...worked great..If your already doing this, there must be some calculations or something that are eating up your cpu resources

Share this post


Link to post
Share on other sites
kag1, how complex was your game, graphic-wise? Blitting to an offscreen surface and then back to the screen would be slower than blitting directly to the screen because you''d throw in an extra full-screen blit (you would acheive double buffering though). Your game probably wasn''t pushing the GDI far enough to be noticeable on your system.

Share this post


Link to post
Share on other sites
no, my game was not a graphics pusher i suppose

what it was, was a map of 15x15 32x32 tiles.. every frame I would bitblt them all to the screen, so a total of 225 different bitblts, without my backbuffer (even if it was poorly implemented) it would flicker all the time, but with it, i had a nice 30fps little tile game

Share this post


Link to post
Share on other sites
Why don''t you just redraw the tiles which have had something move off of them? You might have to do a bit of rewriting in your code, but I''m sure it will be worth it, speed-wise.

Share this post


Link to post
Share on other sites
quote:
Original post by kag1
no, my game was not a graphics pusher i suppose

what it was, was a map of 15x15 32x32 tiles.. every frame I would bitblt them all to the screen, so a total of 225 different bitblts, without my backbuffer (even if it was poorly implemented) it would flicker all the time, but with it, i had a nice 30fps little tile game


Frankly, that isn''t much.

Now, picture a parallaxed background, two tile layers (with, of course, color-keying to enable the background and the first layer to show through), and a sprite layer, with a 35x25 set of 16x16 tiles.

Really, if you have a single layer of tiles with no background nor foreground and only acheive 30 FPS, you can''t consider that very speedy. That''s the whole point: the same program in OpenGL or Direct3D could easily hit a few hundred FPS.

Share this post


Link to post
Share on other sites