Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- template <typename T>
- class CComPtrCustom
- {
- public:
- CComPtrCustom(T *aPtrElement)
- :element(aPtrElement)
- {
- }
- CComPtrCustom()
- :element(nullptr)
- {
- }
- virtual ~CComPtrCustom()
- {
- Release();
- }
- T* Detach()
- {
- auto lOutPtr = element;
- element = nullptr;
- return lOutPtr;
- }
- T* detach()
- {
- return Detach();
- }
- void Release()
- {
- if (element == nullptr)
- return;
- auto k = element->Release();
- element = nullptr;
- }
- CComPtrCustom& operator = (T *pElement)
- {
- Release();
- if (pElement == nullptr)
- return *this;
- auto k = pElement->AddRef();
- element = pElement;
- return *this;
- }
- void Swap(CComPtrCustom& other)
- {
- T* pTemp = element;
- element = other.element;
- other.element = pTemp;
- }
- T* operator->()
- {
- return element;
- }
- operator T*()
- {
- return element;
- }
- operator T*() const
- {
- return element;
- }
- T* get()
- {
- return element;
- }
- T* get() const
- {
- return element;
- }
- T** operator &()
- {
- return &element;
- }
- bool operator !()const
- {
- return element == nullptr;
- }
- operator bool()const
- {
- return element != nullptr;
- }
- bool operator == (const T *pElement)const
- {
- return element == pElement;
- }
- CComPtrCustom(const CComPtrCustom& aCComPtrCustom)
- {
- if (aCComPtrCustom.operator!())
- {
- element = nullptr;
- return;
- }
- element = aCComPtrCustom;
- auto h = element->AddRef();
- h++;
- }
- CComPtrCustom& operator = (const CComPtrCustom& aCComPtrCustom)
- {
- Release();
- element = aCComPtrCustom;
- auto k = element->AddRef();
- return *this;
- }
- _Check_return_ HRESULT CopyTo(T** ppT) throw()
- {
- if (ppT == NULL)
- return E_POINTER;
- *ppT = element;
- if (element)
- element->AddRef();
- return S_OK;
- }
- HRESULT CoCreateInstance(const CLSID aCLSID)
- {
- T* lPtrTemp;
- auto lresult = ::CoCreateInstance(aCLSID, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&lPtrTemp));
- if (SUCCEEDED(lresult))
- {
- if (lPtrTemp != nullptr)
- {
- Release();
- element = lPtrTemp;
- }
- }
- return lresult;
- }
- protected:
- T* element;
- };
- // Driver types supported
- D3D_DRIVER_TYPE gDriverTypes[] =
- {
- D3D_DRIVER_TYPE_HARDWARE
- };
- UINT gNumDriverTypes = ARRAYSIZE(gDriverTypes);
- // Feature levels supported
- D3D_FEATURE_LEVEL gFeatureLevels[] =
- {
- D3D_FEATURE_LEVEL_11_0,
- D3D_FEATURE_LEVEL_10_1,
- D3D_FEATURE_LEVEL_10_0,
- D3D_FEATURE_LEVEL_9_1
- };
- UINT gNumFeatureLevels = ARRAYSIZE(gFeatureLevels);
- void main()
- {
- for (int i = 0; i < 20; i++)
- {
- auto start = std::chrono::high_resolution_clock::now();
- HRESULT hr;
- CComPtrCustom<ID3D11Device> pDevice;
- CComPtrCustom<ID3D11DeviceContext> pImmediateContext;
- CComPtrCustom<IDXGIOutputDuplication> pDeskDupl;
- DXGI_OUTDUPL_DESC OutputDuplDesc;
- CComPtrCustom<ID3D11Texture2D> AcquiredDesktopImage;
- CComPtrCustom<ID3D11Texture2D> pGdiImg;
- CComPtrCustom<ID3D11Texture2D> pDestImg;
- DXGI_OUTPUT_DESC OutputDesc;
- D3D_FEATURE_LEVEL FeatureLevel;
- // Create device
- hr = D3D11CreateDevice(NULL,
- gDriverTypes[0], NULL, 0,
- gFeatureLevels, gNumFeatureLevels,
- D3D11_SDK_VERSION,
- &pDevice, &FeatureLevel,
- &pImmediateContext);
- EXIT_(hr);
- // Get DXGI device
- CComPtrCustom<IDXGIDevice> lDxgiDevice;
- hr = pDevice->QueryInterface(IID_PPV_ARGS(&lDxgiDevice));
- EXIT_(hr);
- // Get DXGI adapter
- CComPtrCustom<IDXGIAdapter> lDxgiAdapter;
- hr = lDxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&lDxgiAdapter));
- EXIT_(hr);
- lDxgiDevice.Release();
- // Get output
- CComPtrCustom<IDXGIOutput> lDxgiOutput;
- hr = lDxgiAdapter->EnumOutputs(0, &lDxgiOutput);
- EXIT_(hr);
- lDxgiAdapter.Release();
- hr = lDxgiOutput->GetDesc(&OutputDesc);
- EXIT_(hr);
- // QI for Output 1
- CComPtrCustom<IDXGIOutput1> lDxgiOutput1;
- hr = lDxgiOutput->QueryInterface(IID_PPV_ARGS(&lDxgiOutput1));
- EXIT_(hr);
- lDxgiOutput.Release();
- // Create desktop duplication
- hr = lDxgiOutput1->DuplicateOutput(pDevice, &pDeskDupl);
- EXIT_(hr);
- lDxgiOutput1.Release();
- pDeskDupl->GetDesc(&OutputDuplDesc);
- // Create GUI drawing texture
- D3D11_TEXTURE2D_DESC desc;
- desc.Width = OutputDuplDesc.ModeDesc.Width;
- desc.Height = OutputDuplDesc.ModeDesc.Height;
- desc.Format = OutputDuplDesc.ModeDesc.Format;
- desc.ArraySize = 1;
- desc.BindFlags = D3D11_BIND_FLAG::D3D11_BIND_RENDER_TARGET;
- desc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
- desc.SampleDesc.Count = 1;
- desc.SampleDesc.Quality = 0;
- desc.MipLevels = 1;
- desc.CPUAccessFlags = 0;
- desc.Usage = D3D11_USAGE_DEFAULT;
- hr = pDevice->CreateTexture2D(&desc, NULL, &pGdiImg);
- EXIT_(hr);
- // Create CPU access texture
- desc.Width = OutputDuplDesc.ModeDesc.Width;
- desc.Height = OutputDuplDesc.ModeDesc.Height;
- desc.Format = OutputDuplDesc.ModeDesc.Format;
- desc.ArraySize = 1;
- desc.BindFlags = 0;
- desc.MiscFlags = 0;
- desc.SampleDesc.Count = 1;
- desc.SampleDesc.Quality = 0;
- desc.MipLevels = 1;
- desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
- desc.Usage = D3D11_USAGE_STAGING;
- hr = pDevice->CreateTexture2D(&desc, NULL, &pDestImg);
- EXIT_(hr);
- CComPtrCustom<IDXGIResource> lDesktopResource;
- DXGI_OUTDUPL_FRAME_INFO lFrameInfo;
- // Get new frame
- hr = pDeskDupl->AcquireNextFrame(
- 250,
- &lFrameInfo,
- &lDesktopResource);
- // QI for ID3D11Texture2D
- hr = lDesktopResource->QueryInterface(IID_PPV_ARGS(&AcquiredDesktopImage));
- EXIT_(hr);
- lDesktopResource.Release();
- // Copy image into GDI drawing texture
- pImmediateContext->CopyResource(pGdiImg, AcquiredDesktopImage);
- // Draw cursor image into GDI drawing texture
- CComPtrCustom<IDXGISurface1> lIDXGISurface1;
- hr = pGdiImg->QueryInterface(IID_PPV_ARGS(&lIDXGISurface1));
- EXIT_(hr);
- // Copy image into CPU access texture
- pImmediateContext->CopyResource(pDestImg, pGdiImg);
- // Copy from CPU access texture to bitmap buffer
- D3D11_MAPPED_SUBRESOURCE resource;
- UINT subresource = D3D11CalcSubresource(0, 0, 0);
- pImmediateContext->Map(pDestImg, subresource, D3D11_MAP_READ_WRITE, 0, &resource);
- auto finish = std::chrono::high_resolution_clock::now();
- std::cout << "Time: " << std::chrono::duration_cast<std::chrono::microseconds>(finish - start).count() << std::endl;
- // BMP 32 bpp
- BITMAPINFO lBmpInfo;
- ZeroMemory(&lBmpInfo, sizeof(BITMAPINFO));
- lBmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- lBmpInfo.bmiHeader.biBitCount = 32;
- lBmpInfo.bmiHeader.biCompression = BI_RGB;
- lBmpInfo.bmiHeader.biWidth = OutputDuplDesc.ModeDesc.Width;
- lBmpInfo.bmiHeader.biHeight = OutputDuplDesc.ModeDesc.Height;
- lBmpInfo.bmiHeader.biPlanes = 1;
- lBmpInfo.bmiHeader.biSizeImage = OutputDuplDesc.ModeDesc.Width * OutputDuplDesc.ModeDesc.Height * 4;
- std::unique_ptr<BYTE> pBuf(new BYTE[lBmpInfo.bmiHeader.biSizeImage]);
- UINT lBmpRowPitch = OutputDuplDesc.ModeDesc.Width * 4;
- BYTE* sptr = reinterpret_cast<BYTE*>(resource.pData);
- BYTE* dptr = pBuf.get() + lBmpInfo.bmiHeader.biSizeImage - lBmpRowPitch;
- UINT lRowPitch = std::min<UINT>(lBmpRowPitch, resource.RowPitch);
- for (size_t h = 0; h < OutputDuplDesc.ModeDesc.Height; ++h)
- {
- memcpy_s(dptr, lBmpRowPitch, sptr, lRowPitch);
- sptr += resource.RowPitch;
- dptr -= lBmpRowPitch;
- }
- // Save bitmap buffer into the file ScreenShot.bmp
- FILE* lfile = NULL;
- TCHAR name[100];
- swprintf(name, L"cap%i.bmp", i);
- auto lerr = _wfopen_s(&lfile, name, L"wb");
- if (lfile != NULL && lerr == 0)
- {
- BITMAPFILEHEADER bmpFileHeader;
- bmpFileHeader.bfReserved1 = 0;
- bmpFileHeader.bfReserved2 = 0;
- bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + lBmpInfo.bmiHeader.biSizeImage;
- bmpFileHeader.bfType = 'MB';
- bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
- fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, lfile);
- fwrite(&lBmpInfo.bmiHeader, sizeof(BITMAPINFOHEADER), 1, lfile);
- fwrite(pBuf.get(), lBmpInfo.bmiHeader.biSizeImage, 1, lfile);
- fclose(lfile);
- }
- wprintf(name);
- printf("\n");
- }
- system("pause");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement