Jump to content
  • Advertisement
Sign in to follow this  

memcpy to dx7 surface

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

I have an issue loading a bitmap file and then copying it to a directx7 surface.
I have isolated the header files and checked all of the resulting values against the image that I am trying to load, they all seem ok.
However when I run it, the image does not display correctly.
I would very much appreciate somebody casting their eye over my code and perhaps giving me a few pointers

I have been chasing this round for a while now. Think I'm going a bit bonkers. - code follows Cheers.

Bitmap::LoadBMP(const char *filename, const char *mode, bool isRLE)
FILE *m_bitMapFile;
PVOID* pixData;
BYTE* surfacePointer;
//HDC hdcImage;

m_bitMapFile = fopen(filename,mode);//open the file for binary reading
//structures defined in winGDi.h
//describing .bmp header information

fread(&bmfh,sizeof(BITMAPFILEHEADER),1,m_bitMapFile);// Read the file header info into bmfh
//fread(&bmih,sizeof(BITMAPINFOHEADER),1,m_bitMapFile);// Read the info header info into bmih


//Now that we have isolated the header info
//A check to ensure the file is a bitmap
//a value of 19778 (0x4d42) should be in BITMAPFILEHEADER.bfType

WORD isBitmap = bmfh.bfType;
if (isBitmap != 19778)
include some error response here
//return false;
}//OK we have a bitmap


//Create our internal DirectDraw surface using values taken from the loaded bmp
//first thing to do is reserve some memory for ddsd.
//This will be passed to the CopyToInternalSurface
ddsd.dwSize = sizeof(ddsd);
ddsd.dwWidth = bmi.bmiHeader.biWidth;
ddsd.dwHeight = bmi.bmiHeader.biHeight;
ddsd.ddpfPixelFormat.dwFlags = DDPF_COMPRESSED;
ddsd.ddpfPixelFormat.dwRGBBitCount = bmi.bmiHeader.biBitCount;
DirectDraw::GetInstance()->GetDirectDrawObject()->CreateSurface(&ddsd, &m_bitmapSurface, NULL);

//Check to see if any compression is in use
// 0 = none, if this is true the wronf function has been called - return
// 1 = RLE 8-bit/pixel,Decode before copying to Surface
// 2 = RLE 4-bit/pixel, Decode before copying to surface
//decisions can be made for decoding based on this value.
unsigned int compressed = bmi.bmiHeader.biCompression;

if (compressed == 0)//no compression
//find the size of the image data
//subtracting to offBits from the size is the most accurate way of doing this.
DWORD size;
size = bmfh.bfSize - bmfh.bfOffBits;
//DWORD size = bmi.bmiHeader.biSizeImage;
temppixelData = new BYTE[size];
size_t result;
result = fread(temppixelData,sizeof(BYTE),size,m_bitMapFile);
int e = feof(m_bitMapFile);

//temppixelData now holds the raw image data.
surfacePointer = (BYTE*)ddsd.lpSurface;

for(int y=0; y < bmi.bmiHeader.biHeight; y++)
memcpy(surfacePointer +y*ddsd.lPitch, temppixelData+y*ddsd.dwWidth, ddsd.dwWidth*ddsd.ddpfPixelFormat.dwRGBBitCount);

m_bitmapwidth = bmi.bmiHeader.biWidth;
m_bitmapheight = bmi.bmiHeader.biHeight;


else if (compressed ==1)//RLE 8

else if (compressed ==2)//RLE 4
//check for pallete then decode

Share this post

Link to post
Share on other sites
Break into the debugger or log the values before you do the copy, and make sure the values obtained for the locked surface are what you expect.
In particular, ddsd.ddpfPixelFormat.dwRGBBitCount is in bits, not bytes, so you need to divide it by 8.
Also, y*ddsd.dwWidth should probably be multiplied by the number of bytes per pixel.
Do you need to use the DDPF_COMPRESSED flag?
Not sure what exactly that will do..

Share this post

Link to post
Share on other sites
I'm confused. First of all you create the surface with compression, then you check if compression is used in the bitmap, you have a comment explicitly stating that if no compression is used we don't even attempt to load the bitmap, and finally you do the exact opposite - you load an uncompressed bitmap into a compressed surface and don't handle the compressed bitmap cases.

Share this post

Link to post
Share on other sites
Erik and mhagain, thanks for the reply. I will try these thing out. My reason for handling an uncompressed images was that I am new to this and I wanted to be sure that I was copying to the surface correctly before I move onto trying this with compressed data. I didnt want to come across issues later on that appeared to compression related that were infact relateing to the moving of the data. My BITMAP class already has a function to load an uncompressed image that works well, but I have a need to be able to handle RLE compression. Thanks again for your reply

Share this post

Link to post
Share on other sites
I think I am getting somewhere with this. it seems that the surface lock is changing the [color=#1C2837][color=#000000]ddsd[color=#666600].[color=#000000]ddpfPixelFormat[color=#666600].[color=#000000]dwRGBBitCount.

[color=#1C2837][color=#000000]I cant imagine why.
[color=#1C2837][color=#000000]Can any body?

Share this post

Link to post
Share on other sites
It's also an output parameter, and it is supposed to change and tell you information about the surface you lock. The surface is already created and has a specific format, and you can't change that by locking it. The structure will be changed to reflect the actual contents of the surface, as that is the only type of data you can write to it with any reliable result.

Share this post

Link to post
Share on other sites
Hi Erik

So my surface is unchanged. I have also made the changes that you suggested earlier. I now see my image. the height is good. However the image width is not correct, it is squashed and is grey scale and the image background appears to have stripes. All of the other values are correct. could this be a problem with the DWORD boundary of the bitmap?

Share this post

Link to post
Share on other sites
Yes it could. Always read the Pitch, sometimes called row-bytes or similar, and use that to get the source and destination data for copying rows, as there may be padding. Also, make sure the bit-depth is the same in both source and destination, so you're not trying to copy 32 bit data to a 24 bit surface, or the other way around.

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!