wyrd Posted August 3, 2003 Posted August 3, 2003 (edited) After pain staking hours figuring out how all this lovely GDI+ and Win32 GDI stuff worked and interacted together, I finally came up with a basic class library which you can just plug-n-play for faster drawing. Obviously there's room for improvement as it only implements a few basic Win32 functions for drawing, but it's already proved useful in the game I'm creating. :) If you find any bugs let me know. Before getting to how to use the class library (it's really a no-brainer), here's my initial tests on my 800mhz athlon, G2 MX, 256mb of RAM rig (yeah, nothin' special). Draw Area: 640x480 Images Drawn Per Frame: 336 Size Of Images: 32x32 FPS: 43 Increase Over GDI+: ~14 FPS Draw Area: 480x360 Images Drawn Per Frame: 176 Size Of Images: 32x32 FPS: 74 Increase Over GDI+: ~25 FPS I originally tried w/ letting .NET handle the backbuffer and all that with SetStyles. Unfortunately I didn't quite as good of a FPS boost. It seems like in this case you're better off doing your own backbuffer. Okay, so here's how to use it. :) GDIBitmap _image; GDIBitmap _buffer; Graphics _main; public Constructor() { // Load images. _image = new GDIBitmap("hi.bmp"); // Create buffer. _buffer = new GDIBitmap(this.Width, this.Height); // Create main drawing area. _main = this.CreateGraphics(); } // Pretend this is a dispose pattern. public void Dispose() { _image.Dispose(); _buffer.Dispose(); _main.Dispose(); } // Some event to start the loop. public void Event() { while (true) { _drawBuffer(); _drawMain(); this.DoEvents(); } } private void _drawBuffer() { GDIDraw.BitBtl(_buffer.DeviceContext, 0, 0, _image.Width, _image.Height, _image.DeviceContext, 0, 0, RasterOperations.SrcCopy); } private void _drawMain() { IntPtr dcMain = _main.GetHdc(); GDIDraw.BitBlt(dcMain, 0, 0, _buffer.Width, _buffer.Height, _buffer.DeviceContext, 0, 0, RasterOperations.SrcCopy); _main.ReleaseHdc(dcMain); } Just as easy as GDI+ (well, maybe not, you need to create your own backbuffer), and gives more speed. :) Ohhh yeah! Ah, and one thing of note; not sure if I should of created a new thread for this, but it didn't exactly fit the topic of my other two posts (one was asking for help and the other was about speeding up GDI+). If this should of been posted in one of my other two threads then I apologize for wasting space. That wasn't my intention.gdi.zip Edited August 3, 2003 by wyrd Quote Gamer extraordinaire. Programmer wannabe.
aewarnick Posted August 4, 2003 Posted August 4, 2003 One thing to note about comparing the speed of plain old BitBlt and GDI+ is that BitBlt does not support transparency without using more BitBlt operations, while DrawImage and DrawImageUnscaled does. You may want to do another test with just with GDI+ to see if making part of the image transparent slows does the speed of drawing or not. If it does not, then you are going to have to find out how to draw partial transparent images with BitBlt using masks before you can really do a "fair" comparison. I wanted to do that but have not gotten around to it yet. Quote C#
wyrd Posted August 4, 2003 Author Posted August 4, 2003 You have a good point. However, my map is not drawn with transparent images. Even if transparency drawing is around the same speed (which I doubt it), using regular BitBlt over Graphics.DrawImage will still come in quite handy. When I get around to drawing transparent images it shouldn't be any more difficult then just adding a reference to TransparentBlt and using that instead of BitBlt for images I want to draw transparently. http://www.mentalis.org/apilist/TransparentBlt.shtml Quote Gamer extraordinaire. Programmer wannabe.
*Experts* Volte Posted August 4, 2003 *Experts* Posted August 4, 2003 TransparentBlt contains a memory leak in all operating systems preceding Windows 2000, and should be avoided like the plague. The only correct way to do transparent BitBlting is by creating the mask and using the SrcAnd/MergePaint combination. Look at my BitBlt tutorial (GDI32 Part III) tutorial on EliteVB. It's in the Graphics section. It's for VB, but it's fairly transferrable. Quote
wyrd Posted August 4, 2003 Author Posted August 4, 2003 Ah, figures it wouldn't be that easy. :) I'll take a look at your tutorial, thanks. Quote Gamer extraordinaire. Programmer wannabe.
wyrd Posted August 5, 2003 Author Posted August 5, 2003 Anyone know where I can find out what the values for the pen styles are for CreatePen? ie; PS_SOLID, PS_DOT, etc. I've searched up and down in the MSDN library and can't seem to find any information on their values. Quote Gamer extraordinaire. Programmer wannabe.
*Experts* mutant Posted August 5, 2003 *Experts* Posted August 5, 2003 There is a list here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pens_9wha.asp Quote
wyrd Posted August 5, 2003 Author Posted August 5, 2003 Yeah, but it doesn't give me the values. Are the values just 0-7? Quote Gamer extraordinaire. Programmer wannabe.
*Experts* mutant Posted August 5, 2003 *Experts* Posted August 5, 2003 Oh, you were looking for the values :). Yes, I checked them in the VC++ compiler, they are 0-6 in the order they are shown on that page. Quote
*Experts* mutant Posted August 5, 2003 *Experts* Posted August 5, 2003 I also had a look at Wingdi.h, it seems to define more styles: /* Pen Styles */ #define PS_SOLID 0 #define PS_DASH 1 /* ------- */ #define PS_DOT 2 /* ....... */ #define PS_DASHDOT 3 /* _._._._ */ #define PS_DASHDOTDOT 4 /* _.._.._ */ #define PS_NULL 5 #define PS_INSIDEFRAME 6 #define PS_USERSTYLE 7 #define PS_ALTERNATE 8 #define PS_STYLE_MASK 0x0000000F #define PS_ENDCAP_ROUND 0x00000000 #define PS_ENDCAP_SQUARE 0x00000100 #define PS_ENDCAP_FLAT 0x00000200 #define PS_ENDCAP_MASK 0x00000F00 #define PS_JOIN_ROUND 0x00000000 #define PS_JOIN_BEVEL 0x00001000 #define PS_JOIN_MITER 0x00002000 #define PS_JOIN_MASK 0x0000F000 #define PS_COSMETIC 0x00000000 #define PS_GEOMETRIC 0x00010000 #define PS_TYPE_MASK 0x000F0000 Quote
*Experts* Volte Posted August 5, 2003 *Experts* Posted August 5, 2003 You can use the API Viewer 2003 obtained from AllAPI to get API declares, constants and types from Win32 API. It even does its best to convert to VB.NET or C# if you want it to (though it doesn't do a great job). Even for a .NET developer it's a must-have in your utility box. :) Quote
wyrd Posted August 5, 2003 Author Posted August 5, 2003 Nice.. very nice. Thanks.. both of you. Quote Gamer extraordinaire. Programmer wannabe.
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.