From e6b741b0dc822af4dbd7799ee5991f79b7036118 Mon Sep 17 00:00:00 2001 From: Alex Beng <599267065@qq.com> Date: Sun, 3 Dec 2023 09:13:24 +0800 Subject: [PATCH 1/8] rm dxgi --- source/CMakeLists.txt | 2 +- source/src/AutoTrack.cpp | 15 +- source/src/ErrorCode.cpp | 7 +- source/src/capture/dxgi/Dxgi.cpp | 367 ------------------ source/src/capture/dxgi/Dxgi.h | 42 -- .../capture/dxgi/include/capture.interop.h | 13 - .../dxgi/include/composition.interop.h | 59 --- source/src/capture/dxgi/include/d3dHelpers.h | 173 --------- .../capture/dxgi/include/direct3d11.interop.h | 40 -- source/src/pch.h | 5 - source/src/utils/Logger.cpp | 7 +- source/src/version/version.ver | 2 +- source/src/version/version_hash.hash | 2 +- 13 files changed, 9 insertions(+), 725 deletions(-) delete mode 100644 source/src/capture/dxgi/Dxgi.cpp delete mode 100644 source/src/capture/dxgi/Dxgi.h delete mode 100644 source/src/capture/dxgi/include/capture.interop.h delete mode 100644 source/src/capture/dxgi/include/composition.interop.h delete mode 100644 source/src/capture/dxgi/include/d3dHelpers.h delete mode 100644 source/src/capture/dxgi/include/direct3d11.interop.h diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 03d13098..e1911ac0 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -92,7 +92,7 @@ FetchContent_Declare(fmt GIT_REPOSITORY https://github.com/fmtlib/fmt.git GIT_TA FetchContent_MakeAvailable(fmt) set_target_properties(fmt PROPERTIES FOLDER "cvAutoTrack/dependencies") -target_link_libraries(cvAutoTrack PRIVATE ${OpenCV_LIBS} cereal::cereal fmt::fmt-header-only d3d11.lib d3dcompiler.lib dxgi.lib) +target_link_libraries(cvAutoTrack PRIVATE ${OpenCV_LIBS} cereal::cereal fmt::fmt-header-only d3d11.lib d3dcompiler.lib) if(BUILD_SUBMODULE) if(CMAKE_BUILD_TYPE MATCHES "Debug") diff --git a/source/src/AutoTrack.cpp b/source/src/AutoTrack.cpp index bb710535..96358149 100644 --- a/source/src/AutoTrack.cpp +++ b/source/src/AutoTrack.cpp @@ -4,7 +4,7 @@ #include "ErrorCode.h" #include "resources/Resources.h" -#include "capture/dxgi/Dxgi.h" +// #include "capture/dxgi/Dxgi.h" #include "capture/bitblt/Bitblt.h" #include "filter/kalman/Kalman.h" #include "utils/Utils.h" @@ -76,18 +76,7 @@ bool AutoTrack::SetUseBitbltCaptureMode() bool AutoTrack::SetUseDx11CaptureMode() { - if (genshin_handle.config.capture == nullptr) - { - genshin_handle.config.capture = std::make_shared(); - return true; - } - if (genshin_handle.config.capture->mode == Capture::DirectX) - { - return true; - } - genshin_handle.config.capture.reset(); - genshin_handle.config.capture = std::make_shared(); - return true; + return false; } bool AutoTrack::ImportMapBlock(int id_x, int id_y, const char* image_data, int image_data_size, int image_width, int image_height) diff --git a/source/src/ErrorCode.cpp b/source/src/ErrorCode.cpp index 994b8d53..18c4da51 100644 --- a/source/src/ErrorCode.cpp +++ b/source/src/ErrorCode.cpp @@ -39,16 +39,13 @@ std::string get_sys_version() } std::string get_gpu_name() { + return "获取GPU信息失败"; // Get the name of the GPU IDXGIAdapter* pAdapter = nullptr; IDXGIFactory* pFactory = nullptr; try { - HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pFactory)); - if (FAILED(hr)) - { - return "Unknown"; - } + HRESULT hr; hr = pFactory->EnumAdapters(0, &pAdapter); if (FAILED(hr)) diff --git a/source/src/capture/dxgi/Dxgi.cpp b/source/src/capture/dxgi/Dxgi.cpp deleted file mode 100644 index cc3c496c..00000000 --- a/source/src/capture/dxgi/Dxgi.cpp +++ /dev/null @@ -1,367 +0,0 @@ -#include "pch.h" -#include "Dxgi.h" -#include - -using namespace winrt; -using namespace Windows; -using namespace Windows::Foundation; -using namespace Windows::System; -using namespace Windows::Graphics; -using namespace Windows::Graphics::Capture; -using namespace Windows::Graphics::DirectX; -using namespace Windows::Graphics::DirectX::Direct3D11; -using namespace Windows::Foundation::Numerics; -using namespace Windows::UI; -using namespace Windows::UI::Composition; - -namespace TianLi::DirectX -{ - static bool is_init_d3d = false; - static winrt::com_ptr d3dDevice;// = CreateD3DDevice(); - static winrt::impl::com_ref dxgiDevice;// = d3dDevice.as(); - D3D11_TEXTURE2D_DESC desc_type{ - 0, 0, 1, 1, DXGI_FORMAT_B8G8R8A8_UNORM, {1, 0}, D3D11_USAGE_STAGING, 0, D3D11_CPU_ACCESS_READ, 0 }; -} - -Dxgi::Dxgi() -{ - mode = Capture::DirectX; - if (TianLi::DirectX::is_init_d3d == false) - { - TianLi::DirectX::is_init_d3d = true; - TianLi::DirectX::d3dDevice = CreateD3DDevice(); - TianLi::DirectX::dxgiDevice = TianLi::DirectX::d3dDevice.as(); - } -} - -Dxgi::~Dxgi() -{ - try - { - if (m_session != nullptr) - m_session.Close(); - if (m_framePool != nullptr) - m_framePool.Close(); - } - catch (...) - { - // - } - m_session = nullptr; - m_framePool = nullptr; - m_swapChain = nullptr; - m_item = nullptr; -} - -bool Dxgi::init() -{ - // 只需要定义一下,不会用上,唯一的作用是避免依赖d3d11.dll - // 这背后大概有什么科学原理吧,可能 - static cv::VideoCapture Video; - - if (is_need_init == false) - { - return true; - } - - if (!giHandle) - { - err = { 10003,"句柄为空" }; - return false; - } - - // TODO: 中断时重开原神,进入这里 - m_device = CreateDirect3DDevice(TianLi::DirectX::dxgiDevice.get()); - m_item = CreateCaptureItemForWindow(giHandle); - if (m_item == nullptr) - { - err = { 10013,"未能捕获窗口" }; - return false; - } - auto size = m_item.Size(); - m_swapChain = CreateDXGISwapChain(TianLi::DirectX::d3dDevice, static_cast(size.Width), static_cast(size.Height), static_cast(DirectXPixelFormat::B8G8R8A8UIntNormalized), 2); - - if (size.Width < 480 || size.Height < 360) - { - err = { 14, "窗口画面大小小于480x360,无法使用" }; - return false; - } - - TianLi::DirectX::d3dDevice->GetImmediateContext(m_d3dContext.put()); - - try - { - auto fun_get_frame_pool = [=]()->auto { - auto device = CreateDirect3DDevice(TianLi::DirectX::dxgiDevice.get()); - return winrt::Windows::Graphics::Capture:: - Direct3D11CaptureFramePool::Create(device, DirectXPixelFormat::B8G8R8A8UIntNormalized, 2, size); - }; - // 另一个线程运行 get_frame_pool - std::future f_frame_pool = std::async(std::launch::async, fun_get_frame_pool); - - m_framePool = f_frame_pool.get(); - m_session = m_framePool.CreateCaptureSession(m_item); - } - catch (...) - { - // Ignore any errors - } - - // 判断 WindowsSDK 版本大于等于 10.0.22000.0 -#if (WINVER >= _WIN32_WINNT_WIN10_21H1) - try - { - if (winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Graphics.Capture.GraphicsCaptureSession", L"IsBorderRequired")) - { - - winrt::Windows::Graphics::Capture::GraphicsCaptureAccess:: - RequestAccessAsync( - winrt::Windows::Graphics::Capture:: - GraphicsCaptureAccessKind::Borderless) - .get(); - m_session.IsBorderRequired(false); - m_session.IsCursorCaptureEnabled(false); - } - } - catch (...) - { - // Ignore any errors - } -#endif - - m_lastSize = size; - - m_session.StartCapture(); - - is_need_init = false; - return true; -} - -bool Dxgi::uninit() -{ - is_need_init = true; - return true; -} -bool get_client_box(HWND window, uint32_t width, uint32_t height, - D3D11_BOX* client_box) -{ - RECT client_rect{}, window_rect{}; - POINT upper_left{}; - - /* check iconic (minimized) twice, ABA is very unlikely */ - bool client_box_available = - !IsIconic(window) && GetClientRect(window, &client_rect) && - !IsIconic(window) && (client_rect.right > 0) && - (client_rect.bottom > 0) && - (DwmGetWindowAttribute(window, DWMWA_EXTENDED_FRAME_BOUNDS, - &window_rect, - sizeof(window_rect)) == S_OK) && - ClientToScreen(window, &upper_left); - if (client_box_available) { - const uint32_t left = - (upper_left.x > window_rect.left) - ? (upper_left.x - window_rect.left) - : 0; - client_box->left = left; - - const uint32_t top = (upper_left.y > window_rect.top) - ? (upper_left.y - window_rect.top) - : 0; - client_box->top = top; - - uint32_t texture_width = 1; - if (width > left) { - texture_width = - min(width - left, (uint32_t)client_rect.right); - } - - uint32_t texture_height = 1; - if (height > top) { - texture_height = - min(height - top, (uint32_t)client_rect.bottom); - } - - client_box->right = left + texture_width; - client_box->bottom = top + texture_height; - - client_box->front = 0; - client_box->back = 1; - - client_box_available = (client_box->right <= width) && - (client_box->bottom <= height); - } - - return client_box_available; -} - -bool Dxgi::capture(cv::Mat& frame) -{ - static ID3D11Texture2D* bufferTexture; - if (m_framePool == nullptr) - { - uninit(); - try - { - if (m_session != nullptr) - m_session.Close(); - if (m_framePool != nullptr) - m_framePool.Close(); - } - catch (...) - { - // - } - m_session = nullptr; - m_framePool = nullptr; - m_swapChain = nullptr; - m_item = nullptr; - bool res = init(); - if (res == false) - { - err = { 10001,"重新初始化捕获池" }; - return false; - } - } - - // 判断是否可以获取新的的画面 - Direct3D11CaptureFrame new_frame{ nullptr }; - // 获取最新的画面 - try - { - // Debug下每次都获取最新的画面 -#ifdef _DEBUG - Direct3D11CaptureFrame new_frame_null{ nullptr }; - do - { - new_frame = m_framePool.TryGetNextFrame(); - if (new_frame == nullptr) - { - err = { 10002,"获取新的画面失败" }; - return false; - } - new_frame_null = m_framePool.TryGetNextFrame(); - if (new_frame_null != nullptr) - { - new_frame.Close(); - new_frame = new_frame_null; - } - } while (new_frame_null == nullptr); -#else - new_frame = m_framePool.TryGetNextFrame(); -#endif // _DEBUG - } - catch (...) - { - // Ignore any errors - err = { 10003,"获取下一帧画面失败" }; - return false; - } - if (new_frame == nullptr) - { - err = { 10004,"未能获取到新一帧画面" }; - return false; - } - auto frame_size = new_frame.ContentSize(); - if (TianLi::DirectX::desc_type.Width != static_cast(m_lastSize.Width) || TianLi::DirectX::desc_type.Height != static_cast(m_lastSize.Height)) - { - TianLi::DirectX::desc_type.Width = m_lastSize.Width; - TianLi::DirectX::desc_type.Height = m_lastSize.Height; - } - if (frame_size.Width != m_lastSize.Width || frame_size.Height != m_lastSize.Height) - { - m_framePool.Recreate( - m_device, - DirectXPixelFormat::B8G8R8A8UIntNormalized, - 2, - frame_size); - m_lastSize = frame_size; - - m_swapChain->ResizeBuffers( - 2, - static_cast(m_lastSize.Width), - static_cast(m_lastSize.Height), - static_cast(DirectXPixelFormat::B8G8R8A8UIntNormalized), - 0); - - } - auto frameSurface = GetDXGIInterfaceFromObject(new_frame.Surface()); - - //auto d3dDevice = GetDXGIInterfaceFromObject(m_device); - TianLi::DirectX::d3dDevice->CreateTexture2D(&TianLi::DirectX::desc_type, nullptr, &bufferTexture); - D3D11_BOX client_box; - bool client_box_available = get_client_box(giHandle, TianLi::DirectX::desc_type.Width, TianLi::DirectX::desc_type.Height, &client_box); - - if (client_box_available) - { - m_d3dContext->CopySubresourceRegion(bufferTexture, - 0, 0, 0, 0, frameSurface.get(), - 0, &client_box); - } - else - { - m_d3dContext->CopyResource(bufferTexture, frameSurface.get()); - } - if (bufferTexture == nullptr) - { - err = { 10005,"未能从GPU拷贝画面到CPU" }; - return false; - } - - D3D11_MAPPED_SUBRESOURCE mappedTex; - m_d3dContext->Map(bufferTexture, 0, D3D11_MAP_READ, 0, &mappedTex); - - - - auto data = mappedTex.pData; - auto pitch = mappedTex.RowPitch; - if (data == nullptr) - { - err = { 10006,"指针指向为空" }; - return false; - } - - // 将画面转换为OpenCV的Mat(疑似会崩溃) - try { - frame = cv::Mat(frame_size.Height, frame_size.Width, CV_8UC4, (void*)data, pitch); - } - catch(std::exception e){ - err = { 504, fmt::format("FATAL!! 出现了致命的错误,已自动跳过,原因:{}",e.what()) }; - return false; - } - if (frame_size.Width < 480 || frame_size.Height < 360) - { - err = { 14, "窗口画面大小小于480x360,无法使用" }; - return false; - } - - if (client_box_available) - { - if (client_box.right - client_box.left > frame_size.Width || client_box.bottom - client_box.top > frame_size.Height) - { - err = { 14, "窗口画面小于裁剪框,截图失败" }; - return false; - } - frame = frame(cv::Rect(0, 0, client_box.right - client_box.left, client_box.bottom - client_box.top)); - } - - frame = frame.clone(); - // 释放资源 - bufferTexture->Release(); - return true; -} - -bool Dxgi::setHandle(HWND handle) -{ - if (giHandle != handle) - { - if (handle == nullptr) - { - err = { 10006,"设置的句柄为空" }; - return false; - } - uninit(); - giHandle = handle; - init(); - } - return true; -} diff --git a/source/src/capture/dxgi/Dxgi.h b/source/src/capture/dxgi/Dxgi.h deleted file mode 100644 index cd22fd17..00000000 --- a/source/src/capture/dxgi/Dxgi.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once -#include "../Capture.h" - -class Dxgi : public Capture -{ -public: - Dxgi(); - ~Dxgi(); - - bool init() override; - bool uninit() override; - bool capture(cv::Mat &frame) override; - bool setHandle(HWND handle = 0) override; - -private: - winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice m_device{nullptr}; - winrt::com_ptr m_d3dContext{nullptr}; - winrt::Windows::Graphics::Capture::GraphicsCaptureItem m_item{nullptr}; - /// - /// 存储应用程序捕获的帧。 - /// 尝试从帧池获取下一个捕获的帧。 - /// 捕获帧存储在帧池中时引发的事件。 - /// - winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool m_framePool{nullptr}; - /// - /// 允许应用程序进行屏幕捕获 - /// 启动捕获会话,允许应用程序捕获帧。 - /// - winrt::Windows::Graphics::Capture::GraphicsCaptureSession m_session{nullptr}; - winrt::Windows::Graphics::SizeInt32 m_lastSize; - winrt::com_ptr m_swapChain{nullptr}; - - std::atomic m_closed = false; - -private: - bool is_need_init = false; - HWND giHandle = nullptr; - -private: - // D3D11_TEXTURE2D_DESC desc_type{ - // 0, 0, 1, 1, DXGI_FORMAT_B8G8R8A8_UNORM, {1, 0}, D3D11_USAGE_STAGING, 0, D3D11_CPU_ACCESS_READ, 0}; -}; diff --git a/source/src/capture/dxgi/include/capture.interop.h b/source/src/capture/dxgi/include/capture.interop.h deleted file mode 100644 index dda19fce..00000000 --- a/source/src/capture/dxgi/include/capture.interop.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include -#include -#include - -inline auto CreateCaptureItemForWindow(HWND hwnd) -{ - auto activation_factory = winrt::get_activation_factory(); - auto interop_factory = activation_factory.as(); - winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = { nullptr }; - interop_factory->CreateForWindow(hwnd, winrt::guid_of(), reinterpret_cast(winrt::put_abi(item))); - return item; -} \ No newline at end of file diff --git a/source/src/capture/dxgi/include/composition.interop.h b/source/src/capture/dxgi/include/composition.interop.h deleted file mode 100644 index 1341bd7a..00000000 --- a/source/src/capture/dxgi/include/composition.interop.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once -#include -#include -#include - -inline auto CreateCompositionGraphicsDevice( - winrt::Windows::UI::Composition::Compositor const& compositor, - ::IUnknown* device) -{ - winrt::Windows::UI::Composition::CompositionGraphicsDevice graphicsDevice{ nullptr }; - auto compositorInterop = compositor.as(); - winrt::com_ptr graphicsInterop; - winrt::check_hresult(compositorInterop->CreateGraphicsDevice(device, graphicsInterop.put())); - winrt::check_hresult(graphicsInterop->QueryInterface(winrt::guid_of(), - reinterpret_cast(winrt::put_abi(graphicsDevice)))); - return graphicsDevice; -} - -inline void ResizeSurface( - winrt::Windows::UI::Composition::CompositionDrawingSurface const& surface, - winrt::Windows::Foundation::Size const& size) -{ - auto surfaceInterop = surface.as(); - SIZE newSize = {}; - newSize.cx = static_cast(std::round(size.Width)); - newSize.cy = static_cast(std::round(size.Height)); - winrt::check_hresult(surfaceInterop->Resize(newSize)); -} - -inline auto SurfaceBeginDraw( - winrt::Windows::UI::Composition::CompositionDrawingSurface const& surface) -{ - auto surfaceInterop = surface.as(); - winrt::com_ptr context; - POINT offset = {}; - winrt::check_hresult(surfaceInterop->BeginDraw(nullptr, __uuidof(ID2D1DeviceContext), context.put_void(), &offset)); - context->SetTransform(D2D1::Matrix3x2F::Translation((FLOAT)offset.x,(FLOAT) offset.y)); - return context; -} - -inline void SurfaceEndDraw( - winrt::Windows::UI::Composition::CompositionDrawingSurface const& surface) -{ - auto surfaceInterop = surface.as(); - winrt::check_hresult(surfaceInterop->EndDraw()); -} - -inline auto CreateCompositionSurfaceForSwapChain( - winrt::Windows::UI::Composition::Compositor const& compositor, - ::IUnknown* swapChain) -{ - winrt::Windows::UI::Composition::ICompositionSurface surface{ nullptr }; - auto compositorInterop = compositor.as(); - winrt::com_ptr surfaceInterop; - winrt::check_hresult(compositorInterop->CreateCompositionSurfaceForSwapChain(swapChain, surfaceInterop.put())); - winrt::check_hresult(surfaceInterop->QueryInterface(winrt::guid_of(), - reinterpret_cast(winrt::put_abi(surface)))); - return surface; -} \ No newline at end of file diff --git a/source/src/capture/dxgi/include/d3dHelpers.h b/source/src/capture/dxgi/include/d3dHelpers.h deleted file mode 100644 index b9714f73..00000000 --- a/source/src/capture/dxgi/include/d3dHelpers.h +++ /dev/null @@ -1,173 +0,0 @@ -#pragma once -#include "composition.interop.h" - -struct SurfaceContext -{ -public: - SurfaceContext(std::nullptr_t) {} - SurfaceContext( - winrt::Windows::UI::Composition::CompositionDrawingSurface surface) - { - m_surface = surface; - m_d2dContext = SurfaceBeginDraw(m_surface); - } - ~SurfaceContext() - { - SurfaceEndDraw(m_surface); - m_d2dContext = nullptr; - m_surface = nullptr; - } - - winrt::com_ptr GetDeviceContext() { return m_d2dContext; } - -private: - winrt::com_ptr m_d2dContext; - winrt::Windows::UI::Composition::CompositionDrawingSurface m_surface{ nullptr }; -}; - -struct D3D11DeviceLock -{ -public: - D3D11DeviceLock(std::nullopt_t) {} - D3D11DeviceLock(ID3D11Multithread* pMultithread) - { - m_multithread.copy_from(pMultithread); - m_multithread->Enter(); - } - ~D3D11DeviceLock() - { - m_multithread->Leave(); - m_multithread = nullptr; - } -private: - winrt::com_ptr m_multithread; -}; - -inline auto -CreateWICFactory() -{ - winrt::com_ptr wicFactory; - winrt::check_hresult( - ::CoCreateInstance( - CLSID_WICImagingFactory, - nullptr, - CLSCTX_INPROC_SERVER, - winrt::guid_of(), - wicFactory.put_void())); - - return wicFactory; -} - -inline auto -CreateD2DDevice( - winrt::com_ptr const& factory, - winrt::com_ptr const& device) -{ - winrt::com_ptr result; - winrt::check_hresult(factory->CreateDevice(device.as().get(), result.put())); - return result; -} - -inline auto -CreateD3DDevice( - D3D_DRIVER_TYPE const type, - winrt::com_ptr& device) -{ - WINRT_ASSERT(!device); - - UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; - -//#ifdef _DEBUG -// flags |= D3D11_CREATE_DEVICE_DEBUG; -//#endif - - return D3D11CreateDevice( - nullptr, - type, - nullptr, - flags, - nullptr, 0, - D3D11_SDK_VERSION, - device.put(), - nullptr, - nullptr); -} - -inline auto -CreateD3DDevice() -{ - winrt::com_ptr device; - HRESULT hr = CreateD3DDevice(D3D_DRIVER_TYPE_HARDWARE, device); - - if (DXGI_ERROR_UNSUPPORTED == hr) - { - hr = CreateD3DDevice(D3D_DRIVER_TYPE_WARP, device); - } - - winrt::check_hresult(hr); - return device; -} - -inline auto -CreateD2DFactory() -{ - D2D1_FACTORY_OPTIONS options{}; - -//#ifdef _DEBUG -// options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION; -//#endif - - winrt::com_ptr factory; - - winrt::check_hresult(D2D1CreateFactory( - D2D1_FACTORY_TYPE_SINGLE_THREADED, - options, - factory.put())); - - return factory; -} - -inline auto -CreateDXGISwapChain( - winrt::com_ptr const& device, - const DXGI_SWAP_CHAIN_DESC1* desc) -{ - auto dxgiDevice = device.as(); - winrt::com_ptr adapter; - winrt::check_hresult(dxgiDevice->GetParent(winrt::guid_of(), adapter.put_void())); - winrt::com_ptr factory; - winrt::check_hresult(adapter->GetParent(winrt::guid_of(), factory.put_void())); - - winrt::com_ptr swapchain; - winrt::check_hresult(factory->CreateSwapChainForComposition( - device.get(), - desc, - nullptr, - swapchain.put())); - - return swapchain; -} - -inline auto -CreateDXGISwapChain( - winrt::com_ptr const& device, - uint32_t width, - uint32_t height, - DXGI_FORMAT format, - uint32_t bufferCount) -{ - DXGI_SWAP_CHAIN_DESC1 desc = {}; - desc.Width = width; - desc.Height = height; - desc.Format = format; - desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.BufferCount = bufferCount; - desc.Scaling = DXGI_SCALING_STRETCH; - desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; - desc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; - - return CreateDXGISwapChain(device, &desc); -} -/// DXGI_ALPHA_MODE_UNSPECIFIED \ No newline at end of file diff --git a/source/src/capture/dxgi/include/direct3d11.interop.h b/source/src/capture/dxgi/include/direct3d11.interop.h deleted file mode 100644 index b6d40cd4..00000000 --- a/source/src/capture/dxgi/include/direct3d11.interop.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once -#include - -extern "C" -{ - HRESULT __stdcall CreateDirect3D11DeviceFromDXGIDevice(::IDXGIDevice* dxgiDevice, - ::IInspectable** graphicsDevice); - - HRESULT __stdcall CreateDirect3D11SurfaceFromDXGISurface(::IDXGISurface* dgxiSurface, - ::IInspectable** graphicsSurface); -} - -struct __declspec(uuid("A9B3D012-3DF2-4EE3-B8D1-8695F457D3C1")) - IDirect3DDxgiInterfaceAccess : ::IUnknown -{ - virtual HRESULT __stdcall GetInterface(GUID const& id, void** object) = 0; -}; - -inline auto CreateDirect3DDevice(IDXGIDevice* dxgi_device) -{ - winrt::com_ptr<::IInspectable> d3d_device; - winrt::check_hresult(CreateDirect3D11DeviceFromDXGIDevice(dxgi_device, d3d_device.put())); - return d3d_device.as(); -} - -inline auto CreateDirect3DSurface(IDXGISurface* dxgi_surface) -{ - winrt::com_ptr<::IInspectable> d3d_surface; - winrt::check_hresult(CreateDirect3D11SurfaceFromDXGISurface(dxgi_surface, d3d_surface.put())); - return d3d_surface.as(); -} - -template -auto GetDXGIInterfaceFromObject(winrt::Windows::Foundation::IInspectable const& object) -{ - auto access = object.as(); - winrt::com_ptr result; - winrt::check_hresult(access->GetInterface(winrt::guid_of(), result.put_void())); - return result; -} \ No newline at end of file diff --git a/source/src/pch.h b/source/src/pch.h index 0c31c593..c1237244 100644 --- a/source/src/pch.h +++ b/source/src/pch.h @@ -68,11 +68,6 @@ #include #include -// Helpers -#include "capture/dxgi/include/composition.interop.h" -#include "capture/dxgi/include/d3dHelpers.h" -#include "capture/dxgi/include/direct3d11.interop.h" -#include "capture/dxgi/include/capture.interop.h" // DUMP部分 #include "Windows.h" diff --git a/source/src/utils/Logger.cpp b/source/src/utils/Logger.cpp index d7550003..33250a45 100644 --- a/source/src/utils/Logger.cpp +++ b/source/src/utils/Logger.cpp @@ -159,16 +159,13 @@ std::string TianLi::Utils::Logger::get_sys_version() std::string TianLi::Utils::Logger::get_gpu_name() { + return "获取GPU信息失败"; // Get the name of the GPU IDXGIAdapter* pAdapter = nullptr; IDXGIFactory* pFactory = nullptr; try { - HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pFactory)); - if (FAILED(hr)) - { - return "Unknown"; - } + HRESULT hr; hr = pFactory->EnumAdapters(0, &pAdapter); if (FAILED(hr)) diff --git a/source/src/version/version.ver b/source/src/version/version.ver index fa5fce04..5210382a 100644 --- a/source/src/version/version.ver +++ b/source/src/version/version.ver @@ -1 +1 @@ -8.0.0 \ No newline at end of file +8.0.1 \ No newline at end of file diff --git a/source/src/version/version_hash.hash b/source/src/version/version_hash.hash index fa81a293..6b0068bc 100644 --- a/source/src/version/version_hash.hash +++ b/source/src/version/version_hash.hash @@ -1 +1 @@ -8a6fd33 \ No newline at end of file +aee4d33 \ No newline at end of file From 6c29ef84b9f29c3787a446a6f99a14a8dd77f45c Mon Sep 17 00:00:00 2001 From: Alex Beng <599267065@qq.com> Date: Sun, 3 Dec 2023 15:39:52 +0800 Subject: [PATCH 2/8] feat: add use time in test_impl_cpp --- tests/impl_cpp/main.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/impl_cpp/main.cpp b/tests/impl_cpp/main.cpp index 5dc1dfc2..e90c39ab 100644 --- a/tests/impl_cpp/main.cpp +++ b/tests/impl_cpp/main.cpp @@ -165,8 +165,10 @@ void Run_GetAll() double x, y, a, r; int mapId, uid; std::string mapType; + double time_beg = GetTickCount(); if (GetAllInfo(x, y, mapId, a, r, uid)) { + double time_end = GetTickCount(); switch (mapId) { case 0: @@ -185,9 +187,10 @@ void Run_GetAll() 坐标:x = {:6.2f}; y = {:6.2f} 朝向:角色 = {:4.2f}; 相机 = {:4.2f} UID:{:d} +UseTime:{:4.2f}ms ---------------- )", - mapType, x, y, a, r, uid); + mapType, x, y, a, r, uid, time_end - time_beg); } else { From 69c1d936d215ebaf30b8b7d42c4fc9406c5e7415 Mon Sep 17 00:00:00 2001 From: Alex Beng <599267065@qq.com> Date: Sun, 3 Dec 2023 15:41:25 +0800 Subject: [PATCH 3/8] fix: make KF work with 2-dim state and 2-dim control --- source/src/AutoTrack.cpp | 1 - source/src/algorithms/algorithms.include.h | 8 ++ .../algorithms/algorithms.visual.odometer.h | 96 +++++++++++++++++++ source/src/filter/Filter.h | 2 +- source/src/filter/kalman/Kalman.cpp | 72 +++++++------- source/src/filter/kalman/Kalman.h | 24 ++++- source/src/filter/smooth/Smooth.cpp | 4 +- source/src/filter/smooth/Smooth.h | 2 +- source/src/filter/untouched/Untouched.cpp | 2 +- source/src/filter/untouched/Untouched.h | 2 +- .../match/position/genshin.match.position.cpp | 37 ++++++- source/src/pch.h | 1 + source/src/version/version.ver | 2 +- source/src/version/version_hash.hash | 2 +- 14 files changed, 201 insertions(+), 54 deletions(-) create mode 100644 source/src/algorithms/algorithms.visual.odometer.h diff --git a/source/src/AutoTrack.cpp b/source/src/AutoTrack.cpp index 96358149..f660f0d5 100644 --- a/source/src/AutoTrack.cpp +++ b/source/src/AutoTrack.cpp @@ -4,7 +4,6 @@ #include "ErrorCode.h" #include "resources/Resources.h" -// #include "capture/dxgi/Dxgi.h" #include "capture/bitblt/Bitblt.h" #include "filter/kalman/Kalman.h" #include "utils/Utils.h" diff --git a/source/src/algorithms/algorithms.include.h b/source/src/algorithms/algorithms.include.h index 0507a477..048b0fe2 100644 --- a/source/src/algorithms/algorithms.include.h +++ b/source/src/algorithms/algorithms.include.h @@ -1,5 +1,6 @@ #pragma once #include +#include "utils/Utils.h" typedef std::pair error_info; @@ -20,3 +21,10 @@ struct position_calculation_config bool error = false; error_info err = {0, ""}; }; + +struct odometer_config +{ + bool error = false; + error_info err = {0, ""}; + double scale = 1.0; +}; \ No newline at end of file diff --git a/source/src/algorithms/algorithms.visual.odometer.h b/source/src/algorithms/algorithms.visual.odometer.h new file mode 100644 index 00000000..ccb10285 --- /dev/null +++ b/source/src/algorithms/algorithms.visual.odometer.h @@ -0,0 +1,96 @@ +#pragma once +#include "algorithms.include.h" + +// 视觉里程计 +// 每次小地图更新时调用 +// init:传入小地图与大地图的像素缩放比例 +// when mini map update:尝试与上一张小地图进行匹配,匹配成功,则返回控制量dx dy + +// TODO:把这个缩放比例使用仿射/自己组Ax=B求解,并测试性能。 +// TODO:封装一下,此版本测试filter可行性 + +cv::Mat last_mini_map; +bool inited = false; + +bool orb_match(cv::Mat &img1, cv::Mat &img2, cv::Point2f &offset); + +void set_mini_map(const cv::Mat &giMiniMapRef) +{ + last_mini_map = giMiniMapRef.clone(); + inited = true; +} + +bool control_odometer_calculation(const cv::Mat &giMiniMapRef, cv::Point2d &control, odometer_config &config) +{ + if (!inited) { + // JUST INIT IT + last_mini_map = giMiniMapRef.clone(); + inited = true; + control = cv::Point2d(0, 0); + return false; + } + else { + auto curr_mini_map = giMiniMapRef.clone(); + // use orb match to get the u, aka offset + cv::Point2f offset; + if (orb_match(last_mini_map, curr_mini_map, offset)) { + control = cv::Point2d(offset.x * config.scale, offset.y * config.scale); + last_mini_map = curr_mini_map.clone(); + return true; + } + else { + control = cv::Point2d(0, 0); + return false; + } + } +} + +// 草,surfmatch跟定位功能耦合有、严重 +// 这里再造一个orb match + 最优比次优 +// 几乎必然是同比例的,返回偏移量 +bool orb_match(cv::Mat &img1, cv::Mat &img2, cv::Point2f &offset) +{ + // 不crop了,因为上一张会被crop两次。 + // img1 = TianLi::Utils::crop_border(img1, 0.15); + // img2 = TianLi::Utils::crop_border(img2, 0.15); + // resize 是等比例缩放,就不超了 + + // 分别计算orb特征点 + cv::Ptr orb = cv::ORB::create(5000); + std::vector kp1, kp2; + cv::Mat desp1, desp2; + orb->detectAndCompute(img1, cv::Mat(), kp1, desp1); + orb->detectAndCompute(img2, cv::Mat(), kp2, desp2); + + if (desp1.empty() || desp2.empty()) { + return false; + } + + // 首先采用knnMatch剔除最近匹配点距离与次近匹配点距离比率大于0.6的舍去 + cv::BFMatcher matcher(cv::NORM_HAMMING); + std::vector> matches; + matcher.knnMatch(desp1, desp2, matches, 2); + std::vector good_matches; + for (int i = 0; i < matches.size(); i++) { + if (matches[i][0].distance < 0.6 * matches[i][1].distance) { + good_matches.push_back(matches[i][0]); + } + } + + if (good_matches.size() == 0) { + return false; + } + + auto img2_copy = img2.clone(); + // 画出good matches,然后保存 + // cv::drawMatches(img1, kp1, img2, kp2, good_matches, img2_copy); + // cv::imwrite("good_matches.jpg", img2_copy); + + // 计算偏移量,直接取平均 + cv::Point2f sum_offset(0, 0); + for (int i = 0; i < good_matches.size(); i++) { + sum_offset += kp2[good_matches[i].trainIdx].pt - kp1[good_matches[i].queryIdx].pt; + } + offset = cv::Point2f(sum_offset.x / good_matches.size(), sum_offset.y / good_matches.size()); + return true; +} \ No newline at end of file diff --git a/source/src/filter/Filter.h b/source/src/filter/Filter.h index c0b055b0..cbf74caf 100644 --- a/source/src/filter/Filter.h +++ b/source/src/filter/Filter.h @@ -7,7 +7,7 @@ class Filter Filter(); virtual ~Filter(); public: - virtual cv::Point2d filterting(const cv::Point2d& pos) = 0; + virtual cv::Point2d filterting(const cv::Point2d &pos, const cv::Point2f &u_k) = 0; virtual cv::Point2d re_init_filterting(const cv::Point2d& pos) = 0; public: enum FilterType diff --git a/source/src/filter/kalman/Kalman.cpp b/source/src/filter/kalman/Kalman.cpp index b0303db2..8c47b5ee 100644 --- a/source/src/filter/kalman/Kalman.cpp +++ b/source/src/filter/kalman/Kalman.cpp @@ -5,36 +5,29 @@ Kalman::Kalman() { type = FilterType::Kalman; - KF = cv::KalmanFilter(stateNum, measureNum, 0); - state = cv::Mat(stateNum, 1, CV_32F); //state(x,y,detaX,detaY) + KF = cv::KalmanFilter(stateNum, measureNum, controlNum); + state = cv::Mat(stateNum, 1, CV_32F); processNoise = cv::Mat(stateNum, 1, CV_32F); measurement = cv::Mat::zeros(measureNum, 1, CV_32F); //measurement(x,y) randn(state, cv::Scalar::all(0), cv::Scalar::all(0.1)); //随机生成一个矩阵,期望是0,标准差为0.1; - KF.transitionMatrix = (cv::Mat_(4, 4) << - 1, 0, 1, 0, - 0, 1, 0, 1, - 0, 0, 1, 0, - 0, 0, 0, 1);//元素导入矩阵,按行; - - //setIdentity: 缩放的单位对角矩阵; - //!< measurement matrix (H) 观测模型 - setIdentity(KF.measurementMatrix); - - //!< process noise covariance matrix (Q) - // wk 是过程噪声,并假定其符合均值为零,协方差矩阵为Qk(Q)的多元正态分布; + // set A + KF.transitionMatrix = (cv::Mat_(2, 2) << + 1, 0, + 0, 1); + // set B + KF.controlMatrix = (cv::Mat_(2, 2) << + 1, 0, + 0, 1); + // set Q setIdentity(KF.processNoiseCov, cv::Scalar::all(1e-5)); + // set H + KF.measurementMatrix = (cv::Mat_(2, 2) << + 1, 0, + 0, 1); + // set R + setIdentity(KF.measurementNoiseCov, cv::Scalar::all(1e-5)); - //!< measurement noise covariance matrix (R) - //vk 是观测噪声,其均值为零,协方差矩阵为Rk,且服从正态分布; - setIdentity(KF.measurementNoiseCov, cv::Scalar::all(1e-1)); - - //!< priori error estimate covariance matrix (P'(k)): P'(k)=A*P(k-1)*At + Q)*/ A代表F: transitionMatrix - //预测估计协方差矩阵; - setIdentity(KF.errorCovPost, cv::Scalar::all(1)); - - //!< corrected state (x(k)): x(k)=x'(k)+K(k)*(z(k)-H*x'(k)) - //initialize post state of kalman filter at random randn(KF.statePost, cv::Scalar::all(0), cv::Scalar::all(0.1)); } @@ -42,9 +35,14 @@ Kalman::~Kalman() { } -cv::Point2d Kalman::filterting(const cv::Point2d& pos) +cv::Point2d Kalman::filterting(const cv::Point2d& pos, const cv::Point2f& u_k) { - cv::Mat prediction = KF.predict(); + // use u_k to predict + // make u_k to cv::Mat + cv::Mat u_k_mat = cv::Mat::zeros(2, 1, CV_32F); + u_k_mat.at(0, 0) = u_k.x; + u_k_mat.at(1, 0) = u_k.y; + cv::Mat prediction = KF.predict(u_k_mat); cv::Point2d predictPt = cv::Point2d(prediction.at(0), prediction.at(1)); //3.update measurement @@ -60,23 +58,22 @@ cv::Point2d Kalman::filterting(const cv::Point2d& pos) cv::Point2d Kalman::re_init_filterting(const cv::Point2d& pos) { - KF.init(stateNum, measureNum, 0); + KF.init(stateNum, measureNum, controlNum); state = cv::Mat(stateNum, 1, CV_32F); //state(x,y,detaX,detaY) processNoise = cv::Mat(stateNum, 1, CV_32F); measurement = cv::Mat::zeros(measureNum, 1, CV_32F); //measurement(x,y) randn(state, cv::Scalar::all(0), cv::Scalar::all(0.1)); //随机生成一个矩阵,期望是0,标准差为0.1; - KF.transitionMatrix = (cv::Mat_(4, 4) << - 1, 0, 1, 0, - 0, 1, 0, 1, - 0, 0, 1, 0, - 0, 0, 0, 1);//元素导入矩阵,按行; - - //setIdentity: 缩放的单位对角矩阵; - //!< measurement matrix (H) 观测模型 - setIdentity(KF.measurementMatrix); - + // set A + KF.transitionMatrix = (cv::Mat_(2, 2) << + 1, 0, + 0, 1); + // set B + KF.controlMatrix = (cv::Mat_(2, 2) << + 1, 0, + 0, 1); + // set Q //!< process noise covariance matrix (Q) // wk 是过程噪声,并假定其符合均值为零,协方差矩阵为Qk(Q)的多元正态分布; setIdentity(KF.processNoiseCov, cv::Scalar::all(1e-5)); @@ -87,6 +84,7 @@ cv::Point2d Kalman::re_init_filterting(const cv::Point2d& pos) //!< priori error estimate covariance matrix (P'(k)): P'(k)=A*P(k-1)*At + Q)*/ A代表F: transitionMatrix //预测估计协方差矩阵; + // 这啥啊,这不计算中的误差协方差 setIdentity(KF.errorCovPost, cv::Scalar::all(1)); //!< corrected state (x(k)): x(k)=x'(k)+K(k)*(z(k)-H*x'(k)) diff --git a/source/src/filter/kalman/Kalman.h b/source/src/filter/kalman/Kalman.h index 42989f4b..fecd1aad 100644 --- a/source/src/filter/kalman/Kalman.h +++ b/source/src/filter/kalman/Kalman.h @@ -6,14 +6,32 @@ class Kalman : public Filter Kalman(); ~Kalman(); public: - virtual cv::Point2d filterting(const cv::Point2d& pos) override; + virtual cv::Point2d filterting(const cv::Point2d &pos, const cv::Point2f &u_k) override; virtual cv::Point2d re_init_filterting(const cv::Point2d& pos) override; private: - int stateNum = 4; + int stateNum = 2; int measureNum = 2; + int controlNum = 2; + // motion model + // x(k) = A*x(k-1) + B*u(k) + w(k) + // w(k) ~ N(0, Q) + + // update model + // z(k) = H*x(k) + v(k) + // v(k) ~ N(0, R) + + // Where: + // x = [x y]' + // z = [x y]' + // u = [dx dy]' + // A = [1 0; 0 1] + // B = [1 0; 0 1] + // H = [1 0; 0 1] + // Q = [1 0; 0 1] * 1e-5 + // R = [1 0; 0 1] * 1e-5 cv::KalmanFilter KF; - cv::Mat state; /* (phi, delta_phi) */ + cv::Mat state; cv::Mat processNoise; cv::Mat measurement; }; \ No newline at end of file diff --git a/source/src/filter/smooth/Smooth.cpp b/source/src/filter/smooth/Smooth.cpp index e1d22f27..f25f4a0d 100644 --- a/source/src/filter/smooth/Smooth.cpp +++ b/source/src/filter/smooth/Smooth.cpp @@ -10,7 +10,7 @@ Smooth::~Smooth() { } -cv::Point2d Smooth::filterting(const cv::Point2d& pos) +cv::Point2d Smooth::filterting(const cv::Point2d &pos, const cv::Point2f &u_k) { mean_pos = pos * 0.1 + mean_pos * 0.9; return mean_pos; @@ -19,5 +19,5 @@ cv::Point2d Smooth::filterting(const cv::Point2d& pos) cv::Point2d Smooth::re_init_filterting(const cv::Point2d& pos) { mean_pos = pos; - return filterting(pos); + return filterting(pos, cv::Point2f(0, 0)); } diff --git a/source/src/filter/smooth/Smooth.h b/source/src/filter/smooth/Smooth.h index 0b97b6cb..298c3472 100644 --- a/source/src/filter/smooth/Smooth.h +++ b/source/src/filter/smooth/Smooth.h @@ -6,7 +6,7 @@ class Smooth : public Filter Smooth(); ~Smooth(); public: - virtual cv::Point2d filterting(const cv::Point2d& pos) override; + virtual cv::Point2d filterting(const cv::Point2d &pos, const cv::Point2f &u_k) override; virtual cv::Point2d re_init_filterting(const cv::Point2d& pos) override; private: cv::Point2d mean_pos; diff --git a/source/src/filter/untouched/Untouched.cpp b/source/src/filter/untouched/Untouched.cpp index cc414913..a56e505b 100644 --- a/source/src/filter/untouched/Untouched.cpp +++ b/source/src/filter/untouched/Untouched.cpp @@ -10,7 +10,7 @@ Untouched::~Untouched() { } -cv::Point2d Untouched::filterting(const cv::Point2d& pos) +cv::Point2d Untouched::filterting(const cv::Point2d &pos, const cv::Point2f &u_k) { return pos; } diff --git a/source/src/filter/untouched/Untouched.h b/source/src/filter/untouched/Untouched.h index 5052fe65..f1162fb6 100644 --- a/source/src/filter/untouched/Untouched.h +++ b/source/src/filter/untouched/Untouched.h @@ -6,6 +6,6 @@ class Untouched : public Filter Untouched(); ~Untouched(); public: - virtual cv::Point2d filterting(const cv::Point2d& pos) override; + virtual cv::Point2d filterting(const cv::Point2d &pos, const cv::Point2f &u_k) override; virtual cv::Point2d re_init_filterting(const cv::Point2d& pos) override; }; \ No newline at end of file diff --git a/source/src/genshin/match/position/genshin.match.position.cpp b/source/src/genshin/match/position/genshin.match.position.cpp index 60affcce..9a825753 100644 --- a/source/src/genshin/match/position/genshin.match.position.cpp +++ b/source/src/genshin/match/position/genshin.match.position.cpp @@ -4,6 +4,7 @@ #include "resources/Resources.h" #include "Match/surf/SurfMatch.h" #include "filter/kalman/Kalman.h" +#include "algorithms/algorithms.visual.odometer.h" cv::Mat to_color(cv::Mat& img_object) { @@ -176,14 +177,40 @@ void TianLi::Genshin::Match::get_avatar_position(const GenshinMinimap& genshin_m { cv::Point2d pos = out_genshin_position.position; cv::Point2d filt_pos; - if (out_genshin_position.config.is_coveying || out_genshin_position.config.is_continuity == false) - { + // 查看od初始化了没 + auto u_k = cv::Point2d(0, 0); + auto od_valid = control_odometer_calculation(genshin_minimap.img_minimap, u_k, odometer_config()); + if (!od_valid) { + // TODO:no u_k update filt_pos = out_genshin_position.config.pos_filter->re_init_filterting(pos); + set_mini_map(genshin_minimap.img_minimap); } - else - { - filt_pos = out_genshin_position.config.pos_filter->filterting(pos); + else { + cout << "u_k: " << u_k << endl; + filt_pos = out_genshin_position.config.pos_filter->filterting(pos, u_k); } + + + // if (out_genshin_position.config.is_coveying || out_genshin_position.config.is_continuity == false) + // { + // filt_pos = out_genshin_position.config.pos_filter->re_init_filterting(pos); + // // TODO:封装 + // set_mini_map(genshin_minimap.img_minimap); + // } + // else + // { + // auto u_k = cv::Point2d(0, 0); + // auto od_valid = control_odometer_calculation(genshin_minimap.img_minimap, u_k, odometer_config()); + // if (od_valid) + // { + // filt_pos = out_genshin_position.config.pos_filter->filterting(pos, u_k); + // } + // else + // { + // // TODO:no u_k update + // filt_pos = out_genshin_position.config.pos_filter->re_init_filterting(pos); + // } + // } out_genshin_position.position = filt_pos; } diff --git a/source/src/pch.h b/source/src/pch.h index c1237244..06c1771e 100644 --- a/source/src/pch.h +++ b/source/src/pch.h @@ -68,6 +68,7 @@ #include #include +// Helpers // DUMP部分 #include "Windows.h" diff --git a/source/src/version/version.ver b/source/src/version/version.ver index 5210382a..24afbc91 100644 --- a/source/src/version/version.ver +++ b/source/src/version/version.ver @@ -1 +1 @@ -8.0.1 \ No newline at end of file +8.0.3 \ No newline at end of file diff --git a/source/src/version/version_hash.hash b/source/src/version/version_hash.hash index 6b0068bc..333e2596 100644 --- a/source/src/version/version_hash.hash +++ b/source/src/version/version_hash.hash @@ -1 +1 @@ -aee4d33 \ No newline at end of file +a1906da \ No newline at end of file From 9d900d1e7d35109e36567abdaeb56ed7fa9ab6f2 Mon Sep 17 00:00:00 2001 From: Alex Beng <599267065@qq.com> Date: Sun, 3 Dec 2023 16:27:21 +0800 Subject: [PATCH 4/8] =?UTF-8?q?fix:=20=E6=9C=80=E4=BC=98=E6=AF=94=E6=AC=A1?= =?UTF-8?q?=E4=BC=98=E4=B8=8B=E6=A0=87=E9=94=99=E8=AF=AF,=20=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E5=9C=A8=E8=AE=BF=E9=97=AE=E5=89=8D=E5=88=A4=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/src/algorithms/algorithms.visual.odometer.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/src/algorithms/algorithms.visual.odometer.h b/source/src/algorithms/algorithms.visual.odometer.h index ccb10285..c645d917 100644 --- a/source/src/algorithms/algorithms.visual.odometer.h +++ b/source/src/algorithms/algorithms.visual.odometer.h @@ -70,6 +70,10 @@ bool orb_match(cv::Mat &img1, cv::Mat &img2, cv::Point2f &offset) cv::BFMatcher matcher(cv::NORM_HAMMING); std::vector> matches; matcher.knnMatch(desp1, desp2, matches, 2); + // 解决没有匹配点的情况 + if (matches.size() == 0) { + return false; + } std::vector good_matches; for (int i = 0; i < matches.size(); i++) { if (matches[i][0].distance < 0.6 * matches[i][1].distance) { From 914f35a2b4b2b4faec90fdd10f423cbacfc9d5d5 Mon Sep 17 00:00:00 2001 From: Alex Beng <599267065@qq.com> Date: Sun, 3 Dec 2023 16:39:16 +0800 Subject: [PATCH 5/8] add KF test doc --- ...13\350\257\225\346\226\207\346\241\243.md" | 646 ++++++++++++++++++ 1 file changed, 646 insertions(+) create mode 100644 "doc/KF/\346\265\213\350\257\225\346\226\207\346\241\243.md" diff --git "a/doc/KF/\346\265\213\350\257\225\346\226\207\346\241\243.md" "b/doc/KF/\346\265\213\350\257\225\346\226\207\346\241\243.md" new file mode 100644 index 00000000..61d6a393 --- /dev/null +++ "b/doc/KF/\346\265\213\350\257\225\346\226\207\346\241\243.md" @@ -0,0 +1,646 @@ +这是一份简单的KF测试结果文档。 + +# 静态测试 +测试设置:同一地点,仅转动相机,不移动角色,是否会有坐标变化。 + +## before +``` +全部信息: +地区:提瓦特大陆 +坐标:x = 7345.00; y = 5176.05 +朝向:角色 = 68.30; 相机 = -108.98 +UID:xxxx +UseTime:3829.00ms +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 7344.87; y = 5176.03 +朝向:角色 = 68.30; 相机 = -108.98 +UID:xxxx +UseTime:3266.00ms +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 7344.86; y = 5176.03 +朝向:角色 = 68.30; 相机 = -108.98 +UID:xxxx +UseTime:3469.00ms +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 7344.86; y = 5176.03 +朝向:角色 = 68.30; 相机 = -108.98 +UID:xxxx +UseTime:3468.00ms +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 7344.88; y = 5176.02 +朝向:角色 = 68.30; 相机 = -108.98 +UID:xxxx +UseTime:3453.00ms +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 7483.24; y = 5229.08 +朝向:角色 = 68.08; 相机 = -1.76 +UID:xxxx +UseTime:3343.00ms +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 7483.30; y = 5229.07 +朝向:角色 = 68.72; 相机 = 63.98 +UID:xxxx +UseTime:3344.00ms +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 7483.30; y = 5229.08 +朝向:角色 = 68.72; 相机 = 55.55 +UID:xxxx +UseTime:3203.00ms +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 7437.17; y = 5211.40 +朝向:角色 = 68.08; 相机 = 152.93 +UID:xxxx +UseTime:3281.00ms +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 7437.13; y = 5211.40 +朝向:角色 = 67.82; 相机 = 163.48 +UID:xxxx +UseTime:3265.00ms +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 7344.87; y = 5176.02 +朝向:角色 = 67.89; 相机 = -49.22 +UID:xxxx +UseTime:3219.00ms +``` + +x_min = 7344.86, x_max = 7483.30, y_min = 5176.02, y_max = 5229.08 +delta_x = 138.44, delta_y = 53.06 + +## 正确 KF 后 + +``` +全部信息: +地区:提瓦特大陆 +坐标:x = 7357.13; y = 5179.53 +朝向:角色 = -15.55; 相机 = -66.45 +UID:xxxx +UseTime:4000.00ms +---------------- +[ INFO:0@10.524] global ocl.cpp:5370 cv::ocl::Context::Impl::__init_buffer_pools OpenCL: Initializing buffer pool for context@0 with max capacity: poolSize=0 poolSizeHostPtr=0 +u_k: [3.26497, 4.86567] + +全部信息: +地区:提瓦特大陆 +坐标:x = 7360.40; y = 5184.39 +朝向:角色 = -9.46; 相机 = -10.90 +UID:xxxx +UseTime:3531.00ms +---------------- +u_k: [0.0130302, 0.010909] + +全部信息: +地区:提瓦特大陆 +坐标:x = 7360.41; y = 5184.40 +朝向:角色 = -9.30; 相机 = 79.80 +UID:xxxx +UseTime:3469.00ms +---------------- +u_k: [-0.016, -0.014] + +全部信息: +地区:提瓦特大陆 +坐标:x = 7360.39; y = 5184.39 +朝向:角色 = -9.30; 相机 = 158.55 +UID:xxxx +UseTime:3391.00ms +---------------- +u_k: [0, 0] +[ INFO:18@21.340] global ocl.cpp:984 cv::ocl::OpenCLExecutionContext::Impl::getInitializedExecutionContext OpenCL: initializing thread execution context +[ INFO:19@21.340] global ocl.cpp:984 cv::ocl::OpenCLExecutionContext::Impl::getInitializedExecutionContext OpenCL: initializing thread execution context + +全部信息: +地区:提瓦特大陆 +坐标:x = 7360.39; y = 5184.39 +朝向:角色 = -9.95; 相机 = -118.12 +UID:xxxx +UseTime:3391.00ms +---------------- +u_k: [0.00518135, -0.00518135] + +全部信息: +地区:提瓦特大陆 +坐标:x = 7360.40; y = 5184.39 +朝向:角色 = -9.46; 相机 = -94.92 +UID:xxxx +UseTime:3406.00ms +---------------- +u_k: [0.0102857, -0.0177144] + +全部信息: +地区:提瓦特大陆 +坐标:x = 7360.41; y = 5184.37 +朝向:角色 = -9.46; 相机 = 42.19 +UID:xxxx +UseTime:3390.00ms +---------------- +u_k: [-0.0106194, 0.00353974] +[ INFO:20@31.815] global ocl.cpp:984 cv::ocl::OpenCLExecutionContext::Impl::getInitializedExecutionContext OpenCL: initializing thread execution context + +全部信息: +地区:提瓦特大陆 +坐标:x = 7360.40; y = 5184.37 +朝向:角色 = -9.95; 相机 = -144.14 +UID:xxxx +UseTime:3375.00ms +---------------- +[ INFO:21@32.049] global ocl.cpp:984 cv::ocl::OpenCLExecutionContext::Impl::getInitializedExecutionContext OpenCL: initializing thread execution context +u_k: [0, 0] + +全部信息: +地区:提瓦特大陆 +坐标:x = 7360.40; y = 5184.37 +朝向:角色 = -9.30; 相机 = 116.72 +UID:xxxx +UseTime:3328.00ms +---------------- +u_k: [0.00169489, 0.00169489] + +全部信息: +地区:提瓦特大陆 +坐标:x = 7360.40; y = 5184.37 +朝向:角色 = -9.46; 相机 = 41.48 +UID:xxxx +UseTime:3390.00ms +---------------- +u_k: [0, 0] + +全部信息: +地区:提瓦特大陆 +坐标:x = 7360.40; y = 5184.37 +朝向:角色 = -9.95; 相机 = -161.02 +UID:xxxx +UseTime:3390.00ms +---------------- +u_k: [0.00197532, 0.00395062] + +全部信息: +地区:提瓦特大陆 +坐标:x = 7360.40; y = 5184.38 +朝向:角色 = -9.95; 相机 = -161.02 +UID:xxxx +UseTime:3375.00ms +---------------- +``` + +x_min = 7357.13, x_max = 7360.41, y_min = 5184.37, y_max = 5184.40 +delta_x = 3.28, delta_y = 0.03 + +# 动态测试 + +设置1:传送至离岛码头,沿码头的路来回,对比坐标变化。 + +## before + +``` +全部信息: +地区:提瓦特大陆 +坐标:x = 8235.30; y = 3892.49 +朝向:角色 = -98.90; 相机 = -95.98 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 8240.09; y = 3890.67 +朝向:角色 = -97.93; 相机 = -82.97 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 8241.30; y = 3894.15 +朝向:角色 = -131.30; 相机 = -37.97 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 8240.97; y = 3896.56 +朝向:角色 = 109.94; 相机 = 48.52 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 8224.04; y = 3889.63 +朝向:角色 = 73.70; 相机 = 79.80 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 8204.52; y = 3883.35 +朝向:角色 = 70.06; 相机 = 77.70 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 8179.75; y = 3884.92 +朝向:角色 = 71.40; 相机 = 78.40 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 2353.03; y = -6201.35 +朝向:角色 = 83.30; 相机 = 83.32 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 8157.19; y = 3874.29 +朝向:角色 = 53.23; 相机 = 58.71 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 8169.76; y = 3873.65 +朝向:角色 = 61.10; 相机 = 62.23 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = -0.00; y = 0.00 +朝向:角色 = 52.08; 相机 = 56.95 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = -0.00; y = -0.01 +朝向:角色 = 36.59; 相机 = 35.86 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = -0.00; y = 0.00 +朝向:角色 = 36.30; 相机 = 45.00 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 8109.44; y = 3823.84 +朝向:角色 = 42.43; 相机 = 46.41 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 6346.54; y = 11744.20 +朝向:角色 = 46.01; 相机 = 60.47 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = -0.00; y = -0.01 +朝向:角色 = -161.78; 相机 = 156.45 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = -0.00; y = -0.00 +朝向:角色 = -149.12; 相机 = -165.94 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = -0.00; y = -0.00 +朝向:角色 = -129.08; 相机 = -137.11 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = -0.00; y = -0.00 +朝向:角色 = -132.36; 相机 = -131.13 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = -0.00; y = 0.01 +朝向:角色 = -126.98; 相机 = -124.80 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = -8251.77; y = -8121.34 +朝向:角色 = -98.15; 相机 = -119.53 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 2353.20; y = -6202.37 +朝向:角色 = -103.37; 相机 = -105.82 +UID:xxxx +---------------- + +全部信息: +地区:提瓦特大陆 +坐标:x = 8184.81; y = 3878.47 +朝向:角色 = -101.23; 相机 = -100.55 +UID:xxxx---------------- +``` +x_min = -8251.77, x_max = 8184.81, y_min = -8121.34, y_max = 11744.20 +delta_x = 16436.58, delta_y = 19865.54 + +## 正确 KF 后 + +``` + +全部信息: +地区:提瓦特大陆 +坐标:x = 8283.21; y = 3893.72 +朝向:角色 = 83.34; 相机 = 81.21 +UID:xxxx +UseTime:1594.00ms +---------------- +u_k: [0.488606, -0.0950788] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8283.70; y = 3893.63 +朝向:角色 = 177.39; 相机 = 56.95 +UID:xxxx +UseTime:1062.00ms +---------------- +u_k: [0.00422564, 1.0244] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8283.71; y = 3894.65 +朝向:角色 = 21.62; 相机 = 12.30 +UID:xxxx +UseTime:1094.00ms +---------------- +u_k: [17.4744, 3.60716] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8301.18; y = 3898.26 +朝向:角色 = 94.71; 相机 = 100.90 +UID:xxxx +UseTime:1047.00ms +---------------- +u_k: [17.8496, -3.19362] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8319.03; y = 3895.06 +朝向:角色 = 88.27; 相机 = 87.54 +UID:xxxx +UseTime:1046.00ms +---------------- +u_k: [16.4306, 1.07886] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8335.46; y = 3896.14 +朝向:角色 = 85.46; 相机 = 86.13 +UID:xxxx +UseTime:1031.00ms +---------------- +u_k: [15.3696, 1.3528] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8350.83; y = 3897.50 +朝向:角色 = 82.33; 相机 = 79.80 +UID:xxxx +UseTime:1047.00ms +---------------- +u_k: [10.5003, 2.47144] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8361.33; y = 3899.97 +朝向:角色 = 68.20; 相机 = 74.88 +UID:xxxx +UseTime:1047.00ms +---------------- +u_k: [14.6771, 6.60857] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8376.01; y = 3906.58 +朝向:角色 = 61.32; 相机 = 61.88 +UID:xxxx +UseTime:1047.00ms +---------------- +u_k: [13.9347, 7.57053] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8389.94; y = 3914.15 +朝向:角色 = 61.74; 相机 = 62.23 +UID:xxxx +UseTime:1032.00ms +---------------- +u_k: [10.4507, -4.74733] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8400.39; y = 3909.40 +朝向:角色 = 54.51; 相机 = 55.20 +UID:xxxx +UseTime:1047.00ms +---------------- +u_k: [9.55936, 9.33013] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8409.95; y = 3918.73 +朝向:角色 = 42.40; 相机 = 45.00 +UID:xxxx +UseTime:1032.00ms +---------------- +u_k: [8.70193, 9.08178] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8418.65; y = 3927.81 +朝向:角色 = 43.34; 相机 = 46.76 +UID:xxxx +UseTime:1032.00ms +---------------- +u_k: [8.782, 8.98534] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8427.44; y = 3936.80 +朝向:角色 = 28.73; 相机 = 7.38 +UID:xxxx +UseTime:1047.00ms +---------------- +u_k: [3.52, 6.4] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8430.96; y = 3943.20 +朝向:角色 = -144.15; 相机 = -129.73 +UID:xxxx +UseTime:1047.00ms +---------------- +u_k: [-2.7294, -2.8473] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8428.23; y = 3940.35 +朝向:角色 = 89.22; 相机 = -133.59 +UID:xxxx +UseTime:1078.00ms +---------------- +u_k: [-12.1266, -12.8671] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8416.10; y = 3927.48 +朝向:角色 = -134.42; 相机 = -133.24 +UID:xxxx +UseTime:1062.00ms +---------------- +u_k: [-8.656, -8.69715] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8407.44; y = 3918.78 +朝向:角色 = -133.63; 相机 = -132.89 +UID:xxxx +UseTime:1079.00ms +---------------- +u_k: [-6.59826, -6.1273] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8400.84; y = 3912.66 +朝向:角色 = -131.83; 相机 = -130.43 +UID:xxxx +UseTime:1078.00ms +---------------- +u_k: [-8.13429, -6.1] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8392.71; y = 3906.56 +朝向:角色 = -123.41; 相机 = -122.70 +UID:xxxx +UseTime:1094.00ms +---------------- +u_k: [-14.0613, -8.48533] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8378.65; y = 3898.07 +朝向:角色 = -122.47; 相机 = -118.48 +UID:xxxx +UseTime:1094.00ms +---------------- +u_k: [-8.98025, -3.92188] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8369.67; y = 3894.15 +朝向:角色 = -111.88; 相机 = -111.80 +UID:xxxx +UseTime:1079.00ms +---------------- +u_k: [-11.637, -5.14715] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8358.03; y = 3889.00 +朝向:角色 = -104.72; 相机 = -104.06 +UID:xxxx +UseTime:1125.00ms +---------------- +u_k: [-21.6501, -4.1861] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8336.38; y = 3884.82 +朝向:角色 = -99.54; 相机 = -96.33 +UID:xxxx +UseTime:1062.00ms +---------------- +u_k: [-13.5919, -1.66449] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8322.79; y = 3883.15 +朝向:角色 = -98.73; 相机 = -96.33 +UID:xxxx +UseTime:1094.00ms +---------------- +u_k: [-11.5921, -0.869935] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8311.20; y = 3882.28 +朝向:角色 = -86.07; 相机 = -91.41 +UID:xxxx +UseTime:1094.00ms +---------------- +u_k: [-14.6852, 0.852] + +全部信息: +地区:提瓦特大陆 +坐标:x = 8296.51; y = 3883.13 +朝向:角色 = -77.71; 相机 = -84.38 +UID:xxxx +UseTime:1359.00ms``` +x_min = -132.68, x_max = -0.00, y_min = -61.64, y_max = 0.00 +delta_x = 132.68, delta_y = 61.64 +``` +x_min = 8296.51, x_max = 8430.96, y_min = 3882.28, y_max = 3943.20 +delta_x = 134.45, delta_y = 60.92 + +设置2:在离岛码头传送锚点和七天神像之间tp,并随机走动,对比坐标变换 + +tp有问题,见已知问题。 + +# 已知问题 + +1. 在大小地图匹配初始化失败(应该是小地图匹配的特征点过少)/tp之后,即坐标从 0,0 开始,观测更新后无法收敛到正确的坐标。 + +aka,机器人学中的绑架问题尚未解决。 \ No newline at end of file From cfb95554820b2cdbb5eeb11c41f25410ab0c646e Mon Sep 17 00:00:00 2001 From: Alex Beng <599267065@qq.com> Date: Sun, 3 Dec 2023 18:52:41 +0800 Subject: [PATCH 6/8] rollback rm dxgi commits --- source/CMakeLists.txt | 2 +- source/src/AutoTrack.cpp | 1 + source/src/ErrorCode.cpp | 7 +++++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 1a945c57..0f9b05a5 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -94,7 +94,7 @@ FetchContent_Declare(fmt GIT_REPOSITORY https://github.com/fmtlib/fmt.git GIT_TA FetchContent_MakeAvailable(fmt) set_target_properties(fmt PROPERTIES FOLDER "cvAutoTrack/dependencies") -target_link_libraries(cvAutoTrack PRIVATE ${OpenCV_LIBS} cereal::cereal fmt::fmt-header-only d3d11.lib d3dcompiler.lib) +target_link_libraries(cvAutoTrack PRIVATE ${OpenCV_LIBS} cereal::cereal fmt::fmt-header-only d3d11.lib d3dcompiler.lib dxgi.lib) if(WITH_DYNAMIC_OPENCV) add_custom_command(TARGET cvAutoTrack POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OpenCV_CONFIG_PATH}/../bin/opencv_world480$<$:d>.dll" "$") diff --git a/source/src/AutoTrack.cpp b/source/src/AutoTrack.cpp index 539975d0..5a23de80 100644 --- a/source/src/AutoTrack.cpp +++ b/source/src/AutoTrack.cpp @@ -4,6 +4,7 @@ #include "ErrorCode.h" #include "resources/Resources.h" +#include "capture/dxgi/Dxgi.h" #include "capture/bitblt/Bitblt.h" #include "filter/kalman/Kalman.h" #include "utils/Utils.h" diff --git a/source/src/ErrorCode.cpp b/source/src/ErrorCode.cpp index 5278e89c..78aa2465 100644 --- a/source/src/ErrorCode.cpp +++ b/source/src/ErrorCode.cpp @@ -39,14 +39,17 @@ std::string get_sys_version() } std::string get_gpu_name() { - return "获取GPU信息失败"; // Get the name of the GPU #ifdef BUILD_CAPTURE_DXGI IDXGIAdapter* pAdapter = nullptr; IDXGIFactory* pFactory = nullptr; try { - HRESULT hr; + HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pFactory)); + if (FAILED(hr)) + { + return "Unknown"; + } hr = pFactory->EnumAdapters(0, &pAdapter); if (FAILED(hr)) From 5cccaa1809208516250823e97a343b952d0f100d Mon Sep 17 00:00:00 2001 From: Alex Beng <599267065@qq.com> Date: Sun, 3 Dec 2023 18:58:48 +0800 Subject: [PATCH 7/8] rollback rm dxgi --- .../capture/dxgi/include/capture.interop.h | 14 ++ .../dxgi/include/composition.interop.h | 60 ++++++ source/src/capture/dxgi/include/d3dHelpers.h | 173 ++++++++++++++++++ .../capture/dxgi/include/direct3d11.interop.h | 40 ++++ 4 files changed, 287 insertions(+) create mode 100644 source/src/capture/dxgi/include/capture.interop.h create mode 100644 source/src/capture/dxgi/include/composition.interop.h create mode 100644 source/src/capture/dxgi/include/d3dHelpers.h create mode 100644 source/src/capture/dxgi/include/direct3d11.interop.h diff --git a/source/src/capture/dxgi/include/capture.interop.h b/source/src/capture/dxgi/include/capture.interop.h new file mode 100644 index 00000000..3297c0f5 --- /dev/null +++ b/source/src/capture/dxgi/include/capture.interop.h @@ -0,0 +1,14 @@ +#pragma once +#include +#include +#include + +inline auto CreateCaptureItemForWindow(HWND hwnd) +{ + auto activation_factory = winrt::get_activation_factory(); + auto interop_factory = activation_factory.as(); + winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = { nullptr }; + interop_factory->CreateForWindow(hwnd, winrt::guid_of(), reinterpret_cast(winrt::put_abi(item))); + return item; +} + \ No newline at end of file diff --git a/source/src/capture/dxgi/include/composition.interop.h b/source/src/capture/dxgi/include/composition.interop.h new file mode 100644 index 00000000..2b9d2196 --- /dev/null +++ b/source/src/capture/dxgi/include/composition.interop.h @@ -0,0 +1,60 @@ +#pragma once +#include +#include +#include + +inline auto CreateCompositionGraphicsDevice( + winrt::Windows::UI::Composition::Compositor const& compositor, + ::IUnknown* device) +{ + winrt::Windows::UI::Composition::CompositionGraphicsDevice graphicsDevice{ nullptr }; + auto compositorInterop = compositor.as(); + winrt::com_ptr graphicsInterop; + winrt::check_hresult(compositorInterop->CreateGraphicsDevice(device, graphicsInterop.put())); + winrt::check_hresult(graphicsInterop->QueryInterface(winrt::guid_of(), + reinterpret_cast(winrt::put_abi(graphicsDevice)))); + return graphicsDevice; +} + +inline void ResizeSurface( + winrt::Windows::UI::Composition::CompositionDrawingSurface const& surface, + winrt::Windows::Foundation::Size const& size) +{ + auto surfaceInterop = surface.as(); + SIZE newSize = {}; + newSize.cx = static_cast(std::round(size.Width)); + newSize.cy = static_cast(std::round(size.Height)); + winrt::check_hresult(surfaceInterop->Resize(newSize)); +} + +inline auto SurfaceBeginDraw( + winrt::Windows::UI::Composition::CompositionDrawingSurface const& surface) +{ + auto surfaceInterop = surface.as(); + winrt::com_ptr context; + POINT offset = {}; + winrt::check_hresult(surfaceInterop->BeginDraw(nullptr, __uuidof(ID2D1DeviceContext), context.put_void(), &offset)); + context->SetTransform(D2D1::Matrix3x2F::Translation((FLOAT)offset.x,(FLOAT) offset.y)); + return context; +} + +inline void SurfaceEndDraw( + winrt::Windows::UI::Composition::CompositionDrawingSurface const& surface) +{ + auto surfaceInterop = surface.as(); + winrt::check_hresult(surfaceInterop->EndDraw()); +} + +inline auto CreateCompositionSurfaceForSwapChain( + winrt::Windows::UI::Composition::Compositor const& compositor, + ::IUnknown* swapChain) +{ + winrt::Windows::UI::Composition::ICompositionSurface surface{ nullptr }; + auto compositorInterop = compositor.as(); + winrt::com_ptr surfaceInterop; + winrt::check_hresult(compositorInterop->CreateCompositionSurfaceForSwapChain(swapChain, surfaceInterop.put())); + winrt::check_hresult(surfaceInterop->QueryInterface(winrt::guid_of(), + reinterpret_cast(winrt::put_abi(surface)))); + return surface; +} + \ No newline at end of file diff --git a/source/src/capture/dxgi/include/d3dHelpers.h b/source/src/capture/dxgi/include/d3dHelpers.h new file mode 100644 index 00000000..b9714f73 --- /dev/null +++ b/source/src/capture/dxgi/include/d3dHelpers.h @@ -0,0 +1,173 @@ +#pragma once +#include "composition.interop.h" + +struct SurfaceContext +{ +public: + SurfaceContext(std::nullptr_t) {} + SurfaceContext( + winrt::Windows::UI::Composition::CompositionDrawingSurface surface) + { + m_surface = surface; + m_d2dContext = SurfaceBeginDraw(m_surface); + } + ~SurfaceContext() + { + SurfaceEndDraw(m_surface); + m_d2dContext = nullptr; + m_surface = nullptr; + } + + winrt::com_ptr GetDeviceContext() { return m_d2dContext; } + +private: + winrt::com_ptr m_d2dContext; + winrt::Windows::UI::Composition::CompositionDrawingSurface m_surface{ nullptr }; +}; + +struct D3D11DeviceLock +{ +public: + D3D11DeviceLock(std::nullopt_t) {} + D3D11DeviceLock(ID3D11Multithread* pMultithread) + { + m_multithread.copy_from(pMultithread); + m_multithread->Enter(); + } + ~D3D11DeviceLock() + { + m_multithread->Leave(); + m_multithread = nullptr; + } +private: + winrt::com_ptr m_multithread; +}; + +inline auto +CreateWICFactory() +{ + winrt::com_ptr wicFactory; + winrt::check_hresult( + ::CoCreateInstance( + CLSID_WICImagingFactory, + nullptr, + CLSCTX_INPROC_SERVER, + winrt::guid_of(), + wicFactory.put_void())); + + return wicFactory; +} + +inline auto +CreateD2DDevice( + winrt::com_ptr const& factory, + winrt::com_ptr const& device) +{ + winrt::com_ptr result; + winrt::check_hresult(factory->CreateDevice(device.as().get(), result.put())); + return result; +} + +inline auto +CreateD3DDevice( + D3D_DRIVER_TYPE const type, + winrt::com_ptr& device) +{ + WINRT_ASSERT(!device); + + UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; + +//#ifdef _DEBUG +// flags |= D3D11_CREATE_DEVICE_DEBUG; +//#endif + + return D3D11CreateDevice( + nullptr, + type, + nullptr, + flags, + nullptr, 0, + D3D11_SDK_VERSION, + device.put(), + nullptr, + nullptr); +} + +inline auto +CreateD3DDevice() +{ + winrt::com_ptr device; + HRESULT hr = CreateD3DDevice(D3D_DRIVER_TYPE_HARDWARE, device); + + if (DXGI_ERROR_UNSUPPORTED == hr) + { + hr = CreateD3DDevice(D3D_DRIVER_TYPE_WARP, device); + } + + winrt::check_hresult(hr); + return device; +} + +inline auto +CreateD2DFactory() +{ + D2D1_FACTORY_OPTIONS options{}; + +//#ifdef _DEBUG +// options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION; +//#endif + + winrt::com_ptr factory; + + winrt::check_hresult(D2D1CreateFactory( + D2D1_FACTORY_TYPE_SINGLE_THREADED, + options, + factory.put())); + + return factory; +} + +inline auto +CreateDXGISwapChain( + winrt::com_ptr const& device, + const DXGI_SWAP_CHAIN_DESC1* desc) +{ + auto dxgiDevice = device.as(); + winrt::com_ptr adapter; + winrt::check_hresult(dxgiDevice->GetParent(winrt::guid_of(), adapter.put_void())); + winrt::com_ptr factory; + winrt::check_hresult(adapter->GetParent(winrt::guid_of(), factory.put_void())); + + winrt::com_ptr swapchain; + winrt::check_hresult(factory->CreateSwapChainForComposition( + device.get(), + desc, + nullptr, + swapchain.put())); + + return swapchain; +} + +inline auto +CreateDXGISwapChain( + winrt::com_ptr const& device, + uint32_t width, + uint32_t height, + DXGI_FORMAT format, + uint32_t bufferCount) +{ + DXGI_SWAP_CHAIN_DESC1 desc = {}; + desc.Width = width; + desc.Height = height; + desc.Format = format; + desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.BufferCount = bufferCount; + desc.Scaling = DXGI_SCALING_STRETCH; + desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + desc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; + + return CreateDXGISwapChain(device, &desc); +} +/// DXGI_ALPHA_MODE_UNSPECIFIED \ No newline at end of file diff --git a/source/src/capture/dxgi/include/direct3d11.interop.h b/source/src/capture/dxgi/include/direct3d11.interop.h new file mode 100644 index 00000000..0886332a --- /dev/null +++ b/source/src/capture/dxgi/include/direct3d11.interop.h @@ -0,0 +1,40 @@ +#pragma once +#include + +extern "C" +{ + HRESULT __stdcall CreateDirect3D11DeviceFromDXGIDevice(::IDXGIDevice* dxgiDevice, + ::IInspectable** graphicsDevice); + + HRESULT __stdcall CreateDirect3D11SurfaceFromDXGISurface(::IDXGISurface* dgxiSurface, + ::IInspectable** graphicsSurface); +} + +struct __declspec(uuid("A9B3D012-3DF2-4EE3-B8D1-8695F457D3C1")) + IDirect3DDxgiInterfaceAccess : ::IUnknown +{ + virtual HRESULT __stdcall GetInterface(GUID const& id, void** object) = 0; +}; + +inline auto CreateDirect3DDevice(IDXGIDevice* dxgi_device) +{ + winrt::com_ptr<::IInspectable> d3d_device; + winrt::check_hresult(CreateDirect3D11DeviceFromDXGIDevice(dxgi_device, d3d_device.put())); + return d3d_device.as(); +} + +inline auto CreateDirect3DSurface(IDXGISurface* dxgi_surface) +{ + winrt::com_ptr<::IInspectable> d3d_surface; + winrt::check_hresult(CreateDirect3D11SurfaceFromDXGISurface(dxgi_surface, d3d_surface.put())); + return d3d_surface.as(); +} + +template +auto GetDXGIInterfaceFromObject(winrt::Windows::Foundation::IInspectable const& object) +{ + auto access = object.as(); + winrt::com_ptr result; + winrt::check_hresult(access->GetInterface(winrt::guid_of(), result.put_void())); + return result; +} From 6f2df6bafe1e1bc408836ae2227ee324dcee6fd8 Mon Sep 17 00:00:00 2001 From: Alex Beng <599267065@qq.com> Date: Sun, 3 Dec 2023 19:00:20 +0800 Subject: [PATCH 8/8] rollback rm dxgi --- source/src/capture/dxgi/include/capture.interop.h | 3 +-- source/src/capture/dxgi/include/composition.interop.h | 3 +-- source/src/capture/dxgi/include/direct3d11.interop.h | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/source/src/capture/dxgi/include/capture.interop.h b/source/src/capture/dxgi/include/capture.interop.h index 3297c0f5..dda19fce 100644 --- a/source/src/capture/dxgi/include/capture.interop.h +++ b/source/src/capture/dxgi/include/capture.interop.h @@ -10,5 +10,4 @@ inline auto CreateCaptureItemForWindow(HWND hwnd) winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = { nullptr }; interop_factory->CreateForWindow(hwnd, winrt::guid_of(), reinterpret_cast(winrt::put_abi(item))); return item; -} - \ No newline at end of file +} \ No newline at end of file diff --git a/source/src/capture/dxgi/include/composition.interop.h b/source/src/capture/dxgi/include/composition.interop.h index 2b9d2196..1341bd7a 100644 --- a/source/src/capture/dxgi/include/composition.interop.h +++ b/source/src/capture/dxgi/include/composition.interop.h @@ -56,5 +56,4 @@ inline auto CreateCompositionSurfaceForSwapChain( winrt::check_hresult(surfaceInterop->QueryInterface(winrt::guid_of(), reinterpret_cast(winrt::put_abi(surface)))); return surface; -} - \ No newline at end of file +} \ No newline at end of file diff --git a/source/src/capture/dxgi/include/direct3d11.interop.h b/source/src/capture/dxgi/include/direct3d11.interop.h index 0886332a..b6d40cd4 100644 --- a/source/src/capture/dxgi/include/direct3d11.interop.h +++ b/source/src/capture/dxgi/include/direct3d11.interop.h @@ -37,4 +37,4 @@ auto GetDXGIInterfaceFromObject(winrt::Windows::Foundation::IInspectable const& winrt::com_ptr result; winrt::check_hresult(access->GetInterface(winrt::guid_of(), result.put_void())); return result; -} +} \ No newline at end of file