I have developed a quite large application using MFC. Naturaly, I used GDI for drawing, CCmdTarget for event routing, and the document-view architecture.
It was a convenient development path.
Now, the client is interested in converting this application to .Net.
I would prefer (and they too) writing the new product in C#.
The application displays and interacts with thousands of graphic objects, so
I figured going with GDI+, although seems natuaral, can cause performance issues,
So I am thinking of using OpenGL, specifically - OpenTK - as the graphics library (it's 2D).
I know that OpenGL works differently that these Windows APIs, which rely on Invalidation of portion of the screen. OpenGL has a rendering loop which constantly draws to the screen.
My question is:
Is this an acceptable way to go, thinking of:
performance - will the users need special graphics cards (hardware?). It is graphics intensive, but it's not a high-end game
printing and print preview - are these things complex to achienve?
multiple selection and context menus
Is this library goes well inside windows forms?
I don't think so. Use WPF if you can or DirectX if you can't.
I know it might not be fair but if I'm programming on .NET (microsoft) on windows (microsoft) I'd rather use DirectX ... which is also from microsoft.
As a side note: don't reinvent the wheel. Recoding user controls in open-gl can be very time consuming, if you do make sure you have a good reason.
In my experience developing CAD-like software, the benefits of OpenGL and DirectX are fast depth testing, smooth rotation and panning, lighting and powerful texture capabilities. Obviously there are other benefits but, despite what most tutorials would lead you to believe, implementing a rendering system using either of these APIs is a significant undertaking and should not be taken lightly.
Specifically:
If it is a 2D app and you already have it implemented in GDI then switching to GDI+ will be much easier. Additionally, on modern hardware, 2D GDI or GDI+ can be about as fast as 2D OpenGL or DirectX. And ultimately, the end-user probably won't notice the difference, especially with double buffered support in GDI+.
You do not need (and probably don't want) a continuous rendering loop for your app. In OpenGL and DirectX you can explicitly invalidate the window when your scene changes.
If you go with OpenGL or DirectX you will need to consider putting your objects into display lists or vertex arrays (buffers) for fast drawing. This is not difficult but managing objects in this way adds complexity to the system and will most likely significantly change the architecture of your rendering system.
Printing in either OpenGL or DirectX can also be tedious. On the one hand you can render to a bitmap and print that out. However, for high quality images you may want vectorized images instead, which are difficult to produce with either of these rendering frameworks.
I would also stay away from writing GUIs in OpenGL or DirectX...unless you're really looking for a challenge ;~)
Finally, and this is just an annoyance from an install perspective, the Managed DirectX run-time library that must be installed on the user's machine is around 100 MB.
I have no experience with C#, but I have once built a layer system for a drawing program that used openGL for rendering.
To make this layer I asked openGL for the current framebuffer and converted it to an image to use as a texture under the current canvas. So I guess from there its pretty easy to go to printing and print preview.
Direct X and Open GL much faster than GDI+.
You can also use an TAO framework as an alternative to OpenTK.
Related
I know WPF encapsulates DirectX, but I learned that I can used it to render DirectX or User32
Is DirectX the default renderer when I drag controls to the Window?
If not, how do I force it to render using User32?
Do I need to render the whole Window using User32 if so, or just my control?
Life before WPF:
It will be inevitable not to look back and see that standard window applications reply on two well worn parts of the Windows OS to create its user interface.
a) User32: provides familiar windows look and feel for element.
b) GDI/GDI +: provides drawing support for rendering shapes, text, images etc,
Does WPF render using DirectX or User32?
WPF changes all this and is fundamentally different from window forms. WPF’s underlying technology isn’t GDI/GDI+, instead it uses DirectX. So WPF uses DirectX no matter what type of user interface we create. So it’s like whether we are creating complex 3D graphics or just drawing a button, all the drawing work have to pass through DirectX pipeline. Since WPF relies on DirectX, now we can take advantage of hardware acceleration as well, which means this will hand off much work as possible to the GPU(graphics processing unit) which is dedicated processor on video card, and our CPU(central processing unit) could do some rest.
Does WPF rely on User32?
WPF still relies on User32 for certain services, such as handling and routing input and sorting out which application owns which portion of screen real estate. However, all the drawing is funneled through DirectX.
This is the most significant change in WPF. WPF is not a wrapper for GDI/GDI+. Instead, it’s a replacement—a separate layer that works through DirectX.
Can WPF run without DirectX?
WPF has a dependency on the DirectX runtime. However, both DirectX and
WPF have their own software fallback modes so that, in the absence of
suitable graphics hardware and/or drivers, software rendering will be
used instead. Some graphically intensive features will also be
unavailable when software rendering. WPF allows you to check the
rendering tier that it's running under and tailor the UI to suit
the current environment.
Also I suggest you have a quick read of HAL vs HEL to understand that different Graphics cards determine what can be done via DirectX Hardware or software.
Figure 1. The architecture of DirectX and its relationship to Win32.
In Figure 1, you may notice that there are two layers under DirectX called the HEL (Hardware Emulation Layer) and the HAL (Hardware Abstraction Layer). Here's the deal: DirectX is a very forward-looking design, so it assumes that advanced features are implemented by the hardware. However, if the hardware doesn't support some feature, what happens? This is the basis of the dual-mode HAL and HEL design.
The HAL, or Hardware Abstraction Layer, is the "to the metal" layer. It talks directly to the hardware. This layer is usually the device driver from the vendor, and you communicate to it directly through generic DirectX calls. The bottom line is that HAL is used when the feature you're requesting is supported directly by the hardware and thus is accelerated. For example, when you request a bitmap to be drawn, the hardware blitter does the work rather than a software loop.
The HEL, or Hardware Emulation Layer, is used when the hardware doesn't support the feature that you're requesting. Let's say that you ask the video card to rotate a bitmap. If the hardware doesn't support rotation, the HEL kicks in and software algorithms take over. Obviously, this is slower, but the point is that it does not break your program. It will still work—just slower. In addition, the switching between the HAL and HEL is transparent to you. If you ask DirectX to do something and the HAL does it directly, the hardware will do it. Otherwise, a software emulation will be called to get the job done with HEL.
Refs:
http://vishalnayan.wordpress.com/2011/05/20/windows-presentation-foundation-what-why-and-when/
http://www.yaldex.com/games-programming/0672323699_ch05lev1sec1.html
You can force the Application to use software rendering by setting the ProcessRenderMode to SoftwareOnly.
RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly;
However this is done on the process level and I am not sure if it can be done per Element
If I'm looking to create a game that doesn't necessarily run full screen, but simply needs to feature 2D/3D graphics somewhere in a portion of the screen, what's my best approach?
Some specific questions could be:
What component would the rendered area use?
Are there any game libraries I could leverage for the rendered area?
What would be the most "pure" or "canonical" stack according to Microsoft to use here?
Omega --
Visual Studio 2010 and 2012 are Both WPF apps. WinRT is for Tablets / Mobile. WPF is certainly NOT outdated.
If I were you I wouldn't render everything out the way canvas forces you to, it might be a better approach to have the center item be a UI element named Frame, which is the base element for all UI related content in WPF.
In this way you would be able to leverage all of the possible types of controls in the Frame whether you decided that An ImageSourceType or Canvas is more applicable to a particular features of the game.
Depending on how you want to draw graphics, you could use (but are by no means limited to):
Canvas - which would be totally appropriate for slow moving games. This way you get the benefit of the various WPF layout routines and can define objects inside the scene in XAML/vectors as well.
WPF supports 3D graphics (using Direct3D on the backend) so you could probably set up an orthogonal projection matrix and treat it like a Direct3D context (with the WPF API). I don't have enough experience to know how slow this is compared to D3D, but it's certainly easier (built-in "scene graph" like support from the XAML architecture, for instance).
If you want to go whole-hog with Direct3D you could use SlimDX, which has a WPF shim that I've used in the past, as well as another third party control. There may be other libraries available as well.
Direct blitting to/from a Bitmap using WriteableBitmap (see WriteableBitmapEx for a third-party version with a much friendlier API) or similar.
There are probably a lot of other options too. My preference would be for using Canvas initially if it's a slow-paced game that doesn't need super-fast frame rates (the layout work does incur a fairly substantial overhead, but it's less work and may be easier to get looking exactly the way you want).
If you want absolute control and speed, use D3D through SlimDX, but this is a pretty hefty learning curve if you're new to it.
can anyone suggest any alternative to GDI?
The reason is that I have data that updates rapidly and GDI doesn't support that kind of render velocity... I've tried SharpDX & SlimDX, but none seems to work properly (can't force them to draw on form without errors)
Update 1: I'm developing in C#
Update 2: Data is binded to Visual Studio 2010 default Charts control. A lot of code has been written to add functionality & lags were discovered after large amount of data incoming. Reason is that I need compatibility with .NET Framework 4 & Windows XP and higher.
After spending a lot of time investigating, I've discovered that SlimDX and SharpDX have strict requirements to videocard, drivers, and problems running on Windows XP.
GDI is software only rendering, as well as GDI+ which handles alpha channel for transparency rendering. These two libraries are really limited and slow compared to a GPU based one.
My suggestion is that you should invest the time to implement a SharpDX Direct2D based drawing engine. I never heard about the issue you talked about with forms, I use SharpDX with Winforms and WPF and everything's going great!
If speed is the most important criteria, then you'll have to invest time into a GPU based rendering engine, GDI is way to slow and not adapted to real-time rendering.
Honestly I find it strange that GDI doesn't suffice in that context but there are a lot of alternatives: you could go for DirectDraw for complete power, GDI+ for more advanced manipulations and options, or even external softwares like GTK+.
I know WPF is more complex an flexible so could be thought to do more calculations. But since the rendering is done on the GPU, wouldn't it be faster than Winforms for the same application (functionally and visually)?
I mean when you are not running any games or heavy 3d rendering, the GPU isn't doing heavy work, right? Whereas the CPU is always busy.
Is this a valid assumption or is the GPU utilization of WPF a very minor operation in its pipeline?
EDIT: The application that I am interested is a 3d modeling and animation software, where you have 3d viewports to navigate and edit the scene, and objects inside the scene. But I want to use WPF because of its modern architecture, and it's from scratch.
EDIT2: Also for my purposes I will use DirectX hands down for the app itself because of the high end requirements of the software. As for people using lower end or computers without a dedicated GPU, that's OK since they aren't not in my primary customer area. Just like other high end 3d software for film and games, it will be understandable to require a powerful computer to fully benefit from the application.
Provided the machine has a GPU, you'll get better rendering performance in WPF.
We have a large desktop application that we wrote in WinForms, and are now porting to WPF. We've witnessed much better rendering performance, particularly when resizing windows or redrawing controls.
We've also found that WPF "controls" are more lightweight than WinForm controls. If I recall right, WPF controls do not necessarily require an operating system handle, and don't register for Windows window messages via WndProc, at least not independently.
For your case, since you're building a 3d modeling app, which kind of assumes some 3d hardware on the machine, you should absolutely use WPF over WinForms.
For the app scenario you describe, I would expect WPF to outperform WinForms for 3D work on a full featured GPU by a wide margin.
The difference between the application types is more than just the rendering the 3D vector pipeline. WPF's internal architecture is radically different than WinForms, specifically designed to overcome the caveats learned from years of prior experience with the Windows GDI and WinForms apps.
(WinForms is a relatively thin wrapper around Windows GDI and User model that was originally created in the late 1980's. The Windows User control model has evolved over the past 25 years, but the core architectural patterns are largely unchanged.)
For example, WPF always separates UI rendering from application logic. When the WPF window goes to draw something, the actual rendering happens on a background thread. The refreshed visuals are flipped to the display during the video retrace interval, so you don't get partial blits or "tearing" artifacts on screen.
WinForms does none of this. If you render to DirectX or OpenGL surfaces in a WinForms app, you have to do the work of flipping the video page and making sure it happens at the right time to avoid screen tearing artifacts.
Wpf's default controls are GPU aware and can be custom styled with glows and transparency and whatnot all GPU accelerated. WinForms controls do not benefit significantly from GPU features, since about the only things WinForms (Windows User controls) uses for rendering are 2D bitblit and rectangle fill. Glows, transparency, animations are all possible with WinForms, but you have to do all the work to implement them.
In WPF, UI slickness is mostly a matter of designing and styling to get WPF to do it for you. In WinForms, you have to push the pixels yourself.
This is a really tough question to answer.
A huge portion of WPF performance is your GPU. A good GPU works wonders for making WPF perform well. WPF can be very performant. If your requirements are to have a decent GPU, since it's a 3D modeling program, you'll probably find WPF performance to be as good or better than Windows Forms - though this really depends on what you're using.
That being said, it's usually difficult to compare - mostly because WPF allows you to add a lot of visual effects that people tend to never even attempt in Windows Forms. Many WPF applications "seem" faster even though they're actually slower in some instances because of extra visual clues.
That being said, if you have a LOT of controls, WPF can actually outperform Windows Forms by a fair amount. In Windows Forms, each control requires a separate window handle, and receives its own message sets. With a lot of controls, this can actually slow things down pretty dramatically.
The real question here should be is WPF perf. "good enough" for your application. If you're doing a 3D modeling application, chances are WPF will not be your bottleneck- it should be fine.
For 3D modeling, WPF is clearly a lot better choice than WinForms -- but it's still a long ways from ideal. Winforms has no (direct) support for 3D rendering at all, and WPF has some. For a program that's aimed primarily toward 3D rendering, however, you might be better off with something dedicated more specifically to 3D rendering tasks, such as OpenGL or Direct3D.
On their own, neither of those provides a huge advantage over WPF, but unless what you're doing is fairly specialized, I wouldn't use those directly though. I'd use something like OpenSceneGraph or Ogre3D, that can use either of those for its rendering, but provides a much higher-level interface and does more to manage rendering your scene.
Either or both of these probably could use WPF for the actual drawing -- but I'm pretty sure neither one does, at least currently. I don't know whether they ever will either -- they might, but I doubt it's a real priority, since they already support OpenGL and Direct3D. For their purposes WPF provides little advantage.
Seeing as WPF actually uses DirectX under the hood and the fact that you use XAML to specify DirectX objects, WPF is by far the easiest solution.
Example coding a camera in xaml:
<PerspectiveCamera x:Key="Camera"
Position="0, 0, 4"
LookDirection="0, 0, -4"
UpDirection="0, 1, 0"
FieldOfView="30"/>
Is there another way to render graphics in C# beyond GDI+ and XNA?
(For the development of a tile map editor.)
SDL.NET is the solution I've come to love. If you need 3D on top of it, you can use Tao.OpenGL to render inside it. It's fast, industry standard (SDL, that is), and cross-platform.
Yes, I have written a Windows Forms control that wraps DirectX 9.0 and provides direct pixel level manipulation of the video surface.
I actually wrote another post on Stack Overflow asking if there are other better approaches: Unsafe C# and pointers for 2D rendering, good or bad?
While it is relatively high performance, it requires the unsafe compiler option as it uses pointers to access the memory efficiently. Hence the reason for this earlier post.
This is a high level of the required steps:
Download the DirectX SDK.
Create a new C# Windows Forms project and reference the installed
Microsoft DirectX assembly.
Initialize a new DirectX Device object with Presentation Parameters
(windowed, back buffering, etc.) you require.
Create the Device, taking care to record the surface "Pitch" and
current display mode (bits per pixel).
When you need to display something, Lock the backbuffer
surface and store the returned pointer to the start of surface
memory.
Use pointer arithmetic, calculate the actual pixel position in the
data based on the surface pitch,
bits per pixel and the actual x/y pixel coordinate.
In my case for simplicity I am sticking to 32 bpp, meaning setting a pixel is as simple as: *(surfacePointer + (y * pitch + x))=Color.FromARGB(255,0,0);
When finished drawing, Unlock the back buffer surface. Present the surface.
Repeat from step 5 as required.
Be aware that taking this approach you need to be very careful about checking the current display mode (pitch and bits per pxiel) of the target surface. Also you will need to have a strategy in place to deal with window resizing or changes of screen format while your program is running.
Managed DirectX (Microsoft.DirectX namespace) for faster 3D graphics. It's a solid .NET wrapper over DirectX API, which comes with a bit of performance hit for creating .NET objects and marshalling. Unless you are writing a full featured modern 3D engine, it will work fine.
Window Presentation Foundation (WPF) (Windows.Media namespace) - best choice for 2D graphics. Also has limited 3D abilities. Aimed to replace Windows Forms with vector, hardware accelerated resolution-independent framework. Very convenient, supports several flavours of custom controls, resources, data binding, events and commands... also has a few WTFs. Speed is usually faster than GDI and slower than DirectX, and depends greatly on how you do things (seen something to work 60 times faster after rewriting in a sensible way). We had a success implementing 3 1280x1024 screens full of real-time indicators, graphs and plots on a single (and not the best) PC.
You could try looking into WPF, using Visual Studio and/or Expression Blend. I'm not sure how sophisticated you're trying to get, but it should be able to handle a simple editor. Check out this MSDN Article for more info.
You might look into the Cairo graphics library. The Mono project has bindings for C#.
Cairo is an option. I'm currently rewriting my mapping software using both GDI+ and Cairo. It has a tile map generator, among other features.