Private Sub btnShadow_Click(sender As Object, e As RoutedEventArgs) _
Handles btnShadow.Click
UpdateImageSource(ImageEffect.Shadow)
End Sub
Private Sub CreateDeviceResources()
' create the Direct3D device
Dim actualLevel As D3D.FeatureLevel
Dim d3dContext As D3D.DeviceContext = Nothing
Dim d3dDevice = New D3D.Device(IntPtr.Zero)
Dim result = HResult.Ok
For i As Integer = 0 To 1
' use WARP if hardware is not available
Dim dt = If(i = 0, D3D.DriverType.Hardware, D3D.DriverType.Warp)
result = D3D.D3D11.CreateDevice(Nothing, dt, IntPtr.Zero,
D3D.DeviceCreationFlags.BgraSupport Or
D3D.DeviceCreationFlags.SingleThreaded,
Nothing, 0, D3D.D3D11.SdkVersion, d3dDevice,
actualLevel, d3dContext)
Next
result.CheckError()
d3dContext.Dispose()
'store the DXGI device (for trimming
'when the Application Is being suspended)
dxgiD = d3dDevice.QueryInterface(Of DXGI.Device)()
d3dDevice.Dispose()
' create a RenderTarget (DeviceContext for Direct2D drawing)
Dim d2dDevice = D2D.Device1.Create(d2dF, dxgiD)
Dim rt = D2D.DeviceContext1.Create(d2dDevice,
D2D.DeviceContextOptions.None)
d2dDevice.Dispose()
rt.SetUnitMode(D2D.UnitMode.Pixels)
d2dC = rt
' create built-in effects
shadow = D2D.Effects.Shadow.Create(rt)
affineT = D2D.Effects.AffineTransform2D.Create(rt)
compst = D2D.Effects.Composite.Create(rt)
End Sub
Private Sub DiscardDeviceResources()
shadow.Dispose()
affineT.Dispose()
compst.Dispose()
dxgiD.Dispose()
d2dC.Dispose()
End Sub
Private Sub UpdateImageSource(imageEffect__1 As ImageEffect)
Dim w As Integer = btmp.PixelWidth + marginLT + marginRB
Dim h As Integer = btmp.PixelHeight + marginLT + marginRB
Dim surfaceOffset As Point2L = Point2L.Empty
Dim dxgiSurface As DXGI.Surface = Nothing
Dim hr = HResult.Ok
' receive the target DXGI.Surface and offset for drawing
For i As Integer = 0 To 1
hr = sisNative.BeginDraw(New RectL(w, h),
surfaceOffset, dxgiSurface)
If (hr <> DXGI.ResultCode.DeviceRemoved _
AndAlso hr <> DXGI.ResultCode.DeviceReset) _
OrElse i > 0 Then
Exit For
End If
' try to recreate the device resources
' if the old GPU device was removed
DiscardDeviceResources()
CreateDeviceResources()
sisNative.SetDevice(dxgiD)
Next
hr.CheckError()
' the render target object
Dim rt = d2dC
' create the target Direct2D bitmap for the given DXGI.Surface
Dim bpTarget = New D2D.BitmapProperties1(New D2D.PixelFormat(
DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Premultiplied),
CSng(btmp.DpiX), CSng(btmp.DpiY),
D2D.BitmapOptions.Target Or D2D.BitmapOptions.CannotDraw)
Dim targetBmp = D2D.Bitmap1.Create(rt, dxgiSurface, bpTarget)
dxgiSurface.Dispose()
' associate the target bitmap with render target
rt.SetTarget(targetBmp)
targetBmp.Dispose()
' start drawing
rt.BeginDraw()
' clear the target bitmap
rt.Clear(Nothing)
' convert C1Bitmap image to Direct2D image
Dim d2dBitmap = btmp.ToD2DBitmap1(rt, D2D.BitmapOptions.None)
surfaceOffset.Offset(marginLT, marginLT)
' apply the effect
Select Case imageEffect__1
Case ImageEffect.Original
rt.DrawImage(d2dBitmap, surfaceOffset.ToPoint2F())
Exit Select
Case ImageEffect.Shadow
rt.DrawImage(ApplyShadow(d2dBitmap), surfaceOffset.ToPoint2F())
Exit Select
End Select
d2dBitmap.Dispose()
' finish drawing (all drawing commands are executed at that moment)
rt.EndDraw()
' detach and actually dispose the target bitmap
rt.SetTarget(Nothing)
' complete drawing on SurfaceImageSource
sisNative.EndDraw()
End Sub
Private Function ApplyShadow(bitmap As D2D.Bitmap1) As D2D.Effect
shadow.SetInput(0, bitmap)
shadow.BlurStandardDeviation = 5.0F
affineT.SetInputEffect(0, shadow)
affineT.TransformMatrix = Matrix3x2.Translation(20.0F, 20.0F)
compst.SetInputEffect(0, affineT)
compst.SetInput(1, bitmap)
Return compst
End Function
Private Sub MainPage_Unloaded(sender As Object, e As RoutedEventArgs)
DiscardDeviceResources()
btmp.Dispose()
d2dF.Dispose()
dwF.Dispose()
img.Source = Nothing
sisNative.Dispose()
sisNative = Nothing
End Sub