Jump to content
Xtreme .Net Talk

Recommended Posts

Posted (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 by wyrd
Gamer extraordinaire. Programmer wannabe.
Posted

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.

C#
Posted

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

Gamer extraordinaire. Programmer wannabe.
  • *Experts*
Posted

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.

Posted
Ah, figures it wouldn't be that easy. :) I'll take a look at your tutorial, thanks.
Gamer extraordinaire. Programmer wannabe.
Posted
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.
Gamer extraordinaire. Programmer wannabe.
  • *Experts*
Posted

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.

  • *Experts*
Posted

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

  • *Experts*
Posted

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. :)

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...