Archived

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

keethrus

custom graphics functions too slow

Recommended Posts

hello, im looking to speed up my custom graphic functions. i know you can use hardware to speed up some generic graphic things like polygon drawing, but im just creating a 2D game and i still want to know how to speed up my gfx functions regardless. right now im using simple "for" loops to draw something to the screen, like so:
      
Sint32 *imgdata; // assume this already has image pixel data


Sint32 *screenptr // assume this already points to the screen


for ( Sint32 y = starty; y < imgheight; y++ )
{
	for ( Sint32 x = startx; x < imgwidth; x++ )
	{
		screenptr[ y * screenwidth + x ] = imgdata++;
	}
}
      
i know one optimization could be to take the "y * screenwidth + x" outside of the inner for loop, but even optimizations like that leave the program too slow. should i drop down to assembly language, use a memcpy? any suggestions? also, my functions to draw images alpha-blended to the background are even more slow. how can i make my custom graphics functions faster? - jeremiah inlovewithGod.com [edited by - keethrus on May 6, 2003 10:26:33 AM] [edited by - keethrus on May 6, 2003 10:28:17 AM]

Share this post


Link to post
Share on other sites
Here's a suggestion:


    
Sint32* imgptr;
Sint32* screenptr

for (Sint32 y = 0; y < imgheight; y++ ){
memcpy(screenptr, imgptr, imgwidth);
screenptr += screenwidth;
imgdata += imgwidth;
}



This will copy the whole image, without clipping. You might want to add some clipping code to adjust the starting pointers and the width/height of the image, because blitting functions are liable to mess up memory when you give them nonsense-parameters, or even blit half-outside of the screen.

[edited by - marijnh on May 6, 2003 11:54:35 AM]

Share this post


Link to post
Share on other sites
Or use hardware acceleration

--------------------------------

"I''m a half time coder, full time Britney Spears addict"
Targhan

Share this post


Link to post
Share on other sites
Yah, i forgot that, using openGL or directX will beat your own routines for speed most of the time, and these days you can do all kinds of fancy things with them so you do not really need your own blitting routine.
Of course, i think it is a good thing to do something all by yourself once before switching to a library, so you know what is going on behind the scenes.

Marijn

Share this post


Link to post
Share on other sites
quote:
Original post by marijnh
Of course, i think it is a good thing to do something all by yourself once before switching to a library, so you know what is going on behind the scenes.



Well, I certainly wouldn''t want discourage you from playing with software blitting etc., but behind the scenes of mainstream modern graphics (as in D3D/OpenGL polygon rendering) there isn''t much that resembles moving pixels in neat little rectangles. And the market for GBA developers is, ahem, overcrowded, to put it mildly.

Life''s too short to live yourself through the entire 20-30 years of computer graphics development (the ontogenesis/philogenesis thing). For a behind the scenes point of view, I''d suggest AT LEAST something like the Quake1 sources.

Share this post


Link to post
Share on other sites

thanx for the replies. i understand that nowadays games are hardly 2D anymore. however, the game im developing is a top-down 2D game, where the focus isnt 3D graphics. i know i could still use hardware to make my graphics faster, 2D or not, but im still curious as to how to speed up my own custom graphics functions, even if its soley for learning purposes.

memcpy can help, but not if you want to do anything with an alpha channel. the only way i can think of speeding up my graphics routines is to drop down to assembly level. handling an alpha channel on a per-pixel basis in higher-level C/C++ just isnt going to cut it. i may indeed end up using opengl for graphics routines and directx to handle hardware acceleration, but for now im simply curious as to ways to speed my custom graphics functions up.

any more suggestions?

- jeremiah

inlovewithGod.com

Share this post


Link to post
Share on other sites
Well, you can download the trial version of Intel's C++ compiler and play with its vectorization capabilities - it should be able to generate reasonable SIMD (MMX/SSE/SSE2) alpha blending code if you write the C loops just right.

And, by the way, when you start implementing the alphablending stuff, don't listen to the "code optimization" tutorials from the 386 days - e.g. avoid table lookups like hell. Nowadays you can do many multiplies for the price of one (out-of-cache) memory access.

Basically, look for "x86 code optimization" on Google. There is a good site by somebody called Paul Hsieh, I think it was something like azillionmonkeys.com

[edited by - assen on May 6, 2003 1:49:00 PM]

Share this post


Link to post
Share on other sites
A few suggestions:

As already mentioned by marijnh: Instead of ( y * width), keep a y pointer, and just +=width to it after each scan line.

If you want to clip your copies:
figure out how long each horizontal ''span'' is, and using the above y+=width method, do one memcpy per horizontal span.

ie: memcpy (img.dst+dst, img.src+yOff+startX, endX-startX * bytesPerPixel);

This should be a bit faster.

Define your main image buffer as a global variable. Copy it to the screen/BM when you are ready.

If you are using the Windows GDI you''ll have to remember that it is quite slow to draw to the screen. Even if your code is lightning fast, you''re screen updates wont be.

I''m not sure why you need a speed boost though. Is your app sluggish, or are you just curious? I''ve done tons of graphics using windows (BitBlt with my own bitmap classes) and I''ve never had a speed issue that wasn''t easily accounted for.

As far as learning 2D (and 3D) from scratch: GO FOR IT. It''s worth the effort.

Good luck,
Will

Share this post


Link to post
Share on other sites
quote:
quote from RPGeezus
I''m not sure why you need a speed boost though. Is your app sluggish, or are you just curious? I''ve done tons of graphics using windows (BitBlt with my own bitmap classes) and I''ve never had a speed issue that wasn''t easily accounted for.



well, in my current implementation (im programming with SDL in fullscreen) my fps is lower than i expect: 50 fps with a fullscreen single-color rectangle and a couple other images on the screen.

quote:
quote from RPGeezus
As far as learning 2D (and 3D) from scratch: GO FOR IT. It''s worth the effort.



thanx for the encouragement!

- jeremiah

inlovewithGod.com

Share this post


Link to post
Share on other sites
For the fastest software rendering you will need assembly. MMX can speed up most color operations by a factor of four or more. I can also advice to use DirectDraw or another library that gives you direct access to the frame buffer.

And it''s definitely true that learning things from scratch is worth it. My last project is a real-time Pixel Shader 2.0 emulator using soft-wiring technology: swShader.

Share this post


Link to post
Share on other sites
Make sure your back buffer is in system memory not video memory, even if you do that you probably shouldn''t be getting more then about 50 fps but its probably not your bliting routine thats slowing it down.

Bliting is probably like less then 5% of the time its taking per frame. Updating the front buffer is what is likely to be using the majority of your time at this state in your engine because access video memory is extremely slow, and to update the front buffer software the cpu has to copy the whole screen from system memory to video memory.

And if your wondering it would be even slower to have the backbuffer in video memory cause then all your blit routines would would have to access video memory, and thats worse.

The memcpy blit is probably the fastest your going to get (you might be able to shave a few cycles off the outer loop if you wrote it in asm but entirely not worth it). But if you wanna do fancier blits (like alpha blending, or colorkeying) you should do the blit in the same way only replace memcpy with your own function thats written in asm, that way when writing those pain in the ass asm functions you only have to deal with one line at a time at let C handle the rest. Atleast thats the way I did it in the past but I was working on a 200mhz proccessor.

Share this post


Link to post
Share on other sites
quote:
Original post by keethrus

thanx for the replies. i understand that nowadays games are hardly 2D anymore. however, the game im developing is a top-down 2D game, where the focus isnt 3D graphics.[...]
I think you are misunderstanding the point: Poeple aren''t suggesting you make your game 3D, they are suggesting you use a graphics library that takes advantage of hardware acceleration. Direct3D and OpenGL can both be used to make 2D programs, but using them you will get all kinds of neat features for ''free'', like alpha blending. Such effects in software are relatively slow, but in hardware they are extremely fast and don''t take CPU time you can use to do other things (like AI, procedural texture generation, running scripts to make a more intractive game, etc)

[edited by - Big Brother on January 1, 1984 12:00:00 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Extrarius
I think you are misunderstanding the point: Poeple aren't suggesting you make your game 3D, they are suggesting you use a graphics library that takes advantage of hardware acceleration. Direct3D and OpenGL can both be used to make 2D programs, but using them you will get all kinds of neat features for 'free', like alpha blending. Such effects in software are relatively slow, but in hardware they are extremely fast and don't take CPU time you can use to do other things (like AI, procedural texture generation, running scripts to make a more intractive game, etc)



i know, i already acknowledged that.

quote:
Original post by keethrus
i know i could still use hardware to make my graphics faster, 2D or not, but im still curious as to how to speed up my own custom graphics functions, even if its soley for learning purposes.



- jeremiah

inlovewithGod.com

[edited by - keethrus on May 6, 2003 4:03:57 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by RPGeezus
If you are using the Windows GDI you'll have to remember that it is quite slow to draw to the screen. Even if your code is lightning fast, you're screen updates wont be.



The slowness of GDI has been greatly exaggarated. We published a 2D game drawing in resolutions from 1024x768 to 1600x1200 with completely reasonable framerates using nothing but SetDIBitsToDevice. Would it be faster with DirectDraw? Probably. Would this make the game better? Probably not.

[edited by - assen on May 7, 2003 11:43:05 AM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Make sure you''re not compiling in Debug mode (assuming MSVC).
Switching to Release will usually give you about 3-10x speedup

Share this post


Link to post
Share on other sites
i just wanted to say thanx for all the replies!

ap: im using mingw as my compiler, so ill have to check if it has any debug or release modes and see what im doing. thanx.

- jeremiah

inlovewithGod.com

Share this post


Link to post
Share on other sites
quote:
Original post by assen
The slowness of GDI has been greatly exaggarated. We published a 2D game drawing in resolutions from 1024x768 to 1600x1200 with completely reasonable framerates using nothing but DrawDIBitsToDevice. Would it be faster with DirectDraw? Probably. Would this make the game better? Probably not.


Good point-- I don't want to give the impression that GDI is so slow it's unuseable. As mentioned earlier, I've never had a speed issue with it that couldn't be attributed to something else. It's just not as fast as Direct Draw or the other direct access options..

I'm not familiar with the DrawDIBitsToDevice call. I searched MSDN for it and came up empty. Is this something you've written in house?

Could you post a URL to your game?

Cheers,
Will

[edited by - RPGeezus on May 7, 2003 10:37:50 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by RPGeezus
I''m not familiar with the DrawDIBitsToDevice call. I searched MSDN for it and came up empty. Is this something you''ve written in house?



No, it''s something I quoted from memory :-)
It''s SetDIBitsToDevice, of course.

quote:

Could you post a URL to your game?



http://www.haemimontgames.com/celtickings/index.html
http://www.gamerankings.com/htmlpages2/22353.asp

Share this post


Link to post
Share on other sites