Hello,
Firstly, I am unsure whether this problem is related to D3D11 or writing BMP file. Basically I'm trying to take screenshot of my backbuffer and write it into BMP file. However, image is extremely distorted: http://img703.imageshack.us/img703/6115/17480660.jpg. I've failed to figure what could be the problem and hope someone might help me.
Here's my code:
// get resolution
auto backbufferDimension = GetBackBufferDimensions();
// create staging texture
D3D11_TEXTURE2D_DESC desc;
desc.Width = backbufferDimension.x;
desc.Height = backbufferDimension.y;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_STAGING;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.MiscFlags = 0;
auto tex = CreateTexture2D(desc);
// copy backbuffer
GetContext()->CopyResource(tex, backbuffer);
// copy backbuffer into RAM
D3D11_MAPPED_SUBRESOURCE subresource;
GetContext()->Map(tex, 0, D3D11_MAP_READ, 0, &subresource);
uint32 size = backbufferDimension.y * subresource.RowPitch; // someone said row pitch MIGHT be bigger than width * 4
vector<uint8> pixelData(size);
memcpy(pixelData.data(), subresource.pData, size);
GetContext()->Unmap(tex, 0);
// some vars
const uint8 padding[] = {0, 0, 0};
const int paddingSize = (4 - (backbufferDimension.x * 3) % 4) % 4; // BMP's rowpitch must be multiple of 4 (?)
const int rowPitch = backbufferDimension.x * 3 + paddingSize;
// BMP header
BITMAPFILEHEADER bmfh = {};
bmfh.bfType = 'MB';
bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + rowPitch * backbufferDimension.y;
bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
// bitmap info
BITMAPINFOHEADER bmih = {};
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biBitCount = 24;
bmih.biWidth = (int32)backbufferDimension.x;
bmih.biHeight = -(int32)backbufferDimension.y;
bmih.biPlanes = 1;
bmih.biSizeImage = rowPitch * backbufferDimension.y;
// write data to file
fwrite(&bmfh, sizeof(bmfh), 1, file); // write BMP header
fwrite(&bmih, sizeof(bmih), 1, file); // write bitmap info
struct Pixel { uint8 r, g, b, a; };
for(uint32 y = 0; y < backbufferDimension.y; ++y) {
uint8 *rowStart = pixelData.data() + y * subresource.RowPitch; // address where row starts according to rowpitch
Pixel *pixels = (Pixel*)rowStart; // just a typecast from bytes into pixels
for(uint32 x = 0; x < backbufferDimension.x; ++x) {
Pixel &pixel = pixels[x]; // get x'th pixel in the row
fwrite(&pixel.b, 1, 1, file); // write colors
fwrite(&pixel.g, 1, 1, file);
fwrite(&pixel.r, 1, 1, file);
}
fwrite(padding, paddingSize, 1, file); // finish row with padding
}






