We’re working now on updating the map drawing SDK for compatibility with X-Plane 11.
This post is a request for comments from programmers who write plugins that used to draw to the map—it is not a place for general feature requests for the map, or for off topic comments. (And off topic comments will be deleted.)
Background: What broke the map drawing in the first place?
Long story short, the map has changed drastically since the X-Plane 10 version—it didn’t just get a fresh coat of paint.
The biggest obstacle to backward compatibility comes from the fact that we now use an honest-to-God cartographical map projection for map coordinates. Moreover, the map projection changes for different map types—the normal map UI uses a transverse Mercator projection, while the GPS units use a stereographic projection. For that reason alone, just “splatting” old drawing code on top of the new map would not give you the results you want… the old OpenGL local (x, y, z) coordinates do not have a straightforward mapping to the new projected latitude/longitude locations.
A second major change is the fact that the map can now rotate to match the heading of the user’s aircraft. Unless you like the possibility of your map labels being printed upside down, this requires awareness of the map’s rotation and the fact that north isn’t necessarily “up”.
The final big change comes from the draw order. The map is now very strongly divided into layers, and we draw in 3 stages:
- Backgrounds (e.g., terrain)
- Icons (e.g., airports, NAVAIDs, etc.)
- Labels
An individual layer can draw in any or all stages. (For instance, the airports layer draws both airport icons and labels for each icon.) We draw each stage from the bottom layer up, beginning with the terrain at the bottom, then the NAVAIDs & airports somewhere in the middle, and then finishing with the aircraft at the very top. This layering ensures that bigger or less important elements don’t cover up smaller or more important elements—your aircraft, for instance, will always be visible (and selectable), even if it’s in the exact same place as a fix or NAVAID. Likewise, the label for your element will always be visible even if the actual icon is obscured by something above it. (In practice, of course, readability is going to be poor if you have labels overlapping, but that’s not really solvable without much more powerful cartographical tools than we have now.)
While it’s not essential that plugin drawing code respect the layering draw order, it would certainly be nice—it would allow you to ensure that a) your plugin-drawn layer doesn’t cover more important info, and b) less important info doesn’t cover your layer.
Proposed API
With all that in mind, our proposed API for map drawing looks like this:
- Plugin code would call the SDK to create a new map layer. To do so, you would provide:
- An optional drawing callback for OpenGL drawing (which would be layered beneath all built-in icons & text, but above things like X-Plane’s terrain drawing).
- OpenGL drawing here is more or less a “free for all,” with one exception: manipulating the Z buffer is not allowed, due to our reliance on the Z buffer as a means of preserving layer ordering.
- An optional icon callback, where you would provide a set of PNG icons to be drawn, along with their heading, opacity, etc., and X-Plane would “splat” them onto the map above all built-in icon types except the aircraft
- An optional label callback, where you would provide a set of strings for X-Plane to draw above all built-in labels except the aircraft label
- An optional “prepare cache” callback, called whenever the map’s total bounds change (e.g., when the scenery loader loads new DSFs). This allows you to keep your drawing callbacks fast, since you can cache only the data you need for drawing in the current area.
- A flag to indicate whether you’d like your new layer to be disablable from the UI (if so, we would add a checkbox to the right-hand sidebar like we have now for the flight path and compass rose)
- An optional drawing callback for OpenGL drawing (which would be layered beneath all built-in icons & text, but above things like X-Plane’s terrain drawing).
- Drawing, icon, & label callbacks would receive:
- The currently visible bounds of the map
- The current zoom level of the map
- The map units per unit of UI coordinates (useful for drawing text at a fixed size regardless of map scale)
- If your layer is drawing in the standard X-Plane map window, this is map units per boxel; if you’re drawing within the GPS unit, it’s map units per “virtual device pixel,” whose size in real screen pixels is of course fluid since the user can move the camera relative to the GPS in the panel.
- The map’s current mode (currently one of either sectional, low enroute, and high enroute)
- An opaque handle that provides access to the new projection APIs. The projection APIs would provide the following functions:
- project a latitude & longitude into map coordinates for drawing
- unproject an (x, y) pair of map coordinates into a latitude & longitude
- get the scale, in map coordinates, of 1 meter at a given (x, y)
- get the heading (in degrees clockwise from “up”) corresponding to north on the map for a given (x, y)—this is necessary since the X-Plane 11 map can be rotated to match your aircraft’s orientation
- Relative ordering of plugin-created layers would not be guaranteed. So, if you had two plugins which drew the same icon in the same place, but one drew in red and the other in blue, we would make no guarantees about which color the user saw. (And, indeed, some users may see red and others may see blue.)
Questions we have
While the proposal above meets what we believe the needs of third-party developers to be, we almost certainly haven’t considered every use case for this API. (And it’s possible we’re missing important features even for the use cases we have considered!)
To that end, here are some question you, dear plugin developer, can answer for us:
- What’s your use case for the map drawing API?
- Does the proposal above sound workable for your use case? (If not, what’s missing, or what would you change?)
- Do you like the idea of allowing plugin developers to specify whether their new layer is togglable from the standard map UI? (If not, why, and what policy would you like to see instead?)
- Do you have a use case for click selection and click-and-drag functionality in your plugin-created map layers? (This isn’t on the table for the initial update to the map API, but it’s a possibility for future updates.)
Hi Tyler, a dumb question: Where do I find X-Plane’s current (XP10) map API and documentation?
The current documentation home (for a little while longer, at least) is here: http://www.xsquawkbox.net/xpsdk/mediawiki/Main_Page
We’re in the process of moving all the docs you find there over to the developer site (i.e., “here”).
I gotta say, I would *not* recommend building anything new with the old map API, unless for some reason you just have no intention of moving to X-Plane 11.
Thanks; this page I knew, and I use the navigation SDK.
We (vFlyteAir) currently have an XP10 aircraft (a SR20) that uses the old (XP10 style) EFIS map on a MFD (the same as is used by the XP11 default 737). We have updated most of it to X-Plane 11 and it works fine so far. But the map stays the same.
Are there any plans to replace the XP11 default EFIS map (the one you can drag in PlaneMaker onto the panel) with a better one (and really just a map with the same features as the old one: readable icons at high resolutions, Weather, default AI TCAS)?
And a last question: Is there anywhere a documentation about the navigation SDK differences between XP10 and XP11, esp. the “inner” workings of the old and the new FMC in regards to SDK functions like FindNavAid etc.? Or has this been unchanged?
Re: the EFIS, unknown.
For differences between the V10 and V11 FMC SDK, ping Philipp. (His email is his first name at X-Plane.com.)
I do think that at some point both the tech from the map and the tech from Philipp’s cockpit devices will make it into a generic map system for cockpits via Plane-Maker. That’s down the road, though.
Ok, thanks for the info. Then for now I’ll optimize usage of the existing map as good as possible.
I hope the “down the road” generic cockpit map will be layered and more customizable than the old one —eg., custom range, colors, etc. I’m drawing it all from scratch. The existing local map has some minor issues, maybe I’ll submit that as suggestions or a tweak list.
YEah, something modular is definitely our intention.
I’ve never been able to find any reference to a Map API anywhere in the SDK website. Would you mind pointing me to the proper page?
V10 map drawing occurred as a draw callback, found in the XPLMDisplay API: http://www.xsquawkbox.net/xpsdk/mediawiki/Category:XPLMDisplay
I know when it happens, but this is not an API for controlling where and how a map could be displayed. Glad if this becomes available in XP11.
Ah, I see… You’re asking for the ability to stick a map in something like a cockpit instrument, right? That’s on our radar, but it’s probably not on the table for 11.10.
We had a plans to use the map in XP10 with our Tornado to overlay a representation of ground targets for bombs. We decided to stop and wait for XP11. All our use cases seem supported by your specs thnak you! – except support for weapons 🙂
“Click selection” could be useful and quick way for feeding the position of a target to the weapon system
Can you elaborate on what you mean by support for weapons? (For instance, if you just want to draw, say, the position of bombs in flight, you should be able to do so with the existing API, right?)
Tyler, re: bombs I was being mildly ironic (in the most friendly way) about the fact that we are waiting to be able to access the new weapon system from the plugin (so not related to the map).
Your proposal will work great for us (when the weapons syestem will also work)
Haha, fair enough! 🙂
The suggested API sound good enough for me. In my plugin I just use the map to display event areas so mission designer will get better representation of what is going on in a certain area. The opengl is very simple and I only draw simple primitives, nothing fancy.
The option to hide/display the “plugin draw layer” sounds like a nice touch, but I already mapped it to a command, so simmer can display/hide the geometry.
The only thing I really need is the abstraction of calculation, something like “LocalToMap” that will calculate the correct plane location on the map and vise verse, “MapToLocal” or “MapToWorld” although moving the plane on map also move it in XP 3D world, so I can just fetch that.
Other things I can think of are:
1. It would have been nice if we could receive mouse information when clicking on the map. We could use the map as a base to “drawing” or “placing” 2d representatives as an outcome of mouse clicks on the map.
2. Can a plugin have few pre define layers (for example restrict each plugin to 3 internal layers, like 3 different draw callbacks but with hierarchy. They also pertain the draw order described above) or all plugins can only draw only to one layer like FIFO. I’m thinking of layers like in blender, so we can display/hide a full layer, that way we won’t need to manage the layers internally.
Thanks
I think right now our model is you get as many layers as you need, because they are user-visible (e.g. there’s a potential on/off switch).
We do not have a scheme for prioritizing layers between plugins. I’m open to suggestions, but “I want to be on top” is never a good flag because everyone will set it.: -)
I *think* the user would want whichever layer they turn on last to be ‘sent to top’. And idealy this order is remembered between flights. If a new layer is added since last flight (ie a new plugin), ‘send it to top’. First ever start-up? Um, not sure! – let the user sort it out, and remember their preference?
The first time I had to deal with “layers” was when I created 2 different windows that were not purely XPSDK based, I had to manage the drawing of each. Then I bumped into draw priority, like layers but no transparency in my case.
This is why I I thought, wow, it will be nice if the sim will handle the priority for me, and all I have to assign is the order.
Please pay attention that I’m only referring to my plugin layer order not relative to other plugins.
I do agree with @Nathan that a sorting order should be decided, and I’ll do with what ever Laminar team will decide at the end, at least it will be a base we can work on and then make better at the end.
The current feature list sound quite good though, I’m just thinking how it make my life even easier in the long term (tendency to complicate things 🙂 )
Cheers
If you made the map layers yourself, you can just create them in the order you want, as long as that is deterministic, right?
Right, to be clear, as Ben said, the layer order will be consistent for layers created by a given plugin. What we’re not guaranteeing is the relative order of one plugin’s layers with respect to another.
So, Plugin #1 creates layers A, B, and C, and those will always be layered consistently. But, if you also have Plugin #2 running, and it creates layers D, E, and F, we make no guarantees about which set—either (A, B, C) or (D, E, F)—is on top.
@Tyler (“Reply” below your post was missing):
Could it be, that layers of different plugins intermix. Let’s say in order A, B, D, C, E, F?
Definitely not. We’ll draw all of one plugin’s layers before moving on to the next. (Providing you with consistency, at least as far as your plugin is concerned, across machines.)
Just a bit off-topic, but there will be a new Blender exporter with particle system support? Ben also mentioned something about WYSIWIG flood ligths also.
Hi, thanks for the update.
Click-and-drag functionality would be handy for the map in the future. The new displays in aircraft are more and more interactive. Since hardware-mouse systems (like in Airbus, Boeing or figher jets) is diffucult for users (no matching hardware), a direct click and drag directly on the display is handy.
Programming of flight / mission planners probably would also be easier. Interesting for the non Pro’s (They use the FMC).
Maybe later on one could use also it’s own OpenGL shaders for the terrain? Maybe already possible?
Keep up the good work
Best Regards
Florian
By the way +1 for the new weapon system 🙂
While I’m not really a plugin developer, one thing strikes me as odd. Namely:
“An optional drawing callback for OpenGL drawing”
With the effort to transition the renderer to Vulkan/Metal, having something that relies on OpenGL would have a high probability of breaking. Wouldn’t it be more helpful to design new APIs in such a way that they could withstand such a transition?
From conversations with Ben, my understanding is that our plan for transitioning a lot of the existing OpenGL to future graphics APIs is to essentially draw the old stuff to an offscreen buffer in a backwards-compatibility mode, then “splat” them into the new rendering paths. (There are a *lot* of places we allow OpenGL drawing right now… since we’re gonna have to provide a transition for it anyway, adding one more callback between now and the release of the future APIs isn’t going to change anything.)
Right. We’re trying to ensure that the OpenGL/Vulkan interop requirements for the map are no _worse_ than the requirements for 2-d floating UI layers.
At a minimum of compatibility, we expect to support OpenGL UI natively in the sim running in another API for the life of X-Plane 11. So a map layer is kind of like a piece of 2-d UI that happens to have these special rules about coordinate systems and what-not.
It still sounds like this is a backward compatibility measure that will (and probably should) eventually be deprecated. Why burn yourself with that when you have the ability to do something different from the beginning?
We can choose to either (massively) delay map drawing support until we have nailed down what the future-facing drawing API will look like, or create one more OpenGL API that will have to be migrated in *exactly* the same way as all the other existing UI drawing APIs.
We consider this important enough that we’re not willing to delay it.