choppy graphics when drawing xna on a winforms control - winforms

I'm drawing an xna project on a winforms Control using the following code:
this.GraphicsDevice.Present(MainForm.GamePanelHandle);
This winforms control is placed on a Form that is maximized, hiding the taskbar using the following code:
this.FormBorderStyle = FormBorderStyle.None;
this.WindowState = FormWindowState.Maximized;
Unfortunately this makes the xna code run choppily as opposed to letting xna create its own window and setting it fullscreen. As I understand this is because the graphics card needs to pay attention to the whole windowing system and other active forms.
Are there any tricks I could use to make xna run faster when embedded on a fullscreen winforms Form?

Have you tried setting:
DoubleBuffered = true;
in your form's load handler ?
This will at least help out with the Form's painting. i'm not sure if it will have an effect on the XNA stuff but it's worth a try.

If you're displaying a maximized form and even hiding the taskbar, why not go to true fullscreen mode? What are you gaining by using windowed mode that just looks like fullscreen? You are certainly reducing yur framerate by doing this.
In my experience windowed mode works best when your window (XNA control) is just a smaller part of the overall form. This is really the point of windowed mode since it allows you to interact with other standard form controls at the same time.
Going to fullscreen mode gives your application exclusive access to the video framebuffer
and avoids overhead of dealing with windows GDI / GDI+ in windowed mode.
Also, if you're using an integrated graphics card (ie. less powerful) you'll need every GPU and CPU processing cycle you can get.
If you absolutely have to stick to windowed mode, I've found that the smaller the window, the better the performance. In windowed mode, reducing the window size has as big an impact on framerate as reducing the complexity of the scene being displayed does.
You could also consider setting the process priority of your application to AboveNormal or possibly even High. Be aware that doing this will cause other applications to respond more slowly while your application is running. To avoid system instability it is also recommended avoid using RealTime.
In .NET this can be done using the Process.PriorityClass property on a process:
// Set the current application (process) priority to high.
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;

Related

When using a DirectX-based API with WPF (i.e. SlimDX, SharpDX, etc.) can you do sub-window-sized controls?

In our WPF application, we have a need to display about 64 real-time level meters for an audio application. The tests we've thrown at WPF, even when rendering basic primitives as efficiently as we can still show it to be nowhere near where our application needs to be, often times bogging down the main thread so much to the point that it's non-responsive to input.
As such, we have to go with something more optimized for graphics performance such as DirectX (via SlimDX or SharpDX) or OpenGL/ES (via Atlas which converts it to DirectX calls.)
My question is if it's possible to create multiple, small DirectX-based areas, each representing an individual meter, or for that matter, is that even the right approach? I was under the understanding that you have to run it as at a minimum, the entire window, not a portion thereof.
The issues I see with the latter are airspace issues wherein you can't have WPF content in front of DirectX content in the same window, and we really don't want to have to redo all of our controls in DirectX since for the other non-meter 95% of our UI WPF is great!
I have read that you can render DirectX to a brush, then use that inside WPF, or using the WriteableBitmap class which gives you direct access to the buffers WPF then uses in its Render thread, both of which don't seem to suffer from the Airspace issues, but that seems we'd be right back at the same place with WPF being the bottleneck since it still has to do the rendering.
We are of course going to dedicate a few weeks to sample applications testing all of the above, but I'm wondering if I'm even headed in the right direction, and/or if there are any caveats we can avoid by talking to people with experience doing something like this to avoid common pitfalls, etc. As such, any comments will be appreciated.
I'm hoping we can perhaps even start a wiki somewhere to discuss this topic as it seems to be a popular one, albeit spread all over the place making it hard for new entrants to get the information they seek.
With wpf / d3d interop, You should always try to create the smallest number of interop calls. So you should prefer rendering all 64 level meters in a single render target (also it allows you to batch your primitive rendering and draw everything in the smallest number of gpu calls).
you should try to use the D3DImage API that allows you to share your own D3D texture with the wpf renderer.
If WPF can't really handle these 64 moving bars, you could go with a single D3DImage and use Direct3D9 for rendering all bars at once directly to it. For your specific scenario, you shouldn't have any performance problem.

Rendering from WPF's internals to a Directx application

I have a WPF application that is intended for overlaying a HUD in a live stream. The original idea was to create a plugin for xsplit (a popular application for presenting live streams) to display the content of the WPF application. The problem with this approach is that rendering a bitmap to the COM interface of xsplit is far to damaging in CPU performance to release the application (As I believe there are issues in xsplit's COM interface as well as using RenderTargetBitmap taxing the CPU).
I've been looking at directly rendering the overlay into the game (The target DirectX application) because it provides a number of benefits. Chiefly it circumvents the performance problems in xsplit, but also opens the application up to a variety of streaming and capture applications.
I'm not a very experienced with DirectX but I think this is the outline of the solution
Initialize the WPF application and capture WPF's Direct3d device (via this method)
Find and hook the target DirectX application's EndScene call (using EasyHook+Slimdx)
Render contents of the WPF Device's surface ontop of hooked DirectX application
The main question I have is how to accomplish step 3 using SlimDX. I'd hope a solution could somehow reuse the surface and not rely on copying as the goal is to not impact the performance of the hooked application. I'd also like to be able to limit the region and support transparency. I am also wondering if using WPF's Direct3d device in the hooked DirectX application's device might cause any instabilities.
Any insight would be appreciated, thank you.
I'm trying to do the same. What I've found so far is that you can render your wpfvisualtree to a bitmap and afterwards write is bitmap to the d3d device captured in point 2.
void render(Direct3D.Device device)
{
wpfRenderTargetBitmap.Render(WpfVisualTree);
wpfRenderTargetBitmap.CopyPixels(devicePtr);
}
I didnt test this yet but I think I'm on the right track with this. The only problem I now have is that I loose all interactivity from my window. Button clicks and so on will no longer be captured...
Any help on that would be nice.

Can DirectX cause WPF applications to render very slowly?

Suppose I have a DirectX game running in full screen and a WPF application running in the background; in addition, the CPU isn't at high levels, and the game's frame rate is good (i.e., 60 FPS).
Is there anything that might cause the WPF application to render itself slowly? (i.e., at 3-5 FPS)
Wikipedia says: "Rather than relying on the older GDI subsystem, WPF utilizes DirectX."
Therefore, my conclusion is that, if DirectX is busy rendering the game, and the graphic card pipelines are full, the WPF application will probably have poor performance. But admittedly I have no knowledge of the prioritization that goes on behind the scenes, but I'm guessing that a background (that is, non active) window will have less priority.

Fast WPF Image Control

I'm looking for an Image control for WPF which can rapidly change images. The built in WPF one is quite slow for the image sizes im using (scaled). I only need about ~3 FPS. I have considered dropping to WinForms and even D3D but I'm not sure thats the best way.
Can anyone suggest something?
WPF's Image control uses the native "Windows Imaging" and Direct3D subsystems of Windows to do all its dirty work, so if used with the right paremeters it will be pretty much as fast as anything you will find.
I suspect the problem is that your settings are causing Windows Imaging load the image at full resolution, then having Direct3D scale it. The solution to this is to do the scaling as you load the image by setting DecodePixelHeight and DecodePixelWidth on the BitmapImage you are using as an ImageSource.
Another technique that many graphics apps use to speed things up is to preload the images in the background. For example, the Windows picture viewer automatically starts loading the next image as soon as the current image is shown.
If you are preloading images, consider doing it in a separate thread. Also make sure you use BitmapCacheOption.OnLoad when you create the BitmapImage or the preloading won't actually occur (the default is OnDemand).

Creating high performance animations in WPF

I'm in a situation that requires many animations with effects like transparency to be applied but when there are about 10 of them running, my application slows down to a grinding halt! :(
I also, tried implementing a particle like effect using a frame by frame manual animation using the CompositionTarget.Rendering event, which changed an Image's Source property at a given framerate. Again, this works fine for the first few instances of the particles on the screen, but when more and more get added I need it to stay performance wise, which is always a tough ask for any application
I was wondering if anyone has any experience using pixel shaders in WPF for animations, or perhaps custom writeablebitmap's for animations?
I basically need to palm off most of the animation processing to the GPU if possible...
Thanks for any help you can give!
Cheers,
Mark
If you want performance you should think about using XNA instead.
Then, you can add the XNA project into your WPF app

Resources