Udostępnij za pośrednictwem


Jak renderować w interwałach klatek z użyciem CompositionTarget

Aparat animacji WPF oferuje wiele funkcji do tworzenia animacji opartej na ramce. Istnieją jednak scenariusze aplikacji, w których potrzebujesz bardziej szczegółowej kontroli nad renderowaniem na podstawie ramki. Obiekt CompositionTarget zapewnia możliwość tworzenia niestandardowych animacji na podstawie wywołania zwrotnego dla ramki.

CompositionTarget jest klasą statyczną reprezentującą powierzchnię wyświetlania, na której jest rysowana aplikacja. Zdarzenie Rendering jest wywoływane za każdym razem, gdy scena aplikacji zostanie narysowana. Szybkość renderowania klatek to liczba losowania sceny na sekundę.

Uwaga

Aby zapoznać się z kompletnym przykładem kodu przy użyciu metody CompositionTarget, zobacz Using the CompositionTarget Sample (Korzystanie z przykładu CompositionTarget).

Przykład

Zdarzenie Rendering jest uruchamiane podczas procesu renderowania WPF. W poniższym przykładzie pokazano, jak zarejestrować delegata EventHandler w metodzie statycznej Rendering w pliku CompositionTarget.

// Add an event handler to update canvas background color just before it is rendered.
CompositionTarget.Rendering += UpdateColor;
' Add an event handler to update canvas background color just before it is rendered.
AddHandler CompositionTarget.Rendering, AddressOf UpdateColor

Możesz użyć metody obsługi zdarzeń renderowania, aby utworzyć niestandardową zawartość rysunku. Ta metoda obsługi zdarzeń jest wywoływana raz na ramkę. Za każdym razem, gdy platforma WPF marshaluje utrwalone dane renderowania w drzewie wizualnym na wykresie sceny kompozycji, wywoływana jest metoda obsługi zdarzeń. Ponadto jeśli zmiany w drzewie wizualnym wymuszają aktualizacje grafu sceny kompozycji, wywoływana jest również metoda obsługi zdarzeń. Pamiętaj, że metoda obsługi zdarzeń jest wywoływana po obliczeniu układu. Można jednak zmodyfikować układ w metodzie obsługi zdarzeń, co oznacza, że układ zostanie obliczony jeszcze raz przed renderowaniem.

W poniższym przykładzie pokazano, jak udostępnić niestandardowy rysunek w metodzie obsługi zdarzeń CompositionTarget . W tym przypadku kolor Canvas tła obiektu jest rysowany z wartością koloru na podstawie położenia współrzędnych myszy. Jeśli przeniesiesz mysz wewnątrz Canvaselementu , jego kolor tła zmieni się. Ponadto obliczana jest średnia szybkość klatek na podstawie bieżącego czasu, który upłynął i łączna liczba renderowanych ramek.

// Called just before frame is rendered to allow custom drawing.
protected void UpdateColor(object sender, EventArgs e)
{
    if (_frameCounter++ == 0)
    {
        // Starting timing.
        _stopwatch.Start();
    }

    // Determine frame rate in fps (frames per second).
    long frameRate = (long)(_frameCounter / this._stopwatch.Elapsed.TotalSeconds);
    if (frameRate > 0)
    {
        // Update elapsed time, number of frames, and frame rate.
        myStopwatchLabel.Content = _stopwatch.Elapsed.ToString();
        myFrameCounterLabel.Content = _frameCounter.ToString();
        myFrameRateLabel.Content = frameRate.ToString();
    }

    // Update the background of the canvas by converting MouseMove info to RGB info.
    byte redColor = (byte)(_pt.X / 3.0);
    byte blueColor = (byte)(_pt.Y / 2.0);
    myCanvas.Background = new SolidColorBrush(Color.FromRgb(redColor, 0x0, blueColor));
}
' Called just before frame is rendered to allow custom drawing.
Protected Sub UpdateColor(ByVal sender As Object, ByVal e As EventArgs)

    If _frameCounter = 0 Then
        ' Starting timing.
        _stopwatch.Start()
    End If
    _frameCounter = _frameCounter + 1

    ' Determine frame rate in fps (frames per second).
    Dim frameRate As Long = CLng(Fix(_frameCounter / Me._stopwatch.Elapsed.TotalSeconds))
    If frameRate > 0 Then
        ' Update elapsed time, number of frames, and frame rate.
        myStopwatchLabel.Content = _stopwatch.Elapsed.ToString()
        myFrameCounterLabel.Content = _frameCounter.ToString()
        myFrameRateLabel.Content = frameRate.ToString()
    End If

    ' Update the background of the canvas by converting MouseMove info to RGB info.
    Dim redColor As Byte = CByte(_pt.X / 3.0)
    Dim blueColor As Byte = CByte(_pt.Y / 2.0)
    myCanvas.Background = New SolidColorBrush(Color.FromRgb(redColor, &H0, blueColor))
End Sub

Możesz dowiedzieć się, że niestandardowe rysowanie działa z różną szybkością na różnych komputerach. Dzieje się tak, ponieważ niestandardowy rysunek nie jest niezależny od szybkości klatek. W zależności od uruchomionego systemu i obciążenia tego systemu Rendering zdarzenie może być wywoływane inną liczbę razy na sekundę. Aby uzyskać informacje na temat określania możliwości i wydajności sprzętu grafiki dla urządzenia z uruchomioną aplikacją WPF, zobacz Graphics Rendering Tiers (Warstwy renderowania grafiki).

Dodawanie lub usuwanie delegata renderowania EventHandler podczas wyzwalania zdarzenia zostanie opóźnione do momentu zakończenia wyzwalania zdarzenia. Jest to zgodne ze sposobem MulticastDelegateobsługi zdarzeń opartych na środowisku uruchomieniowym języka wspólnego (CLR). Należy również pamiętać, że zdarzenia renderowania nie są wywoływane w żadnej określonej kolejności. Jeśli masz wielu EventHandler delegatów, które opierają się na określonej kolejności, należy zarejestrować jedno Rendering zdarzenie i multipleksować delegatów w odpowiedniej kolejności samodzielnie.

Zobacz też