#windows #directx #direct3d #direct2d #directwrite
#Windows #directx #direct3d #direct2d #directwrite
Вопрос:
Скриншот проблемы:
Вот соответствующие фрагменты кода — обработка ошибок и т.д. опущены для ясности.
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", amp;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, amp;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, и не ясно, в чем моя проблема. Я вижу некоторые упоминания о том, что я должен указать начальную позицию моего текста относительно шкалы dpi, но пример очень расплывчатый.
Также стоит упомянуть, что я использую Direct3D и DirectWrite с Direct2D все вместе, аналогично тому, как показано в этом руководстве. Не уверен, что это вызывает мою проблему.
Я был бы очень благодарен за любую помощь. Большое спасибо.
Комментарии:
1. Как вы устанавливаете целевой размер рендеринга? Несколько подозрительно, что ширина окна (на скриншоте) не равна 800.
2. Этот комментарий помог мне найти проблему. Спасибо!
Ответ №1:
Я понял это. Спасибо VTT за то, что указал мне правильное направление.
HWND hWnd = CreateWindow(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
800,
600,
NULL,
NULL,
hInstance,
NULL
);
...
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(amp;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, amp;rect);
// Returns 784 x 561
Итак, решение состояло в том, чтобы:
-Не указывайте sd.BufferDesc.Width и sd.BufferDesc.Height в DXGI_SWAP_CHAIN_DESC, потому что, когда они установлены в 0, они унаследуют размеры из родительского окна.
— Получите фактические размеры с помощью GetClientRect, когда позже потребуются фактические размеры окна.