Movatterモバイル変換


[0]ホーム

URL:


Skip to main content

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Download Microsoft EdgeMore info about Internet Explorer and Microsoft Edge
Table of contentsExit focus mode

Direct2D quickstart for Windows 8

  • 2022-05-26
Feedback

In this article

Direct2D is a native-code, immediate-mode API for creating 2D graphics. This topic illustrates how to use Direct2D to draw to aWindows::UI::Core::CoreWindow.

This topic contains the following sections:

Drawing a Simple Rectangle

To draw a rectangle usingGDI, you could handle theWM_PAINT message, as shown in the following code.

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.

The code for drawing the same rectangle with Direct2D is similar: it creates drawing resources, describes a shape to draw, draws the shape, then releases the drawing resources. The sections that follow describe each of these steps in detail.

Step 1: Include Direct2D Header

In addition to the headers required for the application, include the d2d1.h and d2d1_1.h headers.

Step 2: Create an ID2D1Factory1

One of the first things that any Direct2D example does is create anID2D1Factory1.

DX::ThrowIfFailed(        D2D1CreateFactory(            D2D1_FACTORY_TYPE_SINGLE_THREADED,            __uuidof(ID2D1Factory1),            &options,            &m_d2dFactory            )        );

TheID2D1Factory1 interface is the starting point for using Direct2D; use anID2D1Factory1 to create Direct2D resources.

When you create a factory, you can specify whether it is multi- or single-threaded. (For more information about multi-threaded factories, see the remarks on theID2D1Factory reference page.) This example creates a single-threaded factory.

In general, your application should create the factory once and retain it for the life of the application.

Step 3: Create an ID2D1Device and an ID2D1DeviceContext

After you create a factory, use it to create a Direct2D device and then use the device to create a Direct2D device context. In order to create these Direct2D objects, you must have aDirect3D 11 device , aDXGI device, and aDXGI swap chain. SeeDevices and Device Contexts for info on creating the necessary prerequisites.

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

A device context is a device that can perform drawing operations and create device-dependent drawing resources such as brushes. You also use the device context to link aID2D1Bitmap to a DXGI surface to use as a render target. The device context can render to different types of targets.

The code here declares the properties for bitmap that links to a DXGI swap chain that renders to aCoreWindow. TheID2D1DeviceContext::CreateBitmapFromDxgiSurface method gets a Direct2D surface from the DXGI surface. This makes it so anything rendered to the targetID2D1Bitmap is rendered to the surface of the swap chain.

Once you have the Direct2D surface, use theID2D1DeviceContext::SetTarget method to set it as the active render target.

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

Step 4: Create a Brush

Like a factory, a device context can create drawing resources. In this example, the device context creates a brush.

ComPtr<ID2D1SolidColorBrush> pBlackBrush;DX::ThrowIfFailed(   m_d2dContext->CreateSolidColorBrush(        D2D1::ColorF(D2D1::ColorF::Black),        &pBlackBrush        ));

A brush is an object that paints an area, such as the stroke of a shape or the fill of a geometry. The brush in this example paints an area with a predefined solid color, black.

Direct2D also provides other types of brushes: gradient brushes for painting linear and radial gradients, abitmap brush for painting with bitmaps and patterns, and starting in Windows 8, animage brush for painting with a rendered image.

Some drawing APIs provide pens for drawing outlines and brushes for filling shapes. Direct2D is different: it does not provide a pen object but uses a brush for drawing outlines and filling shapes. When drawing outlines, use theID2D1StrokeStyle interface, or starting in Windows 8 theID2D1StrokeStyle1 interface, with a brush to control path stroking operations.

A brush can only be used with the render target that created it and with other render targets in the same resource domain. In general, you should create brushes once and retain them for the life of the render target that created them.ID2D1SolidColorBrush is the lone exception; because it is relatively inexpensive to create, you can create aID2D1SolidColorBrush every time you draw a frame, without any noticeable performance hit. You can also use a singleID2D1SolidColorBrush and just change its color or opacity every time you use it.

Step 5: Draw the Rectangle

Next, use the device context to draw the rectangle.

 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, &parameters););

TheDrawRectangle method takes two parameters: the rectangle to be drawn, and the brush to be used to paint the rectangle's outline. Optionally, you can also specify the stroke width, dash pattern, line join, and end cap options.

You must call theBeginDraw method before issuing any drawing commands, and you must call theEndDraw method after you've finished issuing drawing commands. TheEndDraw method returns anHRESULT that indicates whether the drawing commands were successful. If it is not successful, the ThrowIfFailed helper function will throw an exception.

TheIDXGISwapChain::Present method swaps the buffer surface with the on screen surface to display the result.

Example code

The code in this topic shows the basic elements of a Direct2D application. For brevity, the topic omits the application framework and error handling code that is characteristic of a well-written application.

 

 


Feedback

Was this page helpful?

YesNo

In this article

Was this page helpful?

YesNo