Link to home
Start Free TrialLog in
Avatar of fRouxSerret
fRouxSerret

asked on

Accessing Memory DC contents

I created a memory device context with the following functions:

CBitmap::CreateBitmap(5040,800,1,24,(UBYTE *)data);
--- Note the big size of the bitmap ---
CDC::CreateCompatibleDC(NULL);
CDC::SelectObject(my_compatible_bitmap_above);

Then I blit a part of it (640x480) on the screen with CDC::BitBlt();

It works.

I would like to modify a dozen of small parts in my compatible bitmap (64 x 64 pixel squares), so that the changes appear on the screen in the next BitBlt().

It don't want to have to copy again all the 5040 x 800 pixels !!

I just want a way to directly access the data used by the compatible dc.
I'll give a A if I get a way to access directly the data in memory (not with BitBlt() or something like that).
I'll give a B for a way to do it without having to create a compatible DC or a Bitmap for each little square.
I already CAN do it by creating a DC for each square, so please don't explain me this method :) .I would like, again, direct access to memory.

Note: if I ask the compatible bitmap to fill a BITMAP structure, all attempts to write these bits cause a protection fault (pointers are valid, but I'm under NT 4, and I don't have write access using this method)

Francis
Avatar of RONSLOW
RONSLOW

GetPixel and SetPixll give you access to the bitmap pixels

If your memory bitmap is still in memory you can draw on it with DC function (like StretchBlt etc).

And you can easily StretchBlt only changed parts of the memory bitmap to the screen (by looking at the direty recatangle when you update).

I don't understand your saying "don't want to copy again all 5040x800 pixels" - I thought you were only copying 640x480 pixels>

I'm not sure why you don't want to create a compatible dc - this is a fairly  inexpensive operator - it isn't as if you are re-creating the bitmap, just the CD to access it.

If you tell me what you actually want to do, then I'll give you further information.

Avatar of fRouxSerret

ASKER

What I'm doing is:
I have a 5040 x 800 picture, with small animated squares on it.
I want a fullscreen VGA 640x480 view on it, with the highest frame rate as possible (scrolling).

I can't use PutPixel() because:

A squares animation cell is a linear RGB (64 x 64 x 3 bytes) memory zone, and I want to update the 5040 x 800 picture with these data. If I use putpixel() or setpixel(), I have to use convert the linear memory data to a COLOR data structure to use PutPixel, and I have to loop through x and y (to make a square). Moreover, it is a function-call per pixel. This is not very optimized !!!

Could you tell me how to create ONLY the compatible DC each time because :

As I said, I already do it by using a DC and a bitmap, but I have
to convert the linear data into a bitmap: If I make it once at initialization, I have to do it for each animation cell (they are many !) => too much memory wasted.
If I do it at rendering time, I have to do it each time: not optimized!

I said "don't want to copy again all 5040x800 pixels", since there is an other approach, consisting in updating the source picture (which is also linear RGB data), and then Creating the Bitmap again and again from this data, which of course is not optimized too !

The animation loop is as follow:

while not-finished:
    update the 5040x800 picture with animation cells (64x64),
    copy a 640x480 part of it to the screen using BitBlt()
    do some stuff
end of while

I CAN DEFINITIVELY NOT use direct draw !

I can't and I won't change the above loop !!
ASKER CERTIFIED SOLUTION
Avatar of RONSLOW
RONSLOW

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>I created a memory device context with the following functions:
>CBitmap::CreateBitmap(5040,800,1,24,(UBYTE *)data);
>--- Note the big size of the bitmap ---
>CDC::CreateCompatibleDC(NULL);
>CDC::SelectObject(my_compatible_bitmap_above);
>
>Then I blit a part of it (640x480) on the screen with
>CDC::BitBlt();
>
>It works.

So it should :-)

>I would like to modify a dozen of small parts in my
>compatible bitmap (64 x 64 pixel squares), so that the
>changes appear on the screen in the next BitBlt().

Then just create another Compatible DC (or use the old one if you want to keep it around) and BitBlt into it.

>It don't want to have to copy again all the 5040 x 800 pixels !!

Why would you need to?

>I just want a way to directly access the data used by the
>compatible dc.

You bitmap IS the data used by the compatible DC.  You can access the bitmap via GDI (including BitBlt) via the DC.

>I'll give a A if I get a way to access directly the data in
>memory (not with BitBlt() or something like that).

You can use GetBits to get at the data.  Or, if you allocate the data yourself and create a bitmap using that memory.

>I'll give a B for a way to do it without having to create
>a compatible DC or a Bitmap for each little square.

Why would you need to?  You create a DC for the whole big bitmap and just draw to the approcricate cell

>I already CAN do it by creating a DC for each square,
>so please don't explain me this method :)

That seems a silly way of doing it

>I would like, again, direct access to memory.

If you REALLY need that the you can have it, but BitBlt is very efficient and powerful

>Note: if I ask the compatible bitmap to fill a BITMAP
>structure, all attempts to write these bits cause a
>protection fault (pointers are valid, but I'm under NT 4, and
>I don't have write access using this method)

Don't quite follow what you are trying to do here.

If you require more info, please don't reject, just put up a comment.
I graded you too fast !!!! It still doesn't work !
Your stuff seems to work, but I still have a (little) problem with it:
If I only do that:
I make a CBitmap containing all the frames of my animcells
I make a CBitmap containing the 5040x800 picture,
I create a compatible DC for the cells Bitmap,
I create a compatible DC for the picture,
I assign the Bitmaps to the respective DCs
I bitblt() a square from the cells bitmap to the picture bitmap,
I never get any error code,
but the picture bitmap is never updated !!!!!!!!!!!!!!!!!!!!
(even if I BitBlt(.....,BLACKNESS) !! )
And that's precisely what I want to do !
The only thing that I want to blit to the real screen DC, is a part of the 5040x800 picture bitmap !!! I don't want to blit the cells directly to the screen: flickering...

Could you tell me what I'm doing wrong ?

Francis
francis@digitalstudio.com