当前位置:网站首页>DXGI acquisition process
DXGI acquisition process
2022-07-27 14:50:00 【Clear water welcomes the rising sun】
Catalog
One 、DXGI technological process
One 、DXGI technological process
DXGI The full name is Microsoft DirectX Graphics Infrastructure, Microsoft graphics device infrastructure .
Its work , It is to provide the interface support of the underlying hardware device for the graphics library .
Because of it , It also enables interaction between different graphic libraries , Because in DXGI in , The interface of resources is IDXGIResource, It can be converted into the interface of the upper graphic library , Such as D3D The texture of .
This article , It mainly introduces the use of DXGI Collection desktop , Compared with the traditional GDI The way , A lot more powerful .
1、 Official information
DXGI
Desktop Duplication API - Win32 apps | Microsoft Docs
2、 The official sample
You can also download it here :https://download.csdn.net/download/shuilan0066/86260425
But this example is complicated ,
The following example is simpler , from github Download from , I forgot the original address
https://download.csdn.net/download/shuilan0066/86260562
3、 Collect desktop process
The key is To get IDXGIOutputDuplication Interface , Then get desktop data through this interface
1)、 get D3D equipment
typedef struct _DX_RESOURCES
{
ID3D11Device* Device;
ID3D11DeviceContext* Context;
ID3D11VertexShader* VertexShader;
ID3D11PixelShader* PixelShader;
ID3D11InputLayout* InputLayout;
ID3D11SamplerState* SamplerLinear;
} DX_RESOURCES;DUPL_RETURN InitializeDx()
{
HRESULT hr = S_OK;
// Driver types supported
D3D_DRIVER_TYPE DriverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
UINT NumDriverTypes = ARRAYSIZE(DriverTypes);
// Feature levels supported
D3D_FEATURE_LEVEL FeatureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_1
};
UINT NumFeatureLevels = ARRAYSIZE(FeatureLevels);
D3D_FEATURE_LEVEL FeatureLevel;
// Create device
for (UINT DriverTypeIndex = 0; DriverTypeIndex < NumDriverTypes; ++DriverTypeIndex)
{
hr = D3D11CreateDevice(nullptr, DriverTypes[DriverTypeIndex], nullptr, 0, FeatureLevels, NumFeatureLevels,
D3D11_SDK_VERSION, &m_DxRes->Device, &FeatureLevel, &m_DxRes->Context);
if (SUCCEEDED(hr))
{
// Device creation success, no need to loop anymore
break;
}
}
if (FAILED(hr))
{
return ProcessFailure(nullptr, L"Failed to create device in InitializeDx", hr);
}
return DUPL_RETURN_SUCCESS;
} DX_RESOURCES *m_DxRes; m_DxRes = new (std::nothrow) DX_RESOURCES;
RtlZeroMemory(m_DxRes, sizeof(DX_RESOURCES));
DUPL_RETURN Ret = InitializeDx();
if (Ret != DUPL_RETURN_SUCCESS)
{
fprintf_s(log_file, "DX_RESOURCES couldn't be initialized.");
return Ret;
}2)、 get DXGI equipment
// Get DXGI device
IDXGIDevice* DxgiDevice = nullptr;
HRESULT hr = m_DxRes->Device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&DxgiDevice));
if (FAILED(hr))
{
return ProcessFailure(nullptr, L"Failed to QI for DXGI Device", hr);
}3)、 obtain DXGI Adapter
Adapter It can be understood as the abstract layer of our graphics card . When we create D3D Equipment time , In fact, which graphics card has been specified in the parameters , I did NULL, And the designation is of hardware type , So it will specify a default ( Of course , I just have a graphics card ). besides , You can also get IDXGIFactory object , And then call EnumAdapters Method to get something Adapter. The code is as follows
// Get DXGI adapter
IDXGIAdapter* DxgiAdapter = nullptr;
hr = DxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&DxgiAdapter));
DxgiDevice->Release();
DxgiDevice = nullptr;
if (FAILED(hr))
{
return ProcessFailure(m_DxRes->Device, L"Failed to get parent DXGI Adapter", hr, SystemTransitionsExpectedErrors);
}4)、 obtain DXGI Output
After specifying the graphics card , We are about to specify its output . We know , Sometimes we may use more than one monitor , obviously , The graphics card supports multiple display devices for output , So we need to specify which output device , We need to call IDXGIAdapter Inside EnumOutputs Method , I just have a monitor , The first parameter is filled directly 0 Just a matter of .
// Get output
IDXGIOutput* DxgiOutput = nullptr;
hr = DxgiAdapter->EnumOutputs(0, &DxgiOutput);
DxgiAdapter->Release();
DxgiAdapter = nullptr;
if (FAILED(hr))
{
return ProcessFailure(m_DxRes->Device, L"Failed to get specified output in DUPLICATIONMANAGER", hr, EnumOutputsExpectedErrors);
}5)、 obtain DXGI Output1
At this time, readers who see this title may ask again ,output1 What the hell is it , I just got it output Why? . Of course ,output1 Nor does it represent the first display , It can be said to be output An extension of , It's in DXGI 1.2 After the launch of , It contains us Desktop Duplication API Interface . Maybe Microsoft wants to be compatible with the previous interface , Let's get output, And then through output To get to the output1. obtain DXGI output1 The code for is as follows :
DxgiOutput->GetDesc(&m_OutputDesc);
// QI for Output 1
IDXGIOutput1* DxgiOutput1 = nullptr;
hr = DxgiOutput->QueryInterface(__uuidof(DxgiOutput1), reinterpret_cast<void**>(&DxgiOutput1));
DxgiOutput->Release();
DxgiOutput = nullptr;
if (FAILED(hr))
{
return ProcessFailure(nullptr, L"Failed to QI for DxgiOutput1 in DUPLICATIONMANAGER", hr);
}6)、 obtain Output Duplication
In what we just got output1 in , You can call DuplicateOutput Method to get Output Duplication, Then we can use it to collect desktop images
IDXGIOutputDuplication* m_DeskDupl;
// Create desktop duplication
hr = DxgiOutput1->DuplicateOutput(m_DxRes->Device, &m_DeskDupl);
DxgiOutput1->Release();
DxgiOutput1 = nullptr;
if (FAILED(hr))
{
if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE)
{
MessageBoxW(nullptr, L"There is already the maximum number of applications using the Desktop Duplication API running, please close one of those applications and then try again.", L"Error", MB_OK);
return DUPL_RETURN_ERROR_UNEXPECTED;
}
return ProcessFailure(m_DxRes->Device, L"Failed to get duplicate output in DUPLICATIONMANAGER", hr, CreateDuplicationExpectedErrors);
}7)、 obtain Output Desc
Before collecting desktop , We need information about display devices , In this way, it is convenient for us to do coding and rendering in the future , Such as the width and height of the display , The refresh rate , Pixel format , Scanning mode , Zoom format and so on . call GetDesc Method , We can get a structure object related to this information , You can read through it , The code is as follows :
DXGI_OUTDUPL_DESC lOutputDuplDesc;
m_DeskDupl->GetDesc(&lOutputDuplDesc);8)、 Get desktop image
At this point , We can get the desktop image , Call directly AcquireNextFrame that will do , The code is as follows :
IDXGIResource* DesktopResource = nullptr;
DXGI_OUTDUPL_FRAME_INFO FrameInfo;
// Get new frame
HRESULT hr = m_DeskDupl->AcquireNextFrame(0, &FrameInfo, &DesktopResource);
if (hr == DXGI_ERROR_WAIT_TIMEOUT)
{
return DUPL_RETURN_SUCCESS;
}
if (FAILED(hr))
{
return ProcessFailure(m_DxRes->Device, L"Failed to acquire next frame in DUPLICATIONMANAGER", hr, FrameInfoExpectedErrors);
}
IDXGIResource This is our image . We can't directly access the data inside , These data exist in video memory .
For NVIDIA's hard coding , It must be in the graphics card , So theoretically, we can throw it directly to help us code . However , NVIDIA does not support IDXGIResource Form of image input , But support DirectX Texture input (dx The minimum version is 9, Is the highest 11,12 It is not supported in official documents ), therefore , We need to turn it into dx texture , Can be thrown in for coding .
9)、 Create texture
D3D11_TEXTURE2D_DESC desc;
DXGI_OUTDUPL_DESC lOutputDuplDesc;
m_DeskDupl->GetDesc(&lOutputDuplDesc);
desc.Width = lOutputDuplDesc.ModeDesc.Width;
desc.Height = lOutputDuplDesc.ModeDesc.Height;
desc.Format = lOutputDuplDesc.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;
desc.Usage = D3D11_USAGE_STAGING;
hr = m_DxRes->Device->CreateTexture2D(&desc, NULL, &m_DestImage);
if (FAILED(hr))
{
ProcessFailure(nullptr, L"Creating cpu accessable texture failed.", hr);
return DUPL_RETURN_ERROR_UNEXPECTED;
}
if (m_DestImage == nullptr)
{
ProcessFailure(nullptr, L"Creating cpu accessable texture failed.", hr);
return DUPL_RETURN_ERROR_UNEXPECTED;
} ID3D11Texture2D* m_AcquiredDesktopImage;
// If still holding old frame, destroy it
if (m_AcquiredDesktopImage)
{
m_AcquiredDesktopImage->Release();
m_AcquiredDesktopImage = nullptr;
}
// QI for IDXGIResource
hr = DesktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void **>(&m_AcquiredDesktopImage));
DesktopResource->Release();
DesktopResource = nullptr;
if (FAILED(hr))
{
return ProcessFailure(nullptr, L"Failed to QI for ID3D11Texture2D from acquired IDXGIResource in DUPLICATIONMANAGER", hr);
}
10)、 Copy image data
void CopyImage(BYTE* ImageData)
{
m_DxRes->Context->CopyResource(m_DestImage, m_AcquiredDesktopImage);
D3D11_MAPPED_SUBRESOURCE resource;
UINT subresource = D3D11CalcSubresource(0, 0, 0);
m_DxRes->Context->Map(m_DestImage, subresource, D3D11_MAP_READ, 0, &resource);
BYTE* sptr = reinterpret_cast<BYTE*>(resource.pData);
//Store Image Pitch
m_ImagePitch = resource.RowPitch;
int height = GetImageHeight();
memcpy_s(ImageData, resource.RowPitch*height, sptr, resource.RowPitch*height);
m_DxRes->Context->Unmap(m_DestImage, subresource);
DoneWithFrame();
} Reference material :
Windows Live software development ——DXGI - Nuggets
【 Technology sharing 】Windows Desktop recording screen acquisition implementation tutorial
Use DirectX Equipment resources - Win32 apps | Microsoft Docs
边栏推荐
- 巨形象的图解 SQL
- 【云享读书会第13期】视频文件的封装格式
- Arduino+ze08-ch2o formaldehyde module, output formaldehyde content
- Database storage series (1) column storage
- Failed to connect to ResourceManager
- Research on Chinese idiom metaphorical knowledge recognition and relevance based on transfer learning and text enhancement
- Forward proxy and reverse proxy
- Annual comprehensive analysis of China's online video market in 2022
- C语言基础知识梳理总结
- Toward Fast, Flexible, and Robust Low-Light Image Enhancement(实现快速、灵活和稳健的弱光图像增强)CVPR2022
猜你喜欢

Dynamic programming - stock trading 5

Docker实践经验:Docker 上部署 mysql8 主从复制

万字详解 Google Play 上架应用标准包格式 AAB

Toward fast, flexible, and robust low light image enhancement cvpr2022
Database storage series (1) column storage

Construction of knowledge map of financial securities and discovery of related stocks from the perspective of knowledge relevance

Slam overview Reading Note 4: a survey on deep learning for localization and mapping: towards the age of spatial 2020

视觉系统设计实例(halcon-winform)-10.PLC通讯

如何做好企业系统漏洞评估

FPGA timing constraint sharing 04_ Output delay constraint
随机推荐
C语言基础练习题目
web上构建3d效果 基于three.js的实例
Skywalking distributed system application performance monitoring tool - medium
FPGA时序约束分享04_output delay 约束
JS 疫情宅在家,学习不能停,七千字长文助你彻底弄懂原型与原型链
idea打jar包与引入jar包
[ManageEngine] what is Siem
RTL8762DK 环境搭建(一)
Dynamic programming - stock trading 5
Graphical SQL is too vivid
Interprocess communication
软件产品第三方测试费用为什么没有统一的报价?
Docker practical experience: deploy mysql8 master-slave replication on docker
自动化配置SSH免密登录和取消SSH免密配置脚本
Ten thousand words detailed Google play online application standard package format AAB
网上券商APP开户安全有保障吗?
Navicate reports an error access violation at address 00000000
DXGI 方式采集流程
Lesson 3: SPFA seeking the shortest path
线程知识总结