I am currently developing a software that involves real-time rendering of performance metrics in graph and chart forms. I need to acquire data, process data and render an image as fast as possible. My backend is in C++, and I am at a point where I have to make a choice regarding the front end.
Given my backend is in C++, I was inclined to go with MFC. The other alternative is to go with WPF C# for frontend and interop with my C++ backend. I read recently that WPF provides for hardware acceleration, this should help me achieve a high frame rate. Does MFC hardware accelerate its graphics too? Does hardware acceleration even matter?
Given WPF's hardware acceleration, does that make WPF the most efficient alternative for graphics in my case?
WPF provides hardware acceleration using DirectX 9 I believe. However for line graphs the limiting factor is the amount of interface elements. We are creating a program in WPF that displays sEMG data real-time using Telerik charts. These can be configured to use direct2d acceleration under the hood which cranks up the performance a bit if you have a lot of datapoints. It's still jerky though because you cannot control the render thread of WPF.
It kind of depends on the amount of features you need in the graph. If the priority is to have silky smooth real-time display don't go with WPF.
Visual Studio 2010 added classes to MFC to support using Direct2D rendering from MFC programs.
To use Direct2D, you start by calling EnableD2DSupport() in your View's OnCreate (technically, I suppose it doesn't have to be in OnCreate, but that's the usual place). Then you'll receive AFX_WM_DRAW2D messages when the D2D display context needs updating, so you'll normally want to add a handler for that, and respond to it by rendering your content as needed.
Another possibility to consider would be to use an existing control to draw your graphs. There are quite a few around, including some that are free with quite liberal licensing. Just for example, CodeProject has a number of Charting controls, a few of which use D2D for their drawing, and quite a few more that don't.
Honestly, I'd be a little surprised at charts having information being updated fast enough for drawing speed to make a huge difference as a rule though. In most typical cases, the real limit will be the user's ability to comprehend what you're drawing. A user simply can't watch 100 different graphs each being updated at (say) 60 Hz, and have much hope of deriving much real meaning from most of them. In most cases, the real challenge isn't to draw more data faster, but to provide better ways for the user to focus on the few things they can follow at a time, and (for example) draw their attention to important changes when needed.
Related
I am creating a privately consumed custom map overlay.
I cannot use an open source server like MapServer, because of the sheer volumes of data and the format that it is in.
Originally it was going to be a client-side solution that pushed an ArrayBuffer to the client and render the data on a map using WebGL, however we later found out that our users' PCs would be minus a GPU, so they cannot smoothly run the WebGL rendering.
So I took the concepts and applied them to OpenTK - I created an IIS server handler that creates an OpenTK instance, and renders a requested tile.
For prototype's sake, it works - however I feel this is not the best solution.
What is the most efficient way to render out tiles?
I would love to pre-render the tiles, but there are just too many datasets (adding 1000 more per day!) to be able to efficiently do this.
Is OpenTK a good route to go down (because of the hardware acceleration it can take advantage of?), or is there too much overhead in setting up an instance?
Or are the C# Graphics libraries a better route to learn and use?
Or even - is it worth ditching IIS and C# all together and using a different language/framework for serving the images?
Your server only has a single GPU, so launching multiple instances of OpenTK will be significantly slower than launching a single instance and queuing tiles for rendering. Context switching inside the GPU drivers hurts. The latest version of OpenTK starts up in milliseconds so that should not be a problem (but you will have to measure.)
I would like to write a simple ray tracer using WPF. It is a learning project and thus I favour configurability over performance (otherwise I'd go for C++).
I still want relatively fast pixel drawing. A previous question on StackOverflow contains code to achieve this in WPF, by obtaining a GDI bitmap. From the relatively little I know about Windows programming,
GDI is slow
DirectX is fast
WPF uses DirectX underneath (not sure which parts of WPF though)
Is it possible to obtain pixel-level access using DirectX (not GDI) through the WPF Canvas (or similar)?
I will also consider suggestions for incorporating DirectX API calls within a WPF window (alongside other WPF controls) if that is possible.
Thanks in advance.
Interesting, but with raytracing, writing the pixels to the screen will (should) not be the slow part. You can use WriteableBitmap for the purpose, though. It's certainly quick enough for what you want.
http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap.aspx
(For info, I use it in this emu/IDE - http://0x10c-devkit.com/ - and it can refresh a low res display with great performance. There's the source to that on the github repository, the LEM1802 plugin.)
Ah, this bit: https://github.com/kierenj/0x10c-DevKit/blob/master/PluginAPI/NyaElektriska.LEM1802/GPU.cs - see UpdateDisplay.
Another solution is WriteableBitmapEx. It extends the builtin WriteableBitmap.
There is an open Source Project Called Direct Canvas wich is A hardware accelerated, 2D drawing API that supports vector graphics, multimedia files, extensible pixel shaders, blending modes and more!
http://directcanvas.codeplex.com/
Demo http://www.youtube.com/user/jdollah69#p/u
I need to speed up my image viewer, and wondering if I should be looking into creating my own DirectX control to do so.
My image viewer displays medical images. They can be pretty large. We're talking 55mb when it comes to mammography. The pixel data is 16bit greyscale stored in a ushort array. Without getting into the gory details, my current approach is loading the pixel data into an ImageSource, and using the WPF Image control.
I've never done anything with DirectX. Is it worth diving into it? Would it be any faster than the native WPF stuff? If so how significantly? Or, should I just forget about DirectX and look into areas where I can improve my current approach?
Before somebody says so, I know WPF utilize DirectX. I'm wondering If removing the WPF layer and writing the DirectX myself will improve performance.
I have some experience drawing multi-gigabyte satellite and chart imagery. Working with imagery around 55MB should probably work okay even without trying to optimize it too much. You haven't really given enough detail to recommend one alternative over the other, so I will give my opinion on the pros and cons.
Using 2D windows APIs will be the simplest to implement and should always be fast enough if you don't need to rotate and simply want to display an image and zoom and pan around. If you treat it as one large image the performance will not be as good when you zoom out if you are drawing with halftoning to give a nice smooth image. This is because it will effectively have to read all 55mb of image every time it draws.
To get around this performance issue you can make multiple bitmaps, effectively mip-mapping your image. As you zoom out you can pick the reduced resolution image closest to the resolution you are trying to draw . If you are not familiar with mip-mapping here is a Wikipedia link:
http://en.wikipedia.org/wiki/Mipmap
Implementing it with DirectX will be 10x as difficult. Different graphics hardware has different maximum texture sizes. Most likely you will need to break your image up in to multiple textures to draw and you will also have to keep track of render states, viewing matrices, etc.
However, if you do use DirectX, you can implement lots of real-time photo adjustments You can do real-time rotation by simply adjusting view matrices. You can do real-time contrast, brightness, gamma, and sharpness easily in a pixel shader.
There are two other API's I might suggest. If you are willing to limit yourself to Vista or later then Direct2D would be a little simpler than Direct3D. Also if you ever will need to implement it on a non-windows platform I would suggest using OpenGL instead. My current project is in Direct3D because a few years ago when we started it OpenGL was falling behind and I didn't forsee the popularity of Android devices. I now wish we had used OpenGL instead.
Try profiling to see where WPF is spending its time. Are you displaying the images at their native resolution? If not it might be worthwhile to do some preprocessing and create 1/2 resolution versions.
I've been writing a small desktop gadget-type application that displays scrolling text along the bottom of the screen (Similar to the old CNN news ticker), however the performance of GDI is just unsatisfactory (As high as 8-12% on a quad core and 20% on a single core) even after I've attempted to clean out bottlenecks.
I was considering using OpenGL instead to render everything, but I don't know if that is a reasonable option to require users to have hardware acceleration for a tiny app like this.
Does anybody have any input on this?
If you're comfortable with using OpenGL and your intended users are happy with the additional dependencies that OpenGL brings then I say go for it. :)
In terms of staying with GDI, I'd make sure you're rendering the text a few times as possible (through such techniques as rendering to bitmap and just scrolling that instead).
If neither one of those two options sounds appealing then there's always DirectX.
You could write the app in WPF and let WPF handle the acceleration for you (it's backed by DirectX).
I wouldn't want to install open gl for a program like that. You say that you "attempted" to eliminate the bottlenecks, but it does not sound like you succeeded. Like lzcd mentioned, there are other ways to scroll text than to repaint it constantly. Why not just draw to a bitmap and scroll that?
I'm trying to visualise a graph and allow people to play with it. I found the excellent Graph# library that can create an initial layout so that part is covered. Now I need to make a control that actually draws it and provides the necessary interactivity.
Graph# comes with a nice visualiser itself, however I don't like it because it is written in WPF (while my app is WinForms), and because I want to add some more interactivity options, which would require quite a remake of it anyway.
The graphs I'm drawing will routinely be pretty large, at about 100 vertices and the same amount of edges (the graphs will be trees 99% of time). That means that the resulting rendering can be up to 2000px by 2000px and even more. The users should be able to zoom in and out, scroll, highlight and drag vertices and edges, and get some popups with additional info when hovering the cursor above a vertex.
I'm worried that the standard System.Drawing might not be able to deliver a decent speed for this. I would like the dragging/zooming/scrolling operations to be smooth, and the popups should open with a little animation as well. Something like 20fps should be a necessity.
I know I can try to speed things up by pre-rendering a lot of the elements and keeping them as bitmaps in memory - but that would probably take up lots of RAM, and I'm still not sure if it would deliver the necessary performance.
What are your thoughts?
"Premature optimization is the root of all evil"
GDI+ can be great for your needs. Don't go and buy 3rd party libraries before you know you even need them.
I've done a thousand polygons on a 1000x800 pixel bitmap and redrawn it completely at over 100 frames per second, using just GDI+
That being said, if you have a lot of drawing to do, and your resolution is big.. Some of the 3rd party drawing libraries can go WAY beyond what managed GDI is capable of.
I recommend leaving Graph# alone, and just hosting it in your Windows Forms application.
The performance you will receive will be much better than trying to reimplement it in System.Drawing.
GDI+ will be plenty fast enough for what you're doing, especially if (as it sounds from your description) everything you're drawing is rectangles and vertical/horizontal lines. Polygons and non-linear shapes are a bit slower, but not much (the speed difference is partially dependent on the SmoothingMode of your Graphics object). Drawing cached Bitmaps with resizing is also quite fast, although it can slow down significantly if you use a high-quality InterpolationMode setting.
As a benchmark, I wrote a .Net Compact Framework GPS application for Windows Mobile that rendered about 10,000 lines on the screen in realtime. This only achieved a frame rate of a few frames per second, but the processing power on a Smartphone is, of course, way less than a modern PC.