Поделиться через


Рисование с использованием Direct2D

После создания графических ресурсов можно приступать к рисованию.

Рисование эллипса

Программа Circle выполняет очень простую логику рисования:

  1. Заливка фона сплошным цветом.
  2. Нарисуйте заполненный круг.

Снимок экрана: программа circle.

Поскольку целевым объектом отрисовки является окно (в отличие от растрового изображения или другой поверхности вне экрана), рисование выполняется в ответ на WM_PAINT сообщения. В следующем коде показана процедура окна для программы Circle.

LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_PAINT:
            OnPaint();
            return 0;

         // Other messages not shown...
    }
    return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
}

Ниже приведен код, который рисует круг.

void MainWindow::OnPaint()
{
    HRESULT hr = CreateGraphicsResources();
    if (SUCCEEDED(hr))
    {
        PAINTSTRUCT ps;
        BeginPaint(m_hwnd, &ps);
     
        pRenderTarget->BeginDraw();

        pRenderTarget->Clear( D2D1::ColorF(D2D1::ColorF::SkyBlue) );
        pRenderTarget->FillEllipse(ellipse, pBrush);

        hr = pRenderTarget->EndDraw();
        if (FAILED(hr) || hr == D2DERR_RECREATE_TARGET)
        {
            DiscardGraphicsResources();
        }
        EndPaint(m_hwnd, &ps);
    }
}

Интерфейс ID2D1RenderTarget используется для всех операций рисования. Метод программы OnPaint выполняет следующие действия:

  1. Метод ID2D1RenderTarget::BeginDraw сигнализирует о начале рисования.
  2. Метод ID2D1RenderTarget::Clear заполняет весь целевой объект отрисовки сплошным цветом. Цвет задается в виде D2D1_COLOR_F структуры. Для инициализации структуры можно использовать класс D2D1::ColorF . Дополнительные сведения см. в разделе Использование цвета в Direct2D.
  3. Метод ID2D1RenderTarget::FillEllipse рисует заполненный эллипс, используя указанную кисть для заливки. Эллипс задается центральной точкой и x- и y-радиусами. Если значения x- и y-radii совпадают, результатом будет круг.
  4. Метод ID2D1RenderTarget::EndDraw сигнализирует о завершении рисования для этого кадра. Все операции рисования должны размещаться между вызовами BeginDraw и EndDraw.

Методы BeginDraw, Clear и FillEllipse имеют тип возврата void . Если во время выполнения любого из этих методов возникает ошибка, сообщение об ошибке происходит через возвращаемое значение метода EndDraw . Метод CreateGraphicsResources показан в разделе Создание ресурсов Direct2D. Этот метод создает целевой объект отрисовки и сплошную кисть.

Устройство может буферизовывать команды рисования и откладывать их выполнение до вызова EndDraw . Вы можете заставить устройство выполнять все ожидающие команды рисования, вызвав ID2D1RenderTarget::Flush. Однако очистка может снизить производительность.

Обработка потери устройства

Во время выполнения программы используемое графическое устройство может стать недоступным. Например, устройство может быть потеряно при изменении разрешения экрана или при удалении видеоадаптера пользователем. В случае потери устройства целевой объект отрисовки также становится недействительным, а также все зависимые от устройства ресурсы, связанные с устройством. Direct2D сообщает о потере устройства, возвращая код ошибки D2DERR_RECREATE_TARGET из метода EndDraw . Если вы получили этот код ошибки, необходимо повторно создать целевой объект отрисовки и все ресурсы, зависящие от устройства.

Чтобы отменить ресурс, просто освободите интерфейс для этого ресурса.

void MainWindow::DiscardGraphicsResources()
{
    SafeRelease(&pRenderTarget);
    SafeRelease(&pBrush);
}

Создание ресурса может быть дорогостоящей операцией, поэтому не создавайте ресурсы для каждого сообщения WM_PAINT . Создайте ресурс один раз и кэшируйте указатель ресурса, пока ресурс не станет недействительным из-за потери устройства или пока этот ресурс больше не нужен.

Цикл отрисовки Direct2D

Независимо от того, что вы рисуете, программа должна выполнять цикл, аналогичный следующему.

  1. Создание независимых от устройств ресурсов.
  2. Отрисовка сцены.
    1. Проверьте, существует ли допустимый целевой объект отрисовки. В противном случае создайте целевой объект отрисовки и ресурсы, зависящие от устройства.
    2. Вызовите ID2D1RenderTarget::BeginDraw.
    3. Выдача команд рисования.
    4. Вызовите ID2D1RenderTarget::EndDraw.
    5. Если EndDraw возвращает D2DERR_RECREATE_TARGET, удалите целевой объект отрисовки и ресурсы, зависящие от устройства.
  3. Повторите шаг 2 всякий раз, когда нужно обновить или перерисовывать сцену.

Если целевым объектом отрисовки является окно, шаг 2 выполняется всякий раз, когда окно получает сообщение WM_PAINT .

Показанный здесь цикл обрабатывает потерю устройства, отменяя зависимые от устройства ресурсы и повторно создавая их в начале следующего цикла (шаг 2а).

Следующая

DPI и Device-Independent пикселей