
#include "movement.h"
#include <opencv2/opencv.hpp>
#include <vector>
#include <cstdlib>
#include <algorithm>
#define NOMINMAX
#include <Windows.h>
#include "config.h"
#include "serial_communication.h"
#include <algorithm> // std::min, std::max
#include <limits>
#include <dxgi1_2.h>
#include <d3d11.h>
#include <wrl/client.h>
// 全局变量
float previous_x = 0.0f;
float previous_y = 0.0f;
// 使用 Microsoft::WRL::ComPtr 来管理 DXGI 和 D3D11 对象
using Microsoft::WRL::ComPtr;
cv::Mat capture_screen() {
// 初始化 D3D11 设备和 DXGI 工厂
ComPtr<ID3D11Device> device;
ComPtr<ID3D11DeviceContext> context;
ComPtr<IDXGIFactory1> factory;
ComPtr<IDXGIAdapter1> adapter;
ComPtr<IDXGIOutput> output;
ComPtr<IDXGIOutput1> output1;
ComPtr<IDXGIOutputDuplication> duplication;
ComPtr<IDXGIResource> desktopResource;
ComPtr<ID3D11Texture2D> acquiredDesktopImage;
// 创建 D3D11 设备
D3D_FEATURE_LEVEL featureLevel;
HRESULT hr = D3D11CreateDevice(NULL, D3D11_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &device, &featureLevel, &context);
if (FAILED(hr)) {
std::cerr << "D3D11CreateDevice failed!" << std::endl;
return cv::Mat();
}
// 获取 DXGI 工厂
hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(factory.GetAddressOf()));
if (FAILED(hr)) {
std::cerr << "CreateDXGIFactory1 failed!" << std::endl;
return cv::Mat();
}
// 获取第一个适配器
hr = factory->EnumAdapters1(0, adapter.GetAddressOf());
if (FAILED(hr)) {
std::cerr << "EnumAdapters1 failed!" << std::endl;
return cv::Mat();
}
// 获取输出
hr = adapter->EnumOutputs(0, output.GetAddressOf());
if (FAILED(hr)) {
std::cerr << "EnumOutputs failed!" << std::endl;
return cv::Mat();
}
hr = output.As(&output1);
if (FAILED(hr)) {
std::cerr << "Failed to get IDXGIOutput1 interface!" << std::endl;
return cv::Mat();
}
// 创建屏幕捕获的复制对象
hr = output1->DuplicateOutput(device.Get(), duplication.GetAddressOf());
if (FAILED(hr)) {
std::cerr << "DuplicateOutput failed!" << std::endl;
return cv::Mat();
}
// 捕获屏幕
DXGI_OUTDUPL_FRAME_INFO frameInfo;
hr = duplication->AcquireNextFrame(1000, &frameInfo, desktopResource.GetAddressOf());
if (FAILED(hr)) {
std::cerr << "AcquireNextFrame failed!" << std::endl;
return cv::Mat();
}
// 获取桌面图像的纹理
hr = desktopResource.As(&acquiredDesktopImage);
if (FAILED(hr)) {
std::cerr << "Failed to get desktop image as texture!" << std::endl;
return cv::Mat();
}
// 获取桌面图像的描述
D3D11_TEXTURE2D_DESC textureDesc;
acquiredDesktopImage->GetDesc(&textureDesc);
// 创建 OpenCV Mat 并从桌面图像中复制像素数据
cv::Mat screenshot(textureDesc.Height, textureDesc.Width, CV_8UC4);
D3D11_MAPPED_SUBRESOURCE mappedResource;
hr = context->Map(acquiredDesktopImage.Get(), 0, D3D11_MAP_READ, 0, &mappedResource);
if (FAILED(hr)) {
std::cerr << "Failed to map the texture!" << std::endl;
return cv::Mat();
}
// 复制像素数据到 OpenCV Mat
memcpy(screenshot.data, mappedResource.pData, textureDesc.Height * textureDesc.Width * 4);
// 解除映射
context->Unmap(acquiredDesktopImage.Get(), 0);
// 释放屏幕帧
duplication->ReleaseFrame();
// 返回捕获的屏幕
return screenshot;
}
链接了dxgi.lib和d3d11.lib,但是还是显示未定义标识符