Discussion OVP and alternatives to GDI-based MFDs

cjp

Addon Developer
Addon Developer
Donator
Joined
Feb 7, 2008
Messages
856
Reaction score
0
Points
0
Location
West coast of Eurasia
As far as I know, current OVP projects now provide the existing GDI system as the single possibility for MFDs to make their visualizations. I understand this is the easy way, as GDI is available on all windows systems, and existing MFDs already use GDI, so it's good for compatibility. But I can also see some disadvantages:

  • It can be relatively slow. For some visualization plugins, it is necessary to do all the GDI drawing on the CPU to a bitmap hDC, and then transfer the bitmap to the video card on each MFD redraw. No hardware acceleration is used for any drawing primitive.
  • It is not portable to non-windows platforms. For instance, in this thread, Hielor needs to convert existing MFDs from GDI to Allegro, because GDI doesn't exist in Linux(*). Also, continued use of GDI prevents a future port of Orbiter itself to non-windows platforms.
So, in this thread I would like to see which alternatives exist to GDI. I know this has already been discussed on M6, and also a bit in this thread, but as far as I can see, no satisfying decision has been made, so it might be worth summarizing which alternatives exist, and which criteria are important.

So, about the criteria, I can think of the following (not in this order):

  1. Can we make backward(**) compatibility? Can existing MFDs be made working on the new system? I think this shouldn't be too hard for any system, as the existing API can be re-implemented using a bitmap hDC, and doing a bitmap copy from the hDC to the target platform. I think all platforms will support this.
  2. Can we make forward(**) compatibility? Can MFDs for the future system be made in such a way that they will also work on older Orbiter versions? This may not be very important, but it could definitely be possible if the API has an implementation on top of GDI.
  3. Can it be made hardware-accelerated? Can visualization plugin developers take the library, implement it on their target (OpenGL, Direct3D or whatever), and implement some of the high-level primitives directly on their target API?
  4. Is it portable to non-windows platforms?
  5. Is it light-weight and fast? (Talking about the "fallback" software implementation here)
  6. Does it contain all the primitives we need?
  7. Does it have a nice license?
Listing some alternatives:

  • Cairo (Has been mentioned by Urwumpe. Is accelerated on multiple targets, so it may be possible to define your own output target. How difficult is this?)
  • Allegro (Used by Hielor for making an MFD in Linux. I got the idea for this thread when I started reading more about Allegro. Seems to be very multi-platform and light-weight, but how easy is it to make it accelerated?)
  • AVSGL (Made by myself. Extremely unfinished and incomplete, probably doesn't compare well with the other alternatives at this stage, but is specially designed with the idea in mind to make it easily accelerated on many target platforms)
  • There are many other graphics libraries out there
  • Final alternative: stick to GDI.

(*) Well, a GDI implementation exists in Wine, but that's not exactly light-weight.
(**) I may be confusing backward and forward here: I'm never really sure.
 

Artlav

Aperiodic traveller
Addon Developer
Beta Tester
Joined
Jan 7, 2008
Messages
5,790
Reaction score
780
Points
203
Location
Earth
Website
orbides.org
Preferred Pronouns
she/her
There was already some progress on that area, the current solution's direction was described like that in the last public beta:

martins said:
Started to implement the 2D drawing interface. There is a new API (orbitersdkincludeDrawAPI.h) which defines
(a) a drawing context (similar function to a HDC in GDI). To make it a bit more elegant, this is implemented as a class ("Sketchpad"), instead of a handle.
(b) "drawing tools" which define drawing resources (fonts, pens. brushes are still to come).

The GraphicsClient class has a few new methods to interact with the 2-D drawing interface:

clbkGetSketchpad creates a new drawing context for a surface (to replace clbkGetDC)
clbkReleaseSketchpad releases the context
clbkCreateFont, clbkReleaseFont, clbkCreatePen, clbkReleasePen to create and destroy drawing resources

The Sketchpad class has various methods for drawing primitives (writing text, drawing lines). It is still very sparse, but will be expanded in the future.


So the idea is as follows:

* Graphics clients derive a class from Sketchpad, to create their own version of a "2D drawing context", using whatever method they like.
* They also derive classes for the drawing resources
* The graphics client itself overloads the clbkGetSketchpad etc. methods to return instances of its own drawing context and drawing resources.

The GDIClient class on sourceforge has been updated to implement this scheme.

Currently, only very few parts of the orbiter core are using the new interface, but I will try to replace all GDI calls with this generic interface over time.

For now, I would just like to get some feedback if this interface is workable at all. Ideally, somebody could implement a non-GDI version (e.g. Cairo, or whatever else is available) and see if the required functions can be implemented. Currently, the whole interface is closely modelled on the GDI functionality, which may not be general enough for other systems.
 

martins

Orbiter Founder
Orbiter Founder
Joined
Mar 31, 2008
Messages
2,448
Reaction score
462
Points
83
Website
orbit.medphys.ucl.ac.uk
I should also add that for the next beta, I plan to have nearly all GDI calls by internal MFD and HUD code replaced by calls to the generic Sketchpad wrapper class. The number of supported primitives will therefore also increase (ellipses, polygons, polylines, etc.) I am also thinking about implementing a few higher-level primitives directly in the base class (e.g. a function that draws an ellipse given its semi-major axis [in pixels], eccentricity and argument of periapsis, since this is something required quite often).

Edit: What is needed now is for somebody to implement a non-GDI version of a Sketchpad-derived class. Are there any suggestions for drawing systems to replace GDI? Cairo has been mentioned at some stage, but I still don't know if this would suit our needs. Are there any 2-D drawing systems that can make use of GPU acceleration?
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
I should also add that for the next beta, I plan to have nearly all GDI calls by internal MFD and HUD code replaced by calls to the generic Sketchpad wrapper class. The number of supported primitives will therefore also increase (ellipses, polygons, polylines, etc.) I am also thinking about implementing a few higher-level primitives directly in the base class (e.g. a function that draws an ellipse given its semi-major axis [in pixels], eccentricity and argument of periapsis, since this is something required quite often).

Edit: What is needed now is for somebody to implement a non-GDI version of a Sketchpad-derived class. Are there any suggestions for drawing systems to replace GDI? Cairo has been mentioned at some stage, but I still don't know if this would suit our needs. Are there any 2-D drawing systems that can make use of GPU acceleration?

That would be great, because if someone wanted a different lower-level implementation, they could just implement another version of Sketchpad.

As for 2-d drawing systems, Allegro (according to http://alleg.sourceforge.net/readme.html ) can use as it's lower-level drivers DirectX, GDI, or (with an additional addon) OpenGL. It can be accelerated, it looks like; don't know for sure though.


-----Posted Added-----


I don't know if you'd be able to use allegro on a subset of a 3d window using DirectX or OpenGL, but that's probably been done before if you can. Also, using the GDI drivers wouldn't make much sense because that would just be putting an additional layer over the top of something we're trying to get rid of.
 

cjp

Addon Developer
Addon Developer
Donator
Joined
Feb 7, 2008
Messages
856
Reaction score
0
Points
0
Location
West coast of Eurasia
I have some experience in making 2D graphics on top of OpenGL. Basically, you set a very simple projection matrix (which ignores the Z-coordinate), and clip the part of the screen with glScissor. At least, that's how I did it. Some say that glScissor is slow, BTW.

Some primitives can be mapped easily on OpenGL. The question is how you combine such accelerated primitives with non-accelerated primitives.

For instance: there is no native support for circles and ellipses in OpenGL. Now, you can easily implement circles and ellipses as polylines (un-filled) or polygons (filled), so it's not a big deal, but you do need to re-implement it. If you wish to not implement a certain primitive (and use the SW implementation), then you'd need to implement the lower-level primitive operation used by the SW implementation. For a typical SW-implementation of a high-level primitive, this would be a drawPixel primitive. But sending lots of drawPixel commands to the video card is probably even slower than the SW rendering itself.

So, for a reasonably fast system(*), you'd either need to re-implement all primitives, or the software implementation of the primitives is such that it doesn't hurt accelerated performance too much. For instance, we saw that a drawEllipse based on drawPixel directly is slow, but if drawEllipse is based on drawPolyline, and drawPolyline on drawLine, and drawLine on drawPixel, then an accelerated driver could be a lot faster by providing drawLine (and maybe drawPolyline), without the need to implement drawEllipse.

Of course the GDI version can be lazy and map drawEllipse directly onto the corresponding GDI function.

(*) That is: faster than SW rendering. SW-only rendering is always possible as a fall-back, by doing the SW-rendering to a bitmap, and then uploading the bitmap to the video card.
 
Top