views:

285

answers:

3

I’m working on creating a full-screen 3-D app (based on Johnny Lee's Wii head tracking app) with some augmented reality features, and it seems that WPF is too slow to render even the simple models I’m using at a reasonable frame rate. I think the problem is that I need to change both the view and projection of the camera on just about every frame, because of the nature of the app (it uses a web cam to track your face, and uses that data to move the camera around and change its perspective).

I've spent a lot of time trying to narrow down the problem, and it's definitely related to the graphics, and not the speed of the head-tracking API that I'm using. Also, I recreated the app in XNA, and it seems to work fine there (28 FPS versus 9 in WPF). Finally, when I remove the "walls" or make the window much smaller (say, 800 x 600), WPF's performance greatly improves, which makes me think that the bottleneck is the graphics calculations.

As a result, I need to either find a new graphics back-end to work with, or find a way to make WPF much faster for this app. I’m mostly looking at DirectX and XNA, and possibly OpenGL. Any recommendations on which of these APIs would be best to use for this app in .NET? Or alternatively, any idea what I'm doing wrong in WPF that's slowing things down?

+1  A: 

I would check out SlimDX, a much thinner DirectX wrapper than XNA or WPF

The problem with changing the projection on every frame is that API's like XNA/WPF werent designed with this in mind, so were optimized to have projection set once in the initialization phase, then not again.

Neil N
Why? I can set my view/projection matrices on each frame in XNA without problems. They are just input to the shaders that does that calulations in hardware. Calculating the matrices themselves and updating those shaders is not a bottleneck.
Peter Lillevold
+2  A: 

I've not done enough with 3D in WPF to be able to say what could be causing the slowness, but I did notice that it's model datastructure isn't very efficient. While this might not be the cause it could be symptomatic of general slowness to the whole pipeline.

One thing that does spring to mind is that WPF is rendering the scene in software rather than using the hardware acceleration on the graphics card. The fact that you get better performance (though you don't say how much better) with a smaller window.

If you remove any textures from your model do you get better performance too?

I don't think it really matters whether you go for Direct3D or OpenGL - virtually all modern cards support them equally well. XNA is the obvious choice if you're sticking with .NET as it's integrated into Visual Studio - even the Express edition.

ChrisF
There is no "texture" per se. I'm just using the SolidColorBrush on all of my models.XNA is probably my first choice at the moment, assuming WPF isn't going to cut it. My ownly problem so far is that the way graphics work in XNA seems very odd to me, but maybe that's just a learning curve I need to get over.
Jonathan Schuster
@Jonathan - the texture idea was only a suggestion - it used to be one of the things that could trigger software rendering.
ChrisF
A: 

I would suggest a hybrid choice here: use WPF for what its good at (Windows UI, composition, etc) and use XNA to render the 3D. There are samples out there that demonstrates combining XNA with WinForms. It should be possible to do the same "trick" to render XNA onto surfaces in WPF.

Update: there are supposedly issues with using XNA directly with WPF. This thread indicates that using XNA with WinForms and then hosting the WinForms control in WPF is a workaround to these issues. I've not tested this myself though (yet).

Peter Lillevold
There are currently some issues embedding XNA in WPF, it has something to do with conflicting device properties from what I understand. The XNA and WPF folks are aware of the issue but I don't think it's been resolved yet. Using something like SlimDX though shouldn't have the same issues.
Bill Reiss
See my update. This could be a way around, but yeah, going with SlimDX is now probably the easiest bet.
Peter Lillevold