Udostępnij przez


Szybki start Direct2D

Direct2D to natywny, bezpośredni interfejs API umożliwiający tworzenie grafiki 2D. W tym temacie pokazano, jak używać Direct2D w typowej aplikacji Win32 do rysowania na HWND.

Notatka

Jeśli chcesz utworzyć aplikację ze Sklepu Windows korzystającą z funkcji Direct2D, zobacz przewodnik Szybki start Direct2D dla systemu Windows 8.

 

Ten temat zawiera następujące sekcje:

Rysowanie prostego prostokąta

Aby narysować prostokąt za pomocą GDI , można obsłużyć komunikat WM_PAINT , co 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 Win32 dołącz nagłówek d2d1.h.

Krok 2: Utwórz ID2D1Factory

Jedną z pierwszych rzeczy, które wykonuje dowolny przykład Direct2D, jest utworzenie ID2D1Factory.

ID2D1Factory* pD2DFactory = NULL;
HRESULT hr = D2D1CreateFactory(
    D2D1_FACTORY_TYPE_SINGLE_THREADED,
    &pD2DFactory
    );

Interfejs ID2D1Factory jest punktem wyjścia do korzystania z direct2D; użyj ID2D1Factory, aby utworzyć zasoby 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 obiektu ID2D1HwndRenderTarget

Po utworzeniu fabryki użyj jej do utworzenia obiektu docelowego renderowania.



// Obtain the size of the drawing area.
RECT rc;
GetClientRect(hwnd, &rc);

// Create a Direct2D render target          
ID2D1HwndRenderTarget* pRT = NULL;          
HRESULT hr = pD2DFactory->CreateHwndRenderTarget(
    D2D1::RenderTargetProperties(),
    D2D1::HwndRenderTargetProperties(
        hwnd,
        D2D1::SizeU(
            rc.right - rc.left,
            rc.bottom - rc.top)
    ),
    &pRT
);

Element docelowy renderowania to urządzenie, które może wykonywać operacje rysowania i tworzyć zasoby rysunkowe zależne od urządzenia, takie jak pędzle. Różne typy obiektów docelowych renderowania są renderowane na różnych urządzeniach. W poprzednim przykładzie użyto ID2D1HwndRenderTarget, który renderuje na części ekranu.

Jeśli to możliwe, obiekt docelowy renderowania używa procesora GPU do przyspieszania operacji renderowania i tworzenia zasobów rysunkowych. W przeciwnym razie obiekt docelowy renderowania używa procesora CPU do przetwarzania instrukcji renderowania i tworzenia zasobów. (To zachowanie można zmodyfikować przy użyciu flag D2D1_RENDER_TARGET_TYPE podczas tworzenia obiektu docelowego renderowania).

Metoda CreateHwndRenderTarget przyjmuje trzy parametry. Pierwszy parametr, struktura D2D1_RENDER_TARGET_PROPERTIES, określa opcje zdalnego wyświetlania, decydując o wymuszeniu renderowania celu renderowania za pomocą oprogramowania lub sprzętu, a także ustawienia DPI. Kod w tym przykładzie używa funkcji pomocnika D2D1::RenderTargetProperties do akceptowania domyślnych właściwości docelowych renderowania.

Drugi parametr, struktura D2D1_HWND_RENDER_TARGET_PROPERTIES, określa HWND, do którego renderowana jest zawartość, początkowy rozmiar obiektu docelowego renderowania (w pikselach) i jego opcje prezentacji. W tym przykładzie użyto funkcji pomocnika D2D1::HwndRenderTargetProperties w celu określenia wartości HWND i rozmiaru początkowego. Używa domyślnych opcji prezentacji.

Trzeci parametr to adres wskaźnika, który otrzymuje referencję do celu renderowania.

Podczas tworzenia elementu docelowego renderowania, jeśli przyspieszenie sprzętowe jest dostępne, przydzielasz zasoby na GPU komputera. Tworząc element docelowy renderowania raz i zachowując go tak długo, jak to możliwe, uzyskujesz korzyści z wydajności. Aplikacja powinna utworzyć elementy docelowe renderowania jednokrotnie i zachować je na czas działania aplikacji lub do momentu odebrania błędu D2DERR_RECREATE_TARGET. Po wystąpieniu tego błędu należy ponownie utworzyć obiekt docelowy renderowania (i wszystkie utworzone przez niego zasoby).

Krok 4. Tworzenie pędzla

Podobnie jak w przypadku fabryki obiekt docelowy renderowania może tworzyć zasoby rysunkowe. W tym przykładzie obiekt docelowy renderowania tworzy pędzel.

ID2D1SolidColorBrush* pBlackBrush = NULL;
if (SUCCEEDED(hr))
{
            
    pRT->CreateSolidColorBrush(
        D2D1::ColorF(D2D1::ColorF::Black),
        &pBlackBrush
        ); 
}

Pędzel to obiekt, który maluje obszar, na przykład poprzez pociągnięcie kształtu lub wypełnienie geometrie. 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 oraz pędzla mapy bitowej do malowania z mapami bitowymi i wzorami.

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 obiektu pióra, 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 z pędzlem do sterowania operacjami obrysu ścieżki.

Pędzla można używać tylko z obiektem docelowym renderowania, który go utworzył, oraz z innymi obiektami docelowymi renderowania znajdującymi się w tej samej domenie zasobów. Ogólnie rzecz biorąc, należy utworzyć pędzle raz i przechowywać je przez cały czas żywotności obiektu docelowego renderowania, który je utworzył. ID2D1SolidColorBrush jest jedynym wyjątkiem; ponieważ jest stosunkowo niedrogi do utworzenia, możesz tworzyć ID2D1SolidColorBrush za każdym razem, gdy rysujesz klatkę, bez zauważalnego spadku wydajności. Można również użyć jednego ID2D1SolidColorBrush i po prostu zmienić jego kolor za każdym razem, gdy go używasz.

Krok 5. Rysowanie prostokąta

Następnie użyj celu renderowania do narysowania prostokąta.

 
pRT->BeginDraw();

pRT->DrawRectangle(
    D2D1::RectF(
        rc.left + 100.0f,
        rc.top + 100.0f,
        rc.right - 100.0f,
        rc.bottom - 100.0f),
        pBlackBrush);

HRESULT hr = pRT->EndDraw();  

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 szerokości obrysu, stylu kreski, łączenia linii i zakończenia 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 wskazującą, czy polecenia rysunku zakończyły się pomyślnie.

Krok 6. Wydawanie zasobów

Jeśli nie ma więcej ramek do rysowania lub gdy zostanie wyświetlony błąd D2DERR_RECREATE_TARGET, zwolnij obiekt docelowy renderowania i wszystkie utworzone przez niego urządzenia.

 
SafeRelease(pRT);
SafeRelease(pBlackBrush);

Kiedy aplikacja przestaje używać zasobów Direct2D (takich jak w momencie jej zakończenia), zwolnij fabrykę Direct2D.

 
SafeRelease(pD2DFactory);

Tworzenie prostej aplikacji Direct2D

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. Aby uzyskać bardziej szczegółowy przewodnik pokazujący pełny kod tworzenia prostej aplikacji Direct2D i demonstrujący najlepsze rozwiązania projektowe, zobacz Tworzenie prostej aplikacji Direct2D.

Tworzenie prostej aplikacji Direct2D