WPF 3.5 SP1 ve Pixel Shader efektlerinin kullanımı...

0 dakikada yazıldı

6413 defa okundu

Düzenle

.NET Framework 3.5 SP1 ile beraber gelen en büyük yeniliklerden biri de
PixelShader kullanımının artık WPF uygulamalarında rahat bir şekilde
mümkün olması. Kendi PixelShader efektlerinizi yazabileceğiniz gibi
hazır kütüphanelerden de faydalanabilirsiniz. Bu yazımızda içerisinde
hem normal PixelShader efektleri hem de geçiş efektleri barındıran
CodePlex üzerindeki Windows Presentation Foundation Pixel Shader
Effects Library
kütüphanesini kullanarak
efektlerin nasıl uygulandığını inceleyeceğiz.

Hazırlığımızı yapalım.

CodePlex üzerindeki Pixel Shader kütüphanesini kullanabilmemiz için
öncesinde bir de Shader Effects BuildTask ve şablonlarını kurmamız
gerek. Bu eklentiler doğrudan Pixel Shader efektlerinin
programlanmasında kullanılıyor. Biz kendi Pixel Shader efektlerimizi
programlamayacak olsak da diğer kütüphane bu eklentileri kullandığı için
bilgisayarımıza kurmamız şart.

WPF Futures içerisinde bulunan Shader Effects BuildTask and
Templates.zip
yüklemesini aşağıdaki adresten bilgisayarınıza
indirebilirsiniz.

http://www.codeplex.com/wpf/

İndirdiğiniz bu paket içerisindeki ShaderBuildTaskSetup.msi
dosyasını çalıştırarak hemen kurulumu tamamlayın. Sonrasında da
isterseniz Pixel Shader programlama için kullanılan şablonları da
bilgisayarınıza yükleyebilirsiniz. Bunun için yükleme paketindeki
Templates.zip dosyasını C:\Users\Daron\Documents\Visual Studio
2008
klasöre açmanız gerek. Bu klasör tabi ki sizin bilgisayarınızdaki
kullanıcı adına göre değişecektir.

Pixel Shader Effects Library

Sıra geldi Pixel Shader Effects Library paketini CodePlex üzerinden
indirmeye. Aşağıdaki adresten tüm paketi bilgisayarınıza indirip kaynak
kodları ile beraber yazılmış Pixel Shader efektlerini inceleyebilir
hatta paket içerisinde gelen örnek uygulamayı da kullanıp kaynak
kodlarını inceleyebilirsiniz.

http://www.codeplex.com/wpffx

Yükleme paketi içerisindeki Visual Studio Solution dosyasını açarsanız
karşınıza 3 ayrı proje gelecektir. "ShaderDemoApp" projesi klasik bir
WPF projesi. Bu proje birazdan bahsedeceğimiz iki projeyi referans
olarak alıp demo amacıyla hazırlanmış durumda. Ayrıca Solution
içerisinde bir ShaderEffectLibrary bir de TransitionEffects
adında projeler var. Bu projelerin her biri harici DLL kütüphaneleri
halinde Compile ediliyor. ShaderEffectLibrary içerisinde standart
PixelShader efektleri varken TransitionEffects içerisinde ise Pixel
Shader kullanılarak hazırlanmış geçiş efektleri var.

Bu paketlerini farklı projeler içerisinde kullanmak için ister
ihtiyacınız olan kütüphanenin projesini kendi solution'larınıza da
ekleyin ister örnek proje üzerinden bu kütüphaneleri Compile ederek
doğrudan DLL'lerini alarak farklı projelerde kullanın. Karar tamamen
size kalmış.

TransitionEffects Kullanımı

Beni ilk heyecanlandıran videolar arası geçiş efektleri olduğu için
hemen TransitionEffects kütüphanesinden başlayacağım. Yeni bir WPF
projesi yaratarak bir önceki adımda indirdiğimiz paket içerisinde
TransitionEffects projesini söz konusu WPF projesi ile aynı Solution
içerisine yerleştirdim. Sonrasında WPF projesine de sağ tıklayarak "Add
Reference" diyip TransitionEffects projesini WPF'e reference olarak
ekledim. Böylece tüm geçiş efektlerini kullanma şansımız olacak.

Videolar arası geçiş yapacağımız için iki ayrı videoyu göstermek üzere
uygulamama iki adet MediaElement ekliyorum.

<Window
x
:Class="Window1"

      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

      Title="Window1"

      Height="300"

      Width="300">

  <Grid>

    <MediaElement
x
:Name="Birinci"

                Source="Butterfly.wmv"

                Panel.ZIndex="1" />

    <MediaElement
x
:Name="Ikinci"

                Source="Bear.wmv"

                Opacity="1"

                Visibility="Visible"

                Panel.ZIndex="0" />

    <Button
HorizontalAlignment
="Right"

          Margin="0,0,8,8"

          VerticalAlignment="Bottom"

          Width="73"

          Height="27"

          Content="Button"

          x:Name="Dugme" />

  </Grid>

</Window>

İki MediaElement ve bir de Button olan formumuza ait XAML kodunu
yukarıda inceleyebilirsiniz. Bu noktada hemen dikkat etmemiz gereken
şeylerden biri MediaElement'lerin ZIndex özellikleri. Hangi videonun
arkada hangisinin önde olduğuna ZIndex ile karar verdim. Bunun
nedeni birazdan kod ile bu sıralamayı değiştirecek olmam.

Uygulama çalıştırıldığında her iki MediaElement de farklı videolar
oynatıyor olacaklar. Amacımız şu an önde olan MediaElement'ten
arkadakine doğru bir geçiş efekti yaratmak.

[VB]

Me.Ikinci.SetValue(Grid.ZIndexProperty, 2)

[C#]

this.Ikinci.SetValue(Grid.ZIndexProperty, 2);

İlk olarak arkadaki MediaElement'imizi düğmeye basıldığı anda öne
alıyoruz. Geçiş efektinin başlangıcında Ikinci adını verdiğimiz
MediaElement otomatik olarak görünmez hale gelecek ve sonrasında da
efekt ile ekranda gözükecek. Öne alma işlemini bitirdikten hemen sonra
animasyonumuzu hazırlıyoruz.

[VB]

Dim Anim As New
TransitionEffects.CloudRevealTransitionEffect

Dim da As New
DoubleAnimation(0.0, 1.0, New
Duration(TimeSpan.FromSeconds(2.0)), FillBehavior.HoldEnd)

da.AccelerationRatio = 0.5

da.DecelerationRatio = 0.5

Anim.BeginAnimation(TransitionEffect.ProgressProperty, da)

[C#]

TransitionEffects.CloudRevealTransitionEffect Anim = new TransitionEffects.CloudRevealTransitionEffect();

DoubleAnimation da = new DoubleAnimation(0.0, 1.0, new Duration(TimeSpan.FromSeconds(2.0)), FillBehavior.HoldEnd);

da.AccelerationRatio = 0.5;

da.DecelerationRatio = 0.5;

Anim.BeginAnimation(TransitionEffect.ProgressProperty, da);

Yukarıdaki kod içerisinde de görebileceğiniz gibi Anim adını
verdiğimiz animasyonumuz doğrudan TransitionEffects kütüphanesinden
CloudRevealTransitionEffect adındaki efektin ta kendisi. Tabi bu
efekte bir de DoubleAnimation ayarlamamız gerek, DoubleAnimation
içerisinde efektin Progress (İlerleme durumu) özelliğinin 0'dan 1'e
kadar geleceğini ve bu işlemin 2 saniye süreceği belirtiyoruz. Diğer
ayarlar efektin hızlanma ve yavaşlama etkenleri ile ilgili.

Son olarak BeginAnimation metoduna da Dependency'miz olan
ProgressProperty'yi ve DoubleAnimation nesnemizi veriyoruz. Toplamda
baktığımızda DoubleAnimation üzerinden efektin sürecinin uzunluğunu
belirleyerek efekti başlatmış olduk.

[VB]

Dim vb As New
VisualBrush(Me.Ikinci)

vb.Viewbox = New Rect(0, 0, Me.Ikinci.ActualWidth, Me.Ikinci.ActualHeight)

vb.ViewboxUnits = BrushMappingMode.Absolute

[C#]

VisualBrush vb = new VisualBrush(this.Ikinci);

vb.Viewbox = new Rect(0, 0, this.Ikinci.ActualWidth, this.Ikinci.ActualHeight);

vb.ViewboxUnits = BrushMappingMode.Absolute;

Efekt süregelirken ekrandaki boyama işleminin yapılabilmesi için bi
VisualBrush ayarlıyoruz. Bu VisualBrush doğrudan bizim
Ikinci adındaki efekte uğrayacak MediaElement'e bağlanıyor.
VisualBrush'ın genişlik ve yüksekliğini de ayarladıktan sonra artık
kendisini Anim değişkenimize teslim edebiliriz.

[VB]

        Anim.OldImage = vb

        Me.Ikinci.Effect = Anim

[C#]

Anim.OldImage = vb;

this.Ikinci.Effect = Anim;

OldImage özelliği üzerinden VisualBrush'ı da aktardıktan sonra
Ikinci adındaki MediaElement'e BitMapEffect olarak
animasyonumuzu eşitliyoruz. Hepsi bu kadar :) Yapının biraz karışık
olduğunu itiraf etmeliyim, Pixel Shader Effects kütüphanesinin kullanımı
ÇOK kolay değil fakat yaptığı işi daha önceleri nasıl yapabileceğimiz
ile karşılaştırırsak aslında gerçekten çok büyük bir yük kaldırdığını
söyleyebiliriz.

Aşağıdaki kodu çalıştırdığınızda istediğiniz geçiş efekti ile gerçek
zamanlı olarak iki video oynarken birbirleri arasında geçişler
yapabildiğinizi göreceksiniz.

[VB]

    Private Sub Dugme_Click(ByVal sender As Object,
ByVal e As System.Windows.RoutedEventArgs) Handles Dugme.Click

        Me.Ikinci.SetValue(Grid.ZIndexProperty, 2)

 

        Dim Anim As New
TransitionEffects.CloudRevealTransitionEffect

 

        Dim da As New
DoubleAnimation(0.0, 1.0, New
Duration(TimeSpan.FromSeconds(2.0)), FillBehavior.HoldEnd)

        da.AccelerationRatio = 0.5

        da.DecelerationRatio = 0.5

        Anim.BeginAnimation(TransitionEffect.ProgressProperty, da)

 

        Dim vb As New
VisualBrush(Me.Ikinci)

        vb.Viewbox = New Rect(0, 0,
Me.Ikinci.ActualWidth, Me.Ikinci.ActualHeight)

        vb.ViewboxUnits = BrushMappingMode.Absolute

 

        Anim.OldImage = vb

        Me.Ikinci.Effect = Anim

    End Sub

[C#]

        void Dugme_Click(object sender, RoutedEventArgs e)

        {

 

            this.Ikinci.SetValue(Grid.ZIndexProperty, 2);

 

            TransitionEffects.CloudRevealTransitionEffect Anim = new TransitionEffects.CloudRevealTransitionEffect();

 

            DoubleAnimation da =
new DoubleAnimation(0.0, 1.0, new Duration(TimeSpan.FromSeconds(2.0)), FillBehavior.HoldEnd);

            da.AccelerationRatio = 0.5;

            da.DecelerationRatio = 0.5;

            Anim.BeginAnimation(TransitionEffect.ProgressProperty, da);

 

            VisualBrush vb = new VisualBrush(this.Ikinci);

            vb.Viewbox = new Rect(0, 0, this.Ikinci.ActualWidth, this.Ikinci.ActualHeight);

            vb.ViewboxUnits = BrushMappingMode.Absolute;

 

            Anim.OldImage = vb;

            this.Ikinci.Effect = Anim;

 

        }

ShaderEffects Library Kullanımı

Bir önceki bölümde geçiş efektlerini kullanırken indirdiğimiz paket
içerisinden TransitionEffect projesini kopyalamıştık. Bu sefer de söz
konusu paketten ShaderEffects projesini kopyalıyoruz ve kendi
yarattığımız bir WPF projesi ile aynı Solution içerisine alıyoruz.
Sonrasında WPF projesine sağ tıklayarak "Add Reference" diyip
ShaderEffects projesini WPF'e reference olarak tanımlıyoruz. Böylece
artık WPF projemizde ShaderEffects kütüphanesini rahatlıkla
kullanabiliriz.

Örneğimizde hemen bir MediaElement yerleştirelim ve bu
MediaElement içerisinde oynatılan videolara Pixel Shader efektleri
uygulayalım.

<Window
x
:Class="Window1"

      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

      Title="Window1"

      Height="300"

      Width="300">

  <Grid>

    <MediaElement
x
:Name="Birinci"

                Source="Butterfly.wmv" />

  </Grid>

</Window>

Uygulamamız açıldığı gibi istediğimiz efekti MediaElement'e uygulamak
için aslında tek yapmamız gereken uygun efekti ayarları ile ürettikten
sonra Birinci adındaki MediaElement'in Effect özelliğine
eşitleyerek BitmapEffect olarak atamak.

[VB]

Dim Emboss As New
ShaderEffectLibrary.EmbossedEffect

Emboss.Amount = 20

Birinci.Effect = Emboss

[C#]

ShaderEffectLibrary.EmbossedEffect
Emboss = new ShaderEffectLibrary.EmbossedEffect();

Emboss.Amount = 20;

Birinci.Effect = Emboss;

Hepsi bu kadar. Onlarca efekt arasında istediğinizi seçip her efektin
kendine özel ayarlarını da yaptıktan sonra ister bu efektleri bir
MediaElement'e ister Image nesnesine bağlayabilirsiniz. Hatta dağa da
ileri gidip Container Element'lerine bile bu gibi efektler
verebilirsiniz.

Hepinize kolay gelsin.