I'm looking for a way to draw a Text to a IDirect3DSurface9 implementing class. My target is to write some text into a screenshot, like the time the screenshot was taken in.
Original (working) code to make a screenshot of my Game:
void CreateScreenShot(IDirect3DDevice9* device, int screenX, int screenY)
{
IDirect3DSurface9* frontbuf; //this is our pointer to the memory location containing our copy of the front buffer
// Creation of the surface where the screen shot will be copied to
device->CreateOffscreenPlainSurface(screenX, screenY, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &frontbuf, NULL);
// Copying of the Back Buffer to our surface
HRESULT hr = device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &frontbuf);
if (hr != D3D_OK)
{
frontbuf->Release();
return;
}
// Aquiring of the Device Context of the surface to be able to draw into it
HDC surfaceDC;
if (frontbuf->GetDC(&surfaceDC) == D3D_OK)
{
drawInformationToSurface(surfaceDC, screenX);
frontbuf->ReleaseDC(surfaceDC);
}
// Saving the surface to a file. Creating the screenshot file
D3DXSaveSurfaceToFile("ScreenShot.bmp", D3DXIFF_BMP, frontbuf, NULL, NULL);
}
Now as you can see I made a helper method called drawInformationToSurface(HDC surfaceDC, int screenX)
which should write the current Time into the Surface before it gets saved to the HDD.
void drawInformationToSurface(HDC surfaceDC, int screenX)
{
// Creation of a new DC for drawing operations
HDC memDC = CreateCompatibleDC(surfaceDC);
// Aquiring of the current time String with my global Helper Method
const char* currentTimeStr = GetCurrentTimeStr();
// Preparing of the HDC
SetBkColor(memDC, 0xff000000);
SetBkMode(memDC, TRANSPARENT);
SetTextAlign(memDC, TA_TOP | TA_LEFT);
SetTextColor(memDC, GUI_FONT_COLOR_Y);
// Draw a the time to the surface
ExtTextOut(memDC, 0, 0, ETO_CLIPPED, NULL, currentTimeStr, strlen(currentTimeStr), NULL);
// Free resources for the mem DC
DeleteDC(memDC);
}
Sadly the taken ScreenShot.bmp only contains a capture of the Game but no additional Text in it.
Where did I go wrong?
CreateCompatibleDC
gives you a new DC that's compatible with an existing one, but it's not actually the same DC. When a new DC is created it has a default 1x1 bitmap selected into it - you need to select your own bitmap in its place before you can render to your memory bitmap (and then restore the old bitmap afterwards).
At the moment your drawing is all taking place to this default 1x1 bitmap and is then simply thrown away when you delete the DC.
Why are you creating a new DC at all in your drawInformationToSurface
function? To me it looks like you should be drawing straight to the passed in surfaceDC
.