]> git.mxchange.org Git - flightgear.git/blobdiff - src/Cockpit/panel.cxx
new FSF address
[flightgear.git] / src / Cockpit / panel.cxx
index b492c0bf402eb7e2b1aa29c8d24cd4d6783280a5..e33803c484d3bff62aec88b1d2db54e464d4b7ec 100644 (file)
 //  WITHOUT ANY WARRANTY; without even the implied warranty of
 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 //  General Public License for more details.
-// 
+//
 //  You should have received a copy of the GNU General Public License
 //  along with this program; if not, write to the Free Software
-//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
 //  $Id$
 
+//JVK
+// On 2D panels all instruments include light sources were in night displayed
+// with a red mask (instrument light). It is not correct for light sources
+// (bulbs). There is added new layer property "emissive" (boolean) (only for
+// textured layers).
+// If a layer has to shine set it in the "instrument_def_file.xml" inside the
+// <layer> tag by adding <emissive>true</emissive> tag. When omitted the default
+// value is for backward compatibility set to false.
+
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
 #endif
 #include <stdio.h>     // sprintf
 #include <string.h>
 
+#include <simgear/compiler.h>
+
+#include SG_GLU_H
+
 #include <plib/ssg.h>
 #include <plib/fnt.h>
 
@@ -38,7 +51,6 @@
 #include <Main/globals.hxx>
 #include <Main/fg_props.hxx>
 #include <Main/viewmgr.hxx>
-#include <Objects/texload.h>
 #include <Time/light.hxx>
 
 #include "hud.hxx"
@@ -54,7 +66,6 @@
 // my hardware/driver requires many more.
 #define POFF_UNITS 4
 
-\f
 ////////////////////////////////////////////////////////////////////////
 // Local functions.
 ////////////////////////////////////////////////////////////////////////
@@ -80,9 +91,9 @@ get_aspect_adjust (int xsize, int ysize)
 bool
 fgPanelVisible ()
 {
-     if(current_panel == 0)
+     if(globals->get_current_panel() == 0)
        return false;
-     if(current_panel->getVisibility() == 0)
+     if(globals->get_current_panel()->getVisibility() == 0)
        return false;
      if(globals->get_viewmgr()->get_current() != 0)
        return false;
@@ -163,10 +174,11 @@ FGCroppedTexture::getTexture ()
 // Implementation of FGPanel.
 ////////////////////////////////////////////////////////////////////////
 
-FGPanel * current_panel = NULL;
 static fntRenderer text_renderer;
 static fntTexFont *default_font = 0;
 static fntTexFont *led_font = 0;
+static sgVec4 panel_color;
+static sgVec4 emissive_panel_color = {1,1,1,1};
 
 /**
  * Constructor.
@@ -175,12 +187,16 @@ FGPanel::FGPanel ()
   : _mouseDown(false),
     _mouseInstrument(0),
     _width(WIN_W), _height(int(WIN_H * 0.5768 + 1)),
-    _x_offset(0), _y_offset(0), _view_height(int(WIN_H * 0.4232)),
-    _jitter(0.0),
+    _view_height(int(WIN_H * 0.4232)),
+    _visibility(fgGetNode("/sim/panel/visibility", true)),
+    _x_offset(fgGetNode("/sim/panel/x-offset", true)),
+    _y_offset(fgGetNode("/sim/panel/y-offset", true)),
+    _jitter(fgGetNode("/sim/panel/jitter", true)),
+    _flipx(fgGetNode("/sim/panel/flip-x", true)),
     _xsize_node(fgGetNode("/sim/startup/xsize", true)),
-    _ysize_node(fgGetNode("/sim/startup/ysize", true))
+    _ysize_node(fgGetNode("/sim/startup/ysize", true)),
+    _enable_depth_test(false)
 {
-  setVisibility(fgPanelVisible());
 }
 
 
@@ -267,13 +283,6 @@ FGPanel::unbind ()
 void
 FGPanel::update (double dt)
 {
-                               // TODO: cache the nodes
-    _visibility = fgGetBool("/sim/panel/visibility");
-    _x_offset = fgGetInt("/sim/panel/x-offset");
-    _y_offset = fgGetInt("/sim/panel/y-offset");
-    _jitter = fgGetFloat("/sim/panel/jitter");
-    _flipx = fgGetBool("/sim/panel/flip-x");
-
                                // Do nothing if the panel isn't visible.
     if ( !fgPanelVisible() ) {
         return;
@@ -315,20 +324,20 @@ FGPanel::update (GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh)
                                // The factors and bounds are just
                                // initial guesses; using sqrt smooths
                                // out the spikes.
-  double x_offset = _x_offset;
-  double y_offset = _y_offset;
+  double x_offset = _x_offset->getIntValue();
+  double y_offset = _y_offset->getIntValue();
 
 #if 0
-  if (_jitter != 0.0) {
+  if (_jitter->getFloatValue() != 0.0) {
     double a_x_pilot = current_aircraft.fdm_state->get_A_X_pilot();
     double a_y_pilot = current_aircraft.fdm_state->get_A_Y_pilot();
     double a_z_pilot = current_aircraft.fdm_state->get_A_Z_pilot();
 
     double a_zx_pilot = a_z_pilot - a_x_pilot;
     
-    int x_adjust = int(sqrt(fabs(a_y_pilot) * _jitter)) *
+    int x_adjust = int(sqrt(fabs(a_y_pilot) * _jitter->getFloatValue())) *
                   (a_y_pilot < 0 ? -1 : 1);
-    int y_adjust = int(sqrt(fabs(a_zx_pilot) * _jitter)) *
+    int y_adjust = int(sqrt(fabs(a_zx_pilot) * _jitter->getFloatValue())) *
                   (a_zx_pilot < 0 ? -1 : 1);
 
                                // adjustments in screen coordinates
@@ -340,7 +349,7 @@ FGPanel::update (GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh)
   glMatrixMode(GL_PROJECTION);
   glPushMatrix();
   glLoadIdentity();
-  if ( _flipx ) {
+  if ( _flipx->getBoolValue() ) {
     gluOrtho2D(winx + winw, winx, winy + winh, winy); /* up side down */
   } else {
     gluOrtho2D(winx, winx + winw, winy, winy + winh); /* right side up */
@@ -374,7 +383,8 @@ FGPanel::draw()
 
   // save some state
   glPushAttrib( GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT
-                | GL_TEXTURE_BIT | GL_PIXEL_MODE_BIT );
+                | GL_TEXTURE_BIT | GL_PIXEL_MODE_BIT | GL_CULL_FACE 
+                | GL_DEPTH_BUFFER_BIT );
 
   // Draw the background
   glEnable(GL_TEXTURE_2D);
@@ -382,8 +392,15 @@ FGPanel::draw()
   glEnable(GL_BLEND);
   glEnable(GL_ALPHA_TEST);
   glEnable(GL_COLOR_MATERIAL);
-  sgVec4 panel_color;
-  sgCopyVec4( panel_color, cur_light_params.scene_diffuse );
+  glEnable(GL_CULL_FACE);
+  glCullFace(GL_BACK);
+  if( _enable_depth_test )
+      glDepthFunc(GL_ALWAYS);
+  else
+    glDisable(GL_DEPTH_TEST);
+
+  FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
+  sgCopyVec4( panel_color, l->scene_diffuse());
   if ( fgGetDouble("/systems/electrical/outputs/instrument-lights") > 1.0 ) {
       if ( panel_color[0] < 0.7 ) panel_color[0] = 0.7;
       if ( panel_color[1] < 0.2 ) panel_color[1] = 0.2;
@@ -438,20 +455,18 @@ FGPanel::draw()
 
   // Draw yellow "hotspots" if directed to.  This is a panel authoring
   // feature; not intended to be high performance or to look good.
-  if(fgGetBool("/sim/panel-hotspots")) {
-    glPushAttrib(GL_ALL_ATTRIB_BITS);
-    glDisable(GL_DEPTH_TEST);
+  if ( fgGetBool("/sim/panel-hotspots") ) {
     glDisable(GL_TEXTURE_2D);
     glColor3f(1, 1, 0);
     
-    for(int i=0; i<_instruments.size(); i++)
+    for ( unsigned int i = 0; i < _instruments.size(); i++ )
       _instruments[i]->drawHotspots();
-
-    glPopAttrib();
   }
 
 
   // restore some original state
+  if( _enable_depth_test )
+    glDepthFunc(GL_LESS);
   glPopAttrib();
   glPolygonOffset(0, 0);
   glDisable(GL_POLYGON_OFFSET_FILL);
@@ -463,7 +478,7 @@ FGPanel::draw()
 void
 FGPanel::setVisibility (bool visibility)
 {
-  _visibility = visibility;
+  _visibility->setBoolValue( visibility );
 }
 
 
@@ -473,7 +488,7 @@ FGPanel::setVisibility (bool visibility)
 bool
 FGPanel::getVisibility () const
 {
-  return _visibility;
+  return _visibility->getBoolValue();
 }
 
 
@@ -503,7 +518,7 @@ void
 FGPanel::setXOffset (int offset)
 {
   if (offset <= 0 && offset >= -_width + WIN_W)
-    _x_offset = offset;
+    _x_offset->setIntValue( offset );
 }
 
 
@@ -514,7 +529,7 @@ void
 FGPanel::setYOffset (int offset)
 {
   if (offset <= 0 && offset >= -_height)
-    _y_offset = offset;
+    _y_offset->setIntValue( offset );
 }
 
 /**
@@ -577,14 +592,18 @@ FGPanel::doMouseAction (int button, int updown, int x, int y)
   }
 
                                // Adjust for offsets.
-  x -= _x_offset;
-  y -= _y_offset;
+  x -= _x_offset->getIntValue();
+  y -= _y_offset->getIntValue();
 
   // Having fixed up the coordinates, fall through to the local
   // coordinate handler.
-  doLocalMouseAction(button, updown, x, y);
+  return doLocalMouseAction(button, updown, x, y);
 } 
 
+void FGPanel::setDepthTest (bool enable) {
+    _enable_depth_test = enable;
+}
+
 
 \f
 ////////////////////////////////////////////////////////////////////////.
@@ -599,14 +618,14 @@ FGPanelAction::FGPanelAction (int button, int x, int y, int w, int h,
                               bool repeatable)
     : _button(button), _x(x), _y(y), _w(w), _h(h), _repeatable(repeatable)
 {
-  for (unsigned int i = 0; i < 2; i++) {
-      for (unsigned int j = 0; j < _bindings[i].size(); j++)
-          delete _bindings[i][j];
-  }
 }
 
 FGPanelAction::~FGPanelAction ()
 {
+  for (unsigned int i = 0; i < 2; i++) {
+      for (unsigned int j = 0; j < _bindings[i].size(); j++)
+          delete _bindings[i][j];
+  }
 }
 
 void
@@ -679,7 +698,7 @@ FGPanelInstrument::~FGPanelInstrument ()
 void
 FGPanelInstrument::drawHotspots()
 {
-  for(int i=0; i<_actions.size(); i++) {
+  for ( unsigned int i = 0; i < _actions.size(); i++ ) {
     FGPanelAction* a = _actions[i];
     float x1 = getXPos() + a->getX();
     float x2 = x1 + a->getWidth();
@@ -782,7 +801,6 @@ FGLayeredInstrument::draw ()
   
   for (int i = 0; i < (int)_layers.size(); i++) {
     glPushMatrix();
-    glPolygonOffset(-1, -POFF_UNITS*(i+2));
     _layers[i]->draw();
     glPopMatrix();
   }
@@ -803,7 +821,7 @@ FGLayeredInstrument::addLayer (FGInstrumentLayer *layer)
 }
 
 int
-FGLayeredInstrument::addLayer (FGCroppedTexture &texture,
+FGLayeredInstrument::addLayer (const FGCroppedTexture &texture,
                               int w, int h)
 {
   return addLayer(new FGTexturedLayer(texture, w, h));
@@ -817,6 +835,28 @@ FGLayeredInstrument::addTransformation (FGPanelTransformation * transformation)
 }
 
 
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGSpecialInstrument.
+////////////////////////////////////////////////////////////////////////
+
+FGSpecialInstrument::FGSpecialInstrument (DCLGPS* sb)
+  : FGPanelInstrument()
+{
+  complex = sb;
+}
+
+FGSpecialInstrument::~FGSpecialInstrument ()
+{
+}
+
+void
+FGSpecialInstrument::draw ()
+{
+  complex->draw();
+}
+
+
 \f
 ////////////////////////////////////////////////////////////////////////
 // Implementation of FGInstrumentLayer.
@@ -904,6 +944,7 @@ void
 FGGroupLayer::draw ()
 {
   if (test()) {
+    transform();
     int nLayers = _layers.size();
     for (int i = 0; i < nLayers; i++)
       _layers[i]->draw();
@@ -924,7 +965,8 @@ FGGroupLayer::addLayer (FGInstrumentLayer * layer)
 
 
 FGTexturedLayer::FGTexturedLayer (const FGCroppedTexture &texture, int w, int h)
-  : FGInstrumentLayer(w, h)
+  : FGInstrumentLayer(w, h),
+    _emissive(false)
 {
   setTexture(texture);
 }
@@ -945,17 +987,14 @@ FGTexturedLayer::draw ()
     transform();
     glBindTexture(GL_TEXTURE_2D, _texture.getTexture()->getHandle());
     glBegin(GL_POLYGON);
-    
+
+    if (_emissive) {
+      glColor4fv( emissive_panel_color );
+    } else {
                                // From Curt: turn on the panel
                                // lights after sundown.
-    sgVec4 panel_color;
-    sgCopyVec4( panel_color, cur_light_params.scene_diffuse );
-    if ( fgGetDouble("/systems/electrical/outputs/instrument-lights") > 1.0 ) {
-        if ( panel_color[0] < 0.7 ) panel_color[0] = 0.7;
-        if ( panel_color[1] < 0.2 ) panel_color[1] = 0.2;
-        if ( panel_color[2] < 0.2 ) panel_color[2] = 0.2;
+      glColor4fv( panel_color );
     }
-    glColor4fv( panel_color );
 
     glTexCoord2f(_texture.getMinX(), _texture.getMinY()); glVertex2f(-w2, -h2);
     glTexCoord2f(_texture.getMaxX(), _texture.getMinY()); glVertex2f(w2, -h2);
@@ -1094,8 +1133,9 @@ FGTextLayer::Chunk::Chunk (const string &text, const string &fmt)
 }
 
 FGTextLayer::Chunk::Chunk (ChunkType type, const SGPropertyNode * node,
-                          const string &fmt, float mult)
-  : _type(type), _fmt(fmt), _mult(mult)
+                          const string &fmt, float mult, float offs,
+                           bool truncation)
+  : _type(type), _fmt(fmt), _mult(mult), _offs(offs), _trunc(truncation)
 {
   if (_fmt.empty()) {
     if (type == TEXT_VALUE)
@@ -1119,7 +1159,9 @@ FGTextLayer::Chunk::getValue () const
       sprintf(_buf, _fmt.c_str(), _node->getStringValue());
       break;
     case DOUBLE_VALUE:
-      sprintf(_buf, _fmt.c_str(), _node->getFloatValue() * _mult);
+      double d = _offs + _node->getFloatValue() * _mult;
+      if (_trunc)  d = (d < 0) ? -floor(-d) : floor(d);
+      sprintf(_buf, _fmt.c_str(), d);
       break;
     }
     return _buf;
@@ -1134,28 +1176,22 @@ FGTextLayer::Chunk::getValue () const
 // Implementation of FGSwitchLayer.
 ////////////////////////////////////////////////////////////////////////
 
-FGSwitchLayer::FGSwitchLayer (int w, int h, const SGPropertyNode * node,
-                             FGInstrumentLayer * layer1,
-                             FGInstrumentLayer * layer2)
-  : FGInstrumentLayer(w, h), _node(node), _layer1(layer1), _layer2(layer2)
+FGSwitchLayer::FGSwitchLayer ()
+  : FGGroupLayer()
 {
 }
 
-FGSwitchLayer::~FGSwitchLayer ()
-{
-  delete _layer1;
-  delete _layer2;
-}
-
 void
 FGSwitchLayer::draw ()
 {
   if (test()) {
     transform();
-    if (_node->getBoolValue()) {
-      _layer1->draw();
-    } else {
-      _layer2->draw();
+    int nLayers = _layers.size();
+    for (int i = 0; i < nLayers; i++) {
+      if (_layers[i]->test()) {
+          _layers[i]->draw();
+          return;
+      }
     }
   }
 }