Ripple Effect in Windows 8.1 Store Applications (C++/CLI)

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.

1

Here’s the solution organization.

3

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.

image

WICImage is responsible for creating WIC factory.

image

RippleImageSource creates D2DFactory, device independent resources, and device dependent resources and fixes image size.

image

image

We only have one device independent resource: ComPtr<ISurfaceImageSourceNative> m_sisNative.

image

And we have several device-dependent resources:

image

image

image

Finally we create properties required to create the effect.

image

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.

image

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.

2

image

Pixel shader is set in the SetDrawInfo callback.

image

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

image

x_image her is our XAML control on a page.

image

First we prepare canvas, we grab render target off the GPU.

image

We clear the canvas.

image

And we draw using WICImage helper.

image

Here’s the code for WICImage.

image

And close the canvas.

image

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.

image

The system invokes render callback for us.

image

And we invoke the pixel shader.

image

image

This causes several callbacks of RippleEffect to be invoked.

   WICImage
   RippleEffect::PrepareForRender
     RippleEffect::UpdateConstants
   RippleEffect::MapInputRectsToOutputRect
   RippleEffect::MapOutputRectToInputRects

image

This is sent to the GPU.

image

Finally, here’s how our simple shader looks.

image

image

The code is available on MSDN here.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: