Skip to main content
GameDev.net gamedev.net
🔒 Locked

C++ Capture Fullscreen Game

Started by thestone Aug 9, 2014 at 11:27 AM 1 replies 5.6k views
Original Post
thestone
thestone

Hello,

I recently started developing a game C++ and wanted to add a screenshot option for the game.

The feature works when the game is windowed but gives me a DEVICE_LOST error when the game is in fullscreen mode.

I managed to isolate my code to a single .cpp file and am testing it on regular fullscreen directX games I have installed :


#include "stdafx.h"
#include <d3d9.h>
#include <d3dx9.h>
#include "DirectXTools.h"

LPDIRECT3D9 directX;
LPDIRECT3DDEVICE9 directXDevice;

void initDevice(HWND myWindow);
void ConvertCharToWC(char* src, wchar_t* target);

void DirectXTools::CaptureWindow(const char* windowName)
{
    Sleep(5000);
    HWND windowHandle = GetForegroundWindow();
    initDevice(windowHandle);
}

void initDevice(HWND myWindow) {
    D3DDISPLAYMODE  ddm;
    D3DPRESENT_PARAMETERS   d3dpp;
    IDirect3DSurface9* g_pSurface;

    if((directX=Direct3DCreate9(D3D_SDK_VERSION))==NULL)
    {
        throw "";
    }

    if(FAILED(directX->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&ddm)))
    {
        throw "";
    }

    ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS));

    d3dpp.Windowed=FALSE;
    d3dpp.Flags=D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
    d3dpp.BackBufferFormat=ddm.Format;
    d3dpp.BackBufferHeight=ddm.Height;
    d3dpp.BackBufferWidth=ddm.Width;
    d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE;
    //  d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
    d3dpp.SwapEffect=D3DSWAPEFFECT_COPY;
    d3dpp.hDeviceWindow=myWindow;
    d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_DEFAULT;
    d3dpp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT;

    if(FAILED(directX->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,myWindow,D3DCREATE_SOFTWARE_VERTEXPROCESSING ,&d3dpp,&directXDevice)))
    {
        throw "";
    }

    if(FAILED(directXDevice->CreateOffscreenPlainSurface(ddm.Width, ddm.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &g_pSurface, NULL)))
    {
        throw "";
    }

    directXDevice->GetFrontBufferData(0, g_pSurface);
    D3DXSaveSurfaceToFile("temp.bmp",D3DXIFF_BMP,g_pSurface,NULL,NULL);
}

The error occurs at the directX->CreateDevice function. it simply returns the error code D3DERR_DEVICELOST.

Notes :

- I researched a little and found out that when a program takes fullscreen control, all other windows become lost.

The thing is, I am passing the foreground window as my device handle so it shouldn't be lost.

- Maybe GetForegroundWindow doesn't know how to handle a fullscreen program, but only windows in windowed mode.

- I tried calling the SetForegroundWindow when the program was minimized in fullscreen mode (meaning it was fullscreen and I alt + tab it) and nothing happened

I tried it again when the program was minimized in windowed mode and it worked.

Anyone has experience with capturing fullscreen games and can solve this issue?

Thanks In Advance.

#Include Graphics
#Include Graphics

Hi there,

Have you tested that the resolution, format, multisample type, etc... is already supported for your device in fullscreen mode?.

Anyway something of you initial values put in the CreateDevice method isnt compatible with your devide in that window mode, you have to test along and get the right mode for you.

Hope it helps.

cozzie
cozzie

Hi. Don't know if it helps, but here's my screenshot function (d3d9).

The main difference with fullscreen vs windowed, is that you need to specify a 'rect'/ part of the window to capture, and you need other X/Y sizes then the total backbuffercount (because your window might render a smaller part then the full backbuffer).


bool CD3d::ScreenShot() const
{
	static int nr = 0;
	++nr;

	CComPtr<IDirect3DSurface9> frontBuffer;    

	stringstream file;
	file << "screen00" << nr << ".jpg";
	string savefile = file.str();
		
    RECT				rcWindow;     
	int					x = mSettings.GetScreenWidth(), y = mSettings.GetScreenHeight();
 
	if(mSettings.GetWindowed())	
	{
		x = GetSystemMetrics(SM_CXSCREEN);
		y = GetSystemMetrics(SM_CYSCREEN);
		GetWindowRect(mHwnd, &rcWindow);   
	}
	if(FAILED(mD3ddev->CreateOffscreenPlainSurface(x, y, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &frontBuffer, NULL))) return false;     
    if(FAILED(mD3ddev->GetFrontBufferData(NULL, frontBuffer)))
	{
		frontBuffer = NULL;
        return false;    
	}
	if(!mSettings.GetWindowed()) D3DXSaveSurfaceToFileA(savefile.c_str(), D3DXIFF_JPG, frontBuffer, NULL, NULL);    
	else D3DXSaveSurfaceToFileA(savefile.c_str(), D3DXIFF_JPG, frontBuffer, NULL, &rcWindow);     
       
	frontBuffer = NULL;
    return true;
}

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.