Skip to main content
GameDev.net gamedev.net
🔒 Locked

Speed

Started by Boops Feb 16, 2004 at 9:26 AM 12 replies 1.3k views
Original Post
Boops
Boops
I draw a map of 9*9 tiles of each 48*48 pixels (so the total map is 432*432 pixels) and it goes around 40 frames per second. I do it pixel by pixel, with SDL, and I optimized a loop that draws the color values from an array to the screen as good as possible... While any 3D game that has to do much more complex operations per pixel goes more than 100fps at much higher resolution!!!! What''s going wrong here (why is it so slow)?
matias suarez
matias suarez
for pixel handling is usually faster system memory than video memory if you work on a buffer and you blit the buffer to the video memory (front or back buffer)

Also if pixel by pixel means a function call per pixel you can save 186624 function calls and the same amount of stack creation/destruction per function call PER FRAME, in most cases you also save the same amount of bounds check since a function for setting an individual pixel does range check.
So... do your math

Simple solution: get a pointer to the front/back buffer and do it directly
Also do it in a 32 bits aligned words for getting the most.
It is also important the order in which you write the memory, i mean line by line of the screen is more performant than line by line od your 9x9 tile.

Assembler rocks!

-Mat
Endurion
Endurion
If you blit tiles, don''t do it pixel by pixel. Since you use SDL, why not use BlitSurface (or called similar). This function will use hw acceleration if possible and be a whole lot faster.
Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>
no_skill
no_skill
you could take a look at the simple gfx "engine" i use in SuperMarioWar (it uses SDL).

http://jnrdev.weed-crew.net/smw

download the source and take a look at
gfxSprite in gfx.h/.cpp

hope it helps.
Boops
Boops
quote:
Original post by Endurion
If you blit tiles, don''t do it pixel by pixel. Since you use SDL, why not use BlitSurface (or called similar). This function will use hw acceleration if possible and be a whole lot faster.



I''ve used this SDL function before, but for an unknown reason on some computers some people got an ugly effect where it would flicker all the time Also, it''s handier to do it pixel by pixel to make transparency effects, since SDL doesn''t support it, as far as I know at least.
TANSTAAFL
TANSTAAFL
SDL_SetColorKey(pSurface,SDL_SRCCOLORKEY,SDL_MapRGB(pSurface->format,255,0,255);
Get off my lawn!
peter_b
peter_b
Plotting pixels is slower that using the blitter. If you also try to read pixel colors, now that will be really slow. Dont quote me on this but i think that reading is 60 times slower that writing to the video memory. I figured maybe you was reading since you said you were doing transparency. If you mean "alpha" rather than bitmasking, than you are required to read from the videomemory in order to see what the pixelcolor is where you want to plot.


There is no fast way to do transparency and rotatoin etc in ddraw(sdl 2d), you have to use 3d hardware for that. sorry :/
Shields up! Rrrrred alert!
Fingers_
Fingers_
SDL has alphablending functions for 2d graphics. Read the documentation for SDL_SetAlpha. If you do per-pixel blending you should also make sure you're not using a hardware surface to do it (because of the slow read).

edit: as a side note... Various games had rotation/scaling and transparency before 3d hardware existed in the consumer market (-1996). Modern CPU's are on average 20+ times more powerful than they were back then. You can do *a lot* with that power.

[edited by - Fingers_ on February 17, 2004 7:25:40 PM]
Boops
Boops
I first draw to a buffer (an array in memory) and then when done put that buffer to screen.

quote:
Original post by Fingers_

edit: as a side note... Various games had rotation/scaling and transparency before 3d hardware existed in the consumer market (-1996). Modern CPU''s are on average 20+ times more powerful than they were back then. You can do *a lot* with that power.



Ok, but then, can someone, please, please, tell me how they do that?
It''s partially just out of curiosity, please answer this one:
Why does Tomb Raider 2 work fast on a pentium 133MHz in software rendering mode with an old 2D video card?
They have to do per pixel calculations, 3D calculations, AI calculations and more, and it works faster than my stupid 2D application on an athlon 1300MHz.
Is it purely the fact that they use assembly, or is there more going on?

Please answer! Thanks!
JTippetts
JTippetts
There are ways to optimize per-pixel blitting. Simply looping through an image and either drawing each pixel or not drawing it based on a conditional is not a fast way.

A lot of 2D apps before hardware acceleration would encode their image data as chunks or scanlines of visible pixels, using some sort of run-length encoding mechanism. Whole lines of visible pixels would be drawn using memcpy() or hand-coded assembly language copy routines. Such methods require a scan conversion of the image before it can be used, processing it into a list of chunks where each chunk is one sequential block of visible pixels.

One simple method I used back in my early days was a simple method to loop through the image and find these sequential blocks of pixels. For each block on a scan-line, I would record the offset from the beginning of the line of that block and the length in pixels of the row. Each block would be put in a bucket, one bucket per scanline, so that when the time came to draw I could simply loop through all the buckets, advancing the screen y coordinate for each bucket, then loop through the contents of the bucket, apply the chunk offsets to the x coordinate, then copy n number of pixels from the scanline buffer array to the screen.

The key to fairly fast 2D is to lock the screen surface and obtain a direct pointer to it, then use memory copy routines to churn out large chunks of pixels as fast as you can, rather than looping through and drawing one pixel at a time. Old software rasterizers used these same ideas, rasterizing triangles and quads one scanline at a time, using memcpy() to write whole chunks of pixels rather than one pixel at a time.

The simple fact of the matter is, hardware acceleration has made most of these techniques completely unnecessary. Sure, CPUs might be 20x faster, but that doesn''t mean quite so much when accessing the pipe between CPU and screen frame buffer. It also doesn''t mean much because average screen resolution has scaled with advances in card technology. Back in the software rasterization days, you saw a lot of games built for 320x240, 640x480, or at most 800x600 resolution. It was extremely difficult to do a 1024x768 game fast using software techniques. As far as resolutions over 1024x768: even if they were supported, they were usually SLOW. And that is still a large amount of data to process for the CPU in addition to AI and other game-related tasks. And it is wasteful to handle it, when you have a full, dedicated processor sitting idle somewhere that could handle it far better.

Why not allow all that expensive player hardware to do its job of drawing the graphics for you, rather than sacrificing convenience and performance to try to do it by hand? Unless it is for the learning exercise, in which case more power to you. But I can think of few situations on the PC that would warrant doing everything on the CPU. (Handhelds are a different story.)

If you are getting flickering, even with double-buffering, using SDL''s 2D drawing/blitting methods you could try switching to a system using 3D API calls (OpenGL for SDL) to draw the 2D graphics. A lot of modern hardware is optimized for 3D, and so might perform better using the 3D calls than the legacy 2D stuff.

Also, make sure the double buffer you are drawing to is created by SDL in video memory, rather than just an array in system memory created by yourself*. The pipeline between system and video is still relatively slow on some cards, and so it may take more than a single refresh cycle to draw the entire array from system memory to screen, causing the flicker. If the double buffer is in video memory and flipped using the appropriate calls, the page flipping is performed very quickly and very efficiently as video memory to video memory moves, which avoids the extremely slow pipeline and reduces the flicker. A further source of flicker may possibly come from running in a window as opposed to running full screen if you are doing so.

(*Note: As a previous poster mentioned, reading from a hardware buffer is very slow. So don''t rely on reading from this double buffer, or else performance will go into the toilet again.)

2D can be done very quickly in software, but it won''t ever be as fast as the acceleration provided by modern hardware. While it can be interesting for a learning exercise, for most games it would be best to take advantage of acceleration when it comes time to draw to the screen. Just my opinion.


Golem
Blender--The Gimp--Python--Lua--SDL
Nethack--Crawl--ADOM--Angband--Dungeondweller
EDI
EDI
Well stated VertexNormal =)

OP:
in my oppinion you should ask yourself these questions

Is what I am making (a game perhaps) meant to be a serious project?

Yes:
Then i should use the best tool for the job, a tool that will fulfill the needs of my project and is commonly compatable for my target platform/audience.

In my oppinion, and from my experience with such, i belive these are the best ''tools'':

if your making a game where you only need image scaling and color keying, then use 2D Hardware accelleration, if you need more control/effects, like alpha blending, modulation and rotation/shearing then use 3D Hardware accelleration


No:
then it doesnt matter what i use (pixel plotting or hardware blting) since it is not serious

hope that helps=)

Raymond Jacobs,

www.EDIGames.com

www.EtherealDarkness.com

Boops
Boops
quote:
Original post by TANSTAAFL
SDL_SetColorKey(pSurface,SDL_SRCCOLORKEY,SDL_MapRGB(pSurface->format,255,0,255);


This is for invisible with a color key you mean?
What I want is partial translucency :/
TANSTAAFL
TANSTAAFL
oh.

then use SDL.
Get off my lawn!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.