UI.Composition 中的 Win2D 效果 (C++)

2023-12-13

Note:目标是创建一个带有丙烯酸背景的窗口,可以通过 OpenGL 进行绘制。任何可以实现这一目标的方法都是值得欢迎的。

我已经能够成功创建一个合成器this教程。并打算根据中给出的示例代码添加高斯模糊this doc

下列的这个帖子,我从Nuget安装了Win2D并复制了文件Generated Files/winrt包括目录。(也尝试运行cppwinrt.exe on the .winmd文件。找不到答案中提到的“Win2D dll””

这是我当前正在运行的代码:

void CompositionHost::BlurBackground() {
    if (m_target.Root()) {

        GaussianBlurEffect blurEffect{};
        blurEffect.Name(L"Blur");
        blurEffect.BlurAmount(1.0f);
        blurEffect.BorderMode(EffectBorderMode::Hard);
        blurEffect.Optimization(EffectOptimization::Balanced);

        CompositionEffectSourceParameter sourceParameter = CompositionEffectSourceParameter(L"source");
        blurEffect.Source(sourceParameter);

        CompositionEffectFactory blurEffectFactory = m_compositor.CreateEffectFactory(blurEffect);
        CompositionEffectBrush blurBrush = blurEffectFactory.CreateBrush();

        CompositionBackdropBrush backDropBrush = m_compositor.CreateBackdropBrush();
        blurBrush.SetSourceParameter(L"source", backDropBrush);

        auto visuals = m_target.Root().as<ContainerVisual>().Children();
        auto visual = m_compositor.CreateSpriteVisual();
        auto element = m_compositor.CreateSpriteVisual();

        element.Brush(blurBrush);
        visuals.InsertAtTop(element);

        visuals.InsertAtTop(visual);
    }
}

执行时出错GaussianBlurEffect blurEffect{}; :

Microsoft C++ exception: winrt::hresult_class_not_registered at memory location 0x00000076EEF8E248.

调用栈

>   Project2.exe!winrt::throw_hresult(const winrt::hresult result) Line 4941    C++
    Project2.exe!winrt::check_hresult(const winrt::hresult result) Line 5038    C++
    Project2.exe!winrt::get_activation_factory<winrt::Windows::Foundation::IActivationFactory>(const winrt::param::hstring & name) Line 6078    C++
    Project2.exe!winrt::impl::factory_cache_entry<winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect,winrt::Windows::Foundation::IActivationFactory>::call<winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect (__cdecl*)(winrt::Windows::Foundation::IActivationFactory const &)>(winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect(*)(const winrt::Windows::Foundation::IActivationFactory &) && callback) Line 6308   C++
    Project2.exe!winrt::impl::call_factory_cast<winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect (__cdecl*)(winrt::Windows::Foundation::IActivationFactory const &),winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect,winrt::Windows::Foundation::IActivationFactory,winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect <lambda>(const winrt::Windows::Foundation::IActivationFactory &)>(winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect::winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect <lambda>(const winrt::Windows::Foundation::IActivationFactory &) && callback) Line 6369    C++
    Project2.exe!winrt::Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect::GaussianBlurEffect() Line 9041    C++

完整代码:

#pragma once
#ifndef UNICODE
#define UNICODE
#endif 

#define BTN_ADD 1000

#include <SDKDDKVer.h>

#define WIN32_LEAN_AND_MEAN  
#include <windows.h>
//#include <D2d1_1.h>
//#include <D3d11_4.h>
//#include <Dwrite.h>
#include <Windows.Graphics.DirectX.Direct3D11.interop.h>
#include <Windows.ui.composition.interop.h>
#include <unknwn.h>
#include <DispatcherQueue.h>

#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>

#include <winrt/base.h>
#include <winrt/Windows.ApplicationModel.Core.h>
//#include <winrt/Windows.Foundation.h>
//#include <winrt/Windows.Graphics.h>
//#include <winrt/Windows.Graphics.DirectX.h>
#include <winrt/Windows.Graphics.DirectX.Direct3D11.h>


#include <winrt/Windows.UI.Composition.Desktop.h>
//#include <winrt/Windows.UI.Core.h>
//#include <winrt/Windows.UI.Input.h>
#include <winrt/Windows.Graphics.Effects.h>

#include <winrt/Microsoft.Graphics.Canvas.Effects.h>
#include <winrt/Windows.Graphics.Effects.h>

using namespace winrt;
//using namespace winrt::Windows::ApplicationModel::Core;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Numerics;
//using namespace winrt::Windows::Graphics::DirectX;
//using namespace winrt::Windows::Graphics::DirectX::Direct3D11;
using namespace winrt::Windows::UI;
using namespace winrt::Windows::UI::Composition;
using namespace winrt::Windows::UI::Composition::Desktop;
using namespace winrt::Windows::UI::Core;
using namespace winrt::Windows::System;
using namespace winrt::Microsoft::Graphics::Canvas::Effects;



namespace abi
{
    using namespace ABI::Windows::Foundation;
    using namespace ABI::Windows::Graphics::DirectX;
    using namespace ABI::Windows::UI::Composition;
}

class CompositionHost
{
public:
    ~CompositionHost();
    static CompositionHost* GetInstance();
    void Initialize(HWND hwnd);
    void AddElement(float size, float x, float y);
    void BlurBackground();
private:
    CompositionHost();
    void EnsureDispatcherQueue();
    void CreateDesktopWindowTarget(HWND window);
    void CreateCompositionRoot();

    winrt::Windows::UI::Composition::Compositor m_compositor{ nullptr };
    winrt::Windows::System::DispatcherQueueController m_dispatcherQueueController{ nullptr };
    winrt::Windows::UI::Composition::Desktop::DesktopWindowTarget m_target{ nullptr };

};

CompositionHost* CompositionHost::GetInstance()
{
    static CompositionHost instance;
    return &instance;
}

void CompositionHost::Initialize(HWND hwnd)
{
    EnsureDispatcherQueue();
    m_compositor = Compositor();

    CreateDesktopWindowTarget(hwnd);
    CreateCompositionRoot();
}

void CompositionHost::EnsureDispatcherQueue()
{
    namespace abi = ABI::Windows::System;

    //if (m_dispatcherQueueController == nullptr)
    {
        DispatcherQueueOptions options
        {
            sizeof(DispatcherQueueOptions), /* dwSize */
            DQTYPE_THREAD_CURRENT,          /* threadType */
            DQTAT_COM_ASTA                  /* apartmentType */
        };

        winrt::Windows::System::DispatcherQueueController controller{ nullptr };
        //auto test1 = &m_dispatcherQueueController;
        //int t = CreateDispatcherQueueController(options, (abi::IDispatcherQueueController **)&test1);
        int t = CreateDispatcherQueueController(options, reinterpret_cast<abi::IDispatcherQueueController**>(put_abi(controller)));
        m_dispatcherQueueController = controller;
        int p = 1;
    }
}

void CompositionHost::CreateDesktopWindowTarget(HWND window)
{
    namespace abi = ABI::Windows::UI::Composition::Desktop;

    auto interop = m_compositor.as<abi::ICompositorDesktopInterop>();
    DesktopWindowTarget target{ nullptr };
    check_hresult(interop->CreateDesktopWindowTarget(window, false, reinterpret_cast<abi::IDesktopWindowTarget**>(put_abi(target))));
    m_target = target;
}

void CompositionHost::CreateCompositionRoot()
{
    auto root = m_compositor.CreateContainerVisual();
    root.RelativeSizeAdjustment({ 1.0f, 1.0f });
    root.Offset({ 124, 12, 0 });
    m_target.Root(root);
}

void CompositionHost::AddElement(float size, float x, float y)
{
    if (m_target.Root())
    {
        auto visuals = m_target.Root().as<ContainerVisual>().Children();
        auto visual = m_compositor.CreateSpriteVisual();

        auto element = m_compositor.CreateSpriteVisual();
        uint8_t r = (double)(double)(rand() % 255);;
        uint8_t g = (double)(double)(rand() % 255);;
        uint8_t b = (double)(double)(rand() % 255);;

        element.Brush(m_compositor.CreateColorBrush({ 255, r, g, b }));
        element.Size({ size, size });
        element.Offset({ x, y, 0.0f, });

        auto animation = m_compositor.CreateVector3KeyFrameAnimation();
        auto bottom = (float)600 - element.Size().y;
        animation.InsertKeyFrame(1, { element.Offset().x, bottom, 0 });

        using timeSpan = std::chrono::duration<int, std::ratio<1, 1>>;

        std::chrono::seconds duration(2);
        std::chrono::seconds delay(3);

        animation.Duration(timeSpan(duration));
        animation.DelayTime(timeSpan(delay));
        element.StartAnimation(L"Offset", animation);
        visuals.InsertAtTop(element);

        visuals.InsertAtTop(visual);
    }
}

void CompositionHost::BlurBackground() {
    if (m_target.Root()) {


        GaussianBlurEffect blurEffect;
        winrt::hstring blurStr = winrt::hstring(L"Blur");
        blurEffect.Name(blurStr);
        blurEffect.BlurAmount(1.0f);
        blurEffect.BorderMode(EffectBorderMode::Hard);
        blurEffect.Optimization(EffectOptimization::Balanced);

        CompositionEffectSourceParameter sourceParameter = CompositionEffectSourceParameter(L"source");
        blurEffect.Source(sourceParameter);



        CompositionEffectFactory blurEffectFactory = m_compositor.CreateEffectFactory(blurEffect);
        CompositionEffectBrush blurBrush = blurEffectFactory.CreateBrush();

        CompositionBackdropBrush backDropBrush = m_compositor.CreateBackdropBrush();
        blurBrush.SetSourceParameter(L"source", backDropBrush);

        auto visuals = m_target.Root().as<ContainerVisual>().Children();
        auto visual = m_compositor.CreateSpriteVisual();
        auto element = m_compositor.CreateSpriteVisual();

        element.Brush(blurBrush);
        visuals.InsertAtTop(element);

        visuals.InsertAtTop(visual);
    }
}

CompositionHost::CompositionHost()
{
}

CompositionHost::~CompositionHost()
{
}


CompositionHost* compHost = CompositionHost::GetInstance();
HWND hwnd;
LRESULT CALLBACK    WindowProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
    // Register the window class.
    const wchar_t CLASS_NAME[] = L"Sample Window Class";

    WNDCLASS wc = { };


    {
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;

    RegisterClass(&wc);

    // Create the window.

    hwnd = CreateWindowEx(
        WS_EX_NOREDIRECTIONBITMAP,                              // Optional window styles.
        CLASS_NAME,                     // Window class
        L"Learn to Program Windows",    // Window text
        WS_OVERLAPPEDWINDOW,             // Window style

        // Size and position
        CW_USEDEFAULT, CW_USEDEFAULT, 900, 672,

        NULL,       // Parent window    
        NULL,       // Menu
        hInstance,  // Instance handle
        NULL        // Additional application data
    );

    if (hwnd == NULL)
    {
        return 0;
    }
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    }

    compHost = CompositionHost::GetInstance();


    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
    {
        compHost->Initialize(hwnd);
        srand(time(nullptr));

        CreateWindow(TEXT("button"), TEXT("Add element"),
            WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
            12, 12, 100, 50,
            hwnd, (HMENU)BTN_ADD, nullptr, nullptr);
    }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);



            //FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));

            EndPaint(hwnd, &ps);
        }
        break;
    case WM_COMMAND: // on Button click
    {
        //double size = (double)(rand() % 150 + 50);
        //double x = (double)(rand() % 600);
        //double y = (double)(rand() % 200);
        //compHost->AddElement(size, x, y);
        compHost->BlurBackground();
        break;
    }
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

None

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

UI.Composition 中的 Win2D 效果 (C++) 的相关文章

  • C++:创建一个由用户输入大小的数组

    我想知道我们是否可以创建一个具有用户指定大小的数组 Ex int a cout lt lt Enter desired size of the array cin gt gt a int array a 上面的程序将不起作用 因为数组大小必
  • 如何通过MFC将应用程序设置保存到注册表中?

    我有一个由 MFC 项目向导创建的 MFC 应用程序 我想在注册表中保存 读取应用程序设置 所以问了这个question https stackoverflow com questions 1880275 good c registry w
  • 在 C/C++ 中读取和写入二进制文件的中间部分

    如果我有一个大的二进制文件 假设它有 100 000 000 个浮点数 C 或 C 有没有办法打开文件并读取特定的浮点数 而不必将整个文件加载到内存中 即我如何快速找出第 62 821 214 个浮点是什么 第二个问题 有没有办法更改文件中
  • 验证码怎么写?

    我正在开发一个注册表 我想放置验证码 我生成一个随机字符串 但如何将其转换为图像 否则我如何开发验证码或任何参考 谢谢 Try out 验证码 http recaptcha net plugins aspnet 或查看博客文章 使用 Asp
  • 如何在 ASP.NET 5/vNext/Core 中使用 Elmah?

    我对如何在 ASP NET 5 MVC 6 项目中使用 Elmah 有点困惑 我从 nuget 得到了包 它添加了 Elmah Mvc 2 1 2 到project json 中的依赖项 我不知道从这里到哪里去 以前 nuget 会向 we
  • ReportViewer“缺少 URL 参数:名称”

    在一个网络应用程序中 我正在处理 ReportViewer 时不断出现错误 缺少 URL 参数 名称 我找到了原因 但没有找到解决方案 导致报告查看器出现异常的 url Reserved ReportViewerWebControl axd
  • 如何将整个流读入 std::string ?

    我正在尝试将整个流 多行 读入字符串中 我正在使用这段代码 它有效 但它冒犯了我的风格感 当然有更简单的方法吗 也许使用字符串流 void Obj loadFromStream std istream stream std string s
  • 无法将方法组分配给 asp.net、linq、c# 中的隐式类型局部变量

    public void selectqueryasso CustomerOrderResult cso new CustomerOrderResult var a from as1 in ds orders from as2 in ds o
  • 慢速 WPF 文本框

    我正在开发一个简单的串行数据查看器 它将用于观察传输到计算机串行端口之一的数据 我使用 C 和 WPF 编写了一个测试应用程序 它只是将最近读取的行放入文本块中 但是 它会跳过所有其他行 我的理论是 在 WPF 渲染窗口之前 新数据会被放入
  • GCC 和 -Wconversion

    让我们编译以下程序 int main uint16 t data 0 data uint16 t std round 3 14f return 0 with g Wconversion prog cpp 我们会得到warning conve
  • 最好的 C++ 编译器是哪个? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 弹出窗口或弹出窗口显示附加信息

    我想在我的应用程序顶部显示带有附加信息的弹出窗口 我的信息是Listview大约 500 个项目我都尝试过 有问题flyout gt 它里面可能有scrollViewer 所以我的列表视图不能正确虚拟化 其他一切都可以 有我的代码 Flyo
  • 如果键不是映射中的初始化键,STL map[key] 返回什么? [复制]

    这个问题在这里已经有答案了 这是一些示例代码 include
  • 使用指针隐藏实现(Pimpl 惯用语)

    是否有可能实现以下目标 x hpp 该文件被许多其他类包含 class x impl forward declare class x public methods private x impl impl x cpp 实施 include
  • STL(标准模板库)中使用的设计模式

    我正在学习STL和设计模式 我想知道是否有任何文档或链接可以解释如何在 STL 中实现设计模式 我做了谷歌但无法获得太多数据 我希望你的意思是 哪些设计模式可以在STL中识别 STL 堆栈是一个容器适配器 适配器是一种设计模式 迭代器也是一
  • 让 AutoMapper 自动映射前缀属性

    我希望 AutoMapper 自动映射成员 如下所示 class Model public int ModelId get set class ModelDto public int Id get set 在这里 我会做一个 CreateM
  • C memcpy 二维数组

    我正在尝试使用将一个二维数组复制到另一个memcpy 我的代码 include
  • 当数据源中只有 1 项时 FormView 不显示 PagerTemplate

    我有一个带有自定义 PagerTemplate 的 FormView 控件和我自己的分页 LinkBut ton 一切都很好 直到我加载的数据集仅包含一个记录 项目并完全隐藏 PagerTemplate 我在网上搜索了一下 找到了几个答案
  • 为什么 `boost::any` 比 `void*` 更好?

    有什么先天优势boost any and boost any cast提供超过使用void and dynamic cast 优点是boost any比类型安全得多void E g int i 5 void p i static cast
  • 类型 '' 未映射

    我已经尝试修复这个错误有一段时间了 每当我的应用程序尝试创建数据上下文的实例时 我都会收到此错误 下面是代码 using System using System Collections Generic using System Linq u

随机推荐

  • Java持久化API中FetchType LAZY和EAGER的区别?

    有什么区别FetchType LAZY and FetchType EAGER在 Java 持久性 API 中 有时您有两个实体 并且它们之间存在关系 例如 您可能有一个名为University另一个实体称为Student一所大学可能有很多
  • 如何在 Flutter 中使用 BottomNavigationBar 维护 Webview 状态

    我正在创建一个 Flutter 应用程序 它使用 BottomNavigationBar 在页面之间进行更改 在其中一个页面中 我有一个 Webview 我正在使用plugin由 Flutter 开发团队开发 当我导航到另一个选项卡然后返回
  • 这是创建审计跟踪的最佳方法吗?

    我正在尝试创建一些功能 以保留给定用户表单中的数据如何随时间变化的审计跟踪 并在该页面的底部提供带日期的审计 例如 02 04 09 21 49 名称从 Tom 更改为 Chris 我这样做的方法是将数据以其当前格式存储在会话中 然后在保存
  • X64 指令在不同 CPU 上表现不同

    在一次采访中 我被问到是否知道 x64 指令的行为取决于所使用的 CPU 我在任何地方都找不到任何相关文档 有谁知道这些指令是什么以及为什么会出现这种情况 有一些留下一个寄存器或一些带有未定义值的标志 英特尔和AMD 在这方面可能有所不同
  • FirebaseMessaging.instance.getInitialMessage() 不适用于启动画面

    在 GetX 状态管理的帮助下 我已将 Firebase Cloud Messaging 集成到我的 Flutter 移动应用中 我还使用 Laravel 和 Firebase Admin SDK 向我的应用程序发送通知 该通知在前台状态和
  • Dialogflow 将企业版 v2 集成到 ios 和 android 应用程序中

    我之前使用的是v1版本的dialogflow 然后他们宣布将暂停它 我将云函数中的代码迁移到了v2 但我找不到将其集成到 ios 和 android 应用程序中的方法 请帮帮我 谢谢 要将代理更新到 V2 您应该创建一个 Cloud Fun
  • 如何将 DataTable 设置为 DataGridComboBoxColum 的 ItemsSource?

    我有一个包含两列的 DataTable 我将它们绑定到 DataGridComboBoxColumn 的所有组合框 其中一列将是项目的文本 其他列将是项目的值 我知道名为 DisplayMemberPath 的属性是我将列的名称指定为项目文
  • WPF 颜色插值

    我正在尝试基于调色板绘制 WPF 控件的背景 其中每种颜色都分配有值 例如 红色 0 深绿 10 绿色 20 浅绿 30 和用户选择的值 例如 25 会给出最终的颜色 我希望生成的颜色是 2 个最接近的颜色值之间的插值 例如 对于 25 的
  • v-on:点击目标不在正确的元素中?

    我正在尝试对锚标记 使用 jQuery 做一些事情 比如在单击时更改它的颜色 但我似乎无法获得正确的目标 a span entry 1 span span entry 2 span a The 事件目标in action 是第一个或第二个跨
  • 在一个窗口中打开多个链接,然后在另一个窗口中打开多个链接

    有没有办法在浏览器中打开一堆3 4个链接window以及另外一堆 3 4 个链接另一个窗口 例如 链接 A facebook com instagram com twitter com 应在浏览器窗口中打开 chrome and 链接 B
  • 加密算法在 Android 2.1 和 2.1 以上版本上给出不同的结果

    在发布这个问题之前我已经搜索了很多 早些时候 代码可以在非 android 4 2 2 1 设备上运行 然后我用谷歌搜索并介绍了以下代码行 这部分解决了这个问题 即它现在可以在 4 2 设备上运行 但不能在 Froyo 上运行 if and
  • 如何使dialogFragment宽度与父级匹配?

    我有这个dialog fragmentt 我有两个问题 1 如何使宽度与父级匹配 请提供最干净 最好的解决方案 In the dialog fragment我有一个编辑文本 当对话框片段打开时 如何使其弹出软键盘 希望大家能够帮忙 这是我的
  • 使用 getDrawingCache 时是否有最大位图大小?

    我正在尝试创建文本的位图TextView 过去我用过这样做getDrawingCache 但是 现在我需要创建一个位图TextView文本比以前长得多 这正在造成getDrawingCache抛出 NullPointerException
  • 无法将加密数据转换为字符串

    我正在尝试学习使用 RNCryptor 这是我正在使用的 let key 1234 let original text hello let data original text data using utf8 let encrypted d
  • 通过模块 xml 文件 Magento 添加一些块到产品视图页面

    您好 我正在开发一个简单的扩展 其中 我需要通过 xml 文件在产品页面上插入一个新块 下面是我的模块的xml文件
  • QStandardItem 缺少 __hash__ 方法

    我发现在将一些 Python2 Qt4 代码转换为 Python3 Qt5 时 显然 QStandardItem 不能再用作字典键 因为它没有 hash 已实施 因此不再被认为是不可变的 这两个片段显示了这个问题 PyQt4 gt gt g
  • 如何找到列表中具有偶数个数字的中位数?

    这就是我现在所拥有的 它只是找到奇数个数字的中位数 def median height height sort x len height x 1 posn x 2 return height posn 中位数是将样本数据集的上半部分与下半部
  • Android Studio 布局设计视图在升级到 v3.0 后显示覆盖

    升级到 Android Studio v3 0 后 我所有布局的设计视图如下所示 即 ActionBarOverlayLayout 覆盖整个设计表面 并且应用程序甚至不使用操作栏 在清单中 应用程序元素是
  • 在带有左侧位置侧边栏的网站中插入谷歌地图

    我在我的 Gmail 帐户中创建了一个公共地图 我在地图上添加了不同的位置 我想将地图插入我的网站 并且想在左侧边栏中显示地点的位置 就像在谷歌地图网站中一样 但我找不到如何操作 This is the map as shown in my
  • UI.Composition 中的 Win2D 效果 (C++)

    Note 目标是创建一个带有丙烯酸背景的窗口 可以通过 OpenGL 进行绘制 任何可以实现这一目标的方法都是值得欢迎的 我已经能够成功创建一个合成器this教程 并打算根据中给出的示例代码添加高斯模糊this doc 下列的这个帖子 我从