Démarrage rapide Direct2D

Direct2D est une API en mode immédiat de code natif permettant de créer des graphiques 2D. Cette rubrique montre comment utiliser Direct2D dans une application Win32 classique pour dessiner vers un HWND.

Notes

Si vous souhaitez créer une application du Windows Store qui utilise Direct2D, consultez le guide de démarrage rapide Direct2D pour Windows 8 rubrique.

 

Cette rubrique contient les sections suivantes :

Dessin d’un rectangle simple

Pour dessiner un rectangle à l’aide de GDI, vous pouvez gérer le message WM_PAINT , comme indiqué dans le code suivant.

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. 

Le code pour dessiner le même rectangle avec Direct2D est similaire : il crée des ressources de dessin, décrit une forme à dessiner, dessine la forme, puis libère les ressources de dessin. Les sections qui suivent décrivent chacune de ces étapes en détail.

Étape 1 : Inclure l’en-tête Direct2D

En plus des en-têtes requis pour une application Win32, incluez l’en-tête d2d1.h.

Étape 2 : Créer un ID2D1Factory

L’une des premières choses que n’importe quel exemple direct2D fait est de créer un ID2D1Factory.

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

L’interface ID2D1Factory est le point de départ de l’utilisation de Direct2D ; utilisez un ID2D1Factory pour créer des ressources Direct2D.

Lorsque vous créez une fabrique, vous pouvez spécifier si elle est multithread ou monothread. (Pour plus d’informations sur les fabriques multithread, consultez les remarques sur la page de référence ID2D1Factory.) Cet exemple crée une fabrique à thread unique.

En général, votre application doit créer la fabrique une seule fois et la conserver pendant toute la durée de vie de l’application.

Étape 3 : Créer un ID2D1HwndRenderTarget

Après avoir créé une fabrique, utilisez-la pour créer une cible de rendu.



// 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
);

Une cible de rendu est un appareil qui peut effectuer des opérations de dessin et créer des ressources de dessin dépendantes de l’appareil, telles que des pinceaux. Différents types de cibles de rendu s’affichent sur différents appareils. L’exemple précédent utilise un ID2D1HwndRenderTarget, qui s’affiche sur une partie de l’écran.

Lorsque cela est possible, une cible de rendu utilise le GPU pour accélérer les opérations de rendu et créer des ressources de dessin. Sinon, la cible de rendu utilise le processeur pour traiter les instructions de rendu et créer des ressources. (Vous pouvez modifier ce comportement à l’aide des indicateurs D2D1_RENDER_TARGET_TYPE lorsque vous créez la cible de rendu.)

La méthode CreateHwndRenderTarget prend trois paramètres. Le premier paramètre, un struct de D2D1_RENDER_TARGET_PROPERTIES , spécifie les options d’affichage à distance, si la cible de rendu doit être rendue sur un logiciel ou un matériel, et le ppp. Le code de cet exemple utilise la fonction d’assistance D2D1::RenderTargetProperties pour accepter les propriétés cibles de rendu par défaut.

Le deuxième paramètre, un struct de D2D1_HWND_RENDER_TARGET_PROPERTIES , spécifie le HWND sur lequel le contenu est rendu, la taille initiale de la cible de rendu (en pixels) et ses options de présentation. Cet exemple utilise la fonction d’assistance D2D1::HwndRenderTargetProperties pour spécifier un HWND et une taille initiale. Il utilise les options de présentation par défaut.

Le troisième paramètre est l’adresse du pointeur qui reçoit la référence cible de rendu.

Lorsque vous créez une cible de rendu et que l’accélération matérielle est disponible, vous allouez des ressources sur le GPU de l’ordinateur. En créant une cible de rendu une seule fois et en la conservant aussi longtemps que possible, vous bénéficiez d’avantages en matière de performances. Votre application doit créer des cibles de rendu une fois et les conserver pendant toute la durée de vie de l’application ou jusqu’à ce que l’erreur D2DERR_RECREATE_TARGET soit reçue. Lorsque vous recevez cette erreur, vous devez recréer la cible de rendu (et toutes les ressources qu’elle a créées).

Étape 4 : Créer un pinceau

Comme une fabrique, une cible de rendu peut créer des ressources de dessin. Dans cet exemple, la cible de rendu crée un pinceau.

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

Un pinceau est un objet qui peint une zone, comme le trait d’une forme ou le remplissage d’une géométrie. Le pinceau de cet exemple peint une zone avec une couleur unie prédéfinie, le noir.

Direct2D fournit également d’autres types de pinceaux : des pinceaux dégradés pour peindre des dégradés linéaires et radials, et un pinceau bitmap pour la peinture avec des bitmaps et des motifs.

Certaines API de dessin fournissent des stylets pour dessiner des contours et des pinceaux pour remplir des formes. Direct2D est différent : il ne fournit pas d’objet de stylet, mais utilise un pinceau pour dessiner des contours et remplir des formes. Lorsque vous dessinez des contours, utilisez l’interface ID2D1StrokeStyle avec un pinceau pour contrôler les opérations de caressement de chemin.

Un pinceau ne peut être utilisé qu’avec la cible de rendu qui l’a créé et avec d’autres cibles de rendu dans le même domaine de ressources. En général, vous devez créer des pinceaux une seule fois et les conserver pendant la durée de vie de la cible de rendu qui les a créés. ID2D1SolidColorBrush est la seule exception ; Étant donné qu’il est relativement peu coûteux à créer, vous pouvez créer un ID2D1SolidColorBrush chaque fois que vous dessinez une image, sans aucun problème de performances notable. Vous pouvez également utiliser un seul ID2D1SolidColorBrush et changer simplement sa couleur chaque fois que vous l’utilisez.

Étape 5 : Dessiner le rectangle

Ensuite, utilisez la cible de rendu pour dessiner le rectangle.

 
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();  

La méthode DrawRectangle prend deux paramètres : le rectangle à dessiner et le pinceau à utiliser pour peindre le contour du rectangle. Si vous le souhaitez, vous pouvez également spécifier les options de largeur de trait, de tiret, de jointure de ligne et d’extrémité.

Vous devez appeler la méthode BeginDraw avant d’émettre des commandes de dessin, et vous devez appeler la méthode EndDraw une fois que vous avez terminé d’émettre des commandes de dessin. La méthode EndDraw retourne un HRESULT qui indique si les commandes de dessin ont réussi.

Étape 6 : Libérer des ressources

Lorsqu’il n’y a plus d’images à dessiner ou lorsque vous recevez l’erreur D2DERR_RECREATE_TARGET , relâchez la cible de rendu et tous les appareils qu’elle a créés.

 
SafeRelease(pRT);
SafeRelease(pBlackBrush);

Lorsque votre application a terminé d’utiliser les ressources Direct2D (par exemple, lorsqu’elle est sur le point de quitter), relâchez la fabrique Direct2D.

 
SafeRelease(pD2DFactory);

Créer une application Direct2D simple

Le code de cette rubrique montre les éléments de base d’une application Direct2D. Par souci de concision, la rubrique omet l’infrastructure d’application et le code de gestion des erreurs caractéristiques d’une application bien écrite. Pour obtenir une procédure détaillée qui montre le code complet pour la création d’une application Direct2D simple et présente les meilleures pratiques de conception, consultez Créer une application Direct2D simple.

Créer une simple application Direct2D