Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

shalom

Memory DC's

This topic is 6196 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi: I''m writing a game in Visual Basic. VB isn''t very good with graphics, so everyone bypasses the VB graphics and uses the GDI. For some reason, though, no-one makes their own device contexts. Everyone uses invisible PictureBox controls (a simple VB control that displays pictures) because they have a DC property. For example, if someone wanted to blit a transparent picture on to the window, they would have three PictureBox controls, let''s say Pic1, Pic2, and Pic3. They would load the picture they want to blit onto in Pic1, the picture they want to blit in Pic2, and a mask in Pic3. They would import the GDI BitBlt function and use the following VB code: BitBlt Pic1.hDC, 0, 0, 100, 100, Pic3.hDC, 0, 0, SRCAND BitBlt Pic1.hDC, 0, 0, 100, 100, Pic2.hDC, 0, 0, SRCPAINT BitBlt Me.hDC, 0, 0, 100, 100, Pic1.hDC, 0, 0, SRCCOPY. This is all fine if your doing a little animation or something, but if I want to make a full game, perhaps using independant classes that may not have access to windows and their PictureBoxes, how do I use the GDI to make memory DC''s? I can''t find it anywhere. How do C programmers, who don''t have access to PictureBox controls, make memory DCs that can be used to temporarily Blt on to and off again? Thanx in advance, Shalom

Share this post


Link to post
Share on other sites
Advertisement
You''ll have much better luck with this post in the general programming forum, so I''am moving it.

Share this post


Link to post
Share on other sites
Windows apps have one or more windows. For any windows you can gets its DC by calling GetDC(hwnd) where hwnd is the handle of the window. This is usually done in response to a paint message (WM_PAINT) but can be done any time. This is what I do...

void Paint (HWND hwnd)
{
HDC dc = GetDC(hwnd);
int savedc = SaveDC(dc);

// there are many DC related draw functions:
// SelectObject(), MoveTo(), LineTo(), SetPixel(),
// BitBlt(), TextOut(), Rectangle(), Ellipse(),
// SetTextColor(), SetTextAlign(), on and on

RestoreDC(dc, savedc);
ReleaseDC(hwnd, dc);
}

DC''s have a ton of state information that you have to make sure is restored before you release them, or you get GDI leaks, so I always save/restore the whole thing.

Share this post


Link to post
Share on other sites
Hi, I can access the window''s DC, but how do I make a temporary DC? For example, let''s take a simple case - double buffering. How would I make a little animation in an imaginary DC and then BitBlt from that imaginary DC to the window''s DC? How do I make a sort of "buffer" DC?

Thanks,
Shalom

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
hi shalom,

Device Contexts are just some sort of a "reference" to the device and they don''t anything on their own (they don''t hold the picture, they just point to the device that displays it...), and for that reason the term "temporary dc" doesn''t really mean anything cause it''s just a refernce to the device and you have to handle some sort of buffer yourself(by maybe having something hidden you draw into and then copying for the hidden object to the display object).

this is just a thought, havn''t been using VB for grahpics or the such

Share this post


Link to post
Share on other sites
In other words, how do I make a buffer that I can point a device context to, with out having access to a window with my invisible objects and whatever?

Share this post


Link to post
Share on other sites
I''m just writing this off the top of my head and its been a while since I''ve used DCs, but I think this will work:

  
HDC buffer;
HDC window;
HBITMAP temp;

window = GetDC( window_hWnd );
buffer = CreateCompatibleDC( window );

temp = CreateCompatibleBitmap( buffer, width_of_image, height_of_image );

SelectObject( buffer, temp );
DeleteObject( temp );
ReleaseDC( window_hWnd, window );


That will create an offscreen DC you can use to draw to. You must create a bitmap object and select it into the DC or you won''t be able to use the DC. I''m sure that I messed up some of the parameters (I don''t remember them all), but you should be able to look up the API functions and see what the parameters should be.

I don''t really remember VB that well, but I''d guess that the VB code would be something like:

  
DIM buffer as Long
DIM window as Long
DIM temp as Long

Set window = GetDC( Form1.hWnd )
Set buffer = CreateCompatibleDC( window );
Set temp = CreateCompatibleBitmap( buffer, width, height )

Call SelectObject( buffer, temp )
Call DeleteObject( temp );
Call ReleaseDC( Form1.hWnd, window );


Im assuming that since you use BitBlt you know how to declare APIs for use in VB.

If you want direct access to the bits being displayed, I recomend that you create the bitmap object that you are going to select into the buffer DC with CreateDIBSection. That way you will have a pointer to the actual bits which will allow you to do things like alpha blending (I realize that alpha blending can be done with GetPixel/SetPixel, but that is to slow).

Feel free to email me any questions you might have
Mike010@netZero.net

Share this post


Link to post
Share on other sites
Thank you so much, Mike. It seems silly to get stuck on such a simple point. I have my entire game planned out and most of it programmed, and I don''t know how to use the GDI! Well, I''ll try it out.

Share this post


Link to post
Share on other sites
Oh no! I used the following code exactly, and it makes a square the right size in the top left corner of the window, but its all black! What did I do wrong?
  Option Explicit

Private Sub Form_Load()
Dim buffer As Long
Dim window As Long
Dim temp As Long
window = GetDC(Form1.hwnd)
buffer = CreateCompatibleDC(window)
temp = CreateCompatibleBitmap(buffer, Picture1.ScaleWidth, Picture1.ScaleHeight)
SelectObject buffer, temp
DeleteObject temp
ReleaseDC Form1.hwnd, window
BitBlt buffer, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, Picture1.hdc, 0, 0, SRCCOPY
BitBlt Me.hdc, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, buffer, 0, 0, SRCCOPY
Form1.Refresh
DeleteDC buffer
End Sub


Sigh... I''m causing so much trouble with such a simple problem. Oh well.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!