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

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(使用前将#替换为@)

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

  • 如何使 Windows 窗体的关闭按钮不关闭窗体但使其不可见?

    该表单有一个 NotifyIcon 对象 当用户单击 关闭 按钮时 我希望表单不关闭而是变得不可见 然后 如果用户想再次查看该表单 可以双击系统托盘中的图标 如果用户想关闭表单 可以右键单击该图标并选择 关闭 有人可以告诉我如何使关闭按钮不
  • 访问私人成员[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 通过将类的私有成员转换为 void 指针 然后转换为结构来访问类的私有成员是否合适 我认为我无权修改包含我需要访问的数据成员的类 如果不道德 我
  • 是否可以强制 XMLWriter 将元素写入单引号中?

    这是我的代码 var ptFirstName tboxFirstName Text writer WriteAttributeString first ptFirstName 请注意 即使我使用 ptFirstName 也会以双引号结束 p
  • 当我使用“control-c”关闭发送对等方的套接字时,为什么接收对等方的套接字不断接收“”

    我是套接字编程的新手 我知道使用 control c 关闭套接字是一个坏习惯 但是为什么在我使用 control c 关闭发送进程后 接收方上的套接字不断接收 在 control c 退出进程后 发送方的套接字不应该关闭吗 谢谢 我知道使用
  • 指针问题(仅在发布版本中)

    不确定如何描述这一点 但我在这里 由于某种原因 当尝试创建我的游戏的发布版本进行测试时 它的敌人创建方面不起作用 Enemies e level1 3 e level1 0 Enemies sdlLib 500 2 3 128 250 32
  • 获取没有非标准端口的原始 url (C#)

    第一个问题 环境 MVC C AppHarbor Problem 我正在调用 openid 提供商 并根据域生成绝对回调 url 在我的本地机器上 如果我点击的话 效果很好http localhost 12345 login Request
  • C#:如何防止主窗体过早显示

    在我的 main 方法中 我像往常一样启动主窗体 Application EnableVisualStyles Application SetCompatibleTextRenderingDefault false Application
  • Cython 和类的构造函数

    我对 Cython 使用默认构造函数有疑问 我的 C 类 Node 如下 Node h class Node public Node std cerr lt lt calling no arg constructor lt lt std e
  • WPF TabControl,用C#代码更改TabItem的背景颜色

    嗨 我认为这是一个初学者的问题 我搜索了所有相关问题 但所有这些都由 xaml 回答 但是 我需要的是后台代码 我有一个 TabControl 我需要设置其项目的背景颜色 我需要在选择 取消选择和悬停时为项目设置不同的颜色 非常感谢你的帮助
  • Web API - 访问 DbContext 类中的 HttpContext

    在我的 C Web API 应用程序中 我添加了CreatedDate and CreatedBy所有表中的列 现在 每当在任何表中添加新记录时 我想填充这些列 为此目的我已经覆盖SaveChanges and SaveChangesAsy
  • 将自定义元数据添加到 jpeg 文件

    我正在开发一个图像处理项目 C 我需要在处理完成后将自定义元数据写入 jpeg 文件 我怎样才能做到这一点 有没有可用的图书馆可以做到这一点 如果您正在谈论 EXIF 元数据 您可能需要查看exiv2 http www exiv2 org
  • Github Action 在运行可执行文件时卡住

    我正在尝试设置运行google tests on a C repository using Github Actions正在运行的Windows Latest 构建过程完成 但是当运行测试时 它被卡住并且不执行从生成的可执行文件Visual
  • 将 xml 反序列化为类,list<> 出现问题

    我有以下 XML
  • C++ 复制初始化和直接初始化,奇怪的情况

    在继续阅读本文之前 请阅读在 C 中 复制初始化和直接初始化之间有区别吗 https stackoverflow com questions 1051379 is there a difference in c between copy i
  • 插入记录后如何从SQL Server获取Identity值

    我在数据库中添加一条记录identity价值 我想在插入后获取身份值 我不想通过存储过程来做到这一点 这是我的代码 SQLString INSERT INTO myTable SQLString Cal1 Cal2 Cal3 Cal4 SQ
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • C - 直接从键盘缓冲区读取

    这是C语言中的一个问题 如何直接读取键盘缓冲区中的数据 我想直接访问数据并将其存储在变量中 变量应该是什么数据类型 我需要它用于我们研究所目前正在开发的操作系统 它被称为 ICS OS 我不太清楚具体细节 它在 x86 32 位机器上运行
  • 为什么 C# Math.Ceiling 向下舍入?

    我今天过得很艰难 但有些事情不太对劲 在我的 C 代码中 我有这样的内容 Math Ceiling decimal this TotalRecordCount this PageSize Where int TotalRecordCount
  • const、span 和迭代器的问题

    我尝试编写一个按索引迭代容器的迭代器 AIt and a const It两者都允许更改容器的内容 AConst it and a const Const it两者都禁止更改容器的内容 之后 我尝试写一个span
  • 根据 GLSL 中向量的特定分量执行最小-最大的最快方法?

    我需要在我的 GLSL 代码中多次调用这种函数 vec2 minx vec2 a vec2 b if a x lt b x return a else return b 我担心过度分支 有没有办法避免 if else 结构 我建议使用 GL

随机推荐

  • 如何使用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