X-Plane 10 Instancing Compatibility Wrapper

This is a compatibility wrapper for using the new XPLMInstance APIs in plugins that support old versions of X-Plane. It consists of 2 files (a .h and a .cpp)

xplm_instance.h

/**
 * This is a backward-compatibility wrapper for the new XPLM300
 * instancing APIs.
 *
 * It can be used to provide compatibility with plugins that support 
 * both X-Plane 10 and 11. X-Plane 10 plugins will not see the performance
 * benefit, of course, but this saves you from needing two separate
 * implementations.
 */

#ifndef xplm_instance_h
#define xplm_instance_h

#include <XPLMScenery.h>

typedef void *	XPLMInstanceRef;

XPLMInstanceRef XPLMCreateInstance(XPLMObjectRef obj, const char * drefs[]);
void			XPLMDestroyInstance(XPLMInstanceRef inst);

// Data is consecutive floats, one for each dataref
void			XPLMInstanceSetPosition(
								XPLMInstanceRef			inst,
								const XPLMDrawInfo_t *	position,
								const float *			data);




// These are boiler plate needed only for the 'lib' implementation of the above APIs.
void			XPLMInstanceInit();
void			XPLMInstanceCleanup();

#endif /* xplm_instance_h */

xplm_instance.cpp

#define XPLM200 1
#define XPLM210 1

#include "xplm_instance.h"
#include "XPLMDataAccess.h"
#include "XPLMDisplay.h"

#include <vector>
#include <algorithm>
using std::vector;
using std::find;

struct	xplm_instance_t {

	XPLMObjectRef				model;
	vector<XPLMDataRef>			datarefs;
	
	XPLMDrawInfo_t				position;
	vector<float>				data;
	
};

static vector<xplm_instance_t *>	s_instances;

XPLMInstanceRef XPLMCreateInstance(XPLMObjectRef obj, const char * drefs[])
{
	xplm_instance_t * i = new xplm_instance_t;
	i->model = obj;
	if(drefs)
	{
		while(*drefs)
		{
			XPLMDataRef	r = XPLMFindDataRef(*drefs);
			i->datarefs.push_back(r);
			i->data.push_back(0);
			
			++drefs;
		}
	}
	memset(&i->position,0,sizeof(i->position));
	s_instances.push_back(i);
	return i;
}

void			XPLMDestroyInstance(XPLMInstanceRef i)
{
	xplm_instance_t * ii = (xplm_instance_t *) i;
	
	vector<xplm_instance_t *>::iterator it = find(s_instances.begin(), s_instances.end(), ii);
	if(it != s_instances.end())
		s_instances.erase(it);
	delete ii;
}

void			XPLMInstanceSetPosition(
								XPLMInstanceRef			instance,
								const XPLMDrawInfo_t *	position,
								const float *			data)
{
	xplm_instance_t * i = (xplm_instance_t *) instance;
	if(data && !i->data.empty())
	{
		memcpy(&i->data[0], data, i->data.size() * sizeof(float));
	}
	memcpy(&i->position, position, sizeof(i->position));
}

static int draw_cb(
                                   XPLMDrawingPhase     inPhase,    
                                   int                  inIsBefore,    
                                   void *               inRefcon)
{
	static XPLMDataRef draw_type = XPLMFindDataRef("sim/graphics/view/plane_render_type");
	
	if(!draw_type || XPLMGetDatai(draw_type) == 1)
	{
		for(vector<xplm_instance_t *>::iterator it = s_instances.begin(); it != s_instances.end(); ++it)
		{
			xplm_instance_t * i = *it;
			for(int d = 0; d < i->data.size(); ++d)
				XPLMSetDataf(i->datarefs[d],i->data[d]);
			XPLMDrawObjects(i->model, 1, &i->position, 1, 0);
		}
	}
	return 1;
}

void			XPLMInstanceInit()
{
	XPLMRegisterDrawCallback(draw_cb, xplm_Phase_Airplanes, 0, NULL);
}

void			XPLMInstanceCleanup()
{
	XPLMUnregisterDrawCallback(draw_cb, xplm_Phase_Airplanes, 0, NULL);
}
  • Facebook
  • Reddit
  • Twitter
  • LinkedIn

About Tyler Young

Tyler is a software developer for X-Plane. Among other projects, he was in charge of the new X-Plane 11 user interface.
Bookmark the permalink.

6 Responses to X-Plane 10 Instancing Compatibility Wrapper

  1. saar says:

    I am not criticizing, but the code is so pre C++11 times 🙂
    Since you defined the new OSs and Compilers as your base line, whty not use "auto" in your examples, can me easier and cleaner. Something like:

    Instead of:
    for(vector::iterator it = s_instances.begin(); it != s_instances.end(); ++it)
    {
    xplm_instance_t * i = *it;
    for(int d = 0; d data.size(); ++d)
    XPLMSetDataf(i->datarefs[d],i->data[d]);
    XPLMDrawObjects(i->model, 1, &i->position, 1, 0);
    }

    We could write:
    for(auto it : s_instances )
    {
    xplm_instance_t * i = *it; (not sure if you need the "*" in this case)
    for(int d = 0; d data.size(); ++d)
    XPLMSetDataf(i->datarefs[d],i->data[d]);
    XPLMDrawObjects(i->model, 1, &i->position, 1, 0);
    }

    I believe we should let the new compilers "work" for us too. I mean I hate these all iterator overhead...

    Cheers and keep the great work
    Saar

  2. Steve.Wilson says:

    Tyler & Ben: Will there need to be a similar compatibility layer added for things like drawing on the 3D cockpit, namely the panel.png as SASL is frequently used? I see the potential for lots of products breaking if this gets gnarly as Vulkan/Metal are integrated.

    Or is it possible that there will be a compatibility layer added within the SDK libraries themselves so that OpenGL calls are automatically translated on build, allowing current drawing routines to remain valid throughout the transistion?

    • Ben Supnik says:

      Drawing to the _panel texture_ (which ends up in the 3-d cockpit) is 2-d drawing to X-Plane, so we are hoping to wrap it in compatibility, just like 2-d window overlays.

      The main issue is that we don't see a way to share _depth buffer_ information between any of the modern drivers (metal, vulkan) and legacy GL, and this means we can't correctly integrate 3-d plugin drawing with our content.

      Our current expectation is to run a GL context and composite 2-d plugin content in place; we are not planning to 'intercept' the calls. But if an OpenGL 2.x or 3.x layer on top of Vulkan or Metal became available we could run plugins on top of that. Molten-GL has the problem of beign payware and (more importantly) GL ES 2.0, while plugins can basically assume full GL 2.1 on desktop (and 3.x + compatibility on windows).

Leave a Reply

Your email address will not be published. Required fields are marked *

Please do not report bugs in the blog comments.
Only bugs reported via the X-Plane Bug Reporter are tracked.