Como aplicar efeitos a primitivos
Este tópico mostra como aplicar uma série de efeitos a primitivos Direct2D e DirectWrite.
Você pode usar a API de efeitos de Direct2D para aplicar grafos de efeito a primitivos renderizados por Direct2D a uma imagem. O exemplo aqui tem dois retângulos arredondados e o texto "Direct2D". Use Direct2D para desenhar os retângulos e DirectWrite para desenhar o texto.
Usando Direct2D efeitos, você pode fazer com que essa imagem se pareça com a próxima imagem. Aplique os efeitos Gaussian Blur, Point Specular Lighting, Aritmetic Composite e Composite aos primitivos 2D para criar a imagem aqui.
Depois de renderizar os retângulos e o texto em uma superfície intermediária, você pode usá-lo como entrada para objetos ID2D1Effect no grafo de imagem.
Neste exemplo, defina a imagem original como a entrada para o efeito Gaussian Blur e, em seguida, defina a saída do desfoque como a entrada para o efeito iluminação especular de ponto. O resultado desse efeito é composto com a imagem original duas vezes para obter a imagem final que é renderizada para a janela.
Aqui está um diagrama do grafo de imagem.
Esse grafo de efeito consiste em quatro objetos ID2D1Effect , cada um representando um efeito interno diferente. Você pode criar e conectar efeitos personalizados da mesma maneira, depois de registrá-los usando ID1D1Factory1::RegisterEffect. O código aqui cria os efeitos, define as propriedades e conecta o grafo de efeito mostrado anteriormente.
Crie o efeito de desfoque gaussiano usando o método ID2D1DeviceContext::CreateEffect e especificando o CLSID adequado. Os CLSIDs para os efeitos internos são definidos em d2d1effects.h. Em seguida, defina o desvio padrão do desfoque usando o 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) );
O efeito desfoque gaussiano desfoca todos os canais da imagem, incluindo o canal alfa.
Crie o efeito de iluminação especular e defina as propriedades. A posição da luz é um vetor de três valores de ponto flutuante, portanto, você deve declará-la como uma variável separada e passá-la para o 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) );
O efeito de iluminação especular usa o canal alfa da entrada para criar um mapa de altura para a iluminação.
Há dois efeitos compostos diferentes que você pode usar o efeito composto e a composição aritmética. Esse grafo de efeito usa ambos.
Crie o efeito composto e defina o modo como D2D1_COMPOSITE_MODE_SOURCE_IN, que gera a interseção das imagens de origem e de destino.
O efeito composto aritmético compõe as duas imagens de entrada com base em uma fórmula definida pelo W3C (World Wide Web Consortium) para o padrão SVG (Elementos Gráficos vetoriais escalonáveis). Crie uma composição aritmética e defina os coeficientes para a 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) );
Os coeficientes para o efeito composto aritmético são mostrados aqui.
D2D1_VECTOR_4F sc_arithmeticCoefficients = D2D1::Vector4F(0.0f, 1.0f, 1.0f, 0.0f);
Nesse grafo de efeito, ambos os efeitos compostos assumem a saída dos outros efeitos e da superfície intermediária como entradas e compõe-os.
Por fim, conecte os efeitos para formar o grafo definindo as entradas para as imagens e bitmaps adequados.
O primeiro efeito, desfoque gaussiano, recebe sua entrada da superfície intermediária para a qual você renderiza os primitivos. Defina a entrada usando o método ID2D1Effect::SetInput e especificando o índice de um objeto ID2D1Image . O desfoque gaussiano e os efeitos de iluminação especular têm apenas uma única entrada. O efeito de iluminação especular usa o canal alfa desfocado do desfoque gaussiano
Os efeitos compostos compostos e aritméticos têm várias entradas. Para garantir que as imagens sejam montadas na ordem certa, você deve especificar o índice correto para cada imagem 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());
Passe o objeto de efeito composto aritmético para o método ID2DDeviceContext::D rawImage e processa e desenha a saída do 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 ) );