style: Format source code and support grouping client
This commit is contained in:
@@ -11,201 +11,211 @@
|
||||
#pragma comment(lib, "d3d11.lib")
|
||||
#pragma comment(lib, "dxgi.lib")
|
||||
|
||||
// author: ChatGPT
|
||||
// author: ChatGPT
|
||||
// update: 962914132@qq.com
|
||||
// DXGI 1.2<EFBFBD><EFBFBD>IDXGIOutputDuplication<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>ͳ GDI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD> 3 <20><><EFBFBD><EFBFBD> 10 <20><>֮<EFBFBD>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1>ʺ<EFBFBD>ʹ<EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><EFBFBD>
|
||||
class ScreenCapturerDXGI : public ScreenCapture {
|
||||
class ScreenCapturerDXGI : public ScreenCapture
|
||||
{
|
||||
private:
|
||||
ID3D11Device* d3dDevice = nullptr;
|
||||
ID3D11DeviceContext* d3dContext = nullptr;
|
||||
IDXGIOutputDuplication* deskDupl = nullptr;
|
||||
ID3D11Texture2D* cpuTexture = nullptr;
|
||||
BYTE* m_NextBuffer = nullptr;
|
||||
ID3D11Device* d3dDevice = nullptr;
|
||||
ID3D11DeviceContext* d3dContext = nullptr;
|
||||
IDXGIOutputDuplication* deskDupl = nullptr;
|
||||
ID3D11Texture2D* cpuTexture = nullptr;
|
||||
BYTE* m_NextBuffer = nullptr;
|
||||
|
||||
public:
|
||||
ScreenCapturerDXGI(BYTE algo, int gop = DEFAULT_GOP, BOOL all = FALSE) : ScreenCapture(32, algo, all) {
|
||||
m_GOP = gop;
|
||||
InitDXGI(all);
|
||||
Mprintf("Capture screen with DXGI: GOP= %d\n", m_GOP);
|
||||
}
|
||||
ScreenCapturerDXGI(BYTE algo, int gop = DEFAULT_GOP, BOOL all = FALSE) : ScreenCapture(32, algo, all)
|
||||
{
|
||||
m_GOP = gop;
|
||||
InitDXGI(all);
|
||||
Mprintf("Capture screen with DXGI: GOP= %d\n", m_GOP);
|
||||
}
|
||||
|
||||
~ScreenCapturerDXGI() {
|
||||
CleanupDXGI();
|
||||
~ScreenCapturerDXGI()
|
||||
{
|
||||
CleanupDXGI();
|
||||
|
||||
SAFE_DELETE_ARRAY(m_FirstBuffer);
|
||||
SAFE_DELETE_ARRAY(m_NextBuffer);
|
||||
SAFE_DELETE_ARRAY(m_RectBuffer);
|
||||
}
|
||||
SAFE_DELETE_ARRAY(m_FirstBuffer);
|
||||
SAFE_DELETE_ARRAY(m_NextBuffer);
|
||||
SAFE_DELETE_ARRAY(m_RectBuffer);
|
||||
}
|
||||
|
||||
void InitDXGI(BOOL all) {
|
||||
m_iScreenX = 0;
|
||||
m_iScreenY = 0;
|
||||
// 1. <20><><EFBFBD><EFBFBD> D3D11 <20>豸
|
||||
D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, nullptr, 0, D3D11_SDK_VERSION, &d3dDevice, nullptr, &d3dContext);
|
||||
|
||||
IDXGIFactory1* pFactory = nullptr;
|
||||
IDXGIAdapter1* dxgiAdapter = nullptr;
|
||||
IDXGIOutput* dxgiOutput = nullptr;
|
||||
IDXGIOutput1* dxgiOutput1 = nullptr;
|
||||
void InitDXGI(BOOL all)
|
||||
{
|
||||
m_iScreenX = 0;
|
||||
m_iScreenY = 0;
|
||||
// 1. <20><><EFBFBD><EFBFBD> D3D11 <20>豸
|
||||
D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, nullptr, 0, D3D11_SDK_VERSION, &d3dDevice, nullptr, &d3dContext);
|
||||
|
||||
// 2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory);
|
||||
if (!pFactory) return;
|
||||
IDXGIFactory1* pFactory = nullptr;
|
||||
IDXGIAdapter1* dxgiAdapter = nullptr;
|
||||
IDXGIOutput* dxgiOutput = nullptr;
|
||||
IDXGIOutput1* dxgiOutput1 = nullptr;
|
||||
|
||||
do {
|
||||
// 3. <20><>ȡ<EFBFBD>豸
|
||||
static UINT idx = 0;
|
||||
idx = pFactory->EnumAdapters1(idx, &dxgiAdapter) == DXGI_ERROR_NOT_FOUND ? 0 : idx;
|
||||
if (!dxgiAdapter) pFactory->EnumAdapters1(idx, &dxgiAdapter);
|
||||
if (!dxgiAdapter)break;
|
||||
// 2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory);
|
||||
if (!pFactory) return;
|
||||
|
||||
// 4. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB>
|
||||
static UINT screen = 0;
|
||||
HRESULT r = dxgiAdapter->EnumOutputs(screen++, &dxgiOutput);
|
||||
if (r == DXGI_ERROR_NOT_FOUND && all) {
|
||||
screen = 0;
|
||||
idx ++;
|
||||
dxgiAdapter->Release();
|
||||
dxgiAdapter = nullptr;
|
||||
continue;
|
||||
}
|
||||
if (!dxgiOutput)break;
|
||||
do {
|
||||
// 3. <20><>ȡ<EFBFBD>豸
|
||||
static UINT idx = 0;
|
||||
idx = pFactory->EnumAdapters1(idx, &dxgiAdapter) == DXGI_ERROR_NOT_FOUND ? 0 : idx;
|
||||
if (!dxgiAdapter) pFactory->EnumAdapters1(idx, &dxgiAdapter);
|
||||
if (!dxgiAdapter)break;
|
||||
|
||||
// 5. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD> 1
|
||||
dxgiOutput->QueryInterface(__uuidof(IDXGIOutput1), (void**)&dxgiOutput1);
|
||||
if (!dxgiOutput1)break;
|
||||
// 4. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD>
|
||||
static UINT screen = 0;
|
||||
HRESULT r = dxgiAdapter->EnumOutputs(screen++, &dxgiOutput);
|
||||
if (r == DXGI_ERROR_NOT_FOUND && all) {
|
||||
screen = 0;
|
||||
idx ++;
|
||||
dxgiAdapter->Release();
|
||||
dxgiAdapter = nullptr;
|
||||
continue;
|
||||
}
|
||||
if (!dxgiOutput)break;
|
||||
|
||||
// 6. <20><><EFBFBD><EFBFBD> Desktop Duplication
|
||||
dxgiOutput1->DuplicateOutput(d3dDevice, &deskDupl);
|
||||
if (!deskDupl)break;
|
||||
// 5. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD> 1
|
||||
dxgiOutput->QueryInterface(__uuidof(IDXGIOutput1), (void**)&dxgiOutput1);
|
||||
if (!dxgiOutput1)break;
|
||||
|
||||
// 7. <20><>ȡ<EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD>С
|
||||
DXGI_OUTDUPL_DESC duplDesc;
|
||||
deskDupl->GetDesc(&duplDesc);
|
||||
m_ulFullWidth = duplDesc.ModeDesc.Width;
|
||||
m_ulFullHeight = duplDesc.ModeDesc.Height;
|
||||
// 6. <20><><EFBFBD><EFBFBD> Desktop Duplication
|
||||
dxgiOutput1->DuplicateOutput(d3dDevice, &deskDupl);
|
||||
if (!deskDupl)break;
|
||||
|
||||
// 8. <20><><EFBFBD><EFBFBD> CPU <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
D3D11_TEXTURE2D_DESC desc = {};
|
||||
desc.Width = m_ulFullWidth;
|
||||
desc.Height = m_ulFullHeight;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Usage = D3D11_USAGE_STAGING;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
d3dDevice->CreateTexture2D(&desc, NULL, &cpuTexture);
|
||||
// 7. <20><>ȡ<EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD>С
|
||||
DXGI_OUTDUPL_DESC duplDesc;
|
||||
deskDupl->GetDesc(&duplDesc);
|
||||
m_ulFullWidth = duplDesc.ModeDesc.Width;
|
||||
m_ulFullHeight = duplDesc.ModeDesc.Height;
|
||||
|
||||
// 9. <20><>ʼ<EFBFBD><EFBFBD> BITMAPINFO
|
||||
m_BitmapInfor_Full = (BITMAPINFO*)new char[sizeof(BITMAPINFO)];
|
||||
memset(m_BitmapInfor_Full, 0, sizeof(BITMAPINFO));
|
||||
m_BitmapInfor_Full->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
m_BitmapInfor_Full->bmiHeader.biWidth = m_ulFullWidth;
|
||||
m_BitmapInfor_Full->bmiHeader.biHeight = m_ulFullHeight;
|
||||
m_BitmapInfor_Full->bmiHeader.biPlanes = 1;
|
||||
m_BitmapInfor_Full->bmiHeader.biBitCount = 32;
|
||||
m_BitmapInfor_Full->bmiHeader.biCompression = BI_RGB;
|
||||
m_BitmapInfor_Full->bmiHeader.biSizeImage = m_ulFullWidth * m_ulFullHeight * 4;
|
||||
// 8. <20><><EFBFBD><EFBFBD> CPU <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
D3D11_TEXTURE2D_DESC desc = {};
|
||||
desc.Width = m_ulFullWidth;
|
||||
desc.Height = m_ulFullHeight;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Usage = D3D11_USAGE_STAGING;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
d3dDevice->CreateTexture2D(&desc, NULL, &cpuTexture);
|
||||
|
||||
// 10. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
m_FirstBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
|
||||
m_NextBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
|
||||
m_RectBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage * 2 + 12];
|
||||
// 9. <20><>ʼ<EFBFBD><EFBFBD> BITMAPINFO
|
||||
m_BitmapInfor_Full = (BITMAPINFO*)new char[sizeof(BITMAPINFO)];
|
||||
memset(m_BitmapInfor_Full, 0, sizeof(BITMAPINFO));
|
||||
m_BitmapInfor_Full->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
m_BitmapInfor_Full->bmiHeader.biWidth = m_ulFullWidth;
|
||||
m_BitmapInfor_Full->bmiHeader.biHeight = m_ulFullHeight;
|
||||
m_BitmapInfor_Full->bmiHeader.biPlanes = 1;
|
||||
m_BitmapInfor_Full->bmiHeader.biBitCount = 32;
|
||||
m_BitmapInfor_Full->bmiHeader.biCompression = BI_RGB;
|
||||
m_BitmapInfor_Full->bmiHeader.biSizeImage = m_ulFullWidth * m_ulFullHeight * 4;
|
||||
|
||||
break;
|
||||
} while (true);
|
||||
// 10. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
m_FirstBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
|
||||
m_NextBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
|
||||
m_RectBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage * 2 + 12];
|
||||
|
||||
// <20>ͷ<EFBFBD> DXGI <20><>Դ
|
||||
if (dxgiOutput1) dxgiOutput1->Release();
|
||||
if (dxgiOutput) dxgiOutput->Release();
|
||||
if (dxgiAdapter) dxgiAdapter->Release();
|
||||
if (pFactory) pFactory->Release();
|
||||
}
|
||||
break;
|
||||
} while (true);
|
||||
|
||||
bool IsInitSucceed() const {
|
||||
return cpuTexture;
|
||||
}
|
||||
// <20>ͷ<EFBFBD> DXGI <20><>Դ
|
||||
if (dxgiOutput1) dxgiOutput1->Release();
|
||||
if (dxgiOutput) dxgiOutput->Release();
|
||||
if (dxgiAdapter) dxgiAdapter->Release();
|
||||
if (pFactory) pFactory->Release();
|
||||
}
|
||||
|
||||
void CleanupDXGI() {
|
||||
if (cpuTexture) cpuTexture->Release();
|
||||
if (deskDupl) deskDupl->Release();
|
||||
if (d3dContext) d3dContext->Release();
|
||||
if (d3dDevice) d3dDevice->Release();
|
||||
}
|
||||
bool IsInitSucceed() const
|
||||
{
|
||||
return cpuTexture;
|
||||
}
|
||||
|
||||
LPBYTE GetFirstScreenData(ULONG* ulFirstScreenLength) override {
|
||||
int ret = CaptureFrame(m_FirstBuffer, ulFirstScreenLength, 1);
|
||||
if (ret)
|
||||
return nullptr;
|
||||
if (m_bAlgorithm == ALGORITHM_GRAY) {
|
||||
ToGray(1 + m_RectBuffer, 1 + m_RectBuffer, m_BitmapInfor_Full->bmiHeader.biSizeImage);
|
||||
}
|
||||
m_FirstBuffer[0] = TOKEN_FIRSTSCREEN;
|
||||
return m_FirstBuffer;
|
||||
}
|
||||
void CleanupDXGI()
|
||||
{
|
||||
if (cpuTexture) cpuTexture->Release();
|
||||
if (deskDupl) deskDupl->Release();
|
||||
if (d3dContext) d3dContext->Release();
|
||||
if (d3dDevice) d3dDevice->Release();
|
||||
}
|
||||
|
||||
LPBYTE ScanNextScreen() override {
|
||||
ULONG ulNextScreenLength = 0;
|
||||
int ret = CaptureFrame(m_NextBuffer, &ulNextScreenLength, 0);
|
||||
if (ret)
|
||||
return nullptr;
|
||||
|
||||
return m_NextBuffer;
|
||||
}
|
||||
LPBYTE GetFirstScreenData(ULONG* ulFirstScreenLength) override
|
||||
{
|
||||
int ret = CaptureFrame(m_FirstBuffer, ulFirstScreenLength, 1);
|
||||
if (ret)
|
||||
return nullptr;
|
||||
if (m_bAlgorithm == ALGORITHM_GRAY) {
|
||||
ToGray(1 + m_RectBuffer, 1 + m_RectBuffer, m_BitmapInfor_Full->bmiHeader.biSizeImage);
|
||||
}
|
||||
m_FirstBuffer[0] = TOKEN_FIRSTSCREEN;
|
||||
return m_FirstBuffer;
|
||||
}
|
||||
|
||||
virtual LPBYTE GetFirstBuffer() const {
|
||||
return m_FirstBuffer + 1;
|
||||
}
|
||||
LPBYTE ScanNextScreen() override
|
||||
{
|
||||
ULONG ulNextScreenLength = 0;
|
||||
int ret = CaptureFrame(m_NextBuffer, &ulNextScreenLength, 0);
|
||||
if (ret)
|
||||
return nullptr;
|
||||
|
||||
return m_NextBuffer;
|
||||
}
|
||||
|
||||
virtual LPBYTE GetFirstBuffer() const
|
||||
{
|
||||
return m_FirstBuffer + 1;
|
||||
}
|
||||
|
||||
private:
|
||||
int CaptureFrame(LPBYTE buffer, ULONG* frameSize, int reservedBytes) {
|
||||
// 1. <20><>ȡ<EFBFBD><C8A1>һ֡
|
||||
IDXGIResource* desktopResource = nullptr;
|
||||
DXGI_OUTDUPL_FRAME_INFO frameInfo;
|
||||
HRESULT hr = deskDupl->AcquireNextFrame(100, &frameInfo, &desktopResource);
|
||||
if (FAILED(hr)) {
|
||||
return -1;
|
||||
}
|
||||
int CaptureFrame(LPBYTE buffer, ULONG* frameSize, int reservedBytes)
|
||||
{
|
||||
// 1. <20><>ȡ<EFBFBD><C8A1>һ֡
|
||||
IDXGIResource* desktopResource = nullptr;
|
||||
DXGI_OUTDUPL_FRAME_INFO frameInfo;
|
||||
HRESULT hr = deskDupl->AcquireNextFrame(100, &frameInfo, &desktopResource);
|
||||
if (FAILED(hr)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 2. <20><>ȡ ID3D11Texture2D
|
||||
ID3D11Texture2D* texture = nullptr;
|
||||
hr = desktopResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&texture);
|
||||
if (FAILED(hr)) {
|
||||
deskDupl->ReleaseFrame();
|
||||
return -2;
|
||||
}
|
||||
// 2. <20><>ȡ ID3D11Texture2D
|
||||
ID3D11Texture2D* texture = nullptr;
|
||||
hr = desktopResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&texture);
|
||||
if (FAILED(hr)) {
|
||||
deskDupl->ReleaseFrame();
|
||||
return -2;
|
||||
}
|
||||
|
||||
// 3. <20><><EFBFBD>Ƶ<EFBFBD> CPU <20><><EFBFBD><EFBFBD>
|
||||
d3dContext->CopyResource(cpuTexture, texture);
|
||||
// 3. <20><><EFBFBD>Ƶ<EFBFBD> CPU <20><><EFBFBD><EFBFBD>
|
||||
d3dContext->CopyResource(cpuTexture, texture);
|
||||
|
||||
// 4. <20>ͷ<EFBFBD> DXGI <20><>Դ
|
||||
deskDupl->ReleaseFrame();
|
||||
texture->Release();
|
||||
desktopResource->Release();
|
||||
// 4. <20>ͷ<EFBFBD> DXGI <20><>Դ
|
||||
deskDupl->ReleaseFrame();
|
||||
texture->Release();
|
||||
desktopResource->Release();
|
||||
|
||||
// 5. <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
D3D11_MAPPED_SUBRESOURCE mapped;
|
||||
hr = d3dContext->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mapped);
|
||||
if (FAILED(hr)) {
|
||||
return -3;
|
||||
}
|
||||
// 5. <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
D3D11_MAPPED_SUBRESOURCE mapped;
|
||||
hr = d3dContext->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mapped);
|
||||
if (FAILED(hr)) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
// 6. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1>ת<EFBFBD><D7AA>
|
||||
BYTE* pData = (BYTE*)mapped.pData;
|
||||
int rowSize = m_ulFullWidth * 4; // ÿ<>е<EFBFBD><D0B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>RGBA<42><41>
|
||||
// 6. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1>ת<EFBFBD><D7AA>
|
||||
BYTE* pData = (BYTE*)mapped.pData;
|
||||
int rowSize = m_ulFullWidth * 4; // ÿ<>е<EFBFBD><D0B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>RGBA<42><41>
|
||||
|
||||
for (int y = 0; y < m_ulFullHeight; y++) {
|
||||
// <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD>껺<EFBFBD><EABBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD><C3A3>ӵײ<D3B5><D7B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
int destIndex = reservedBytes + (m_ulFullHeight - 1 - y) * rowSize;
|
||||
int srcIndex = y * mapped.RowPitch; // Direct3D <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB>
|
||||
memcpy(buffer + destIndex, pData + srcIndex, rowSize);
|
||||
}
|
||||
for (int y = 0; y < m_ulFullHeight; y++) {
|
||||
// <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD>껺<EFBFBD><EABBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD><C3A3>ӵײ<D3B5><D7B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
int destIndex = reservedBytes + (m_ulFullHeight - 1 - y) * rowSize;
|
||||
int srcIndex = y * mapped.RowPitch; // Direct3D <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB>
|
||||
memcpy(buffer + destIndex, pData + srcIndex, rowSize);
|
||||
}
|
||||
|
||||
// 7. <20><><EFBFBD><EFBFBD>
|
||||
d3dContext->Unmap(cpuTexture, 0);
|
||||
// 7. <20><><EFBFBD><EFBFBD>
|
||||
d3dContext->Unmap(cpuTexture, 0);
|
||||
|
||||
*frameSize = m_ulFullWidth * m_ulFullHeight * 4;
|
||||
return 0;
|
||||
}
|
||||
*frameSize = m_ulFullWidth * m_ulFullHeight * 4;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user