Jump to content
  • Advertisement
Sign in to follow this  
bignermo

Handling a bitmap in a memory!

This topic is 4541 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

Hello people, Can anyone help me in this... I am drawing a large number of regions (win32 HRGN) on a hdc. The switch at WM_PAINT message calls my Draw() function which draws the regions (Bosnia and Herzegovina dividend into municipalities - 137 of them). I have implemented the scroll, zoom in/out with all necessary transformations and it works fine. The problem is that the program is slow since it has to redraw all 137 objects each time the window receives the WM_PAINT message. I thought of drawing the regions ONE TIME and to save the bitmap of the DC. Then the WM_PAINT would blit the bitmap, without having to redraw 137 objects. At Gamedev I found the topic about saving a DC to bitmap and then to the file, which I found quite interesting and helpful. Now I am stuck with the problem of saving the bitmap in a memory, potentially as a global variable or pointer, and then to use it in one of the drawing functions, so I could avoid drawing 137 regions. I hope that I can get some help on this. Thanks in advance!

Share this post


Link to post
Share on other sites
Advertisement
1. You need to create a DC that is compatible with the screen, call CreateCompatibleDC. Let's call this a memory DC.
2. Then create a compatible bitmap, call CreateCompatibleBitmap.
3. Draw your regions to the memory DC.
4. Whenever you draw, BitBlt the bitmap from the memory DC to the screen DC.

Voila!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by JY
1. You need to create a DC that is compatible with the screen, call CreateCompatibleDC. Let's call this a memory DC.
2. Then create a compatible bitmap, call CreateCompatibleBitmap.
3. Draw your regions to the memory DC.
4. Whenever you draw, BitBlt the bitmap from the memory DC to the screen DC.

Voila!


That's correct, but consider this:

//This function will be caled when region transformation occurs, ought to
//update the 'bitmap'

void DrawPrimitives()
{
...
HDC memDC = CreateCopmatibleDC(hdc)
HBITMAP my_bitmap = CreateCompatibleBitmap(.....)
SelectObject(memDC, my_bitmap);

/*** THIS IS THE SLOW PART ***
//Drawing to memory DC,
FrameRgn(memDC, region, brush, width, height);

//Set free the memory
...
}

//This function will be caled by the WM_PAINT, and will (shlould) only blit
//the bitmap, i.e. make it fast!

void Draw()
{
//Should the memDC be declared as GLOBAL?

//What to blit and where from??

}

Share this post


Link to post
Share on other sites
Well yes, it's fairly obvious but perhaps I should have mentioned that you don't draw everything on the bitmap AND blit it every time - that would slow the original solution down rather than speed it up.

:o

Share this post


Link to post
Share on other sites
The memory DC does need to have a longer "lifetime" than where it gets created. There are a few ways to accomplish this:

- You can use a global, and init it at 'startup' (i.e. at some time before you need to start drawing).

Note that there's 'global' (file scope) and then there's *really* global. Don't mention the data member in the header file if you don't need to. And anyway, you always want to fight to scope things tighter than that :) So there are more options:

- You can use a static variable within DrawPrimitives(), and in that code, check whether the DC is initialized, and if not, initialize it first.

This can be problematic, depending on how easy it is to "check if initialized". I don't know the details of how any of this Windows API stuff works - just general programming practice. If there's no easy way to check, you could use a pointer variable, and in DrawPrimitives(), check for NULL and allocate and init the DC if it isn't already (and then use the DC through the pointer). However that brings up two more problems: (1) dynamically allocating the HDC (which I don't know if it's possible with the API - then again, maybe HDC is already a typedef for a pointer type; I don't know; read the docs), and (2) deallocating it (there isn't really a good way to "reach into" a function's static members at the end of the program and deallocate them).

(Actually, the 'H' in the Windows API stands for 'handle' doesn't it? hmm...)

So instead, what you normally do in OO-supporting languages is

- Create an object that encapsulates the process. Have an HDC data member, and set it up in the constructor. From the DrawPrimitives() function, call a member function of the object, which in turn draws the HDC.

Something vaguely like:


class Image {
HDC dc;
HBITMAP bitmap;
// other stuff like the dimensions?
public:
Image(/*args?*/) : dc(CreateCompatibleDC(/*args*/)), bitmap(CreateCompatibleBitmap(/*args*/)) {
SelectObject(memDC, my_bitmap);
// other stuff?
}
~Image() {
// Do any necessary cleanup
}
void draw() {
FrameRgn(dc, region, brush, width, height);
}
};

// Now you can instantiate an Image and use it as needed. One possible way
// is to, again, have a static member in DrawPrimitives:

void DrawPrimitives() {
static Image i(/*args?*/);
// That only gets constructed the first time.
i.draw();
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!