我们可以在透明窗口上应用着色器吗

2024-02-11

I am looking to apply a particular shader to a transparent window. for example, on a live desktop, I want to create a transparent window with some filters. something like the following (I have shader file for below filter)

@SimonMourier 建议使用 WinRT 的 Windows.Graphics.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);
        //}

        /*auto d3dDevice = GetDXGIInterfaceFromObject<ID3D11Device>(m_device);
        d3dDevice->GetImmediateContext(m_d3dContext.put());*/

        {
            auto frameSurface = GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());

            com_ptr<ID3D11Texture2D> backBuffer;
            check_hresult(m_swapChain->GetBuffer(0, guid_of<ID3D11Texture2D>(), backBuffer.put_void()));

            m_d3ddevice->CreateRenderTargetView(backBuffer.get(), NULL, &m_RTV);

            // ADDED THIS
            D3D11_TEXTURE2D_DESC txtDesc = {};
            txtDesc.MipLevels = txtDesc.ArraySize = 1;
            txtDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
            txtDesc.SampleDesc.Count = 1;
            txtDesc.Usage = D3D11_USAGE_IMMUTABLE;
            txtDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;

            //auto d3dDevice = GetDXGIInterfaceFromObject<ID3D11Device>(m_device);

            ID3D11Texture2D* tex;
            m_d3ddevice->CreateTexture2D(&txtDesc, NULL,
                &tex);
            frameSurface.copy_to(&tex);

            ID3D11ShaderResourceView* srv_1;
            m_d3ddevice->CreateShaderResourceView(
                tex,
                nullptr,
                &srv_1
            );

            auto texture = srv_1;
            m_d3dContext->PSSetShaderResources(0, 1, &texture);
            // END OF ADDED CHANGES

            // Create the sample state
            D3D11_SAMPLER_DESC SampDesc;
            RtlZeroMemory(&SampDesc, sizeof(SampDesc));
            SampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
            SampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
            SampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
            SampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
            SampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
            SampDesc.MinLOD = 0;
            SampDesc.MaxLOD = D3D11_FLOAT32_MAX;
            m_d3ddevice->CreateSamplerState(&SampDesc, &m_SamplerLinear);

            D3D11_TEXTURE2D_DESC FrameDesc;
            tex->GetDesc(&FrameDesc);

            D3D11_SHADER_RESOURCE_VIEW_DESC ShaderDesc;
            ShaderDesc.Format = FrameDesc.Format;
            ShaderDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
            ShaderDesc.Texture2D.MostDetailedMip = FrameDesc.MipLevels - 1;
            ShaderDesc.Texture2D.MipLevels = FrameDesc.MipLevels;
            // Vertices for drawing whole texture
            VERTEX Vertices[NUMVERTICES] =
            {
                {XMFLOAT3(-1.0f, -1.0f, 0), XMFLOAT2(0.0f, 1.0f)},
                {XMFLOAT3(-1.0f, 1.0f, 0), XMFLOAT2(0.0f, 0.0f)},
                {XMFLOAT3(1.0f, -1.0f, 0), XMFLOAT2(1.0f, 1.0f)},
                {XMFLOAT3(1.0f, -1.0f, 0), XMFLOAT2(1.0f, 1.0f)},
                {XMFLOAT3(-1.0f, 1.0f, 0), XMFLOAT2(0.0f, 0.0f)},
                {XMFLOAT3(1.0f, 1.0f, 0), XMFLOAT2(1.0f, 0.0f)},
            };
            // Create new shader resource view
            ID3D11ShaderResourceView* ShaderResource = nullptr;
            m_d3ddevice->CreateShaderResourceView(tex, &ShaderDesc, &ShaderResource);
            // Set resources
            UINT Stride = sizeof(VERTEX);
            UINT Offset = 0;
            m_d3dContext->OMSetRenderTargets(1, &m_RTV, nullptr);
            m_d3dContext->VSSetShader(m_VertexShader, nullptr, 0);
            m_d3dContext->PSSetShader(m_PixelShader, nullptr, 0);
            m_d3dContext->PSSetShaderResources(0, 1, &ShaderResource);
            m_d3dContext->PSSetSamplers(0, 1, &m_SamplerLinear);
            m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
            D3D11_BUFFER_DESC BufferDesc;
            RtlZeroMemory(&BufferDesc, sizeof(BufferDesc));
            BufferDesc.Usage = D3D11_USAGE_DEFAULT;
            BufferDesc.ByteWidth = sizeof(VERTEX) * NUMVERTICES;
            BufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
            BufferDesc.CPUAccessFlags = 0;
            D3D11_SUBRESOURCE_DATA InitData;
            RtlZeroMemory(&InitData, sizeof(InitData));
            InitData.pSysMem = Vertices;

            ID3D11Buffer* VertexBuffer = nullptr;

            // Create vertex buffer
            m_d3ddevice->CreateBuffer(&BufferDesc, &InitData, &VertexBuffer);


            m_d3dContext->IASetVertexBuffers(0, 1, &VertexBuffer, &Stride, &Offset);
            // Draw textured quad onto render target
            //m_d3dContext->CopyResource(backBuffer.get(), tex);
            m_d3dContext->Draw(NUMVERTICES, 0);
            // 
            //m_d3dContext->CopyResource(backBuffer.get(), frameSurface.get());
            //m_d3dContext->DrawAuto();
        }
    }

    DXGI_PRESENT_PARAMETERS presentParameters = { 0 };
    m_swapChain->Present1(1, 0, &presentParameters);
}

更多参考资料位于:

  • 将 HLSL 像素着色器应用于 Win32 屏幕捕获 https://stackoverflow.com/questions/61515500/applying-hlsl-pixel-shaders-to-win32-screen-capture
  • HWND 的屏幕截图 https://github.com/microsoft/Windows.UI.Composition-Win32-Samples/blob/master/cpp/ScreenCaptureforHWND/README.md

None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我们可以在透明窗口上应用着色器吗 的相关文章

  • 检查空参数的最佳方法(保护子句)

    例如 您通常不希望构造函数中的参数为空 因此看到类似的内容是很正常的 if someArg null throw new ArgumentNullException nameof someArg if otherArg null throw
  • MVC 重定向到没有控制器的视图

    希望应该是一个简单的 我创建了一个通用错误视图 当整个站点的操作方法内发生异常时 我想显示该视图 我创建了一个部分页面 所有导航都位于其中 因此我不需要在此视图上使用控制器 那么如何从控制器内的操作方法重定向到它 像这样的东西 HttpPo
  • SetWindowsHookEx 函数返回 NULL

    我正在研究 DLL 注入 但收到错误如下 挂接进程失败 87 参数不正确 目标进程和dll都是64位的 注入代码为 BOOL HookInjection TCHAR target TCHAR dll name https msdn micr
  • C修改printf()输出到文件

    有没有办法修改printf为了将字符串输出到文件而不是控制台 我尝试在互联网上查找一些内容 发现了类似的电话dup dup2 and fflush这可能与此有关 EDIT 也许我不清楚 问题是这是C考试问题 问题如下 解释一个通常将字符串输
  • 返回 int& 的函数[重复]

    这个问题在这里已经有答案了 我在网上查了一下发现一篇试图解释的文章std move和右值 http thbecker net articles rvalue references section 01 html并发现了一些我实在无法掌握的东
  • 在 GCC 和 Clang 下,使用 lambda 的简单 RAII 包装器的复制初始化意外失败

    我在创建一个简单的 RAII 包装器时遇到了一个意想不到的问题 更不用说下面代码的逻辑不完整性了 复制构造函数和赋值运算符未删除等 这意味着是一个SSCCE 令我印象深刻的是复制初始化我的包装器与临时 lambda 的结果会导致编译错误 而
  • rand() 播种与 time() 问题

    我很难弄清楚如何使用 rand 并使用 Xcode 用 time 为其播种 我想生成 0 到 1 之间的随机十进制数 该代码为我提供了元素 1 和 2 看似随机的数字 但元素 0 始终在 0 077 左右 有什么想法吗 我的代码是 incl
  • F10键没被抓住

    I have a Windows Form and there overriden ProcessCmdKey However this works with all of the F Keys except for F10 I am tr
  • 使用反射获取基类的受保护属性值

    I would like to know if it is possible to access the value of the ConfigurationId property which is located in the base
  • 使用scanf()时如何区分整数和字符

    我只是使用该功能scanf 代码如下 scanf d a printf d a 当我输入1时 它会像我想要的那样打印1 但即使我输入 1a 它也会像以前一样打印 1 当用户输入非整数时 例如 2 3 12ab 1 a 我想向用户显示 输入整
  • 是什么原因导致 Linq 错误:此方法无法转换为存储表达式?

    我有一堆具有相同 select 语句的 Linq to Entity 方法 所以我想我会很聪明 并将其分离到它自己的方法中以减少冗余 但是当我尝试运行代码时 我得到了以下内容错误 该方法不能转化为 商店表达式 这是我创建的方法 public
  • realloc():重新分配为 char * 上的 strcat 腾出空间时下一个大小无效 [重复]

    这个问题在这里已经有答案了 我在以下代码中收到无效内存错误 printf s n FINE 5 printf s LENGTH IS d n FINE 6 strlen buffer char realloc buffer strlen b
  • asp.net c# 防止在从服务器端代码更改索引时触发 selectedindexchanged 事件

    我在同一个 aspx 页面上有两个下拉列表控件
  • 微软语音识别速度

    我正在使用微软的语音识别器开发一个小型练习应用程序 对于我正在做的事情来说 我似乎无法让它足够快地识别单个单词 我希望能够正常说话 系统将从我所说的内容中抓取 关键字 并生成一个字符串 目前我正在使用 5 个单词的自定义语法 红 蓝 黄 绿
  • 你能解释一下这个C++删除问题吗?

    我有以下代码 std string F WideString ws GetMyWideString std string ret StringUtils ConvertWideStringToUTF8 ws ret return ret W
  • 如何将 CSV 文件读入 .NET 数据表

    如何将 CSV 文件加载到System Data DataTable 根据CSV文件创建数据表 常规 ADO net 功能是否允许这样做 我一直在使用OleDb提供者 但是 如果您正在读取具有数值的行 但希望将它们视为文本 则会出现问题 但
  • 是否有任何不使用公共虚拟方法的正当理由? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 是否有任何不使用公共虚拟方法的正当理由 我在某处读到我们应该避免使用公共虚拟方法 但我想向专家确认这是否是有效的声明 对于良好且稳定的 API
  • 正在获取“未终止 [] 设置”。 C# 中的错误

    我正在 C 中使用以下正则表达式 Regex find new Regex url
  • 通过 cmake 链接作为外部项目包含的 opencv 库[重复]

    这个问题在这里已经有答案了 我对 cmake 比较陌生 经过几天的努力无法弄清楚以下事情 我有一个依赖于 opencv 的项目 它本身就是一个 cmake 项目 我想静态链接 opencv 库 我正在做的是我的项目中有一份 opencv 源
  • 将文本从文本文件添加到 PDF 文件[重复]

    这个问题在这里已经有答案了 这是我的代码 using FileStream msReport new FileStream pdfPath FileMode Create step 1 using Document pdfDoc new D

随机推荐

  • 如何使用Java反射获取参数名称[重复]

    这个问题在这里已经有答案了 如何使用 Java 反射获取方法签名 EDIT 我实际上需要参数 NAMES 而不是方法的类型 要获取您调用的类 C 的方法 iC class getMethods i toString EDIT 获得参数名称
  • App Engine:NDB 和数据存储之间的区别

    我现在正在浏览 Google App Engine 文档 Python 发现了两种不同类型的存储 NDB 数据存储 数据库数据存储 两个配额限制 免费 似乎相同 它们的数据库设计也相同 然而NDB会自动将数据缓存在Memcache中 我实际
  • Quartz:不实现接口成员

    我正在使用 Quartz 并使用示例代码并收到错误 CS0738 EmailJob 未实现接口成员IJob Execute IJobExecutionContext EmailJob Execute IJobExecutionContext
  • 在 SignalR Hub 上使用通用方法

    我正在为我的 SignalR 服务器创建一个 Hub 类 并希望使用一种通用方法 这将使我免于编写大量代码 但是 当我尝试从 Xamarin iOS 客户端 也是 C 语言 调用下面的服务器代码时 SignalR 给了我错误 服务器代码 您
  • Java:ExecutorService 在达到一定队列大小后阻塞提交[重复]

    这个问题在这里已经有答案了 我正在尝试编写一个解决方案 其中单个线程生成可以并行执行的 I O 密集型任务 每个任务都有重要的内存数据 所以我希望能够限制当前待处理的任务数量 如果我像这样创建 ThreadPoolExecutor Thre
  • 给定三角形顶点坐标,求 3D 三角形的旋转角度

    我尝试在 3D 中旋转和平移一个等边三角形 直到他的顶点到达某个坐标 顶点坐标F G H and F G H 已知 我能够找到新的质心c 坐标是这样的 c x F x G x H x 3 c y F y G y H y 3 c z F z
  • Android 外部库项目出现 NoClassDefFoundError

    我使用 eclipse 进行 Google Android 开发 我创建了一个图书馆项目 x Is Library在 Android 设置中 其中包括外部 jar 文件 参考库 该库项目在另一个项目 将使用该库项目的实际项目 中引用 这是通
  • 错误 - 未标记为可序列化

    我收到的错误是 Type OrgPermission in Assembly App Code ptjvczom Version 0 0 0 0 Culture neutral PublicKeyToken null is not mark
  • 根据父子数据绘制树形图或组织图

    我在带有 GroupID TreeID 的表中有父子信息 从这张表中我想得出这样的结果 画树的目的只是为了观看 该表有数千个组ID 树结构 我正在使用 NET 平台 我应该如何进行 create table parent child Gro
  • XXX_* 输入生成的 *.pb.go 文件

    我正在研究一个tutorial https ewanvalentine io microservices in golang part 1 关于 gRPC 当我生成 pb go文件 我得到一些XXX 输入我的结构 这是我的consignme
  • Eclipse > Javascript > 代码高亮不能使用对象表示法

    我在用Eclipse Helios 使用 PDT 以及当我使用默认值编辑 JavaScript 文件时JavaScript Editor JSDT 代码高亮 Mark Occurrences 不适用于 JSON style or Objec
  • 嵌套 vue.js 实例/元素

    这可能听起来像一个真正的菜鸟问题 但我对 MVVM 甚至 JS 中的 MVC 都很陌生 所以提前抱歉 我正在使用 vue js 并且到目前为止很喜欢它的简单性 但对于我想做的事情 我认为我需要以不同的方式去做 我想将 Vue 实例 元素嵌套
  • 从两个多态类继承

    给出以下代码 class T public virtual T virtual void foo 0 class U public U U void bar std cout lt lt bar lt lt std endl class A
  • 如何在 join linq 语法中比较 null

    处理 EF 4 C Face join 中的问题 SQL语法 Select a Code b Name from DepartmentMaster a Join DepartmentDetail b on isnull a ID 0 isn
  • 如何在 Snakemake 表格配置中使用列表,用于描述生物信息学管道的测序单元

    如何在 Snakemake 表格配置中使用列表 我使用 Snakemake Tabular 与 BWA mem 映射 配置来描述我的测序单元 在单独的行上测序的文库 在分析的下一阶段 我必须合并测序单元 映射的 bed 文件 并获取合并的
  • 使用 PORT=XXXX 启动节点永久脚本

    当通过特定端口运行节点命令时 我会这样启动应用程序 PORT 1234 node app js 我如何将端口传递给forever命令 无论我做什么 似乎都不想工作 我试过了 将端口作为参数传递 forever start app js 12
  • 循环浏览用户指定的根目录中的子文件夹和文件[重复]

    这个问题在这里已经有答案了 我通过各个文件的循环脚本工作正常 但我现在还需要它来查找多个目录 我被困住了 事情发生的顺序 提示用户选择他们需要的根目录 我需要脚本来查找该根目录中的任何文件夹 如果脚本找到一个 它将打开第一个 所有文件夹 因
  • 如何在Java中使用Graphics2D旋转文本?

    我想使用 Graphics2D 旋转 JPanel 上的文本 我的代码是这样的 double paso d width numeroBarras double alto datos i valor Font fBarras new Font
  • 在 MATLAB 中实现显式欧拉方法(适用于 ODE)

    我到处都找过了 但什么也没找到 首先 我想说我从未使用过 Mat Lab 所以我不知道我在做什么 我尝试了一些方法 但没有任何效果 显然 y 0 2 试图创建一个包含 0 个值为 2 的单位的列表 无论如何 有人可以帮助我吗 我需要在 Ma
  • 我们可以在透明窗口上应用着色器吗

    I am looking to apply a particular shader to a transparent window for example on a live desktop I want to create a trans