Jump to content
Xtreme .Net Talk

Recommended Posts

  • Leaders
Posted

I am making a user control in vb.net. I am trying to use GDI, however, to handle the blitting, since GDI is faster.

 

I am using the hdc's that i retreive from graphics objects to pass to bitblt, and bitblt return values indicate a successful blit. But after I release the hdcs and try to display the bitmap on the screen, i get nothing but blackness.

 

It works, however with GDI+ functions.

 

Here is the GDI+ Version

 

   Dim Source As New Bitmap("D:\Visual studio projects\console\LEDWindows.bmp")
   Dim GSource As Graphics = Graphics.FromImage(Source)
   Dim hDCSource As IntPtr

   Dim Persist As Bitmap
   Dim GPersist As Graphics
   Dim hDCPersist As IntPtr 

   Private Sub NewSize()
       Dim i, j As Integer
       Persist = New Bitmap(m_ConsoleSize.Width * 12, m_ConsoleSize.Height * 20)
       GPersist = Graphics.FromImage(Persist)

       For i = 0 To m_ConsoleSize.Width - 1
           For j = 0 To m_ConsoleSize.Height - 1
               GPersist.DrawImage(Source, i * CharWidth, j * CharHeight, New Rectangle(0, 40, 12, 20), GraphicsUnit.Pixel)
           Next
       Next

       Me.BackgroundImage = Persist
       Me.Refresh()
   End Sub

 

Here is the GDI Version

   Dim Source As New Bitmap("D:\Visual studio projects\console\LEDWindows.bmp")
   Dim GSource As Graphics = Graphics.FromImage(Source)
   Dim hDCSource As IntPtr

   Dim Persist As Bitmap
   Dim GPersist As Graphics
   Dim hDCPersist As IntPtr 

   Private Sub NewSize()
       Dim i, j As Integer
       Persist = New Bitmap(m_ConsoleSize.Width * 12, m_ConsoleSize.Height * 20, Imaging.PixelFormat.Format24bppRgb)
       GPersist = Graphics.FromImage(Persist)
       hDCPersist = GPersist.GetHdc
       hDCSource = GSource.GetHdc

       For i = 0 To m_ConsoleSize.Width - 1
           For j = 0 To m_ConsoleSize.Height - 1
               BitBlt(hDCPersist, i * CharWidth, j * CharHeight, 12, 20, hDCSource, 0, 40, vbSrcCopy)
           Next
       Next

       GPersist.ReleaseHdc(hDCPersist)
       GSource.ReleaseHdc(hDCSource)
       Me.BackgroundImage = Persist
       Me.Refresh()
   End Sub

 

Note that the only difference is that the GDI+ version uses drawimage() and the GDI version grabs the hdc's, uses bitblt(), then releases the hdcs, which would be the GDI equivalent, so I can't figure out why this wont work.

[sIGPIC]e[/sIGPIC]
  • *Experts*
Posted

If you are making a control, just stick with GDI+. GDI32 is faster, but you won't notice it in a control like this (you would only notice it in a graphic intensive application, like a game, and it's possible that in the case of many many calls to the GDI32, GDI+ would end up being faster).

 

Recently there has been a lot of discussion about "Oh, GDI32 is faster than GDI+", but that doesn't mean you should use GDI32 instead of GDI+; GDI+ is a managed part of the .NET Framework that .NET natively supports, while GDI32 requires calls to GDI32.DLL.

 

When I tested it, the speed ratio was about 5:1 - it took about 500ms to draw 2000 images with DrawImage, and about 100ms to draw 2000 images with BitBlt. In that case, it would probably take around 0.25ms to draw with DrawImage and 0.05ms to draw with BitBlt. Not a big deal at all.

  • Leaders
Posted

Ok, dont start this.

 

I am making up to, depending on the size of the control, up to 3200 calls to the blitting function (generally more like 480). Thats graphic intensive. There is a noticable lag when the control is initially drawn, or when the size is changed. I don't want that, and I am NOT using GDI+.

 

In the case of many, many calls to GDI+ vs GDI, GDI wins. No question about it. I've made many applications like this in vb6 with no visible lag, and a few in .net with GDI+, ALWAYS with visible lag.

 

And why would i mind calling GDI32.dll? And what is wrong with calling unmanaged code that is not part of .net?

 

To me it is a big deal, i want my programs to run smoothly.

 

Please, no one tell me not to use GDI. I want to use GDI. When GDI+ is appropriate, as in drawing only a few images, or performing skewing and stretching effects, etc., i will GLADLY use GDI+. But I want to use GDI, it does exactly what I want it to with no unwanted side effects. So PLEASE don't tell me to use GDI+ or DirectX. Pretty please?

[sIGPIC]e[/sIGPIC]
  • *Experts*
Posted

Heh, OK, I didn't realize you were the one that we'd already had this discussion with. From your code, it didn't look like it was being called that many times.

 

Have you declared vbSrcCopy as anything? If Option Explicit is not on, then that will evaluate to 0. vbSrcCopy is not a constant in .NET.

  • Leaders
Posted

Yeah, thats me.

 

Anyways, I always use option explicit, and all my constants are declared. I got the value of vbSrcCopy from vb6.

 

Also, I'm an idiot. I copied the bitblt declaration for vb6 and didnt change the parameters from longs to integers. I fixed it though, and it is still behaving the same.

[sIGPIC]e[/sIGPIC]
  • Leaders
Posted

Oops. I know why this doesnt work.

 

HDC's aquired from graphics objects backed by bitmaps (like my bitmap named Source) are meant to be write only. You cant copy graphics from them, or you will turn up with blackness.

 

So I need to create a GDI compatible source DC.

[sIGPIC]e[/sIGPIC]
  • 3 years later...
  • Leaders
Posted
could you please tell me the value of vbSrcCopy? I have been looking everywhere.

Google Search: The first link has the answer. vbSourceCopy is the same as the Windows API SRCCOPY constant.

 

In the future, new questions should generally go in new threads.

[sIGPIC]e[/sIGPIC]
  • 1 month later...
Posted

I know this is an old thread, but I found this use of bitblt in C# on the web a while ago if it's of any help.

 

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);
}

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