So, getting to the metal right away. I'm writing a c++ program which purpose is to take the screen as an input image and process it with an object detector (from dlib) but I'm having troubles understanding how one can get a pointer to a swapChain and context/content of the screen.
The following code from ScreenGrab (DirectX Tool Kit) seems to be able to do the trick. The issue is that I don't know how to get it to work. I'm using NuGet in visual studio 2017 to get the library (called directxtk_uwp, there is also one called directxtk_desktop_2015 which I am not using.) and I'm getting the following six errors:
- error C2065: 'swapChain': undeclared identifier
- error C2227: left of '->GetBuffer' must point to class/struct/union/generic type
- error C2065: 'immContext': undeclared identifier
- error C2228: left of '.Get' must have class/struct/union
- error C2653: 'DX': is not a class or namespace name
- error C3861: 'ThrowIfFailed': identifier not found
from running the inserted example code from the ScreenGrab wiki-page:
#include <ScreenGrab.h>
#include <wrl\client.h>
#include <Wincodec.h>
int main() {
using namespace DirectX;
using namespace Microsoft::WRL;
ComPtr<ID3D11Texture2D> backBuffer;
HRESULT hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D),
reinterpret_cast<LPVOID*>(backBuffer.GetAddressOf()));
if (SUCCEEDED(hr))
{
hr = SaveWICTextureToFile(immContext.Get(), backBuffer.Get(),
GUID_ContainerFormatJpeg, L"SCREENSHOT.JPG");
}
DX::ThrowIfFailed(hr);
return 0;
}
I have really just started out programming with c++ and came from Java programming, which I've been actively developing in for a year now. So keeping it simple to understand would be appreciated ^^
Just to be clear, I would like something rather fast. I have gotten a screengrab to work with GDI with the following code:
#include <iostream>
#include <Windows.h>
#include <Wincodec.h>
#include <ctime>
#include <cstring>
#include <atlimage.h>
#include <d3d9.h>
using namespace std;
int main()
{
try
{
int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
HWND hDesktopWnd = GetDesktopWindow();
HDC hDesktopDC = GetDC(hDesktopWnd);
HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);
for (int i = 0; i < 10;i++) {
clock_t begin = clock();
HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hDesktopDC,
nScreenWidth, nScreenHeight);
SelectObject(hCaptureDC, hCaptureBitmap);
BitBlt(hCaptureDC, 0, 0, nScreenWidth, nScreenHeight,
hDesktopDC, 0, 0, SRCCOPY | CAPTUREBLT);
CImage image;
image.Attach(hCaptureBitmap);
image.Save("test.jpg");
DeleteObject(hCaptureBitmap);
cout << double(clock() - begin) / (clock_t)1000 << endl;
}
ReleaseDC(hDesktopWnd, hDesktopDC);
DeleteDC(hCaptureDC);
IDirect3DSurface9 *surface;
system("pause");
}
catch (exception& e)
{
cout << "\nexception thrown!" << endl;
cout << e.what() << endl;
system("pause");
}
}
which results in the following:
0.091
0.05
0.052
0.06
0.047
0.05
0.057
0.06
0.06
0.051
and as you can see, that really only gets my up to 1/0.47 ≈ 21 frames per second. I have also seen this answer, but yet again, I have no clue how to get the context and swapChain of the screen. Thank you.