D2D1 имеет явное алиасинг при высоком DPI - PullRequest
0 голосов
/ 20 ноября 2018
  • Напишите простую демонстрацию, чтобы проверить проблему, чем выше DPI, тем более очевиден псевдоним, текст одинаков, попробуйте использовать SetAntialiasMode и SetTextAntialiasMode без улучшения, моя система - версия win10 Professional.
  • Есть ли способ добиться сглаживания при высоком 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 голосов
/ 20 ноября 2018

Похоже, что вы включаете DPI DPI после создания окна.Вместо этого вы должны объявить о разрешении dpi в манифесте приложения.Также нет необходимости выполнять масштабирование вручную, как (logic_width * _dpi_x / 96.0f);, потому что размер окна будет уже в физических пикселях, а не в логических_пикселях.

...