Re: GDI can be fast!



På Fri, 31 Mar 2006 03:00:50 +0200, skrev Donkey <contact_nospam_donkey@xxxxxxxxxxx>:

o//annabee wrote:
Hmm. Ok. On my card, the timings for 16 bit and 32 bit is identical.


Hi,

Just to make myself clear, the problem is selecting a 32 bit image into a 16 bit DC. Matching the resolution to the DC should present nearly identical results, i.e. 16 bit to 16 bit or 32 bit to 32 bit, however 32 to 16 should slow things down a bit as the color table has to be generated. Testing on my systems selecting and deselecting a 1024x1024 32 bit image with 1 meg colors (1st pixel = 000000, 2nd = 000001 etc..) resulted in a noticeable penalty for different color depths. For some reason my Athlon64 performed better than either the PIII or P4 even in 2 bit mode.

Hi Donkey.

I dont select a bitmap into a DC. I just Set the memory bits directly.
This is, _no_ selectobject calls. All drawing to system memory.
I allocate a buffer 1024*768x4 (32-bit) (because thats the resolution I use).
When I change windows color mode to 16 bit, (I use 32 by default), this has null impact on performance. I cant explain why, but there just arnt any here.

I have not tried on lower then 16 bit, as my card does not support it. I be testing all of this on older hardware later on.

At any rate this is an interesting discussion and I would like to continue it if Hutch and Betov can take their stupidity elsewhere. Do you have any test results with specific GDI API calls ?

As I said, I use only the following:

Window.OutputFromRect:
RectSize edx
mov eax ebx | add eax D$edx+Rect.Top

call 'gdi32.SetDIBitsToDevice' PaintDC ,
D$edx+Rect.Left D$edx+Rect.Top ecx, ebx,
D$edx+Rect.Left 0 0 eax,
D$BackBuffer.Memory BITMAPINFOHEADER &DIB_RGB_COLORS
ret

What this does, is it takes a portion of the backbuffer, and transfers those bytes to the final usual DC.

I havent made any real spesific tests yet. But belive me, that even big sprites move like butter.

I just did a small test. I use one sprite, that is 1024x768 pixels, this is placed on top of the background, which is a gray one, and has a caption, with a closebox, and a menu, with to menuitems, and a statusbar.

_When_ I test, all of this gets redrawn in FULL 300 times. This took 89B millseconds. That is 136 frames per second, for a full redraw of the following:

The FULL un-clipped background (filled gray)
3 times a 1024*18 pixel rectangle
pluss the FULLSCREEN bitmap, a spashbitmap, that is a screenshot of my scoreboard in batlefield. This is a sprite, and is drawn with transparency and code that performs complete clipping. Eg. I can wave it around the screen like it was an icon.

So indeed, this is more then 2 fullscreen rebuilts per single update. in full screen, under GDI. No directx or anything.

That is enough for making a 2d game. And it is enough that I can now in much less effort, create an amazingly potent GUI, because I can easily mix in 2D sprites and 3D elements when doing it this way. I can probaly even use the 3d render directly on the backbuffer, with some trickery.

very very fun!
:)))

Donkey
.