Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Direct2D to natywny, bezpośredni interfejs API umożliwiający tworzenie grafiki 2D. W tym temacie pokazano, jak użyć Direct2D do rysowania na Windows::UI::Core::CoreWindow.
Ten temat zawiera następujące sekcje:
- rysowanie prostego prostokąta
- Krok 1. Dołącz nagłówek Direct2D
- Krok 2: Utwórz ID2D1Factory1
- Krok 3. Utwórz ID2D1Device i ID2D1DeviceContext
- Krok 4. Tworzenie pędzla
- Krok 5. Rysowanie prostokąta
- przykładowy kod
Rysowanie prostego prostokąta
Aby narysować prostokąt przy użyciu GDI , można obsłużyć komunikat WM_PAINT, jak pokazano w poniższym kodzie.
switch(message)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
// Obtain the size of the drawing area.
RECT rc;
GetClientRect(
hwnd,
&rc
);
// Save the original object
HGDIOBJ original = NULL;
original = SelectObject(
ps.hdc,
GetStockObject(DC_PEN)
);
// Create a pen.
HPEN blackPen = CreatePen(PS_SOLID, 3, 0);
// Select the pen.
SelectObject(ps.hdc, blackPen);
// Draw a rectangle.
Rectangle(
ps.hdc,
rc.left + 100,
rc.top + 100,
rc.right - 100,
rc.bottom - 100);
DeleteObject(blackPen);
// Restore the original object
SelectObject(ps.hdc, original);
EndPaint(hwnd, &ps);
}
return 0;
// Code for handling other messages.
Kod do rysowania tego samego prostokąta z funkcją Direct2D jest podobny: tworzy zasoby rysunkowe, opisuje kształt do rysowania, rysuje kształt, a następnie zwalnia zasoby rysunkowe. W poniższych sekcjach szczegółowo opisano poszczególne kroki.
Krok 1: Dołącz nagłówek Direct2D
Oprócz nagłówków wymaganych dla aplikacji dołącz nagłówki d2d1.h i d2d1_1.h.
Krok 2: Utwórz ID2D1Factory1
Jedną z pierwszych rzeczy, które wykonuje dowolny przykład Direct2D, jest utworzenie ID2D1Factory1.
DX::ThrowIfFailed(
D2D1CreateFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
__uuidof(ID2D1Factory1),
&options,
&m_d2dFactory
)
);
Interfejs ID2D1Factory1 jest punktem wyjścia do korzystania z Direct2D; użyj ID2D1Factory1 do tworzenia zasobów Direct2D.
Podczas tworzenia fabryki można określić, czy jest ona wielowątkowa, czy pojedyncza. (Aby uzyskać więcej informacji na temat fabryk wielowątowych, zobacz uwagi na stronie referencyjnej ID2D1Factory). W tym przykładzie tworzona jest fabryka jednowątkowa.
Ogólnie rzecz biorąc, aplikacja powinna utworzyć fabrykę raz i zachować ją na okres życia aplikacji.
Krok 3. Tworzenie urządzenia ID2D1Device i ID2D1DeviceContext
Po utworzeniu fabryki użyj jej do utworzenia urządzenia Direct2D, a następnie użyj urządzenia do utworzenia kontekstu urządzenia Direct2D. Aby utworzyć te obiekty Direct2D, musisz mieć urządzenie Direct3D 11 , urządzenia DXGIi łańcuch wymiany DXGI . Aby uzyskać informacje na temat tworzenia niezbędnych wymagań wstępnych, zobacz Urządzenia i konteksty urządzeń.
// Obtain the underlying DXGI device of the Direct3D11.1 device.
DX::ThrowIfFailed(
m_d3dDevice.As(&dxgiDevice)
);
// Obtain the Direct2D device for 2-D rendering.
DX::ThrowIfFailed(
m_d2dFactory->CreateDevice(dxgiDevice.Get(), &m_d2dDevice)
);
// And get its corresponding device context object.
DX::ThrowIfFailed(
m_d2dDevice->CreateDeviceContext(
D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
&m_d2dContext
)
);
Kontekst urządzenia to urządzenie, które może wykonywać operacje rysowania i tworzyć zasoby rysunkowe zależne od urządzenia, takie jak pędzle. Kontekst urządzenia służy również do łączenia ID2D1Bitmap z powierzchnią DXGI do użycia jako obiekt docelowy renderowania. Kontekst urządzenia może być renderowany do różnych typów obiektów docelowych.
Kod w tym miejscu deklaruje właściwości mapy bitowej, które łączą się z łańcuchem wymiany DXGI, który renderuje się do CoreWindow. Metoda ID2D1DeviceContext::CreateBitmapFromDxgiSurface pobiera powierzchnię Direct2D z powierzchni DXGI. Dzięki temu wszystkie elementy renderowane na docelowym ID2D1Bitmap są renderowane na powierzchni łańcucha wymiany.
Gdy masz powierzchnię Direct2D, użyj metody ID2D1DeviceContext::SetTarget, aby ustawić ją jako aktywny element docelowy renderowania.
// Now we set up the Direct2D render target bitmap linked to the swapchain.
// Whenever we render to this bitmap, it will be directly rendered to the
// swapchain associated with the window.
D2D1_BITMAP_PROPERTIES1 bitmapProperties =
BitmapProperties1(
D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
m_dpi,
m_dpi
);
// Direct2D needs the dxgi version of the backbuffer surface pointer.
ComPtr<IDXGISurface> dxgiBackBuffer;
DX::ThrowIfFailed(
m_swapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer))
);
// Get a D2D surface from the DXGI back buffer to use as the D2D render target.
DX::ThrowIfFailed(
m_d2dContext->CreateBitmapFromDxgiSurface(
dxgiBackBuffer.Get(),
&bitmapProperties,
&m_d2dTargetBitmap
)
);
// So now we can set the Direct2D render target.
m_d2dContext->SetTarget(m_d2dTargetBitmap.Get());
Krok 4. Tworzenie pędzla
Podobnie jak w przypadku fabryki kontekst urządzenia może tworzyć zasoby rysunkowe. W tym przykładzie kontekst urządzenia tworzy pędzel.
ComPtr<ID2D1SolidColorBrush> pBlackBrush;
DX::ThrowIfFailed(
m_d2dContext->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::Black),
&pBlackBrush
)
);
Pędzel to obiekt, który maluje obszar, taki jak kontur kształtu lub wypełnienie geometrii. Pędzl w tym przykładzie maluje obszar ze wstępnie zdefiniowanym kolorem stałym, czarnym.
Direct2D udostępnia również inne typy pędzli: pędzle gradientowe do malowania gradientów liniowych i promieniowych, pędzel mapy bitowej do malowania przy użyciu map bitowych i wzorów oraz począwszy od systemu Windows 8, pędzel obrazu do malowania przy użyciu renderowanego obrazu.
Niektóre interfejsy API rysunku udostępniają pióra do rysowania konturów i pędzli do wypełniania kształtów. Direct2D jest inny: nie zapewnia narzędzia rysowniczego, ale używa pędzla do rysowania konturów i wypełniania kształtów. Podczas rysowania konturów należy użyć interfejsu ID2D1StrokeStyle albo, począwszy od systemu Windows 8, interfejsu ID2D1StrokeStyle1 z pędzlem do kontrolowania operacji rysowania ścieżki.
Pędzla można używać tylko z obiektem docelowym renderowania, który go utworzył i z innymi elementami docelowymi renderowania w tej samej domenie zasobów. Ogólnie rzecz biorąc, należy utworzyć pędzle raz i zachować je na czas istnienia docelowego obiektu renderowania, który je utworzył. ID2D1SolidColorBrush jest jedynym wyjątkiem; ponieważ jest stosunkowo niedrogie do utworzenia, można utworzyć ID2D1SolidColorBrush za każdym razem, gdy narysujesz ramkę, bez zauważalnego wpływu na wydajność. Można również użyć jednego ID2D1SolidColorBrush i po prostu zmienić jego kolor lub nieprzezroczystość za każdym razem, gdy go używasz.
Krok 5. Rysowanie prostokąta
Następnie użyj kontekstu urządzenia, aby narysować prostokąt.
m_d2dContext->BeginDraw();
m_d2dContext->DrawRectangle(
D2D1::RectF(
rc.left + 100.0f,
rc.top + 100.0f,
rc.right - 100.0f,
rc.bottom - 100.0f),
pBlackBrush);
DX::ThrowIfFailed(
m_d2dContext->EndDraw()
);
DX::ThrowIfFailed(
m_swapChain->Present1(1, 0, ¶meters);
);
Metoda DrawRectangle przyjmuje dwa parametry: prostokąt do narysowania, a pędzl do malowania konturu prostokąta. Opcjonalnie można również określić opcje grubości linii, styl kreski, łączenie linii i zakończenie linii.
Należy wywołać metodę BeginDraw przed wystawieniem jakichkolwiek poleceń rysunkowych, a po zakończeniu wydawania poleceń rysowania należy wywołać metodę EndDraw. Metoda EndDraw zwraca HRESULT, który wskazuje, czy polecenia rysunku zakończyły się pomyślnie. Jeśli operacja się nie powiedzie, funkcja pomocnicza ThrowIfFailed zgłosi wyjątek.
Metoda IDXGISwapChain::Present zamienia powierzchnię bufora z powierzchnią ekranu, aby wyświetlić wynik.
Przykładowy kod
Kod w tym temacie przedstawia podstawowe elementy aplikacji Direct2D. W celu zwięzłości temat pomija strukturę aplikacji i kod obsługi błędów charakterystyczny dla dobrze napisanej aplikacji.