I've created a WPF application using C# that renders about 50 3D elements and animates the camera in order to move around the scene.
While it all works, I've noticed as the camera moves, ugly video tearing occurs.
I'm well aware of the standard cause of tearing, ie the application is updating frames at a different rate from the monitor/adapter vertical sync.
I've also read that the default screen update rate in WPF is 60 frames per second and that on XP WPF updates without regard to the montior v-sync.
For certain scenes the tearing is less noticeable, but often it is distracting enough to be a real problem.
I'm really hoping there is a resolution, after all Windows Forms has had double buffering for years. Moving to WPF is actally a backward step for many types of application if there is no resolution.
So, on Windows XP, how can I configure WPF to remove tearing?
I'm looking for more helpful answers then "move to Vista". This is simply out of the question for many of the future users of this application.
No answers yet, surely with the number of WPF developers out there someone else has seen this problem?
In the meantime I've investigated/read some more and have come across the Timeline.DesiredFrameRate property.
With my display running at 50hz vertical refresh I tried setting this to 50 FPS in the hope this would brings things in sync. Unfortunately this had no effect on the tearing.
However, I did have to apply it to a single specific animation I created (in code) using BeginAnimation(). I'm not sure how this would affect a "global" framerate at all.
Instead, I would have expected to need to do this at a more global level, say on the viewport, however I couldn't find DesiredFramerate property on the viewport object.
Another area to look at could be the RenderCapability.Tier but I haven't had the time to look in detail yet.
[Update]
No solution but a useful tip. To set the DesiredFramerate globally (ie for all animations in the viewport) you can override the PropertyMetadata for the
Timeline.DesiredFrameRateProperty dependency property:
// Set the global desired framerate to 50 frames per second
Startup += delegate(object sender, StartupEventArgs e)
{
Timeline.DesiredFrameRateProperty.OverrideMetadata(typeof(Timeline),
new PropertyMetadata(50));
};
It's best to place this in the constructor of the standard WPF Application class.
Unfortunately this didn't solve my problem because even setting it to FPS, it must not be synced accurately enough with monitor v-sync.
It is handy to know about though, particularly if you have slow moving animations and want to save CPU usage by setting the FPS much lower then the default 60fps.
[Update]
Setting the DesireFrameRate to some very high value such as 100+ seems to reduce but not remove the flicker. One big drawback however is that the CPU (on my 4 yo PC) goes to 35%.
Related
I have made a very simple hypercasual game everything works fine but after some few minutes of gameplay, the fps goes from 60 to 50 even the phone gets heated up. Similar to this question. I tried profiling but just can't see anything off. Tried even removing some UI elements but still no luck. Tried various vsync settings. Also, I had used this to display the fps. Even without it, the lag can be seen. Even if I just open the game and do nothing then after 5 minutes the fps will become 50. If go back using the home button and re-enter the game then the fps becomes 60 again. Using unity 2018.2.6f1. Never experienced this behavior in my other Android games.
Basically it was a faulty custom vertex shader which was applied to a plane to change the background color which changed color over time. I had not used the mobile vertex color because I was not getting the desired output. But now I'll stick to the mobile one.
The two symptoms you observed are very much likely to be connected.
The phone might heat up, as you are using its full power, which in turn makes the throttling kick in, reducing the perform
I've had the EXACTLY same problem. I was trying to fix it for a very long time. You said something about faulty shaders you use. And this is the key to solve our problem.
I use a 2-color gradient as a BG, so I have to use a shader too. Due to the fact that I'm a total noob in the writing "shader-code", I have to find something in the Internet. And it was my biggest fail)
To fix the problem and remove this fps drop you should remove your gradient and shader attached to it from the scene. And try to find a more optimized shader for 2D-game (or you can always write your own one c:)
Hello: I am trying to create an app which will display a moving sphere. App will vary speed and direction. I've tried Adobe Flash but cannot get it smooth. Smoothness is essential in this case. So I am trying C#.
Initially, I can see that this can be implemented by:
1) Creating a PictureBox of a sphere, and using a Timer, change its coordinates. or
2) Using the this.paint function to draw a filled circle, and somehow, with a timer, erasing and redrawing it.
Can someone recommend the best path to take? I'll have a main menu where the user will chose speed/direction/how many etc... and then simply show the "game window" with the moving spheres. Any guidance would be much appreciated.
This is to be displayed on a PC only.
Thanks
-Ed
I just answered a similar question here.
NOTE: Depending on your needs, it is possible to achieve smooth animations under winforms (under certain conditions) though you are responsible for everything. wpf provides an animation framework but wpf is perhaps a milestone harder.
It probably does not matter should you pursue winforms first or WPF. You arguably could learn the basics under winforms then move over to wpf. wpf may require you to learn quite a bit before you can do anything.
Summary
Essentially what this does is to create an offscreen bitmap that we will draw into first. It is the same size as the UserControl. The control's OnPaint calls DrawOffscreen passing in the Graphics that is attached to the offscreen bitmap. Here we loop around just rendering the tiles/sky that are visible and ignoring others so as to improve performance.
Once it's all done we zap the entire offscreen bitmap to the display in one operation. This serves to eliminate:
Flicker
Tearing effects (typically associated with lateral movement)
There is a Timer that is scheduled to update the positions of all the tiles based on the time since the last update. This allows for a more realistic movement and avoids speed-ups and slow-downs under load. Tiles are moved in the OnUpdate method.
If you note in the code for Timer1OnTick I call Invalidate(Bounds); after animating everything. This does not cause an immediate paint rather Windows will queue a paint operation to be done at a later time. Consecutive pending operations will be fused into one. This means that we can be animating positions more frequently than painting during heavy load. Animation mechanic is independent of paint. That's a good thing, you don't want to be waiting for paints to occur. xna does a similar thing
Please refer to my full SO answer complete with sample code
Here are a few hints to get you going:
First you will need to come to a decision about which platform to target: WPF or Winforms.
Then you should know what to move across what; a nice Bitmap or just a circle across an empty background or a Bitmap or a Form with controls on it.
In Winforms both your approaches will work, esp. if you set a circular region see here for an example of that. (The part in the fun comment!)
And yes, a Timer is the way to animate the sphere. Btw, a Panel or even a Label can display an Bitmap just as well as a PictureBox.
For smooth movements make sure to set the Form.Doublebuffered=true, if you move across a Form. If you move across any other control (except a PictureBox or a Label) you will need to subclass it to get access to the DoubleBuffered property!
It is often also a good idea to keep the Location of a moving item in a variable as a PointF and use floats for its speed because this way you can fine grain the speed and Location changes and also the Timer Intervals!
I am working on an application in WPF using Vlc.DotNet. I was having an issue with the video playing back with a terrible frame rate on my laptop.
After some research I identified that the issue is related to the CPU throttling down. If the laptop power profile is in BatterySaver mode it has the issue. If I switch it to performance, everything works fine. It seems to me like in BatterySaver mode it allows the processor to throttle down, and for some reason doesn't throttle back up correctly when the application needs it to. Is there anyway I can fix this issue?
I tried setting the priority with the code below and it didn't seem to make a difference.
System.Diagnostics.Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
Vlc.DotNet updates and ImageSource with the next rendered image. I have this source bound to an Image on the GUI that displays it. I used the WPF Performance Kit and can see what is happening, but not why. As soon as it starts playing, AKA updating the image on the GUI at 30fps, the frame rate of the entire application drops down to around 5fps.
Have you tried switching to software rendering to avoid the bottleneck of CPU power downs? I know WPF uses a separate thread for rendering and I'm not sure if you can even access it from Process.Threads. What I've done in the past is attach to the power mode changed event and switched the mode dynamically like this so power mode changes don't switch to hardware rendering. Not sure if this will work as I don't what your specific bottleneck is, but hopefully this points you in a good direction.
I am tasked to write a .NET application that displays a slide-show with some information (words or images) and when the user sees certain items, s/he must immediately press space and the time of the key press must be recorded. The items will be displayed one after the other, for about 50ms. I need then to evaluate the difference between the timestamp of the keypress and and the one when the slideshow started (so I will know how long it took the user to react on the presented item). Edit: I must also record the time of the occurence of the special item.
I need to reduce any unpredictable lags that may occur as the application is running, so that the input processing is as realistic as possible, as well as to reduce any lags between the slides. Currently I am thinking of 3 approaches:
Write a standard Windows Forms (GDI+) application.
Write a WPF application
Write a DirectX-enabled windows forms application that utilizes the Tom Miller's Render loop concept (it is praised as effective in terms of performance).
Something else that you might suggest
I must clarify that I will not use advanced display techniques, special effects or designed for the purpose 3D environments - just plain text slides in different fonts and colours, or images. Unfortunately I cannot cite my sources, but I have read that Windows Forms and GDI+ cannot provide me with the desired accuracy. So, is WPF going to provide me with a better solution? Do I need to use the render loop, or some other approach. I am not experienced in such type of performance requirements for desktop applications, and all advices will be appreciated greatly.
I personally love WPF, but I would be very wary of using it for this application. It is not going to have the same time precision as GDI+ or DirectX. There are all sorts things you'll have to work with like the DispatchTimer and it just wasn't build for something like this. WPF is a whole set of gigantic abstractions on top of graphics and the farther you get away from the metal, you're introducing potential problems. If you want to put a video projected on top of a 3D sphere inside a combobox then WPF is the way to go, but if you need accuracy/precision on the scale you're talking, WPF is not the answer. I don't know where you read that WPF will provide you with better accuracy, I can practically guarantee that it will not.
DirectX would most likely be the most accurate in ensuring that a picture is only displayed for 50ms at a time. But GDI+ would be a decent alternative solution because it will make it easier to deal with text from a programming perspective.
Another consideration, screen refresh rates. yikes. if you do the math most LCDs have a 5ms response rate which is 10% of your allotted time. That and they only display at 60Hz. If you're displaying 20 pictures per second (50ms per picture) it is only going to be on the screen for 3 refresh cycles.
I hope this helps.
50 msec isn't long. Maybe encode and play the slideshow as a video?
I have an application which runs fullscreen on a high resolution display (1920x1080).
About 25% of the screen is a StackPanel that scrolls images across the screen.
(the X position is animated with double animation)
The scroll is very laggy and jumpy, and with visible tearing.
This is running on a brand new high-end gaming laptop, running Win7 64bit.
I don't understand why the performance is so poor. Am I doing something wrong? Does this kind of animation run on the CPU or GPU? Is there a smarter way to scroll images across the screen?
WPF can be hardware-accelerated, but only on newer video card drivers. Some of the onboard, out of box drivers, will default back to software rendering, which can feel really slow and clunky. As for the tearing, that's a normal video card setting, called V-Sync. I would try updating the video card drivers to a proprietary driver (nVidia, AMD, etc.), and enabling vertical sync on the card.
You can check to see if it falls into software, or hardware rendering using the methods explained here.
If that doesn't resolve the issue, the only other possibility I can think of is your animation/rendering is not synced to the GUI.
See this msdn article for more details.
A trick that I've seen that can get around this issue is to place a 3D object on your page, view it side on and rotate it e.g. for 4 images have a cube with an image set to each side.
Yes the rotation still requires GPU and processor time but it is taken care of internally by the WPF animation and so doesn't require interaction with code behind once set rolling.