使用WinRT的Windows.Graphics.Capture应用像素着色器

apply pixel shader with WinRT#39;s Windows.Graphics.Capture(使用WinRT的Windows.Graphics.Capture应用像素着色器)

本文介绍了使用WinRT的Windows.Graphics.Capture应用像素着色器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为我以前question的继续,我能够找到一种方法,在WinRT的Windows.Graphics.Capture的帮助下,在没有自己窗口的情况下捕获实时屏幕。我可以直接将注意力集中在特定的窗口句柄上,以获得实时捕获。现在,这个方法的问题是我不能应用像素着色器。具有相同要求但该问题的答案相同的问题Applying HLSL Pixel Shaders to Win32 Screen Capture并不能解决我的问题。

包含详细信息的代码:

#include "pch.h"
#include "SimpleCapture.h"
#include <windows.h>
#include <d3d11.h>
#include <dxgi1_2.h>
#include <sal.h>
#include <new>
#include <warning.h>
#include <DirectXMath.h>
#include "PixelShader.h"

using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::System;
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;

using namespace DirectX;

typedef struct _VERTEX
{
    DirectX::XMFLOAT3 Pos;
    DirectX::XMFLOAT2 TexCoord;
} VERTEX;

//
// A vertex with a position and texture coordinate
//
SimpleCapture::SimpleCapture(
    IDirect3DDevice const& device,
    GraphicsCaptureItem const& item)
{
    m_item = item;
    m_device = device;

    // Set up 
    m_d3ddevice = GetDXGIInterfaceFromObject<ID3D11Device>(m_device);
    m_d3ddevice->GetImmediateContext(m_d3dContext.put());
    auto size = m_item.Size();

    m_swapChain = CreateDXGISwapChain(
        m_d3ddevice,
        static_cast<uint32_t>(size.Width),
        static_cast<uint32_t>(size.Height),
        static_cast<DXGI_FORMAT>(DirectXPixelFormat::B8G8R8A8UIntNormalized),
        2);

    UINT Size = ARRAYSIZE(g_VS1);

    m_d3ddevice->CreateVertexShader(g_VS1, Size, nullptr, &m_VertexShader);

    D3D11_INPUT_ELEMENT_DESC Layout[] =
    {
        {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
        {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}
    };

    UINT NumElements = ARRAYSIZE(Layout);

    m_d3ddevice->CreateInputLayout(Layout, NumElements, g_VS1, Size, &m_InputLayout);

    m_d3dContext->IASetInputLayout(m_InputLayout);
    Size = ARRAYSIZE(g_main);


    // ADDED THIS
    Size = ARRAYSIZE(g_main);
    HRESULT hr = m_d3ddevice->CreatePixelShader(g_main, Size, nullptr, &m_PixelShader);


    // END OF ADDED CHANGES

    // Create framepool, define pixel format (DXGI_FORMAT_B8G8R8A8_UNORM), and frame size. 
    m_framePool = Direct3D11CaptureFramePool::Create(
        m_device,
        DirectXPixelFormat::B8G8R8A8UIntNormalized,
        2,
        size);
    m_session = m_framePool.CreateCaptureSession(m_item);
    m_frameArrived = m_framePool.FrameArrived(auto_revoke, { this, &SimpleCapture::OnFrameArrived });
}
// Start sending capture frames
void SimpleCapture::StartCapture()
{
    CheckClosed();
    m_session.StartCapture();
}

ICompositionSurface SimpleCapture::CreateSurface(
    Compositor const& compositor)
{
    CheckClosed();
    return CreateCompositionSurfaceForSwapChain(compositor, m_swapChain.get());
}

// Process captured frames
void SimpleCapture::Close()
{
    auto expected = false;
    if (m_closed.compare_exchange_strong(expected, true))
    {
        m_frameArrived.revoke();
        m_framePool.Close();
        m_session.Close();

        m_swapChain = nullptr;
        m_framePool = nullptr;
        m_session = nullptr;
        m_item = nullptr;
    }
}

void SimpleCapture::OnFrameArrived(
    Direct3D11CaptureFramePool const& sender,
    winrt::Windows::Foundation::IInspectable const&)
{
    auto newSize = false;

    {
        auto frame = sender.TryGetNextFrame();
        auto frameContentSize = frame.ContentSize();

        //if (frameContentSize.Width != m_lastSize.Width ||
        //    frameContentSize.Height != m_lastSize.Height)
        //{
        //    // The thing we have been capturing has changed size.
        //    // We need to resize our swap chain first, then blit the pixels.
        //    // After we do that, retire the frame and then recreate our frame pool.
        //    newSize = true;
        //    m_lastSize = frameContentSize;
        //    m_swapChain->ResizeBuffers(
        //        2,
        //        static_cast<uint32_t>(m_lastSize.Width),
        //        static_cast<uint32_t>(m_lastSize.Height),
        //        static_cast<DXGI_FORMAT>(DirectXPixelFormat::B8G8R8A8UIntNormalized),
        //        0);
        /

本文标题为:使用WinRT的Windows.Graphics.Capture应用像素着色器

基础教程推荐