Richard Robinson
Richard Robinson

Reputation: 997

How to capture HDR framebuffer in Windows?

I use the following code to read the standard 8-bit framebuffer, however I need to read the 10-bit HDR framebuffer that's used for HDR content on my HDR monitor.

As far as I can tell, BI_RGB is the only relevant enum option. Here's what I have so far, which works for 8-bit channels:

#include <iostream>
#include <windows.h>
#include <fstream>

void capture_screen() {
 int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
 int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);

 HWND hDesktopWnd = GetDesktopWindow();
 HDC hDesktopDC = GetDC(NULL);
 HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);

 HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hDesktopDC, nScreenWidth, nScreenHeight);
 SelectObject(hCaptureDC, hCaptureBitmap);

 BitBlt(hCaptureDC, 0, 0, nScreenWidth, nScreenHeight, hDesktopDC, 0, 0, SRCCOPY | CAPTUREBLT);

 BITMAPINFO bmi = { 0 };

 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
 bmi.bmiHeader.biWidth = nScreenWidth;
 bmi.bmiHeader.biHeight = nScreenHeight;

 bmi.bmiHeader.biPlanes = 1;
 bmi.bmiHeader.biBitCount = 32;
 bmi.bmiHeader.biCompression = BI_RGB;

 auto* pPixels = new RGBQUAD[nScreenWidth * nScreenHeight];

 GetDIBits(hCaptureDC, hCaptureBitmap, 0,nScreenHeight, pPixels, &bmi, DIB_RGB_COLORS);

 //...               
 delete[] pPixels;

 ReleaseDC(hDesktopWnd, hDesktopDC);
 DeleteDC(hCaptureDC);
 DeleteObject(hCaptureBitmap);
}

Upvotes: 3

Views: 1992

Answers (1)

Strive Sun
Strive Sun

Reputation: 6299

Direct3D has added HDR-related features to recent API updates, which use a new interface with the last digits. To access them, you must first query their underlying objects.

Example:

IDXGIOutput* output = /* initialize output */;
IDXGIOutput6* output6;
HRESULT hr = output->QueryInterface(__uuidof(IDXGIOutput6), (void**)&output6);
if(SUCCEEDED(hr)) {
    // Use output6...
    output6->Release();
} else {
    // Error!
}

You will be able to successfully compile this code only if you have sufficiently new version of Windows SDK installed. The code will execute successfully (as opposed to failing with an error code) only if the user has sufficiently new version of Windows 10.

You can then query for monitor capabilities by calling function IDXGIOutput6::GetDesc1. You get structure DXGI_OUTPUT_DESC1 filled, which describes available color space, bits per component, red/green/blue primaries, white point, and the range of luminances available on the device.

Upvotes: 1

Related Questions