酷哭的飞 2023-09-17 10:33 采纳率: 0%
浏览 18

Direct2D绘图,透明,如何使后面画的覆盖前面画的

我最近初学Direct2D。这个窗口是支持透明的,这里我画了两个实心圆,它们有重合的部分

img

    //ID2D1DCRenderTarget* pDCRT;
    //ID2D1SolidColorBrush* pBrush;

    pDCRT->Clear(D2D1::ColorF(D2D1::ColorF(0, 0, 1, 0.5f)));

    D2D1_ELLIPSE pe1 = D2D1::Ellipse(D2D1::Point2F(200, 200), 150, 150); 
    D2D1_ELLIPSE pe2 = D2D1::Ellipse(D2D1::Point2F(350, 200), 150, 150);

    pDCRT->CreateSolidColorBrush(D2D1::ColorF(1, 0, 0, 1), &pBrush);    
    pDCRT->FillEllipse(pe1, pBrush); 
     
    pDCRT->CreateSolidColorBrush(D2D1::ColorF(0, 1, 0, 0.5f), &pBrush);       
    pDCRT->FillEllipse(pe2, pBrush);  

我想让重合的部分只有右边实心圆的颜色,就是让它透明的时候忽略掉左边圆和窗口背景色直接透到桌面,请问,怎么才能实现的效果。

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-09-17 12:31
    关注

    【以下回答由 GPT 生成】

    要实现让重叠的部分只显示右边实心圆的颜色,可以通过以下步骤进行:

    1. 首先,我们需要在创建窗口时设置窗口的样式为WS_EX_LAYERED,以支持透明度。可以使用以下代码片段将窗口的样式设置为WS_EX_LAYERED
    DWORD exStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
    exStyle |= WS_EX_LAYERED;
    SetWindowLong(hWnd, GWL_EXSTYLE, exStyle);
    
    1. 在绘制窗口之前,我们需要使用D2D1::RenderTargetProperties来创建一个具有透明背景的ID2D1HwndRenderTarget对象。可以使用以下代码片段:
    D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties = D2D1::RenderTargetProperties(
        D2D1_RENDER_TARGET_TYPE_DEFAULT,
        D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
        0,
        0,
        D2D1_RENDER_TARGET_USAGE_NONE,
        D2D1_FEATURE_LEVEL_DEFAULT
    );
    
    HRESULT hr = pFactory->CreateHwndRenderTarget(
        renderTargetProperties,
        D2D1::HwndRenderTargetProperties(hWnd, size),
        &pRenderTarget
    );
    
    1. 在绘制实心圆之前,我们需要设置ID2D1HwndRenderTarget的透明度模式为D2D1_ALPHA_MODE_PREMULTIPLIED。可以使用以下代码片段:
    pRenderTarget->SetDpi(dpiX, dpiY);
    pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
    pRenderTarget->BeginDraw();
    pRenderTarget->Clear(D2D1::ColorF(0, 0, 0, 0));
    pRenderTarget->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_ALIASED);
    pRenderTarget->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
    pRenderTarget->SetPixelSnappingPolicy(D2D1_PIXEL_SNAPPING_POLICY_DIPS);
    pRenderTarget->SetTags(0, 0);
    pRenderTarget->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_SOURCE_OVER);
    
    1. 如果要让右边实心圆的颜色覆盖重叠部分,可以修改以下代码段:
    pDCRT->CreateSolidColorBrush(D2D1::ColorF(1, 0, 0, 1), &pBrush);    
    pDCRT->FillEllipse(pe1, pBrush); 
    
    pDCRT->CreateSolidColorBrush(D2D1::ColorF(0, 1, 0, 1), &pBrush);       
    pDCRT->FillEllipse(pe2, pBrush);
    

    其中,右边实心圆的颜色的透明度为1,这样重叠部分就会完全覆盖左边实心圆的颜色。

    完整的代码示例可以参考以下内容:

    #include <Windows.h>
    #include <d2d1.h>
    
    ID2D1Factory* pFactory = nullptr;
    ID2D1HwndRenderTarget* pRenderTarget = nullptr;
    
    LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    
    int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
    {
        // 创建窗口
    
        HWND hWnd = CreateWindowExW(
            WS_EX_LAYERED,
            L"WindowClassName",
            L"Transparent Window",
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
            nullptr, nullptr, hInstance, nullptr
        );
    
        if (hWnd == nullptr)
        {
            return 0;
        }
    
        // 创建Direct2D工厂
    
        HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory);
    
        if (FAILED(hr))
        {
            return 0;
        }
    
        // 设置窗口透明度样式
    
        DWORD exStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
        exStyle |= WS_EX_LAYERED;
        SetWindowLong(hWnd, GWL_EXSTYLE, exStyle);
    
        // 创建透明窗口
    
        RECT windowRect;
        GetWindowRect(hWnd, &windowRect);
    
        D2D1_SIZE_U size = D2D1::SizeU(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
    
        D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties = D2D1::RenderTargetProperties(
            D2D1_RENDER_TARGET_TYPE_DEFAULT,
            D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
            0,
            0,
            D2D1_RENDER_TARGET_USAGE_NONE,
            D2D1_FEATURE_LEVEL_DEFAULT
        );
    
        hr = pFactory->CreateHwndRenderTarget(
            renderTargetProperties,
            D2D1::HwndRenderTargetProperties(hWnd, size),
            &pRenderTarget
        );
    
        if (FAILED(hr))
        {
            return 0;
        }
    
        ShowWindow(hWnd, nCmdShow);
    
        // 消息循环
    
        MSG msg = {};
        while (GetMessage(&msg, nullptr, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
        // 释放资源
    
        pRenderTarget->Release();
        pFactory->Release();
    
        return 0;
    }
    
    LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
        case WM_PAINT:
        {
            if (pRenderTarget == nullptr)
            {
                break;
            }
    
            // 绘制透明窗口
    
            pRenderTarget->BeginDraw();
            pRenderTarget->Clear(D2D1::ColorF(0, 0, 0, 0));
            pRenderTarget->EndDraw();
    
            // 绘制实心圆
    
            D2D1_ELLIPSE pe1 = D2D1::Ellipse(D2D1::Point2F(200, 200), 150, 150);
            D2D1_ELLIPSE pe2 = D2D1::Ellipse(D2D1::Point2F(350, 200), 150, 150);
    
            ID2D1SolidColorBrush* pBrush;
    
            pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(1, 0, 0, 1), &pBrush);
            pRenderTarget->FillEllipse(pe1, pBrush);
    
            pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(0, 1, 0, 1), &pBrush);
            pRenderTarget->FillEllipse(pe2, pBrush);
    
            pBrush->Release();
    
            ValidateRect(hWnd, NULL);
        }
        return 0;
    
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        }
    
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    


    【相关推荐】



    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 9月17日

悬赏问题

  • ¥15 大家知道这个后备文件怎么删吗,为啥这些文件我只看到一份,没有后备呀
  • ¥15 C++为什么这个代码没报错运行不出来啊
  • ¥15 一道ban了很多东西的pyjail题
  • ¥15 关于#r语言#的问题:如何将生成的四幅图排在一起,且对变量的赋值进行更改,让组合的图漂亮、美观@(相关搜索:森林图)
  • ¥15 C++识别堆叠物体异常
  • ¥15 微软硬件驱动认证账号申请
  • ¥15 GPT写作提示指令词
  • ¥20 根据动态演化博弈支付矩阵完成复制动态方程求解和演化相图分析等
  • ¥15 华为超融合部署环境下RedHat虚拟机分区扩容问题
  • ¥15 哪位能做百度地图导航触点播报?