copying 24-bit bitmaps

Started by
3 comments, last by monkey-poop 22 years, 5 months ago
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]
Advertisement
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.
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]
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]

This topic is closed to new replies.

Advertisement