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


Применение эффектов к примитивам

В этом разделе показано, как применить ряд эффектов к Примитивам Direct2D и DirectWrite.

Api эффектов Direct2D можно использовать для применения графов эффектов к примитивам, отображаемым Direct2D, к изображению. В приведенном здесь примере есть два скругленные прямоугольника и текст "Direct2D". Используйте Direct2D для рисования прямоугольников и DirectWrite для рисования текста.

прямоугольники с текстом direct2d внутри.

С помощью эффектов Direct2D можно сделать это изображение похожим на следующее изображение. Чтобы создать изображение, примените эффекты Gaussian Blur, Point Specular Lighting, Arithmetic Composite и Composite к двухмерным примитивам.

применяются прямоугольники с текстом

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

В этом примере задайте исходное изображение в качестве входных данных для эффекта размытия Гауссиана , а затем задайте выходные данные размытия в качестве входных данных для эффекта точечного зеркального освещения. Результат этого эффекта затем композитируется с исходным изображением дважды, чтобы получить окончательное изображение, которое отображается в окне.

Ниже приведена схема графа изображений.

диаграмма эффектов.

Этот граф эффектов состоит из четырех объектов ID2D1Effect , каждый из которых представляет отдельный встроенный эффект. Пользовательские эффекты можно создавать и подключать таким же образом после их регистрации с помощью ID1D1Factory1::RegisterEffect. Приведенный здесь код создает эффекты, задает свойства и соединяет граф эффектов, показанный ранее.

  1. Создайте эффект размытия Gaussian , используя метод ID2D1DeviceContext::CreateEffect и указав соответствующий идентификатор CLSID. Идентификаторы CLSID для встроенных эффектов определены в d2d1effects.h. Затем задается стандартное отклонение размытия с помощью метода ID2D1Effect::SetValue .

    // Create the Gaussian Blur Effect
    DX::ThrowIfFailed(
        m_d2dContext->CreateEffect(CLSID_D2D1GaussianBlur, &gaussianBlurEffect)
        );
    
    // Set the blur amount
    DX::ThrowIfFailed(
        gaussianBlurEffect->SetValue(D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, sc_gaussianBlurStDev)
        );
    

    Эффект размытия Гауссов размывает все каналы изображения, включая альфа-канал.

  2. Создайте эффект зеркального освещения и задайте свойства. Положение света представляет собой вектор из 3 значений с плавающей запятой, поэтому его необходимо объявить как отдельную переменную и передать в метод SetValue .

    // Create the Specular Lighting Effect
    DX::ThrowIfFailed(
        m_d2dContext->CreateEffect(CLSID_D2D1PointSpecular, &specularLightingEffect)
        );
    
    DX::ThrowIfFailed(
        specularLightingEffect->SetValue(D2D1_POINTSPECULAR_PROP_LIGHT_POSITION, sc_specularLightPosition)
        );
    
    DX::ThrowIfFailed(
        specularLightingEffect->SetValue(D2D1_POINTSPECULAR_PROP_SPECULAR_EXPONENT, sc_specularExponent)
        );
    
    DX::ThrowIfFailed(
        specularLightingEffect->SetValue(D2D1_POINTSPECULAR_PROP_SURFACE_SCALE, sc_specularSurfaceScale)
        );
    
    DX::ThrowIfFailed(
        specularLightingEffect->SetValue(D2D1_POINTSPECULAR_PROP_SPECULAR_CONSTANT, sc_specularConstant)
        );
    

    Эффект зеркального освещения использует альфа-канал входных данных для создания карты высоты для освещения.

  3. Существует два разных составных эффекта, которые можно использовать как составной эффект, так и арифметический составной. В этом графе эффектов используются оба варианта.

    Создайте составной эффект и задайте режим D2D1_COMPOSITE_MODE_SOURCE_IN, который выводит пересечение исходного и целевого изображений.

    Арифметический составной эффект состоит из двух входных изображений на основе формулы, определенной консорциумом W3C для стандарта МАСШТАБируемой векторной графики (SVG). Создайте арифметический состав и задайте коэффициенты для формулы.

    // Create the Composite Effects
    DX::ThrowIfFailed(
        m_d2dContext->CreateEffect(CLSID_D2D1Composite, &compositeEffect)
        );
    
    DX::ThrowIfFailed(
        compositeEffect->SetValue(D2D1_COMPOSITE_PROP_MODE, D2D1_COMPOSITE_MODE_SOURCE_IN)
        );
    
    DX::ThrowIfFailed(
        m_d2dContext->CreateEffect(CLSID_D2D1ArithmeticComposite, &m_arithmeticCompositeEffect)
        );
    
    DX::ThrowIfFailed(
        m_arithmeticCompositeEffect->SetValue(D2D1_ARITHMETICCOMPOSITE_PROP_COEFFICIENTS, sc_arithmeticCoefficients)
        );
    

    Здесь показаны коэффициенты для арифметического составного эффекта.

    D2D1_VECTOR_4F sc_arithmeticCoefficients   = D2D1::Vector4F(0.0f, 1.0f, 1.0f, 0.0f);
    

    В этом графе эффектов оба составных эффекта принимают выходные данные других эффектов и промежуточную поверхность в качестве входных и композитных их.

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

    Первый эффект, гауссовское размытие, получает входные данные от промежуточной поверхности, на которую были отрисованы примитивы. Входные данные задаются с помощью метода ID2D1Effect::SetInput и указания индекса объекта ID2D1Image . Эффекты размытия и зеркального освещения имеют только один вход. Эффект зеркального освещения использует размытый альфа-канал гауссовского размытия

    Составной и арифметический составные эффекты имеют несколько входов. Чтобы убедиться, что изображения собраны в правильном порядке, необходимо указать правильный индекс для каждого входного изображения.

    // Connect the graph.
    // Apply a blur effect to the original image.
    gaussianBlurEffect->SetInput(0, m_inputImage.Get());
    
    // Apply a specular lighting effect to the result.
    specularLightingEffect->SetInputEffect(0, gaussianBlurEffect.Get());
    
    // Compose the original bitmap under the output from lighting and blur.
    compositeEffect->SetInput(0, m_inputImage.Get());
    compositeEffect->SetInputEffect(1, specularLightingEffect.Get());
    
    // Compose the original bitmap under the output from lighting and blur.
    m_arithmeticCompositeEffect->SetInput(0, m_inputImage.Get());
    m_arithmeticCompositeEffect->SetInputEffect(1, compositeEffect.Get());
    
  5. Передайте объект арифметического составного эффекта в метод ID2DDeviceContext::D rawImage , и он обрабатывает и рисует выходные данные графа.

        // Draw the output of the effects graph.
        m_d2dContext->DrawImage(
            m_arithmeticCompositeEffect.Get(),
            D2D1::Point2F(
                (size.width - sc_inputBitmapSize.width) / 2,
                (size.height - sc_inputBitmapSize.height) / 2 + sc_offset
                )
            );