copying 24-bit bitmaps
whew.... that''s a tongue twister.
I have a function in my engine that reads individual cells of a bitmap (used for sprite animation). It works perfectly for 8-bit bitmaps, but 24 bit is another story.
Here''s the function, the 24-bit copying pointed out:
int CBitmap::LoadSpriteFrame (Sprite *sprite, // Sprite to load with data
Bitmap *bitmap, // Bitmap to scan image data from
int frame, // Frame to load
int cx, int cy, // Cell or absolute pos. to scan image from
int mode) // If 0 then cx, cy is cell position, else
// cx, cy are absolute coords
{
DDSURFACEDESC2 ddsd; // DirectDraw surface description
// Is this a valid sprite?
if (!sprite)
return FALSE;
// Test the mode of extraction, cell based or absolute
if (mode == BITMAP_EXTRACT_MODE_CELL)
{
// Re-compute x,y
cx = cx * (sprite->width + 1) + 1;
cy = cy * (sprite->height + 1) + 1;
}
// Get the address to the destination surface memory
// Set the size of the structure
ddsd.dwSize = sizeof (ddsd);
// Lock the display surface
(sprite->images[frame])->Lock (NULL,
&ddsd,
DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
NULL);
// Copy the bitmap
switch (bitmap->bitmapInfoHeader.biBitCount)
{
case 8:
{
// Assign a pointer to the memory surface for manipulation
UCHAR *destPtr = (UCHAR *)ddsd.lpSurface;
// Extract bitmap data
UCHAR *sourcePtr = bitmap->buffer + cy * bitmap->bitmapInfoHeader.biWidth + cx;
// Iterate through each scanline and copy bitmap
for (int indexY = 0; indexY < sprite->height; indexY++)
{
// Copy next line of data to destination
memcpy (destPtr, sourcePtr, sprite->width);
// Advance pointers
destPtr += (sprite->width + sprite->widthFill);
sourcePtr += bitmap->bitmapInfoHeader.biWidth;
}
} break;
///////////////////////////////
case 24:
{
// Assign a pointer to the memory surface for manipulation
UCHAR *destPtr = (UCHAR *)ddsd.lpSurface;
// Iterate through each scanline and copy bitmap
for (int indexY = 0; indexY < sprite->height; indexY++)
{
for (int indexX = 0; indexX < sprite->width; indexX++)
{
// Get BGR values
UCHAR blue = (UCHAR)(*bitmap->buffer + cy * 3 + 0),
green = (UCHAR)(*bitmap->buffer + cy * 3 + 1),
red = (UCHAR)(*bitmap->buffer + cy * 3 + 2);
// This builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode)
DWORD pixel = _RGB32BIT(0, red, green, blue);
// write the pixel
destPtr[cx + (cy * ddsd.lPitch >> 2)] = pixel;
}
}
} break;
////////////////////////
}
// Unlock the surface
(sprite->images[frame])->Unlock (NULL);
// Set state to loaded
sprite->attr |= SPRITE_ATTR_LOADED;
return TRUE;
}
The bitmap appears as a single pixel on the screen. Does anyone see my big blundering mistake?
[Edited by - monkey-poop on May 3, 2007 10:30:54 AM]
I haven''t studied your code in any great depth, but try
changing
(UCHAR)(*bitmap->buffer + cy * 3 + 0)
to (UCHAR)*(bitmap->buffer + cy * 3 + 0)
as * binds more closely than the other operators.
changing
(UCHAR)(*bitmap->buffer + cy * 3 + 0)
to (UCHAR)*(bitmap->buffer + cy * 3 + 0)
as * binds more closely than the other operators.
Thank you for the suggestion, but unfortunately that did not work. I''m sure it has something more to do with advancing pointers or something in that direction. But I appreciate any ideas.....
[Edited by - monkey-poop on May 3, 2007 3:52:38 PM]
[Edited by - monkey-poop on May 3, 2007 3:52:38 PM]
cx and cy are never updated in the loop and therefore you always read the same pixel (and draw always the same).
Thanks Prosper/LOADED. I had an idea it had something to do with advancing pointers, just haden''t been sure where. Do you have any ideas what I can do to fix this? This is the first time I''ve ever played with a raw bitmap buffer. As you can see from the 8-bit version, cx and cy aren''t updated, but I update destPtr and srcPtr at the end of the loop.
Thanks again
[Edited by - monkey-poop on May 3, 2007 4:33:38 PM]
Thanks again
[Edited by - monkey-poop on May 3, 2007 4:33:38 PM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement