Проблемы с рендерингом DirectWrite - кажется, что квады перекрываются, с некоторым псевдонимом - PullRequest
1 голос
/ 08 марта 2019

Снимок экрана проблемы:

here

Вот соответствующие биты кода - обработка ошибок и т. Д. Для ясности опущены.

D2D1_BITMAP_PROPERTIES1 bp;
bp.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
bp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
bp.dpiX = 96.0f;
bp.dpiY = 96.0f;
bp.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
bp.colorContext = nullptr;

...

d2dDeviceContext->SetTarget(targetBitmap);

....

writeFactory->CreateTextFormat(L"Arial", nullptr, DWRITE_FONT_WEIGHT_LIGHT, DWRITE_FONT_STYLE_NORMAL, 
DWRITE_FONT_STRETCH_NORMAL, 32.0f, L"en-US", &textFormatAccountCreds);
textFormatAccountCreds->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING);
textFormatAccountCreds->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR);

std::wostringstream outAccountName;
outAccountName << "Account Name:";
writeFactory->CreateTextLayout(outAccountName.str().c_str(), (UINT32)outAccountName.str().size(), textFormatAccountCreds, (float)800, 
(float)600, &textLayoutAccountName);

const float color[4] = { 1.0f, 0.5f, 0.3f, 1.0f };
immediateContext->ClearRenderTargetView(renderTargetView, color);

d2dDeviceContext->BeginDraw();
d2dDeviceContext->DrawTextLayout(D2D1::Point2F(2.0f, 5.0f), textLayoutAccountName, blackBrush);
d2dDeviceContext->EndDraw();

swapChain->Present(0, 0);

Как вы можете видеть на скриншоте, текст отображается очень плохо - в частности, первая буква "n" обрезается слева, а также первая буква "u" и заглавная буква "N"."происходит странное наложение имен.Я могу изменить размер / положение текста, и проблемы с рендерингом проявляются по-разному, но они все еще сохраняются.

Что мне здесь не хватает?Я ознакомился с большинством документов DirectWrite на MSDN, и неясно, в чем заключается моя проблема.Я вижу некоторые упоминания о том, что мне следует указать начальную позицию моего текста относительно шкалы точек на дюйм, но пример очень расплывчатый.

Стоит также упомянуть, что я использую Direct3D и DirectWrite с Direct2D все вместе, аналогично тому, как видно из этого урока .Не уверен, что это вызывает мою проблему.

Буду очень признателен за любую помощь.Большое спасибо.

1 Ответ

0 голосов
/ 09 марта 2019

Я понял это. Приветствую VTT за указание в правильном направлении.

HWND hWnd = CreateWindow(
    szWindowClass,
    szTitle,
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    800,
    600,
    NULL,
    NULL,
    hInstance,
    NULL
);

...

DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = 800;
sd.BufferDesc.Height = 600;
sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = hWnd;
sd.SampleDesc.Count = 4;
sd.SampleDesc.Quality = m4xMsaaQuality - 1;
sd.Windowed = TRUE;
sd.Flags = 0;

Видимо, размеры, которые вы передаете в CreateWindow, включают пространство для меню и границ окна, поэтому фактические размеры пространства, которое вы можете нарисовать в окне, меньше.

RECT rect;
GetClientRect(hWnd, &rect);
// Returns 784 x 561

Таким образом, решение было: -Опустите указание sd.BufferDesc.Width и sd.BufferDesc.Height в DXGI_SWAP_CHAIN_DESC, потому что когда они установлены в 0, они наследуют измерения из родительского окна. -Получить фактические размеры, используя GetClientRect, когда фактические размеры окна понадобятся позже.

...