Как я могу захватить многоуровневые окна с DirectX?

0

Я разрабатываю приложение захвата экрана с помощью DirectX, приложение работает в большинстве ситуаций, за исключением случаев, когда на экране есть многоуровневые окна, которые игнорируются при захвате DirectX.

Я знаю, используя GDI, я могу использовать флаг CAPTUREBLT для захвата этих окон, но я не знаю, как это сделать с DirectX, поэтому мой вопрос:

Используя DirectX, как я могу захватывать слоистые окна?

Мой код:

LPDIRECT3D9 d3d9;
LPDIRECT3DDEVICE9 d3ddev;
IDirect3DSurface9* dest;

void Init()
{
    CoInitialize(NULL);

    d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

    ww = GetSystemMetrics(SM_CXSCREEN);
    wh = GetSystemMetrics(SM_CYSCREEN);

    HWND hwnd = GetDesktopWindow();
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp, sizeof(d3dpp));
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.BackBufferCount = 1;
    d3dpp.BackBufferWidth = ww;
    d3dpp.BackBufferHeight = wh;
    d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
    d3dpp.MultiSampleQuality = 0;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
    d3dpp.hDeviceWindow = hwnd;
    d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
    d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;

    d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);

    d3ddev->CreateOffscreenPlainSurface(ww, wh, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &dest, NULL);
}


void Screenshot()
{
    d3ddev->GetFrontBufferData(0, dest);

    D3DLOCKED_RECT rect;
    ZeroMemory(&rect, sizeof(D3DLOCKED_RECT));
    dest->LockRect(&rect, NULL, D3DLOCK_READONLY);
    uchar *bits = (uchar*)rect.pBits;
    dest->UnlockRect();

    //Use bits
}

void End()
{
    dest->Release();
    d3ddev->Release();
    d3d9->Release();

    CoUninitialize();
}
  • 0
    Почему вы подразумеваете под слоем окна? Поверхности наложения?
  • 0
    Когда я имею в виду многослойные окна, я имею в виду этот ответ: stackoverflow.com/a/1194281/2014561 , который работает для захвата экрана без игнорирования какого-либо окна, но это GDI-способ захвата экрана. Я не уверен, что это оверлейная поверхность.
Теги:
directx
screen-capture

1 ответ

0

Я фиксирую экран в Direct-X, используя:

HRESULT dxReadPixels(IDirect3DDevice9* Device, void* Buffer, HDC& DC, int& Width, int& Height, D3DFORMAT Format)
{
    IDirect3DSurface9* RenderTarget = nullptr;
    IDirect3DSurface9* DestTarget = nullptr;
    HRESULT result = Device->GetRenderTarget(0, &RenderTarget);

    if (result == S_OK)
    {
        if (Width == 0 || Height == 0 || Format == D3DFMT_UNKNOWN)
        {
            D3DSURFACE_DESC descriptor = {};
            RenderTarget->GetDesc(&descriptor);
            Width = descriptor.Width;
            Height = descriptor.Height;
            Format = descriptor.Format;
        }

        if (Buffer)
        {
            RenderTarget->GetDC(&DC);
            result = Device->CreateOffscreenPlainSurface(Width, Height, Format, D3DPOOL_SYSTEMMEM, &DestTarget, nullptr);
            result = Device->GetRenderTargetData(RenderTarget, DestTarget);

            D3DLOCKED_RECT rect;
            DestTarget->LockRect(&rect, 0, D3DLOCK_READONLY);
            memcpy(Buffer, rect.pBits, Width * Height * 4);
            DestTarget->UnlockRect();
        }
    }

    SafeRelease(RenderTarget);
    SafeRelease(DestTarget);
    return result;
}

Не уверен ни в каком способе сделать это быстрее или что-то еще, но он работает достаточно хорошо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню