]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/HUD/HUD.hxx
5258be14ccfaea5ee8b186808b1b13fc22d71b12
[flightgear.git] / src / Instrumentation / HUD / HUD.hxx
1 // HUD.hxx -- Head Up Display
2 //
3 // Written by Michele America, started September 1997.
4 //
5 // Copyright (C) 1997  Michele F. America  [micheleamerica#geocities:com]
6 // Copyright (C) 2006  Melchior FRANZ  [mfranz#aon:at]
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21
22 #ifndef _HUD_HXX
23 #define _HUD_HXX
24
25 #include <simgear/compiler.h>
26
27 #ifdef HAVE_CONFIG_H
28 #  include <config.h>
29 #endif
30
31 #include <vector>
32 #include <deque>
33 #include STL_FSTREAM
34
35 SG_USING_STD(deque);
36 SG_USING_STD(vector);
37 SG_USING_NAMESPACE(std);
38
39 #include <plib/sg.h>
40
41 #include <simgear/math/SGLimits.hxx>
42 #include <simgear/constants.h>
43 #include <simgear/structure/subsystem_mgr.hxx>
44
45 #include <Airports/runways.hxx>     // FGRunway
46 #include <GUI/gui.h>                // fntRenderer ?   guiErrorMessage()
47 #include <GUI/new_gui.hxx>          // FGFontCache, FGColor
48 #include <Include/fg_typedefs.h>
49 #include <Main/fg_props.hxx>
50
51
52 class FGViewer;
53 class SGCondition;
54
55
56
57 class LineSegment {
58 public:
59     LineSegment(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1)
60         : _x0(x0), _y0(y0), _x1(x1), _y1(y1) {}
61
62     void draw() const {
63         glVertex2f(_x0, _y0);
64         glVertex2f(_x1, _y1);
65     }
66
67 private:
68     GLfloat _x0, _y0, _x1, _y1;
69 };
70
71
72
73 class LineList {
74 public:
75     void add(const LineSegment& seg) { _list.push_back(seg); }
76     void erase() { _list.erase(_list.begin(), _list.end()); }
77     inline unsigned int size() const { return _list.size(); }
78     void draw() {
79         glBegin(GL_LINES);
80         vector<LineSegment>::const_iterator it, end = _list.end();
81         for (it = _list.begin(); it != end; ++it)
82             it->draw();
83         glEnd();
84     }
85
86 private:
87     vector<LineSegment> _list;
88 };
89
90
91
92 class HUDText {
93 public:
94     HUDText(fntRenderer *f, float x, float y, const char *s, int align = 0, int digits = 0);
95     void draw();
96     enum {
97         LEFT    = 0x0001,
98         RIGHT   = 0x0002,
99         TOP     = 0x0004,
100         BOTTOM  = 0x0008,
101         HCENTER = 0x0010,
102         VCENTER = 0x0020,
103         CENTER  = (HCENTER|VCENTER),
104     };
105
106 private:
107     fntRenderer *_fnt;
108     float _x, _y;
109     int _digits;
110     static const int BUFSIZE = 64;
111     char _msg[BUFSIZE];
112 };
113
114
115
116 class TextList {
117 public:
118     TextList() { _font = 0; }
119
120     void setFont(fntRenderer *Renderer) { _font = Renderer; }
121     void add(float x, float y, const char *s, int align = 0, int digit = 0) {
122         _list.push_back(HUDText(_font, x, y, s, align, digit));
123     }
124     void erase() { _list.erase(_list.begin(), _list.end()); }
125     void draw() {
126         assert(_font);
127
128         // FIXME
129         glPushAttrib(GL_COLOR_BUFFER_BIT);
130         glEnable(GL_BLEND);
131
132         _font->begin();
133         vector<HUDText>::iterator it, end = _list.end();
134         for (it = _list.begin(); it != end; ++it)
135             it->draw();
136         _font->end();
137
138         glDisable(GL_TEXTURE_2D);
139         glPopAttrib();
140     }
141
142 private:
143     fntRenderer *_font;
144     vector<HUDText> _list;
145 };
146
147
148
149
150
151
152 class HUD : public SGSubsystem, public SGPropertyChangeListener {
153 public:
154     HUD();
155     ~HUD();
156     void init();
157     void update(double);
158
159     // called from Main/renderer.cxx to draw 2D and 3D HUD
160     void draw();
161
162     // listener callback to read various HUD related properties
163     void valueChanged(SGPropertyNode *);
164     // set current glColor
165     void setColor() const;
166     inline bool isVisible() const { return _visible; }
167     inline bool isAntialiased() const { return _antialiased; }
168     inline bool isTransparent() const { return _transparent; }
169     inline bool is3D() const { return _3Denabled; }
170     inline float alphaClamp() const { return _cl; }
171     inline double timer() const { return _timer; }
172
173     enum Units { FEET, METER };
174     Units getUnits() const { return _units; }
175
176     enum {
177         HORIZONTAL = 0x0000,  // keep that at zero?
178         VERTICAL   = 0x0001,
179         TOP        = 0x0002,
180         BOTTOM     = 0x0004,
181         LEFT       = 0x0008,
182         RIGHT      = 0x0010,
183         NOTICKS    = 0x0020,
184         NOTEXT     = 0x0040,
185         BOTH       = (LEFT|RIGHT),
186     };
187
188 protected:
189     void common_draw();
190     int load(const char *, float x = 320.0f, float y = 240.0f,
191             int level = 0, const string& indent = "");
192
193 private:
194     void draw3D();
195     void draw2D(GLfloat, GLfloat, GLfloat, GLfloat);
196
197     class Input;
198     class Item;
199     class Label;
200     class Scale;
201     class Gauge;
202     class Tape;
203     class Dial;
204     class TurnBankIndicator;
205     class Ladder;
206     class Runway;
207     class AimingReticle;
208
209     deque<Item *> _items;
210
211     SGPropertyNode_ptr _current;
212     SGPropertyNode_ptr _visibility;
213     SGPropertyNode_ptr _3DenabledN;
214     SGPropertyNode_ptr _antialiasing;
215     SGPropertyNode_ptr _transparency;
216     SGPropertyNode_ptr _red, _green, _blue, _alpha;
217     SGPropertyNode_ptr _alpha_clamp;
218     SGPropertyNode_ptr _brightness;
219     bool _visible;
220     bool _3Denabled;
221     bool _antialiased;
222     bool _transparent;
223     float _r, _g, _b, _a, _cl;
224
225     SGPropertyNode_ptr _scr_widthN, _scr_heightN;
226     int _scr_width, _scr_height;
227     SGPropertyNode_ptr _unitsN;
228     Units _units;
229     double _timer;
230
231     fntRenderer *_font_renderer;
232     FGFontCache *_font_cache;
233     fntTexFont *_font;
234     float _font_size;
235     int _style;
236
237     TextList _text_list;
238     LineList _line_list;
239     LineList _stipple_line_list;
240 };
241
242
243
244 class HUD::Input {
245 public:
246     Input(const SGPropertyNode *n, float factor = 1.0, float offset = 0.0,
247             float min = -SGLimitsf::max(), float max = SGLimitsf::max()) :
248         _valid(false),
249         _property(0),
250         _damped(SGLimitsf::max())
251     {
252         if (!n)
253             return;
254         _factor = n->getFloatValue("factor", factor);
255         _offset = n->getFloatValue("offset", offset);
256         _min = n->getFloatValue("min", min);
257         _max = n->getFloatValue("max", max);
258         _coeff = 1.0 - 1.0 / powf(10, fabsf(n->getFloatValue("damp", 0.0)));
259         SGPropertyNode *p = ((SGPropertyNode *)n)->getNode("property", false);
260         if (p) {
261             const char *path = p->getStringValue();
262             if (path && path[0]) {
263                 _property = fgGetNode(path, true);
264                 _valid = true;
265             }
266         }
267     }
268
269     bool getBoolValue() const {
270         assert(_property);
271         return _property->getBoolValue();
272     }
273
274     const char *getStringValue() const {
275         assert(_property);
276         return _property->getStringValue();
277     }
278
279     float getFloatValue() {
280         assert(_property);
281         float f = _property->getFloatValue() * _factor + _offset;
282         if (_damped == SGLimitsf::max())
283             _damped = f;
284         if (_coeff > 0.0f)
285             f = _damped = f * (1.0f - _coeff) + _damped * _coeff;
286         return clamp(f);
287     }
288
289     inline float isValid() const { return _valid; }
290     inline float min() const { return _min; }
291     inline float max() const { return _max; }
292     inline float factor() const { return _factor; }
293     float clamp(float v) const { return v < _min ? _min : v > _max ? _max : v; }
294
295     void set_min(float m, bool force = true) {
296         if (force || _min == -SGLimitsf::max())
297             _min = m;
298     }
299     void set_max(float m, bool force = true) {
300         if (force || _max == SGLimitsf::max())
301             _max = m;
302     }
303
304 private:
305     bool _valid;
306     SGConstPropertyNode_ptr _property;
307     float _factor;
308     float _offset;
309     float _min;
310     float _max;
311     float _coeff;
312     float _damped;
313 };
314
315
316
317 class HUD::Item {
318 public:
319     Item(HUD *parent, const SGPropertyNode *, float x = 0.0f, float y = 0.0f);
320     virtual ~Item () {}
321     virtual void draw() = 0;
322     virtual bool isEnabled();
323
324 protected:
325     inline float get_span()       const { return _scr_span; }
326     inline int   get_digits()     const { return _digits; }
327
328     inline bool option_vert()    const { return (_options & VERTICAL) == VERTICAL; }
329     inline bool option_left()    const { return (_options & LEFT) == LEFT; }
330     inline bool option_right()   const { return (_options & RIGHT) == RIGHT; }
331     inline bool option_both()    const { return (_options & BOTH) == BOTH; }
332     inline bool option_noticks() const { return (_options & NOTICKS) == NOTICKS; }
333     inline bool option_notext()  const { return (_options & NOTEXT) == NOTEXT; }
334     inline bool option_top()     const { return (_options & TOP) == TOP; }
335     inline bool option_bottom()  const { return (_options & BOTTOM) == BOTTOM; }
336
337     void draw_line(float x1, float y1, float x2, float y2);
338     void draw_stipple_line(float x1, float y1, float x2, float y2);
339     void draw_text(float x, float y, char *msg, int align = 0, int digit = 0);
340     void draw_circle(float x1, float y1, float r) const;
341     void draw_bullet(float, float, float);
342
343     HUD         *_hud;
344     string      _name;
345     int         _options;
346     float       _x, _y, _w, _h;
347     float       _center_x, _center_y;
348
349 private:
350     SGCondition *_condition;
351     float       _disp_factor;   // Multiply by to get numbers shown on scale.
352     float       _scr_span;      // Working values for draw;
353     int         _digits;
354 };
355
356
357
358 class HUD::Label : public Item {
359 public:
360     Label(HUD *parent, const SGPropertyNode *, float x, float y);
361     virtual void draw();
362
363 private:
364     enum Format {
365         INVALID,
366         NONE,
367         INT,
368         LONG,
369         FLOAT,
370         DOUBLE,
371         STRING,
372     };
373
374     Format  check_format(const char *) const;
375     bool    blink();
376
377     Input   _input;
378     Format  _mode;
379     string  _format;
380     int     _halign;    // HUDText alignment
381     int     _blink;
382     bool    _box;
383     float   _text_y;
384     float   _pointer_width;
385     float   _pointer_length;
386
387     SGCondition *_blink_condition;
388     double  _blink_interval;
389     double  _blink_target;  // time for next blink state change
390     bool    _blink_state;
391 };
392
393
394
395 // abstract base class for both moving scale and moving needle (fixed scale)
396 // indicators.
397 //
398 class HUD::Scale : public Item {
399 public:
400     Scale(HUD *parent, const SGPropertyNode *, float x, float y);
401     virtual void draw    ( void ) {}  // No-op here. Defined in derived classes.
402
403 protected:
404     inline float factor() const { return _display_factor; }
405     inline float range_to_show() const { return _range_shown; }
406
407     Input _input;
408     float _major_divs;      // major division marker units
409     float _minor_divs;      // minor division marker units
410     unsigned int _modulo;   // Roll over point
411
412 private:
413     float _range_shown;     // Width Units.
414     float _display_factor;  // factor => screen units/range values.
415 };
416
417
418 class HUD::Gauge : public Scale {
419 public:
420     Gauge(HUD *parent, const SGPropertyNode *, float x, float y);
421     virtual void draw();
422 };
423
424
425
426 // displays the indicated quantity on a scale that moves past the
427 // pointer. It may be horizontal or vertical.
428 //
429 class HUD::Tape : public Scale {
430 public:
431     Tape(HUD *parent, const SGPropertyNode *, float x, float y);
432     virtual void draw();
433
434 protected:
435     void draw_fixed_pointer(float, float, float, float, float, float);
436     void zoomed_scale(int, int);
437
438 private:
439     float  _val_span;
440     float  _half_width_units;
441     bool   _draw_tick_bottom;
442     bool   _draw_tick_top;
443     bool   _draw_tick_right;
444     bool   _draw_tick_left;
445     bool   _draw_cap_bottom;
446     bool   _draw_cap_top;
447     bool   _draw_cap_right;
448     bool   _draw_cap_left;
449     float  _marker_offset;
450     bool   _pointer;
451     int    _zoom;
452
453     enum PointerType { FIXED, MOVING } _pointer_type;
454     enum TickType { LINE, CIRCLE } _tick_type;
455     enum TickLength { VARIABLE, CONSTANT } _tick_length;
456 };
457
458
459
460 class HUD::Dial : public Scale {
461 public:
462     Dial(HUD *parent, const SGPropertyNode *, float x, float y);
463     virtual void draw();
464
465 private:
466     float  _radius;
467     int    _divisions;
468 };
469
470
471
472 class HUD::TurnBankIndicator : public Item {
473 public:
474     TurnBankIndicator(HUD *parent, const SGPropertyNode *, float x, float y);
475     virtual void draw();
476
477 private:
478     void draw_scale();
479     void draw_tee();
480     void draw_line(float, float, float, float);
481     void draw_tick(float angle, float r1, float r2, int side);
482
483     Input _bank;
484     Input _sideslip;
485
486     float _gap_width;
487     bool  _bank_scale;
488 };
489
490
491
492 class HUD::Ladder : public Item {
493 public:
494     Ladder(HUD *parent, const SGPropertyNode *, float x, float y);
495     virtual void draw();
496
497 private:
498     void draw_zenith(float, float);
499     void draw_nadir(float, float);
500
501     void draw_text(float x, float y, char *s, int align = 0) {
502         _locTextList.add(x, y, s, align, 0);
503     }
504
505     void draw_line(float x1, float y1, float x2, float y2) {
506         _locLineList.add(LineSegment(x1, y1, x2, y2));
507     }
508
509     void draw_stipple_line(float x1, float y1, float x2, float y2) {
510         _locStippleLineList.add(LineSegment(x1, y1, x2, y2));
511     }
512
513     enum   Type { PITCH, CLIMB_DIVE } _type;
514     Input  _pitch;
515     Input  _roll;
516     float  _width_units;
517     int    _div_units;
518     unsigned int _scr_hole;
519     float  _vmax;
520     float  _vmin;
521     float  _compression;
522     bool   _dynamic_origin;
523     bool   _clip_plane;
524     bool   _frl;               // fuselage reference line
525     bool   _target_spot;
526     bool   _target_markers;
527     bool   _velocity_vector;
528     bool   _drift_marker;
529     bool   _alpha_bracket;
530     bool   _energy_marker;
531     bool   _climb_dive_marker;
532     bool   _glide_slope_marker;
533     float  _glide_slope;
534     bool   _energy_worm;
535     bool   _waypoint_marker;
536     bool   _zenith;
537     bool   _nadir;
538     bool   _hat;
539
540     // The Ladder has its own temporary display lists
541     TextList _locTextList;
542     LineList _locLineList;
543     LineList _locStippleLineList;
544 };
545
546
547
548 // responsible for rendering the active runway in the hud (if visible).
549 //
550 class HUD::Runway : public Item {
551 public:
552     Runway(HUD *parent, const SGPropertyNode *, float x, float y);
553     virtual void draw();
554
555 private:
556     void boundPoint(const sgdVec3& v, sgdVec3& m);
557     bool boundOutsidePoints(sgdVec3& v, sgdVec3& m);
558     bool drawLine(const sgdVec3& a1, const sgdVec3& a2, const sgdVec3& p1, const sgdVec3& p2);
559     void drawArrow();
560     bool get_active_runway(FGRunway& rwy);
561     void get_rwy_points(sgdVec3 *points);
562     void setLineWidth();
563
564     SGPropertyNode_ptr _agl;
565     sgdVec3 _points3d[6], _points2d[6];
566     double _mm[16];
567     double _pm[16];
568     double _arrow_scale;  // scales of runway indication arrow
569     double _arrow_radius;
570     double _line_scale;   // maximum line scale
571     double _scale_dist;   // distance where to start scaling the lines
572     double _default_pitch;
573     double _default_heading;
574     GLint  _view[4];
575     FGRunway _runway;
576     FGViewer* _cockpit_view;
577     unsigned short _stipple_out;    // stipple pattern of the outline of the runway
578     unsigned short _stipple_center; // stipple pattern of the center line of the runway
579     bool   _draw_arrow;             // draw arrow when runway is not visible in HUD
580     bool   _draw_arrow_always;      // always draws arrow
581     float  _left, _right, _top, _bottom;
582 };
583
584
585 class HUD::AimingReticle : public Item {
586 public:
587     AimingReticle(HUD *parent, const SGPropertyNode *, float x, float y);
588     virtual void draw();
589
590 private:
591     SGCondition *_active_condition;  // stadiametric (true) or standby (false)
592     Input   _diameter;               // inner/outer radius relation
593     float   _bullet_size;
594     float   _inner_radius;
595 };
596
597
598
599 #endif // _HUD_HXX