Cómo aplicar efectos a primitivos

En este tema se muestra cómo aplicar una serie de efectos a Direct2D y DirectWrite primitivos.

Puedes usar la API de efectos de Direct2D para aplicar gráficos de efectos a primitivos representados por Direct2D en una imagen. El ejemplo aquí tiene dos rectángulos redondeados y el texto "Direct2D". Usa Direct2D para dibujar los rectángulos y DirectWrite para dibujar el texto.

rectángulos con el texto

Con los efectos de Direct2D, puedes hacer que esta imagen tenga un aspecto similar al de la imagen siguiente. Aplique los efectos Gaussian Blur, Point Specular Lighting, Arithmetic Composite y Composite a los primitivos 2D para crear la imagen aquí.

rectángulos con el texto

Después de representar los rectángulos y el texto en una superficie intermedia, puede usarlo como entrada para los objetos ID2D1Effect en el gráfico de imágenes.

En este ejemplo, establezca la imagen original como entrada en el efecto Desenfoque gaussiano y, a continuación, establezca la salida del desenfoque como entrada para el efecto de iluminación especular puntual. El resultado de este efecto se compone con la imagen original dos veces para obtener la imagen final que se representa en la ventana.

Este es un diagrama del gráfico de imágenes.

diagrama de gráfico de efectos.

Este gráfico de efectos consta de cuatro objetos ID2D1Effect , cada uno que representa un efecto integrado diferente. Puede crear y conectar efectos personalizados de la misma manera, después de registrarlos mediante ID1D1Factory1::RegisterEffect. El código aquí crea los efectos, establece las propiedades y conecta el gráfico de efectos mostrado anteriormente.

  1. Cree el efecto de desenfoque gaussiano mediante el método ID2D1DeviceContext::CreateEffect y especifique el CLSID adecuado. Los CLSID para los efectos integrados se definen en d2d1effects.h. A continuación, establezca la desviación estándar del desenfoque mediante el método 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)
        );
    

    El efecto de desenfoque gaussiano desenfoca todos los canales de la imagen, incluido el canal alfa.

  2. Cree el efecto de iluminación especular y establezca las propiedades. La posición de la luz es un vector de 3 valores de punto flotante, por lo que debe declararla como una variable independiente y pasarla al método 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)
        );
    

    El efecto de iluminación especular usa el canal alfa de la entrada para crear un mapa de altura para la iluminación.

  3. Hay dos efectos compuestos diferentes que puede usar el efecto compuesto y la composición aritmética. Este gráfico de efectos usa ambos.

    Cree el efecto compuesto y establezca el modo en D2D1_COMPOSITE_MODE_SOURCE_IN, que genera la intersección de las imágenes de origen y destino.

    El efecto compuesto aritmético compone las dos imágenes de entrada basadas en una fórmula definida por World Wide Web Consortium (W3C) para el estándar Scalable Vector Graphics (SVG). Cree una composición aritmética y establezca los coeficientes de la fórmula.

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

    Aquí se muestran los coeficientes del efecto compuesto aritmético .

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

    En este gráfico de efectos, ambos efectos compuestos toman la salida de los otros efectos y la superficie intermedia como entradas y los compone.

  4. Por último, conecte los efectos para formar el gráfico estableciendo las entradas en las imágenes y mapas de bits adecuados.

    El primer efecto, desenfoque gaussiano, recibe su entrada de la superficie intermedia en la que se representaron los primitivos. La entrada se establece mediante el método ID2D1Effect::SetInput y se especifica el índice de un objeto ID2D1Image . Los efectos de iluminación especular y desenfoque gaussiano tienen una sola entrada. El efecto de iluminación especular utiliza el canal alfa borroso del desenfoque gaussiano

    Los efectos compuestos y aritméticos tienen varias entradas. Para asegurarse de que las imágenes se reúnen en el orden correcto, debe especificar el índice correcto para cada imagen de entrada.

    // 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. Pase el objeto de efecto compuesto aritmético al método ID2DDeviceContext::D rawImage y procesa y dibuja la salida del grafo.

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