The sample is a Windows 8.1 application demonstrating simple DirectX effect.
This effect will produce a sinusoidal wave across a loaded image, like in a picture below. The code is from the patterns & practices DirectXRipple sample where I upgraded it to VS13, removed deprecated code, and cleaned it up a little.
Here’s the solution organization.
Step 1. Initialization
We need to prepare several things for the effect to work, these are the following 4 classes:
WICImage ImageSource RippleImageSource RippleEffect
And here is the execution sequence:
App::App App::OnLaunched ---> MainPage::OnNavigatedTo WICImage::WICImage ImageSource::ImageSource RippleImageSource::RippleImageSource RippleEffect::Register ImageSource::CreateDeviceIndependentResources RippleImageSource::CreateDeviceResources ImageSource::CreateDeviceResources ImageSource::SetDpi RippleEffect::CreateRippleImpl RippleEffect::RippleEffect RippleEffect::Initialize BasicReaderWriter::BasicReaderWriter() BasicReaderWriter::ReadData RippleEffect::GetInputCount <--- MainPage::OnNavigatedTo
In the page that will show the image, we grab hardcoded width/height and set WICImage and RippleImageSource.
WICImage is responsible for creating WIC factory.
RippleImageSource creates D2DFactory, device independent resources, and device dependent resources and fixes image size.
We only have one device independent resource: ComPtr<ISurfaceImageSourceNative> m_sisNative.
And we have several device-dependent resources:
Finally we create properties required to create the effect.
Before we continue, we have to create Get and Set methods for each binding.
We are done with setting the GPU device. At this point the execution environment will call back into CreateRippleImpl function that we provided.
Next sequence of callbacks are all initiated by the execution environment. Initialize function is responsible for loading shaders, in this case a single pixel shader. Note that we prepare HLSL pixel shader and Visual Studio compiles it for us into “*.cso” format.
Pixel shader is set in the SetDrawInfo callback.
Step 2. Load an image
Here’s the sequence:
WICImage ---> MainPage::OnLoadImageClicked <--- MainPage::OnLoadImageClicked WICImage::LoadImage ---> MainPage::DrawImage ImageSource::BeginDraw ImageSource::Clear ImageSource::DrawImage WICImage::DrawBitmap ImageSource::EndDraw <--- MainPage::DrawImage
x_image her is our XAML control on a page.
First we prepare canvas, we grab render target off the GPU.
We clear the canvas.
And we draw using WICImage helper.
Here’s the code for WICImage.
And close the canvas.
Step 3. Apply effect
Here’s the sequence:
WICImage ---> MainPage::OnPointerPressed <--- MainPage::OnPointerPressed MainPage::OnRenderDisplaySurface RippleImageSource::Ripple RippleImageSource::UpdateRipple RippleImageSource::RenderRipple
First, we set pointer position and initial effect timestamp.
The system invokes render callback for us.
And we invoke the pixel shader.
This causes several callbacks of RippleEffect to be invoked.
WICImage RippleEffect::PrepareForRender RippleEffect::UpdateConstants RippleEffect::MapInputRectsToOutputRect RippleEffect::MapOutputRectToInputRects
This is sent to the GPU.
Finally, here’s how our simple shader looks.
The code is available on MSDN here.