D2D1在高DPI下具有明显的混叠

时间:2018-11-20 07:52:59

标签: direct2d hdpi

  • 编写一个简单的演示来验证问题,DPI越高,别名越明显,文本相同,请尝试使用SetAntialiasMode和SetTextAntialiasMode没有改善,我的系统是win10专业版。
  • 是否有一些方法可以在高DPI下实现抗锯齿? dpi: 384 and capture screen

    static ID2D1Factory * g_factory;
    static IDWriteFactory*  g_dwrite_factory;
    static ID2D1HwndRenderTarget * g_render_target;
    static INT32 _dpi_x = 96;
    static INT32 _dpi_y = 96;
    
    #define DIP_TEST
    
    void OnSize(LPARAM lparam)
    {    
    UINT32 width = LOWORD(lparam);
    UINT32 height = HIWORD(lparam);
    
    UINT32 pixel_width = (UINT32)(width * _dpi_x / 96.0f);
    UINT32 pixel_height = (UINT32)(height * _dpi_x / 96.0f);
    
    if (g_render_target)
    g_render_target->Resize(D2D1::SizeU(pixel_width, pixel_height));
    }
    
    bool AppInit()
    {
    #ifdef DIP_TEST
    SetProcessDPIAware();
    _dpi_x = 384;
    _dpi_y = 384; 
    #endif
    
    D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &g_factory);
    DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&g_dwrite_factory));
    
    RECT rc;
    GetClientRect(g_hwnd, &rc);
    
    UINT32 logic_width = rc.right - rc.left;
    UINT32 logic_height = rc.bottom - rc.top;
    UINT32 w = (UINT32)(logic_width * _dpi_x / 96.0f);
    UINT32 h = (UINT32)(logic_height * _dpi_x / 96.0f);
    
    D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED);
    D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, pixelFormat);//D2D1_RENDER_TARGET_TYPE_SOFTWARE为了截图
    #ifdef DIP_TEST
    props.dpiX = (float)_dpi_x;
    props.dpiY = (float)_dpi_y;
    #endif
    
    g_factory->CreateHwndRenderTarget(props,
    D2D1::HwndRenderTargetProperties(g_hwnd, D2D1::SizeU(w, h)),
    &g_render_target);
    
    return true;
    }
    
    void OnPaint()
    {
    if (!g_render_target)
        return;
    
    ...
    g_render_target->BeginDraw();
    g_render_target->Clear(D2D1::ColorF(0.f, 0.f, 0.0f));
    //g_render_target->SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
    stroke_brush->SetColor(D2D1::ColorF(1.0f, 0.0f, 0.0f, 1.0f));
    D2D1_RECT_F textLayoutRect = D2D1::RectF(100.0f, 150.0f, 600.0f, 600.0f);
    g_render_target->DrawTextW(sz, text_len, dwrite_text_format, textLayoutRect, stroke_brush, D2D1_DRAW_TEXT_OPTIONS_NONE, DWRITE_MEASURING_MODE_NATURAL);     
    g_render_target->DrawEllipse(D2D1::Ellipse(D2D1::Point2F(300.5, 200.5), 250, 150), stroke_brush, 2);
    g_render_target->EndDraw(); 
    ...
    }
    

1 个答案:

答案 0 :(得分:0)

似乎在创建窗口后启用了DPI感知。您应该在应用程序清单中声明dpi意识。同样,也不需要像(logic_width * _dpi_x / 96.0f);那样执行手动尺寸缩放,因为窗口大小已经在物理像素中,而不是逻辑像素中。