Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WPF: What is the best way to achieve continuous rendering? #16

Open
trmcnealy opened this issue Jun 24, 2022 · 1 comment
Open

WPF: What is the best way to achieve continuous rendering? #16

trmcnealy opened this issue Jun 24, 2022 · 1 comment

Comments

@trmcnealy
Copy link

Remove the Timer from the "MainWindow" and replace it with.

private void Checkbox1_Checked(object     sender, RoutedEventArgs e) => CompositionTarget.Rendering += CompositionTarget_Rendering;
private void Checkbox1_Unchecked(object   sender, RoutedEventArgs e) => CompositionTarget.Rendering -= CompositionTarget_Rendering;
private void CompositionTarget_Rendering(object? sender, EventArgs e)
{
    SkElement1.InvalidateVisual();
}
@swharden
Copy link
Owner

swharden commented Jun 24, 2022

Hi @trmcnealy,

Thanks for this suggestion! I'm not very familiar with the pros and cons of using CompositionTarget.Rendering vs a timer for drawing graphics. A quick search advises timers are superior for limiting frame rate or implementing physics simulations where models should progress at a standard rate. This may favor the use of timers since many of the other projects on https://swharden.com/csdv/ (e.g., boids) would benefit from a constant speed.

EDIT: A more extensive search reveals some people recommend the opposite!

This discussion is worth including on the page though, so I'll create a new page comparing/contrasting these methods and link to it from all the relevant WPF pages.

Note that the web page being referenced is

which references project code that lives here:

public partial class MainWindow : Window
{
readonly DispatcherTimer Timer1 = new();
public MainWindow()
{
InitializeComponent();
Timer1.Interval = System.TimeSpan.FromMilliseconds(10);
Timer1.Tick += Timer1_Tick;
}
private void SKElement_PaintSurface(object sender, SkiaSharp.Views.Desktop.SKPaintSurfaceEventArgs e)
{
ICanvas canvas = new SkiaCanvas() { Canvas = e.Surface.Canvas };
canvas.FillColor = Colors.Navy;
canvas.FillRectangle(0, 0, (float)SkElement1.ActualWidth, (float)SkElement1.ActualHeight);
canvas.StrokeColor = Colors.White.WithAlpha(.5f);
canvas.StrokeSize = 2;
for (int i = 0; i < 100; i++)
{
float x = Random.Shared.Next((int)SkElement1.ActualWidth);
float y = Random.Shared.Next((int)SkElement1.ActualHeight);
float r = Random.Shared.Next(5, 50);
canvas.DrawCircle(x, y, r);
}
}
private void SKElement_SizeChanged(object sender, SizeChangedEventArgs e) => SkElement1.InvalidateVisual();
private void Button_Click(object sender, RoutedEventArgs e) => SkElement1.InvalidateVisual();
private void Timer1_Tick(object? sender, System.EventArgs e) => SkElement1.InvalidateVisual();
private void Checkbox1_Checked(object sender, RoutedEventArgs e) => Timer1.Start();
private void Checkbox1_Unchecked(object sender, RoutedEventArgs e) => Timer1.Stop();
}

It sounds like CompositionTarget.Rendering is an event that fires at the rate of vsync (usually 60 Hz) and this topic is discussed on several pages:

@swharden swharden changed the title [Suggestion] (projects\maui-graphics\QuickstartWpf) WPF: What is the best way to achieve continuous rendering? Jun 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants