共用方式為


如何將效果套用至基本類型

本主題說明如何將一系列效果套用至Direct2DDirectWrite基本類型。

您可以使用 Direct2D 效果 API ,將效果圖形套用至 Direct2D 轉譯至影像所呈現的基本類型。 這裡的範例有兩個圓角矩形和文字 「Direct2D」。 使用 Direct2D 繪製矩形,並DirectWrite繪製文字。

內含文字 「direct2d」 的矩形。

使用 Direct2D 效果,您可以讓此影像看起來像下一個影像。 將 Gaussian Blur點反射光源算術複合複合 效果套用至 2D 基本類型,以在這裡建立影像。

套用數個效果之後,內含文字 「direct2d」 的矩形。

將矩形和文字轉譯為中繼表面之後,您可以使用這個做為影像圖形中 ID2D1Effect 物件的輸入。

在此範例中,將原始影像設定為 Gaussian Blur 效果 的輸入,然後將模糊的輸出設定為 點反射光源效果的輸入。 然後,此效果的結果會與原始影像複合兩次,以取得轉譯至視窗的最終影像。

以下是影像圖表的圖表。

效果圖表。

此效果圖表包含四個 ID2D1Effect 物件,每個物件都代表不同的內建效果。 您可以使用 ID1D1Factory1::RegisterEffect來註冊自訂效果,並以相同的方式建立和連接自訂效果。 此處的程式碼會建立效果、設定屬性,並連接稍早顯示的效果圖表。

  1. 使用ID2D1DeviceCoNtext::CreateEffect方法建立Gaussian 模糊效果,並指定適當的 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)
        );
    

    Gaussian 模糊效果會模糊影像的所有通道,包括 Alpha 色板。

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

    反射光源效果會使用輸入的 Alpha 色板來建立光源的高度地圖。

  3. 有兩個不同的複合效果,您可以使用 複合 效果和 算術複合。 此效果圖表會使用這兩者。

    建立 複合 效果,並將模式設定為D2D1_COMPOSITE_MODE_SOURCE_IN,這會輸出來源和目的地影像的交集。

    術複合 效果會根據 World Wide Web Consortium (W3) C 所定義的公式,為可調整向量圖形 (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. 最後,您會將輸入設定為適當的影像和點陣圖,以連接效果以形成圖形。

    第一個效果 Gaussian 模糊會從您呈現基本類型之中繼表面接收其輸入。 您可以使用 ID2D1Effect::SetInput 方法設定輸入,並指定 ID2D1Image 物件的索引。 Gaussian 模糊和 反射光源 效果只有單一輸入。 反射光源效果會使用 Gaussian 模糊的模糊色板

    複合算術複合效果有多個輸入。 若要確定影像以正確的順序組合在一起,您必須為每個輸入影像指定正確的索引。

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