turn_indicator.cxx turn_indicator.hxx \
vertical_speed_indicator.cxx vertical_speed_indicator.hxx \
inst_vertical_speed_indicator.cxx inst_vertical_speed_indicator.hxx \
+ od_gauge.hxx od_gauge.cxx wxradar.hxx wxradar.cxx \
tacan.cxx tacan.hxx
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
#include "turn_indicator.hxx"
#include "vertical_speed_indicator.hxx"
#include "inst_vertical_speed_indicator.hxx" // (TJ)
+#include "od_gauge.hxx"
+#include "wxradar.hxx"
#include "tacan.hxx"
FGInstrumentMgr::FGInstrumentMgr ()
{
set_subsystem("annunciator", new Annunciator);
+ set_subsystem("od_gauge", new FGODGauge, 1.0);
config_props = new SGPropertyNode;
} else if ( name == "vertical-speed-indicator" ) {
set_subsystem( "instrument" + temp.str(),
new VerticalSpeedIndicator( node ) );
+ } else if ( name == "wxradar" ) {
+ set_subsystem( "instrument" + temp.str(),
+ new wxRadarBg ( node ), 0.5 );
} else if ( name == "inst-vertical-speed-indicator" ) { // (TJ)
set_subsystem( "instrument" + temp.str(),
new InstVerticalSpeedIndicator( node ) );
--- /dev/null
+// Owner Drawn Gauge helper class
+//
+// Written by Harald JOHNSEN, started May 2005.
+//
+// Copyright (C) 2005 Harald JOHNSEN - hjohnsen@evc.net
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+//
+//
+
+#include <plib/ssg.h>
+#include <simgear/screen/extensions.hxx>
+#include <simgear/screen/RenderTexture.h>
+#include <simgear/debug/logstream.hxx>
+#include SG_GLU_H
+
+#include <Main/globals.hxx>
+#include <Scenery/scenery.hxx>
+#include "od_gauge.hxx"
+
+FGODGauge::FGODGauge() :
+ rtAvailable( false ),
+ rt( 0 )
+{
+}
+
+// done here and not in init() so we don't allocate a rendering context if it is
+// never used
+void FGODGauge::allocRT () {
+ GLint colorBits = 0;
+ glGetIntegerv( GL_BLUE_BITS, &colorBits );
+ textureWH = 256;
+ rt = new RenderTexture();
+ if( colorBits < 8 )
+ rt->Reset("rgba=5,5,5,1 ctt");
+ else
+ rt->Reset("rgba ctt");
+
+ if( rt->Initialize(256, 256, true) ) {
+ SG_LOG(SG_ALL, SG_INFO, "FGODGauge:Initialize sucessfull");
+ if (rt->BeginCapture())
+ {
+ SG_LOG(SG_ALL, SG_INFO, "FGODGauge:BeginCapture sucessfull, RTT available");
+ rtAvailable = true;
+ glViewport(0, 0, textureWH, textureWH);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D( -256.0, 256.0, -256.0, 256.0 );
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glDisable(GL_LIGHTING);
+ glEnable(GL_COLOR_MATERIAL);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_FOG);
+ glDisable(GL_DEPTH_TEST);
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_ALPHA_TEST);
+ glAlphaFunc(GL_GREATER, 0.0f);
+ glDisable(GL_SMOOTH);
+ glEnable(GL_BLEND);
+ glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
+ rt->EndCapture();
+ } else
+ SG_LOG(SG_ALL, SG_WARN, "FGODGauge:BeginCapture failed, RTT not available, using backbuffer");
+ } else
+ SG_LOG(SG_ALL, SG_WARN, "FGODGauge:Initialize failed, RTT not available, using backbuffer");
+}
+
+FGODGauge::~FGODGauge() {
+ delete rt;
+}
+
+void FGODGauge::init () {
+}
+
+void FGODGauge::update (double dt) {
+}
+
+void FGODGauge::beginCapture(int viewSize) {
+ if( ! rt )
+ allocRT();
+ if(rtAvailable) {
+ rt->BeginCapture();
+ }
+ else
+ set2D();
+ textureWH = viewSize;
+ glViewport(0, 0, textureWH, textureWH);
+}
+
+void FGODGauge::beginCapture(void) {
+ if( ! rt )
+ allocRT();
+ if(rtAvailable) {
+ rt->BeginCapture();
+ }
+ else
+ set2D();
+}
+
+void FGODGauge::Clear(void) {
+ if(rtAvailable) {
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ else {
+ glDisable(GL_BLEND);
+ glDisable(GL_ALPHA_TEST);
+ glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
+ glRectf(-256.0, -256.0, 256.0, 256.0);
+ glEnable(GL_BLEND);
+ glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
+ glEnable(GL_ALPHA_TEST);
+ }
+}
+
+void FGODGauge::endCapture(GLuint texID) {
+ glBindTexture(GL_TEXTURE_2D, texID);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, textureWH, textureWH);
+ if(rtAvailable)
+ rt->EndCapture();
+ else
+ set3D();
+}
+
+void FGODGauge::setSize(int viewSize) {
+ textureWH = viewSize;
+ glViewport(0, 0, textureWH, textureWH);
+}
+
+bool FGODGauge::serviceable(void) {
+ return rtAvailable;
+}
+
+/**
+ * Locate a texture SSG node in a branch.
+ */
+static ssgTexture *
+find_texture_node (ssgEntity * node, const char * name)
+{
+ if( node->isA( ssgTypeTexture() ) ) {
+ ssgTexture *tex = (ssgTexture *) node;
+ char * texture_name = tex->getFilename();
+ if (texture_name != 0 && !strcmp(name, texture_name))
+ return tex;
+ }
+ else if (node->isAKindOf(ssgTypeBranch())) {
+ int nKids = node->getNumKids();
+ for (int i = 0; i < nKids; i++) {
+ ssgTexture * result =
+ find_texture_node(((ssgBranch*)node)->getKid(i), name);
+ if (result != 0)
+ return result;
+ }
+ }
+ return 0;
+}
+
+void FGODGauge::set_texture(const char * name, GLuint new_texture) {
+ ssgEntity * root = globals->get_scenery()->get_aircraft_branch();
+ ssgTexture * node = find_texture_node( root, name );
+ if( node )
+ node->setHandle( new_texture );
+}
+
+void FGODGauge::set2D() {
+ glPushAttrib ( GL_ENABLE_BIT | GL_VIEWPORT_BIT | GL_TRANSFORM_BIT | GL_LIGHTING_BIT ) ;
+
+ glDisable(GL_LIGHTING);
+ glEnable(GL_COLOR_MATERIAL);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_FOG);
+ glDisable(GL_DEPTH_TEST);
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glEnable(GL_TEXTURE_2D);
+ glDisable(GL_SMOOTH);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ glViewport ( 0, 0, textureWH, textureWH ) ;
+ glMatrixMode ( GL_PROJECTION ) ;
+ glPushMatrix () ;
+ glLoadIdentity () ;
+ gluOrtho2D( -256.0, 256.0, -256.0, 256.0 );
+ glMatrixMode ( GL_MODELVIEW ) ;
+ glPushMatrix () ;
+ glLoadIdentity () ;
+
+ glAlphaFunc(GL_GREATER, 0.0f);
+
+}
+
+void FGODGauge::set3D() {
+ glMatrixMode ( GL_PROJECTION ) ;
+ glPopMatrix () ;
+ glMatrixMode ( GL_MODELVIEW ) ;
+ glPopMatrix () ;
+ glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
+ glPopAttrib () ;
+}
--- /dev/null
+// Owner Drawn Gauge helper class
+//
+// Written by Harald JOHNSEN, started May 2005.
+//
+// Copyright (C) 2005 Harald JOHNSEN - hjohnsen@evc.net
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+//
+//
+
+#ifndef _OD_GAUGE_HXX
+#define _OD_GAUGE_HXX
+
+
+#include <plib/ssg.h>
+#include <simgear/structure/subsystem_mgr.hxx>
+
+class RenderTexture;
+
+/**
+ * Owner Drawn Gauge helper class.
+ */
+class FGODGauge : public SGSubsystem {
+
+public:
+ FGODGauge ( SGPropertyNode *node );
+ FGODGauge();
+ ~FGODGauge();
+ virtual void init ();
+ virtual void update (double dt);
+
+ /**
+ * Start the rendering of the RTT context.
+ * @param viewSize size of the destination texture
+ */
+ void beginCapture(int viewSize);
+ /**
+ * Start the rendering of the RTT context.
+ */
+ void beginCapture(void);
+ /**
+ * Clear the background.
+ */
+ void Clear(void);
+ /**
+ * Finish rendering and save the buffer to a texture.
+ * @param texID name of a gl texture
+ */
+ void endCapture(GLuint texID);
+ /**
+ * Set the size of the destination texture.
+ * @param viewSize size of the destination texture
+ */
+ void setSize(int viewSize);
+ /**
+ * Say if we can render to a texture.
+ * @return true if rtt is available
+ */
+ bool serviceable(void);
+ /**
+ * Replace an opengl texture name inside the aircraft scene graph.
+ * This is to replace a static texture by a dynamic one
+ * @param name texture filename
+ * @param new_texture dynamic texture to replace the old one
+ */
+ void set_texture(const char * name, GLuint new_texture);
+
+private:
+ int textureWH;
+ RenderTexture *rt;
+ bool rtAvailable;
+
+ void allocRT(void);
+ void set2D(void);
+ void set3D(void);
+};
+
+#endif // _OD_GAUGE_HXX
--- /dev/null
+// Wx Radar background texture
+//
+// Written by Harald JOHNSEN, started May 2005.
+//
+// Copyright (C) 2005 Harald JOHNSEN - hjohnsen@evc.net
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+//
+//
+
+#include <plib/sg.h>
+#include <plib/ssg.h>
+#include <Main/fg_props.hxx>
+#include <Main/globals.hxx>
+#include <Cockpit/panel.hxx>
+#include <Cockpit/hud.hxx>
+
+#include <simgear/constants.h>
+#include <simgear/misc/sg_path.hxx>
+#include <simgear/environment/visual_enviro.hxx>
+#include "instrument_mgr.hxx"
+#include "od_gauge.hxx"
+#include "wxradar.hxx"
+
+// texture name to use in 2D and 3D instruments
+static const char *odgauge_name = "Aircraft/Instruments/Textures/od_wxradar.rgb";
+
+wxRadarBg::wxRadarBg ( SGPropertyNode *node) :
+ name("wxRadar"),
+ num(0),
+ resultTexture( 0 ),
+ wxEcho( 0 ),
+ last_switchKnob( "off" ),
+ sim_init_done ( false ),
+ odg( 0 )
+{
+ int i;
+ for ( i = 0; i < node->nChildren(); ++i ) {
+ SGPropertyNode *child = node->getChild(i);
+ string cname = child->getName();
+ string cval = child->getStringValue();
+ if ( cname == "name" ) {
+ name = cval;
+ } else if ( cname == "number" ) {
+ num = child->getIntValue();
+ } else {
+ SG_LOG( SG_INSTR, SG_WARN, "Error in wxRadar config logic" );
+ if ( name.length() ) {
+ SG_LOG( SG_INSTR, SG_WARN, "Section = " << name );
+ }
+ }
+ }
+}
+
+wxRadarBg::wxRadarBg ()
+{
+}
+
+wxRadarBg::~wxRadarBg ()
+{
+}
+
+void
+wxRadarBg::init ()
+{
+ string branch;
+ branch = "/instrumentation/" + name;
+
+ _Instrument = fgGetNode(branch.c_str(), num, true );
+ _serviceable_node = _Instrument->getChild("serviceable", 0, true);
+ resultTexture = FGTextureManager::createTexture( odgauge_name );
+ resultTexture->ref();
+ SGPath tpath(globals->get_fg_root());
+ tpath.append("Aircraft/Instruments/Textures/wxecho.rgb");
+ // no mipmap or else alpha will mix with pixels on the border of shapes, ruining the effect
+ wxEcho = new ssgTexture( tpath.c_str(), false, false, false);
+ wxEcho->ref();
+
+ _Instrument->setFloatValue("trk", 0.0);
+ _Instrument->setFloatValue("tilt", 0.0);
+ _Instrument->setStringValue("status","");
+ // those properties are used by a radar instrument of a MFD
+ // input switch = OFF | TST | STBY | ON
+ // input mode = WX | WXA | MAP
+ // ouput status = STBY | TEST | WX | WXA | MAP | blank
+ // input lightning = true | false
+ // input TRK = +/- n degrees
+ // input TILT = +/- n degree
+ // input autotilt = true | false
+ // input range = n nm (20/40/80)
+ // input display-mode = arc | rose | map | plan
+
+ FGInstrumentMgr *imgr = (FGInstrumentMgr *) globals->get_subsystem("instrumentation");
+ odg = (FGODGauge *) imgr->get_subsystem("od_gauge");
+}
+
+void
+wxRadarBg::update (double delta_time_sec)
+{
+ if( ! sim_init_done ) {
+ if( ! fgGetBool("sim/sceneryloaded", false) )
+ return;
+ sim_init_done = true;
+ }
+ if ( !odg || ! _serviceable_node->getBoolValue() ) {
+ _Instrument->setStringValue("status","");
+ return;
+ }
+ string switchKnob = _Instrument->getStringValue("switch", "on");
+ string modeButton = _Instrument->getStringValue("mode", "wx");
+ bool drawLightning = _Instrument->getBoolValue("lightning", true);
+ float range_nm = _Instrument->getFloatValue("range", 40.0);
+ float range_m = range_nm * SG_NM_TO_METER;
+
+ if( last_switchKnob != switchKnob ) {
+ // since 3D models don't share textures with the rest of the world
+ // we must locate them and replace their handle by hand
+ // only do that when the instrument is turned on
+ if( last_switchKnob == "off" )
+ odg->set_texture( odgauge_name, resultTexture->getHandle());
+ last_switchKnob = switchKnob;
+ }
+ odg->beginCapture(256);
+ odg->Clear();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glPushMatrix();
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ if( switchKnob == "off" ) {
+ _Instrument->setStringValue("status","");
+ } else if( switchKnob == "stby" ) {
+ _Instrument->setStringValue("status","STBY");
+ } else if( switchKnob == "tst" ) {
+ _Instrument->setStringValue("status","TST");
+ // find something interesting to do...
+ } else {
+ string display_mode = _Instrument->getStringValue("display-mode", "arc");
+ // pretend we have a scan angle bigger then the FOV
+ // TODO:check real fov, enlarge if < nn, and do clipping if > mm
+ const float fovFactor = 1.45f;
+ float view_heading = get_heading() * SG_DEGREES_TO_RADIANS;
+ float range = 200.0f / range_nm;
+ _Instrument->setStringValue("status", modeButton.c_str());
+ if( display_mode == "arc" ) {
+ glTranslatef(0.0f, -180.0f, 0.0f);
+ range = 2*180.0f / range_nm;
+ } else if( display_mode == "map" ) {
+// float view_heading = get_track() * SG_DEGREES_TO_RADIANS;
+ } else if( display_mode == "plan" ) {
+ // no sense I presume
+ float view_heading = 0.0;
+ } else {
+ // rose
+ }
+ range /= SG_NM_TO_METER;
+ // we will rotate the echo quads, this gives a better rendering
+ const float rot_x = cos ( view_heading );
+ const float rot_y = sin ( view_heading );
+
+ list_of_SGWxRadarEcho *radarEcho = sgEnviro.get_radar_echo();
+ list_of_SGWxRadarEcho::iterator iradarEcho;
+ const float LWClevel[] = { 0.1f, 0.5f, 2.1f };
+ const float symbolSize = 1.0f / 8.0f ;
+ // draw the radar echo, we do that in 3 passes, one for each color level
+ // this is to 'merge' same colors together
+ glBindTexture(GL_TEXTURE_2D, wxEcho->getHandle() );
+ glColor3f(1.0f, 1.0f, 1.0f);
+ glBegin( GL_QUADS );
+
+ for(int level = 0; level <= 2 ; level++ ) {
+ float col = level * symbolSize;
+ for(iradarEcho = radarEcho->begin() ; iradarEcho != radarEcho->end() ; iradarEcho++ ) {
+ int cloudId = (iradarEcho->cloudId) ;
+ bool upgrade = ((cloudId >> 5) & 1);
+ float lwc = iradarEcho->LWC + (upgrade ? 1.0f : 0.0f);
+ // skip ns
+ if( iradarEcho->LWC >= 0.5 && iradarEcho->LWC <= 0.6)
+ continue;
+ if( (! iradarEcho->lightning) && ( lwc >= LWClevel[level]) ) {
+ float dist = sgSqrt( iradarEcho->dist );
+ float size = iradarEcho->radius * 2.0;
+ if( dist - size > range_m )
+ continue;
+ dist = dist * range;
+ size = size * range;
+ // compute the relative angle from the view direction
+ float angle = ( view_heading + iradarEcho->heading );
+ if( angle > SG_PI )
+ angle -= 2.0*SG_PI;
+ if( angle < - SG_PI )
+ angle += 2.0*SG_PI;
+ // and apply a fov factor to simulate a greater scan angle
+ angle = angle * fovFactor + SG_PI / 2.0;
+ float x = cos( angle ) * dist;
+ float y = sin( angle ) * dist;
+ // use different shapes so the display is less boring
+ float row = symbolSize * (float) (4 + (cloudId & 3) );
+ float size_x = rot_x * size;
+ float size_y = rot_y * size;
+ glTexCoord2f( col, row);
+ glVertex2f( x - size_x, y - size_y);
+ glTexCoord2f( col+symbolSize, row);
+ glVertex2f( x + size_y, y - size_x);
+ glTexCoord2f( col+symbolSize, row+symbolSize);
+ glVertex2f( x + size_x, y + size_y);
+ glTexCoord2f( col, row+symbolSize);
+ glVertex2f( x - size_y, y + size_x);
+ }
+ }
+ }
+ glEnd(); // GL_QUADS
+
+ // draw lightning echos
+ if( drawLightning ) {
+ float col = 3 * symbolSize;
+ float row = 4 * symbolSize;
+ for(iradarEcho = radarEcho->begin() ; iradarEcho != radarEcho->end() ; iradarEcho++ ) {
+ if( iradarEcho->lightning ) {
+ float dist = iradarEcho->dist;
+ dist = dist * range;
+ float angle = (view_heading - iradarEcho->heading);
+ if( angle > SG_PI )
+ angle -= 2.0*SG_PI;
+ if( angle < - SG_PI )
+ angle += 2.0*SG_PI;
+ angle = angle * fovFactor - SG_PI / 2.0;
+ float x = cos( angle ) * dist;
+ float y = sin( angle ) * dist;
+ glColor3f(1.0f, 1.0f, 1.0f);
+ float size = symbolSize * 0.5f;
+ glBegin( GL_QUADS );
+ glTexCoord2f( col, row);
+ glVertex2f( x - size, y - size);
+ glTexCoord2f( col+symbolSize, row);
+ glVertex2f( x + size, y - size);
+ glTexCoord2f( col+symbolSize, row+symbolSize);
+ glVertex2f( x + size, y + size);
+ glTexCoord2f( col, row+symbolSize);
+ glVertex2f( x - size, y + size);
+ glEnd();
+ }
+ }
+ }
+ // erase what is out of sight of antenna
+ /*
+ |\ /|
+ | \ / |
+ | \ / |
+ ---------
+ | |
+ | |
+ ---------
+ */
+ float yOffset = 180.0f, xOffset = 256.0f;
+ if( display_mode != "arc" ) {
+ yOffset = 40.0f;
+ xOffset = 240.0f;
+ }
+ glDisable(GL_BLEND);
+ glColor4f(1.0f, 0.0f, 0.0f, 0.01f);
+ glBegin( GL_QUADS );
+ glTexCoord2f( 0.5f, 0.25f);
+ glVertex2f(-xOffset, 0.0 + yOffset);
+ glTexCoord2f( 1.0f, 0.25f);
+ glVertex2f(xOffset, 0.0 + yOffset);
+ glTexCoord2f( 1.0f, 0.5f);
+ glVertex2f(xOffset, 256.0 + yOffset);
+ glTexCoord2f( 0.5f, 0.5f);
+ glVertex2f(-xOffset, 256.0 + yOffset);
+ glEnd();
+
+ glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
+// glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
+ glDisable(GL_ALPHA_TEST);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ glBegin( GL_TRIANGLES );
+ glVertex2f(0.0, 0.0);
+ glVertex2f(-256.0, 0.0);
+ glVertex2f(-256.0, 256.0);
+
+ glVertex2f(0.0, 0.0);
+ glVertex2f(256.0, 0.0);
+ glVertex2f(256.0, 256.0);
+
+ glVertex2f(-256, 0.0);
+ glVertex2f(256.0, 0.0);
+ glVertex2f(-256.0, -256.0);
+
+ glVertex2f(256, 0.0);
+ glVertex2f(256.0, -256.0);
+ glVertex2f(-256.0, -256.0);
+ glEnd();
+
+ // DEBUG only
+/* glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
+ glBegin( GL_LINES );
+ glVertex2f(0.0, 0.0);
+ glVertex2f(-256.0, 256.0);
+ glVertex2f(0.0, 0.0);
+ glVertex2f(256.0, 256.0);
+ glEnd();*/
+
+ glEnable(GL_BLEND);
+ glEnable(GL_ALPHA_TEST);
+ }
+ glPopMatrix();
+ odg->endCapture( resultTexture->getHandle() );
+}
--- /dev/null
+// Wx Radar background texture
+//
+// Written by Harald JOHNSEN, started May 2005.
+//
+// Copyright (C) 2005 Harald JOHNSEN - hjohnsen@evc.net
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+//
+//
+
+#ifndef _INST_WXRADAR_HXX
+#define _INST_WXRADAR_HXX
+
+#include <simgear/props/props.hxx>
+#include <simgear/structure/subsystem_mgr.hxx>
+
+class ssgTexture;
+class FGODGauge;
+
+class wxRadarBg : public SGSubsystem {
+
+
+public:
+
+ wxRadarBg ( SGPropertyNode *node );
+ wxRadarBg ();
+ virtual ~wxRadarBg ();
+
+ virtual void init ();
+ virtual void update (double dt);
+
+private:
+
+ string name;
+ int num;
+
+ SGPropertyNode_ptr _serviceable_node;
+ SGPropertyNode_ptr _Instrument;
+ ssgTexture *resultTexture;
+ ssgTexture *wxEcho;
+ string last_switchKnob;
+ bool sim_init_done;
+ FGODGauge *odg;
+};
+
+#endif // _INST_WXRADAR_HXX
return FG_OPTIONS_OK;
}
+static int
+fgOptLivery( const char *arg )
+{
+ string opt = arg;
+ string livery_path = "livery/" + opt;
+ fgSetString("/sim/model/texture-path", livery_path.c_str() );
+ return FG_OPTIONS_OK;
+}
+
static map<string,size_t> fgOptionMap;
/*
{"adf", true, OPTION_FUNC, "", false, "", fgOptADF },
{"dme", true, OPTION_FUNC, "", false, "", fgOptDME },
{"min-status", true, OPTION_STRING, "/sim/aircraft-min-status", false, "all", 0 },
+ {"livery", true, OPTION_FUNC, "", false, "", fgOptLivery },
{0}
};
#include "acmodel.hxx"
+class fgLoaderOptions : ssgLoaderOptions {
+
+public:
+ virtual void makeTexturePath ( char* path, const char *fname ) const ;
+ string livery_path;
+
+};
+
+void fgLoaderOptions::makeTexturePath ( char *path, const char *fname ) const
+{
+ /* Remove all leading path information. */
+ const char* seps = "\\/" ;
+ const char* fn = & fname [ strlen ( fname ) - 1 ] ;
+ for ( ; fn != fname && strchr(seps,*fn) == NULL ; fn-- )
+ /* Search back for a seperator */ ;
+ if ( strchr(seps,*fn) != NULL )
+ fn++ ;
+ fname = fn ;
+ // if we have a livery path and the texture is found there then we use that
+ // path in priority, if the texture was not found or we add no additional
+ // livery path then we use the current model path or model/texture-path
+ if( livery_path.size() ) {
+ make_path( path, livery_path.c_str(), fname );
+ if( ulFileExists( path ) )
+ return;
+ }
+ make_path ( path, texture_dir, fname ) ;
+}
+
+static fgLoaderOptions _fgLoaderOptions;
+
\f
////////////////////////////////////////////////////////////////////////
// Implementation of FGAircraftModel
void
FGAircraftModel::init ()
{
+ ssgLoaderOptions *currLoaderOptions = ssgGetCurrentOptions();
+ ssgSetCurrentOptions( (ssgLoaderOptions*)&_fgLoaderOptions );
_aircraft = new SGModelPlacement;
string path = fgGetString("/sim/model/path", "Models/Geometry/glider.ac");
+ string texture_path = fgGetString("/sim/model/texture-path");
+ if( texture_path.size() ) {
+ SGPath temp_path;
+ if ( !ulIsAbsolutePathName( texture_path.c_str() ) ) {
+ temp_path = globals->get_fg_root();
+ temp_path.append( SGPath( path ).dir() );
+ temp_path.append( texture_path );
+ _fgLoaderOptions.livery_path = temp_path.str();
+ } else
+ _fgLoaderOptions.livery_path = texture_path;
+ }
try {
ssgBranch *model = fgLoad3DModelPanel( globals->get_fg_root(),
path,
// Register that one at the scenery manager
globals->get_scenery()->register_placement_transform(_aircraft->getTransform());
+ ssgSetCurrentOptions( currLoaderOptions );
}
void