Jump to content

2D Drawing computed from 3D data in X-plane Plugin


seyc
 Share

Recommended Posts

Hi,

I'd like to do 2D drawing related to 3D data in a quite simple plugin as follow :

 

  1. I statically store the 3D point i'd like to mark in the 2D step : it's the start of runway "11" of airport "TFFR". The lat/lon/elevation are extracted from the file "apt.dat".
  2. In a 3D step (xplm_Phase_Airplanes),
    1. i convert World coordinates to X-plane local coordinates
    2. i retrieve the OpenGL matrices (GL_MODELVIEW_MATRIX, GL_MODELVIEW_MATRIX, GL_VIEWPORT) needed to convert local coordinates to screen coordinates
    3. i compute the related screen coordinates using "gluProject"
    4. i store these coordinates for further use.
    5. I draw a red mark using the local coordinates
  3. In a 2D step (xplm_Phase_Gauges), I draw a blue mark using the screen coordinates i saved in the previous step.

But (and this is the problem), the blue mark (2D draw) is wrong as you can see in the attached picture but the red mark is well positionned (the blue mark and the red mark are related to the same 3D point).

 

Have you guys ideas about what's wrong ?

Thank you very much.

Seyc

 

The source code is :

/* * jlhplugin.c * *  Created on: 6 févr. 2014 *      Author: jl *///---------------------------------------------------------------------------#include <string.h>//---------------------------------------------------------------------------#define XPLM210 1#define XPLM200 1#define LIN 1#include <GL/gl.h>#include <GL/glu.h>#include <XPLMPlugin.h>#include <XPLMProcessing.h>#include <XPLMDisplay.h>#include <XPLMGraphics.h>//---------------------------------------------------------------------------typedef struct _my_3d_data{      GLdouble       runwayScreenPoint[3] ;      int            runwayScreenPointIsValid ;} t_my_3d_data ;static t_my_3d_data my_3d_data ;static int The_3D_Part_Drawing_Callback(XPLMDrawingPhase inPhase, int inIsBefore, void *inRefcon) ;static int The_2D_Part_Drawing_Callback(XPLMDrawingPhase inPhase, int inIsBefore, void *inRefcon) ;// TFFR Airport : values read in "apt.dat"static GLdouble  runwayLat = 16.26830000 ;static GLdouble  runwayLon = -061.54794200 ;static GLdouble  airportElevationInMetersAMSL = 35 * 0.3048 ; //Given in Feet AMSL -> translated in Meters AMSLPLUGIN_API void   XPluginStop(void){}PLUGIN_API int XPluginStart(      char *      outName,      char *      outSig,      char *      outDesc){   strcpy(outName, "Essai") ;   strcpy(outSig, "Essai Plugin") ;   strcpy(outDesc, "My best try.") ;   memset(&my_3d_data, 0, sizeof(t_my_3d_data)) ;   XPLMRegisterDrawCallback(The_3D_Part_Drawing_Callback, xplm_Phase_Airplanes, 0, &my_3d_data) ;   XPLMRegisterDrawCallback(The_2D_Part_Drawing_Callback, xplm_Phase_Gauges, 0, &my_3d_data) ;   return GL_TRUE ;}PLUGIN_API int XPluginEnable(void){   return GL_TRUE ;}PLUGIN_API void XPluginDisable(void){}PLUGIN_API void XPluginReceiveMessage(XPLMPluginID inFrom, int inMsg, void * inParam){}static int The_3D_Part_Drawing_Callback(XPLMDrawingPhase inPhase, int inIsBefore, void *inRefcon){   t_my_3d_data *my_3d_data = (t_my_3d_data *) inRefcon ;   GLdouble       modelM[16] ;                        // Our current model view matrix   GLdouble       projM [16] ;                        // Our current projection matrix   GLint          viewport[4] ;                       // The current viewport   // Compute the local (OpenGL) coordinates of the runway point :   GLdouble runwayLocalX = 0.0 ;   GLdouble runwayLocalY = 0.0 ;   GLdouble runwayLocalZ = 0.0 ;   XPLMWorldToLocal   (         runwayLat, runwayLon, airportElevationInMetersAMSL, &runwayLocalX, &runwayLocalY, &runwayLocalZ   ) ;   // Compute the screen coordinates of the local runway point   my_3d_data->runwayScreenPointIsValid = GL_FALSE ;   glGetDoublev (GL_MODELVIEW_MATRIX , modelM) ;   glGetDoublev (GL_PROJECTION_MATRIX, projM) ;   glGetIntegerv(GL_VIEWPORT         , viewport) ;   const GLint result =      gluProject      (            runwayLocalX,            runwayLocalY,            runwayLocalZ,            modelM,            projM,            viewport,            &my_3d_data->runwayScreenPoint[0],            &my_3d_data->runwayScreenPoint[1],            &my_3d_data->runwayScreenPoint[2]      ) ;   if (result != GL_FALSE)   {      my_3d_data->runwayScreenPointIsValid = GL_TRUE ;   }   // Now Draw   XPLMSetGraphicsState(0, 0, 0, 0, 0, 0, 0) ;   // 3D:  Runway point in RED   glLineWidth(3.0) ;   glColor3f(1.0, 0.0, 0.0) ;   glBegin(GL_LINES) ;   {     glVertex3d(runwayLocalX - 100.0, runwayLocalY, runwayLocalZ) ;     glVertex3d(runwayLocalX + 100.0, runwayLocalY, runwayLocalZ);     glVertex3d(runwayLocalX, runwayLocalY, runwayLocalZ - 100.0) ;     glVertex3d(runwayLocalX, runwayLocalY, runwayLocalZ + 100.0);     glVertex3d(runwayLocalX, runwayLocalY - 100.0, runwayLocalZ) ;     glVertex3d(runwayLocalX, runwayLocalY + 100.0, runwayLocalZ);   }   glEnd() ;   return 1 ;}static int The_2D_Part_Drawing_Callback(XPLMDrawingPhase inPhase, int inIsBefore, void *inRefcon){   t_my_3d_data *my_3d_data = (t_my_3d_data *) inRefcon ;   if (my_3d_data->runwayScreenPointIsValid != GL_FALSE)   {      // Now Draw      XPLMSetGraphicsState(0, 0, 0, 0, 0, 0, 0) ;      // 2D:  Runway point in BLUE      glLineWidth(3.0) ;      glColor3f(0.0, 0.0, 1.0) ;      glBegin(GL_LINES) ;      {         glVertex2d(my_3d_data->runwayScreenPoint[0] - 30.0, my_3d_data->runwayScreenPoint[1]);         glVertex2d(my_3d_data->runwayScreenPoint[0] + 30.0, my_3d_data->runwayScreenPoint[1]);         glVertex2d(my_3d_data->runwayScreenPoint[0], my_3d_data->runwayScreenPoint[1] - 30.0);         glVertex2d(my_3d_data->runwayScreenPoint[0], my_3d_data->runwayScreenPoint[1] + 30.0);      }      glEnd() ;   }   return 1 ;}/* -------------------------------------------------------------------------------------------------------------- */

post-20363-0-37486300-1416645283_thumb.j

Link to comment
Share on other sites

...Have you guys ideas about what's wrong ?...

Here is what I found in XPLMDisplay.h :

 * Upon entry the OpenGL context will be correctly set up for you and OpenGL  * will be in 'local' coordinates for 3d drawing and panel coordinates for 2d  * drawing.

If the result is not valid in the gauge phase this means that what you used (matrices and viewport) to compute the 2D coordinates during the 3D phase is not valid for the 2D phase.

 

Easy check : read the matrices and viewport during the gauge phase and compare them to what you read during the airplanes phase.

 

PhM

Link to comment
Share on other sites

Hello PhM,

 

the GL_VIEWPORT vectors are the same in the 3D part and in the 2D part (the width and the height of the screen managed by X-plane are set at index 2 and index 3).

 

the GL_MODELVIEW_MATRIX matrices are not the same (identity matrix in the 2D part) and the GL_PROJECTION_MATRIX matrices are also different.

 

Perhaps, another transformation must be applied to the "screen coordinates" that are computed in the 3D part.

 

Seyc

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...