GDI+ 1.0 vs GDI+ 1.1

Yes, I knew that BitBlt was faster but I was talking about DrawImageUnscaled and the TextureBrush being the same speed probably.
 
I ran my own tests and confirmed what wyrd is seeing. I draw roughly 330 32x32 rectangles with DrawImage and I only get about 30 FPS. I create the Graphics object outside of the main loop. Inside the loop I do a few small calculations (maybe 4 multiplications) and use a double loop to call DrawImage.

I only call DoEvents once a second (after the FPS is calculated) to minimize extra time.

If you make the form bigger, it slows down even more.

My machine is a P4 1.69 Ghz with 1.5 gig memory and a Radeon 9500 Pro (rocks!). I havent tried using BitBlt in C# yet, but I know that in VB6 days Id get something crazy like 300 or 400 FPS.

Ive attached the TEST project. Dont flame me on the code, only took 1.25 hours to write :)

-nerseus
 

Attachments

*wonders what size the form was when I zipped it up :)*

It will change the amount of tiles drawn based on the Forms size. I originally had the form starting out maximized but I didnt like that, not one little bit (FAR too slow) :)

-nerseus
 
I get 115 on my GeForce 3. :)

However, at fullscreen, it drops to 9.
 
Also, I edited your code, to change it so that it only draws in the forms Paint event (as it should be), made it so that instead of calling draw() it calls this.Invalidate(), and also turned on the UserPaint, AllPaintingInWmPaint, and DoubleBuffer styles for the form, and the FPS shot up to about 181. Still went down to about 13 at fullscreen (1600x1200). It also updated the tiles when you resize the form more smoothly; theres no "jumpy" effect.
 
Ive just started using DirectX for my 2d games and I actually found Direct3D to be better (faster) to use than DirectDraw. The 2 most important objects are: DirectX.Direct3D.Surface and DirectX.Direct3D.Sprite. Be sure to reference both Direct3D and Direct3DX, because the Direct3D.Sprite object is a part of Direct3DX.

- SysRq
 
Theyre discussing whether GDI+ 1.0 or GDI+ 1.1 is faster. Everyone knows DirectX is faster but theyre discussing normal Windows drawing without DirectX.
 
Is Bltbit in .NET? In my VB.NET upgrade script (I have about 50 tasks, so theres a lot of work yet to do), i seem to remember that it was one of the things it flagged as not being able to upgrade. Maybe Im totally confused with something else...
 
Well, its not part of .NET, its part of the Windows API. Its the same ol BitBlt that you used with VB6.
 
oh right I get it, and that is why it won;t be upgraded, its unmanaged code. So is GDI the next in line? Or is this only good for drawing lines? :)
 
It has many more uses then drawing lines :).
You can show images with it, draw custom controls, and all kinds of things like that. Its also good for games that dont require a lot of reources and dont have a huge number of objects to draw.
 
Here is an example of something I did, with some help from guys here:
C#:
[DllImport("gdi32.dll")] //Included in 95 and later.
			static extern  bool  BitBlt(
				IntPtr hDest, // handle to destination DC
				int XDest, // x-coord of destination upper-left corner
				int YDest, // y-coord of destination upper-left corner
				int WDest, // width of destination rectangle
				int HDest, // height of destination rectangle
				IntPtr hDCSrc, // handle to source DC
				int XStart, // x-coordinate of source upper-left corner
				int YStart, // y-coordinate of source upper-left corner
				int RasterOpCode // raster operation code
				);
//------------------------------
			public static void DrawBitBlt(Graphics g, Bitmap bmp, ref Rectangle destRec)
			{
				IntPtr hDC= g.GetHdc();
				IntPtr hBmp = bmp.GetHbitmap();

				IntPtr ImageDC= a.Api.CreateCompatibleDC(hDC);
				IntPtr offscreenDC= a.Api.CreateCompatibleDC(hDC);

				IntPtr drawBmp= a.Api.CreateCompatibleBitmap(hDC, destRec.Size.Width, destRec.Size.Height);

				IntPtr oldBmp= a.Api.SelectObject(ImageDC, hBmp);
				IntPtr oldDrawBmp= a.Api.SelectObject(offscreenDC, drawBmp);

				if(bmp.Size.Equals(destRec.Size))
				{
					a.Api.BitBlt(offscreenDC, 0, 0, destRec.Width, destRec.Height, ImageDC, 0, 0, SrcCopy);
				}
				else
					a.Api.StretchBlt(offscreenDC, 0, 0, destRec.Width, destRec.Height, ImageDC, 0, 0, bmp.Width, bmp.Height, SrcCopy);

				a.Api.BitBlt(hDC, destRec.X, destRec.Y, destRec.Width, destRec.Height, offscreenDC, 0, 0, SrcCopy);

				a.Api.SelectObject(ImageDC, oldBmp);
				a.Api.DeleteObject(hBmp);

				a.Api.SelectObject(offscreenDC, oldDrawBmp);
				a.Api.DeleteObject(drawBmp);

				a.Api.DeleteDC(ImageDC);
				a.Api.DeleteDC(offscreenDC);

				g.ReleaseHdc(hDC);
			}
 
I just thought Id throw this out there. Its an example of using GDI+ CachedBitmap, which is about 3x faster than DrawImage. But probably not faster than BitBlt. CachedBitmap is really only handy when the bitmap that it is based upon is not going to change. If the base were to change, youd have to Destroy the old and create a new CachedBitmap. And that is not very efficient.
 

Attachments

Boy is that helpful!! I have been looking for a way to avoid using the api.

Will this technique draw the image with ImageAttributes so that I can have a semi transparent image?
 
I did go ahead and test that. I just added:

bmp.MakeTransparent(System.Drawing.Color.Black)

And it does make the background transparent. (unfortunately my image is not an entirely black background, but oh well) So this method would work well for drawing sprites quickly too.
 
Actually I meant the whole image being semi-transparent to transparent using ImageAttributes.
C#:
public static ImageAttributes TrasparentImage(int percent)
			{
				if(percent <= 100 && percent >= 0)
				{
					float matrixEl= a.Numbers.PercentToDec(percent);
					matrixEl= 1*matrixEl;
					ImageAttributes IA = new ImageAttributes();		ColorMatrix wmColorMatrix = new ColorMatrix();
					wmColorMatrix.Matrix33= matrixEl;
					IA.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
					return IA;
				}
				else return null;
			}
This returns ImageAttributes that must be used as an argument to DrawImage. Does the CatchedBitmap have that?
 
Back
Top