Harald JOHNSEN:
Changes ======= - acmodel.cxx : we now have an optional new property (/sim/model/texture-path) that is used as the first path in wich aircraft textures are searched. If textures are not found there then the usual texture path or model path is used ; This allows to replace only needed textures for liveries ; - options.cxx : added a new --livery=xxx option for the user pleasure ; this will just set the /sim/model/texture-path property with /livery/xxxx - od_gauge.cxx, og_gauge.hxx, cockpit.cxx, cockpit.hxx, generic-instrumentation.xml : added an helper class that contain a rendering context for glass instrument or any other opengl drawn instrument ; - wxradar.cxx, instrument_mgr.cxx, wxradar.hxx : first experimentation of a weather radar ;
This commit is contained in:
parent
f057fd0d48
commit
68f248879c
8 changed files with 746 additions and 0 deletions
|
@ -23,6 +23,7 @@ libInstrumentation_a_SOURCES = \
|
|||
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
|
||||
|
|
|
@ -36,12 +36,15 @@
|
|||
#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;
|
||||
|
||||
|
@ -150,6 +153,9 @@ bool FGInstrumentMgr::build ()
|
|||
} 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 ) );
|
||||
|
|
214
src/Instrumentation/od_gauge.cxx
Normal file
214
src/Instrumentation/od_gauge.cxx
Normal file
|
@ -0,0 +1,214 @@
|
|||
// 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 () ;
|
||||
}
|
90
src/Instrumentation/od_gauge.hxx
Normal file
90
src/Instrumentation/od_gauge.hxx
Normal file
|
@ -0,0 +1,90 @@
|
|||
// 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
|
322
src/Instrumentation/wxradar.cxx
Normal file
322
src/Instrumentation/wxradar.cxx
Normal file
|
@ -0,0 +1,322 @@
|
|||
// 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() );
|
||||
}
|
58
src/Instrumentation/wxradar.hxx
Normal file
58
src/Instrumentation/wxradar.hxx
Normal file
|
@ -0,0 +1,58 @@
|
|||
// 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
|
|
@ -1152,6 +1152,15 @@ fgOptDME( const char *arg )
|
|||
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;
|
||||
|
||||
/*
|
||||
|
@ -1352,6 +1361,7 @@ struct OptionDesc {
|
|||
{"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}
|
||||
};
|
||||
|
||||
|
|
|
@ -31,6 +31,37 @@
|
|||
#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;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of FGAircraftModel
|
||||
|
@ -60,8 +91,21 @@ FGAircraftModel::~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,
|
||||
|
@ -83,6 +127,7 @@ FGAircraftModel::init ()
|
|||
|
||||
// Register that one at the scenery manager
|
||||
globals->get_scenery()->register_placement_transform(_aircraft->getTransform());
|
||||
ssgSetCurrentOptions( currLoaderOptions );
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue