D2D1 имеет явное алиасинг при высоком DPI
- Напишите простую демонстрацию, чтобы проверить проблему, чем выше DPI, тем более очевиден псевдоним, текст одинаков, попробуйте использовать SetAntialiasMode и SetTextAntialiasMode без улучшений, моя система - версия win10 Professional.
Есть ли способ добиться сглаживания при высоком DPI?
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 ответ
Решение
Кажется, что вы включаете DPI DPI после создания окна. Вместо этого вы должны указать dpi-осведомленность в манифесте приложения Также нет необходимости выполнять ручное масштабирование, как (logic_width * _dpi_x / 96.0f);
потому что размер окна будет уже в физических пикселях, а не в логических_пикселях.