mirror of
https://github.com/Blinue/Magpie.git
synced 2026-06-24 02:04:10 +00:00
初步支持 WinRT Capturer API
This commit is contained in:
parent
a0eef70a9a
commit
8d21ff0c75
11 changed files with 156 additions and 161 deletions
|
|
@ -20,9 +20,37 @@ namespace Magpie {
|
|||
{
|
||||
""effect"": ""scale"",
|
||||
""type"": ""Anime4KxDenoise""
|
||||
},
|
||||
{
|
||||
""effect"": ""scale"",
|
||||
""type"": ""mitchell"",
|
||||
""scale"": [0,0],
|
||||
""useSharperVersion"": true
|
||||
},
|
||||
{
|
||||
""effect"": ""sharpen"",
|
||||
""type"": ""adaptive"",
|
||||
""curveHeight"": 0.2
|
||||
}
|
||||
]";
|
||||
private const string CommonEffectJson = @"[
|
||||
{
|
||||
""effect"": ""scale"",
|
||||
""type"": ""lanczos6"",
|
||||
""scale"": [0,0],
|
||||
""ARStrength"": 0.7
|
||||
},
|
||||
{
|
||||
""effect"": ""sharpen"",
|
||||
""type"": ""adaptive"",
|
||||
""curveHeight"": 0.6
|
||||
},
|
||||
{
|
||||
""effect"": ""sharpen"",
|
||||
""type"": ""builtIn"",
|
||||
""sharpness"": 0.5,
|
||||
""threshold"": 0.5
|
||||
}
|
||||
]";
|
||||
|
||||
IKeyboardMouseEvents keyboardEvents = null;
|
||||
|
|
@ -57,6 +85,7 @@ namespace Magpie {
|
|||
}
|
||||
|
||||
private void MainForm_FormClosing(object sender, FormClosingEventArgs e) {
|
||||
DestroyMagWindow();
|
||||
Settings.Default.Save();
|
||||
}
|
||||
|
||||
|
|
@ -94,9 +123,7 @@ namespace Magpie {
|
|||
HookCursorAtRuntime();
|
||||
}
|
||||
} else {
|
||||
NativeMethods.BroadcastMessage(NativeMethods.MAGPIE_WM_DESTORYMAG);
|
||||
thread.Abort();
|
||||
thread = null;
|
||||
DestroyMagWindow();
|
||||
}
|
||||
}
|
||||
}});
|
||||
|
|
@ -111,6 +138,14 @@ namespace Magpie {
|
|||
|
||||
}
|
||||
|
||||
private void DestroyMagWindow() {
|
||||
NativeMethods.BroadcastMessage(NativeMethods.MAGPIE_WM_DESTORYMAG);
|
||||
if(thread != null) {
|
||||
thread.Abort();
|
||||
thread = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void HookCursorAtRuntime() {
|
||||
IntPtr hwndSrc = NativeMethods.GetForegroundWindow();
|
||||
int pid = NativeMethods.GetWindowProcessId(hwndSrc);
|
||||
|
|
|
|||
|
|
@ -16,13 +16,16 @@ cbuffer constants : register(b0) {
|
|||
|
||||
|
||||
D2D_PS_ENTRY(main) {
|
||||
InitMagpieSampleInputWithScale(float2(2, 2));
|
||||
float4 coord0 = D2DGetInputCoordinate(0);
|
||||
coord0.xy /= float2(2,2); // 将 dest 坐标映射为 src 坐标
|
||||
float4 coord1 = D2DGetInputCoordinate(1);
|
||||
coord1.xy /= float2(2, 2); // 将 dest 坐标映射为 src 坐标
|
||||
|
||||
float2 f = frac(coord.xy / coord.zw);
|
||||
float2 f = frac(coord1.xy / coord1.zw);
|
||||
// 截取整数部分,如果使用 round 会有 bug,因为在特殊情况下 f 可能等于 0.75
|
||||
int2 i = int2(f * 2);
|
||||
float l = Uncompress(SampleInputRGBAOffNoCheck(1, (float2(0.5, 0.5) - f)))[i.y * 2 + i.x];
|
||||
float l = Uncompress(D2DSampleInput(1, coord1.xy + (float2(0.5, 0.5) - f) * coord1.zw))[i.y * 2 + i.x];
|
||||
|
||||
float3 yuv = RGB2YUV(SampleInputCur(0));
|
||||
float3 yuv = RGB2YUV(D2DSampleInput(0, coord0.xy).xyz);
|
||||
return float4(YUV2RGB(yuv.x+l, yuv.y, yuv.z), 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,14 @@ public:
|
|||
return _d3dDevice.Get();
|
||||
}
|
||||
|
||||
const ID2D1Device* GetD2DDevice() const {
|
||||
return _d2dDevice.Get();
|
||||
}
|
||||
|
||||
ID2D1Device* GetD2DDevice() {
|
||||
return _d2dDevice.Get();
|
||||
}
|
||||
|
||||
void Render(std::function<void()> renderFunc) {
|
||||
if (_lowLantencyMode) {
|
||||
WaitForSingleObjectEx(_frameLatencyWaitableObject, 1000, true);
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ public:
|
|||
_SetDestSize(srcSize);
|
||||
_ReadEffectsJson(effectsJson);
|
||||
|
||||
// 计算输出位置
|
||||
float x = float(_hostClient.right - _hostClient.left - _outputSize.cx) / 2;
|
||||
float y = float(_hostClient.bottom - _hostClient.top - _outputSize.cy) / 2;
|
||||
// 计算输出位置,x 和 y 必须为整数,否则会使画面模糊
|
||||
float x = float((_hostClient.right - _hostClient.left - _outputSize.cx) / 2);
|
||||
float y = float((_hostClient.bottom - _hostClient.top - _outputSize.cy) / 2);
|
||||
_outputRect = RectF(x, y, x + _outputSize.cx, y + _outputSize.cy);
|
||||
}
|
||||
|
||||
|
|
@ -38,66 +38,28 @@ public:
|
|||
|
||||
|
||||
void Render() override {
|
||||
ComPtr<ID2D1Image> outputImg = nullptr;
|
||||
_outputEffect->GetOutput(&outputImg);
|
||||
if (_firstEffect) {
|
||||
_firstEffect->SetInput(0, _inputBmp.Get());
|
||||
|
||||
_d2dContext.GetD2DDC()->DrawImage(
|
||||
outputImg.Get(),
|
||||
Point2F(_outputRect.left, _outputRect.top)
|
||||
);
|
||||
}
|
||||
ComPtr<ID2D1Image> outputImg = nullptr;
|
||||
_outputEffect->GetOutput(&outputImg);
|
||||
|
||||
void SetInput(IWICBitmapSource* srcBmp) {
|
||||
assert(srcBmp != nullptr);
|
||||
|
||||
if (!_d2dSourceEffect) {
|
||||
// 创建 Source effect
|
||||
Debug::ThrowIfComFailed(
|
||||
_d2dContext.GetD2DDC()->CreateEffect(CLSID_D2D1BitmapSource, &_d2dSourceEffect),
|
||||
L"创建 D2D1BitmapSource 失败"
|
||||
_d2dContext.GetD2DDC()->DrawImage(
|
||||
outputImg.Get(),
|
||||
Point2F(_outputRect.left, _outputRect.top)
|
||||
);
|
||||
} else {
|
||||
_d2dContext.GetD2DDC()->DrawImage(
|
||||
_inputBmp.Get(),
|
||||
Point2F(_outputRect.left, _outputRect.top)
|
||||
);
|
||||
if (_firstEffect) {
|
||||
_firstEffect->SetInputEffect(0, _d2dSourceEffect.Get());
|
||||
} else {
|
||||
_outputEffect = _firstEffect = _d2dSourceEffect;
|
||||
}
|
||||
}
|
||||
|
||||
Debug::ThrowIfComFailed(
|
||||
_d2dSourceEffect->SetValue(D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE, srcBmp),
|
||||
L"设置 D2D1BitmapSource 源失败"
|
||||
);
|
||||
|
||||
if (!_outputEffect) {
|
||||
_outputEffect = _d2dSourceEffect;
|
||||
}
|
||||
}
|
||||
|
||||
void SetInput(ID2D1Bitmap* srcBmp, const RECT& clientRect) {
|
||||
void SetInput(ComPtr<ID2D1Bitmap> srcBmp) {
|
||||
assert(srcBmp != nullptr);
|
||||
|
||||
if (!_d2dCropEffect) {
|
||||
// 创建 Crop Effect
|
||||
Debug::ThrowIfComFailed(
|
||||
_d2dContext.GetD2DDC()->CreateEffect(CLSID_D2D1Crop, &_d2dCropEffect),
|
||||
L"创建 D2D1Crop 失败"
|
||||
);
|
||||
|
||||
if (!_firstEffect) {
|
||||
_outputEffect = _firstEffect = _d2dCropEffect;
|
||||
} else {
|
||||
_firstEffect->SetInputEffect(0, _d2dCropEffect.Get());
|
||||
}
|
||||
}
|
||||
|
||||
Debug::ThrowIfComFailed(
|
||||
_d2dCropEffect->SetValue(
|
||||
D2D1_CROP_PROP_RECT,
|
||||
RectF(clientRect.left, clientRect.top, clientRect.right, clientRect.bottom)
|
||||
),
|
||||
L"设置 D2D1_CROP_PROP_RECT 失败"
|
||||
);
|
||||
_d2dCropEffect->SetInput(0, srcBmp);
|
||||
_inputBmp = srcBmp;
|
||||
}
|
||||
|
||||
const D2D1_RECT_F& GetOutputRect() const {
|
||||
|
|
@ -570,8 +532,8 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
ComPtr<ID2D1Effect> _d2dSourceEffect = nullptr;
|
||||
ComPtr<ID2D1Effect> _d2dCropEffect = nullptr;
|
||||
ComPtr<ID2D1Bitmap> _inputBmp = nullptr;
|
||||
|
||||
ComPtr<ID2D1Effect> _firstEffect = nullptr;
|
||||
ComPtr<ID2D1Effect> _outputEffect = nullptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,19 +8,21 @@
|
|||
class GDIWindowCapturer : public WindowCapturerBase {
|
||||
public:
|
||||
GDIWindowCapturer(
|
||||
D2DContext& d2dContext,
|
||||
HWND hwndSrc,
|
||||
const RECT& srcRect,
|
||||
IWICImagingFactory2* wicImgFactory,
|
||||
bool useBitblt = false
|
||||
): _wicImgFactory(wicImgFactory), _srcRect(srcRect), _hwndSrc(hwndSrc), _useBitblt(useBitblt) {
|
||||
): WindowCapturerBase(d2dContext), _wicImgFactory(wicImgFactory), _srcRect(srcRect), _hwndSrc(hwndSrc), _useBitblt(useBitblt) {
|
||||
}
|
||||
|
||||
std::variant<ComPtr<IWICBitmapSource>, ComPtr<ID2D1Bitmap1>> GetFrame() override {
|
||||
if (_useBitblt) {
|
||||
return _GetFrameWithBitblt();
|
||||
} else {
|
||||
return _GetFrameWithNoBitblt();
|
||||
}
|
||||
ComPtr<ID2D1Bitmap> GetFrame() override {
|
||||
ComPtr<IWICBitmapSource> wicBmp = _useBitblt ? _GetFrameWithBitblt() : _GetFrameWithNoBitblt();
|
||||
|
||||
ComPtr<ID2D1Bitmap> bmp;
|
||||
_d2dContext.GetD2DDC()->CreateBitmapFromWicBitmap(wicBmp.Get(), &bmp);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@
|
|||
class MagCallbackWindowCapturer : public WindowCapturerBase {
|
||||
public:
|
||||
MagCallbackWindowCapturer(
|
||||
D2DContext& d2dContext,
|
||||
HINSTANCE hInstance,
|
||||
HWND hwndHost,
|
||||
const RECT& srcRect,
|
||||
IWICImagingFactory2* wicImgFactory
|
||||
): _srcRect(srcRect), _wicImgFactory(wicImgFactory) {
|
||||
const RECT& srcRect
|
||||
): WindowCapturerBase(d2dContext), _srcRect(srcRect) {
|
||||
if (_instance) {
|
||||
Debug::Assert(false, L"已存在 MagCallbackWindowCapturer 实例");
|
||||
}
|
||||
|
|
@ -47,13 +47,13 @@ public:
|
|||
_instance = nullptr;
|
||||
}
|
||||
|
||||
std::variant<ComPtr<IWICBitmapSource>, ComPtr<ID2D1Bitmap1>> GetFrame() override {
|
||||
ComPtr<ID2D1Bitmap> GetFrame() override {
|
||||
// MagSetWindowSource 是同步执行的
|
||||
if (!MagSetWindowSource(_hwndMag, _srcRect)) {
|
||||
Debug::WriteErrorMessage(L"MagSetWindowSource 失败");
|
||||
}
|
||||
|
||||
return _wicBmp;
|
||||
return _bmp;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -75,28 +75,22 @@ private:
|
|||
Debug::WriteErrorMessage(L"srcdata 不是BGRA格式");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Debug::ThrowIfComFailed(
|
||||
_instance->_wicImgFactory->CreateBitmapFromMemory(
|
||||
srcheader.width,
|
||||
srcheader.height,
|
||||
GUID_WICPixelFormat32bppPBGRA,
|
||||
srcheader.stride,
|
||||
(UINT)srcheader.cbSize,
|
||||
(BYTE*)srcdata,
|
||||
&_instance->_wicBmp
|
||||
),
|
||||
L"´ÓÄÚ´æ´´½¨ WICBitmap ʧ°Ü"
|
||||
|
||||
_instance->_d2dContext.GetD2DDC()->CreateBitmap(
|
||||
{ srcheader.width, srcheader.height },
|
||||
BitmapProperties(PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE)),
|
||||
& _instance->_bmp
|
||||
);
|
||||
D2D1_RECT_U destRect = { 0, 0, srcheader.width, srcheader.height };
|
||||
_instance->_bmp->CopyFromMemory(&destRect, srcdata, srcheader.stride);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HWND _hwndMag = NULL;
|
||||
const RECT& _srcRect;
|
||||
IWICImagingFactory2* _wicImgFactory;
|
||||
|
||||
ComPtr<IWICBitmap> _wicBmp = nullptr;
|
||||
ComPtr<ID2D1Bitmap> _bmp = nullptr;
|
||||
|
||||
static MagCallbackWindowCapturer* _instance;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -86,10 +86,6 @@ private:
|
|||
L"非法的抓取模式"
|
||||
);
|
||||
|
||||
Debug::ThrowIfWin32Failed(
|
||||
GetWindowRect(_hwndSrc, &_srcRect),
|
||||
L"GetWindowRect ʧ°Ü"
|
||||
);
|
||||
Utils::GetClientScreenRect(_hwndSrc, _srcClient);
|
||||
|
||||
_RegisterHostWndClass();
|
||||
|
|
@ -120,22 +116,23 @@ private:
|
|||
|
||||
if (captureMode == 0) {
|
||||
_windowCapturer.reset(new WinRTCapturer(
|
||||
*_d2dContext,
|
||||
_hwndSrc,
|
||||
_srcClient,
|
||||
*_d2dContext
|
||||
_srcClient
|
||||
));
|
||||
} else if (captureMode == 1) {
|
||||
_windowCapturer.reset(new GDIWindowCapturer(
|
||||
*_d2dContext,
|
||||
_hwndSrc,
|
||||
_srcClient,
|
||||
_wicImgFactory.Get()
|
||||
));
|
||||
} else {
|
||||
_windowCapturer.reset(new MagCallbackWindowCapturer(
|
||||
*_d2dContext,
|
||||
hInstance,
|
||||
_hwndHost,
|
||||
_srcClient,
|
||||
_wicImgFactory.Get()
|
||||
_srcClient
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -168,7 +165,9 @@ private:
|
|||
void _Render() {
|
||||
try {
|
||||
const auto& frame = _windowCapturer->GetFrame();
|
||||
_renderManager->Render(frame, _srcRect, _srcClient);
|
||||
if (frame) {
|
||||
_renderManager->Render(frame);
|
||||
}
|
||||
} catch (const magpie_exception& e) {
|
||||
Debug::WriteErrorMessage(L"渲染失败:" + e.what());
|
||||
} catch (...) {
|
||||
|
|
@ -285,7 +284,6 @@ private:
|
|||
HINSTANCE _hInst;
|
||||
HWND _hwndHost = NULL;
|
||||
HWND _hwndSrc;
|
||||
RECT _srcRect{};
|
||||
RECT _srcClient{};
|
||||
RECT _hostClient{};
|
||||
|
||||
|
|
|
|||
|
|
@ -46,56 +46,23 @@ public:
|
|||
}
|
||||
|
||||
void Render(
|
||||
const std::variant<ComPtr<IWICBitmapSource>, ComPtr<ID2D1Bitmap1>>& frame,
|
||||
const RECT& srcRect,
|
||||
const RECT& srcClient
|
||||
ComPtr<ID2D1Bitmap> frame
|
||||
) {
|
||||
if (frame.index() == 0) {
|
||||
_d2dContext.Render([&]() {
|
||||
_d2dContext.GetD2DDC()->Clear();
|
||||
assert(frame);
|
||||
|
||||
_effectManager->SetInput(std::get<0>(frame).Get());
|
||||
_effectManager->Render();
|
||||
_d2dContext.Render([&]() {
|
||||
_d2dContext.GetD2DDC()->Clear();
|
||||
|
||||
if (_frameCatcher) {
|
||||
_frameCatcher->Render();
|
||||
}
|
||||
if (_cursorManager) {
|
||||
_cursorManager->Render();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const auto& f = std::get<1>(frame);
|
||||
if (!f) {
|
||||
return;
|
||||
_effectManager->SetInput(frame);
|
||||
_effectManager->Render();
|
||||
|
||||
if (_frameCatcher) {
|
||||
_frameCatcher->Render();
|
||||
}
|
||||
|
||||
_d2dContext.Render([&]() {
|
||||
_d2dContext.GetD2DDC()->Clear();
|
||||
|
||||
RECT rect{};
|
||||
|
||||
_effectManager->SetInput(
|
||||
f.Get(),
|
||||
{
|
||||
srcClient.left - srcRect.left,
|
||||
srcClient.top - srcRect.top,
|
||||
srcClient.right - srcRect.left,
|
||||
srcClient.bottom - srcRect.top
|
||||
}
|
||||
);
|
||||
_effectManager->Render();
|
||||
|
||||
if (_frameCatcher) {
|
||||
_frameCatcher->Render();
|
||||
}
|
||||
if (_cursorManager) {
|
||||
_cursorManager->Render();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (_cursorManager) {
|
||||
_cursorManager->Render();
|
||||
}
|
||||
});
|
||||
}
|
||||
private:
|
||||
IDWriteFactory* _GetDWFactory() {
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ using namespace Windows::Graphics::DirectX::Direct3D11;
|
|||
class WinRTCapturer : public WindowCapturerBase {
|
||||
public:
|
||||
WinRTCapturer(
|
||||
D2DContext& d2dContext,
|
||||
HWND hwndSrc,
|
||||
const RECT& srcRect,
|
||||
D2DContext& d2dContext
|
||||
) : _srcRect(srcRect), _hwndSrc(hwndSrc), _d2dContext(d2dContext),
|
||||
const RECT& srcClient
|
||||
) : WindowCapturerBase(d2dContext), _srcClient(srcClient), _hwndSrc(hwndSrc),
|
||||
_captureFramePool(nullptr), _captureSession(nullptr), _captureItem(nullptr), _wrappedDevice(nullptr)
|
||||
{
|
||||
winrt::init_apartment(winrt::apartment_type::multi_threaded);
|
||||
|
|
@ -87,10 +87,10 @@ public:
|
|||
winrt::uninit_apartment();
|
||||
}
|
||||
|
||||
std::variant<ComPtr<IWICBitmapSource>, ComPtr<ID2D1Bitmap1>> GetFrame() override {
|
||||
ComPtr<ID2D1Bitmap> GetFrame() override {
|
||||
winrt::Direct3D11CaptureFrame frame = _captureFramePool.TryGetNextFrame();
|
||||
if (!frame) {
|
||||
return ComPtr<ID2D1Bitmap1>();
|
||||
return ComPtr<ID2D1Bitmap>();
|
||||
}
|
||||
winrt::IDirect3DSurface d3dSurface = frame.Surface();
|
||||
|
||||
|
|
@ -106,18 +106,39 @@ public:
|
|||
L"´Ó»ñÈ¡ IDirect3DSurface »ñÈ¡ IDXGISurface ʧ°Ü"
|
||||
);
|
||||
|
||||
ComPtr<ID2D1Bitmap1> bmp;
|
||||
ComPtr<ID2D1Bitmap> withFrame;
|
||||
auto p = BitmapProperties(PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE));
|
||||
_d2dContext.GetD2DDC()->CreateSharedBitmap(__uuidof(IDXGISurface), dxgiSurface.get(), &p, &withFrame);
|
||||
|
||||
RECT srcRect{};
|
||||
Debug::ThrowIfComFailed(
|
||||
_d2dContext.GetD2DDC()->CreateBitmapFromDxgiSurface(dxgiSurface.get(), BitmapProperties1(D2D1_BITMAP_OPTIONS_NONE, PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE)), &bmp),
|
||||
L""
|
||||
DwmGetWindowAttribute(_hwndSrc, DWMWA_EXTENDED_FRAME_BOUNDS, &srcRect, sizeof(srcRect)),
|
||||
L"GetWindowRect ʧ°Ü"
|
||||
);
|
||||
return bmp;
|
||||
|
||||
ComPtr<ID2D1Bitmap> withoutFrame;
|
||||
_d2dContext.GetD2DDC()->CreateBitmap(
|
||||
{ UINT32(_srcClient.right - _srcClient.left), UINT32(_srcClient.bottom - _srcClient.top) },
|
||||
BitmapProperties(PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE)),
|
||||
&withoutFrame
|
||||
);
|
||||
|
||||
D2D1_POINT_2U destPoint{ 0,0 };
|
||||
D2D1_RECT_U srcPoint{
|
||||
UINT32(_srcClient.left - srcRect.left),
|
||||
UINT32(_srcClient.top - srcRect.top),
|
||||
UINT32(_srcClient.right - srcRect.left),
|
||||
UINT32(_srcClient.bottom - srcRect.top)
|
||||
};
|
||||
|
||||
withoutFrame->CopyFromBitmap(&destPoint, withFrame.Get(), &srcPoint);
|
||||
|
||||
return withoutFrame;
|
||||
}
|
||||
|
||||
private:
|
||||
const RECT& _srcRect;
|
||||
HWND _hwndSrc;
|
||||
D2DContext& _d2dContext;
|
||||
const RECT& _srcClient;
|
||||
|
||||
winrt::Direct3D11CaptureFramePool _captureFramePool;
|
||||
winrt::GraphicsCaptureSession _captureSession;
|
||||
|
|
|
|||
|
|
@ -1,15 +1,18 @@
|
|||
#pragma once
|
||||
#include "pch.h"
|
||||
#include <variant>
|
||||
#include "D2DContext.h"
|
||||
|
||||
class WindowCapturerBase {
|
||||
public:
|
||||
WindowCapturerBase() {}
|
||||
WindowCapturerBase(D2DContext& d2dContext): _d2dContext(d2dContext) {}
|
||||
|
||||
virtual ~WindowCapturerBase() {}
|
||||
|
||||
WindowCapturerBase(const WindowCapturerBase&) = delete;
|
||||
WindowCapturerBase(WindowCapturerBase&&) = delete;
|
||||
|
||||
virtual std::variant<ComPtr<IWICBitmapSource>, ComPtr<ID2D1Bitmap1>> GetFrame() = 0;
|
||||
virtual ComPtr<ID2D1Bitmap> GetFrame() = 0;
|
||||
|
||||
protected:
|
||||
D2DContext& _d2dContext;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <dxgi1_6.h>
|
||||
#include <dwrite_3.h>
|
||||
#include <wrl.h>
|
||||
#include <dwmapi.h>
|
||||
|
||||
// C 运行时头文件
|
||||
#include <malloc.h>
|
||||
|
|
@ -46,3 +47,4 @@
|
|||
#pragma comment(lib, "dxguid.lib")
|
||||
#pragma comment(lib, "shlwapi.lib")
|
||||
#pragma comment(lib, "windowsapp")
|
||||
#pragma comment(lib, "dwmapi.lib")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue