]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/od_gauge.cxx
- Code cleanups.
[flightgear.git] / src / Instrumentation / od_gauge.cxx
1 // Owner Drawn Gauge helper class
2 //
3 // Written by Harald JOHNSEN, started May 2005.
4 //
5 // Copyright (C) 2005  Harald JOHNSEN
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 //
22
23 #ifdef HAVE_CONFIG_H
24 #  include "config.h"
25 #endif
26
27 #include <plib/ssg.h>
28 #include <simgear/screen/extensions.hxx>
29 #include <simgear/screen/RenderTexture.h>
30 #include <simgear/debug/logstream.hxx>
31 #include SG_GLU_H
32
33 #include <Main/globals.hxx>
34 #include <Scenery/scenery.hxx>
35 #include "od_gauge.hxx"
36
37 FGODGauge::FGODGauge() :
38     rtAvailable( false ),
39     rt( 0 )
40 {
41 }
42
43 // done here and not in init() so we don't allocate a rendering context if it is
44 // never used
45 void FGODGauge::allocRT () {
46     GLint colorBits = 0;
47     glGetIntegerv( GL_BLUE_BITS, &colorBits );
48     textureWH = 256;
49     rt = new RenderTexture();
50     if( colorBits < 8 )
51         rt->Reset("rgba=5,5,5,1 ctt");
52     else
53         rt->Reset("rgba ctt");
54
55     if( rt->Initialize(256, 256, true) ) {
56         SG_LOG(SG_ALL, SG_INFO, "FGODGauge:Initialize sucessfull");
57         if (rt->BeginCapture())
58         {
59             SG_LOG(SG_ALL, SG_INFO, "FGODGauge:BeginCapture sucessfull, RTT available");
60             rtAvailable = true;
61             glViewport(0, 0, textureWH, textureWH);
62             glMatrixMode(GL_PROJECTION);
63             glLoadIdentity();
64             gluOrtho2D( -256.0, 256.0, -256.0, 256.0 );
65             glMatrixMode(GL_MODELVIEW);
66             glLoadIdentity();
67             glDisable(GL_LIGHTING);
68             glEnable(GL_COLOR_MATERIAL);
69             glDisable(GL_CULL_FACE);
70             glDisable(GL_FOG);
71             glDisable(GL_DEPTH_TEST);
72             glClearColor(0.0, 0.0, 0.0, 0.0);
73             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
74             glBindTexture(GL_TEXTURE_2D, 0);
75             glEnable(GL_TEXTURE_2D);
76             glEnable(GL_ALPHA_TEST);
77             glAlphaFunc(GL_GREATER, 0.0f);
78             glDisable(GL_SMOOTH);
79             glEnable(GL_BLEND);
80             glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
81             rt->EndCapture();
82         } else
83             SG_LOG(SG_ALL, SG_WARN, "FGODGauge:BeginCapture failed, RTT not available, using backbuffer");
84     } else
85         SG_LOG(SG_ALL, SG_WARN, "FGODGauge:Initialize failed, RTT not available, using backbuffer");
86 }
87
88 FGODGauge::~FGODGauge() {
89     delete rt;
90 }
91
92 void FGODGauge::init () {
93 }
94
95 void FGODGauge::update (double dt) {
96 }
97
98 void FGODGauge::beginCapture(int viewSize) {
99     if( ! rt )
100         allocRT();
101     if(rtAvailable) {
102         rt->BeginCapture();
103     }
104     else
105         set2D();
106      textureWH = viewSize;
107     glViewport(0, 0, textureWH, textureWH);
108 }
109
110 void FGODGauge::beginCapture(void) {
111     if( ! rt )
112         allocRT();
113     if(rtAvailable) {
114         rt->BeginCapture();
115     }
116     else
117         set2D();
118 }
119
120 void FGODGauge::Clear(void) {
121     if(rtAvailable) {
122         glClear(GL_COLOR_BUFFER_BIT);
123     }
124     else {
125         glDisable(GL_BLEND);
126         glDisable(GL_ALPHA_TEST);
127           glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
128         glRectf(-256.0, -256.0, 256.0, 256.0);
129         glEnable(GL_BLEND);
130         glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
131         glEnable(GL_ALPHA_TEST);
132     }
133 }
134
135 void FGODGauge::endCapture(GLuint texID) {
136     glBindTexture(GL_TEXTURE_2D, texID);
137     // don't use mimaps if we don't update them
138     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
139
140     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, textureWH, textureWH);
141     if(rtAvailable)
142         rt->EndCapture();
143     else
144         set3D();
145     glBindTexture(GL_TEXTURE_2D, 0);
146 }
147
148 void FGODGauge::setSize(int viewSize) {
149     textureWH = viewSize;
150     glViewport(0, 0, textureWH, textureWH);
151 }
152
153 bool FGODGauge::serviceable(void) {
154     return rtAvailable;
155 }
156
157 /**
158  * Locate a texture SSG node in a branch.
159  */
160 static const char *strip_path(const char *name) {
161     /* Remove all leading path information. */
162     const char* seps = "\\/" ;
163     const char* fn = & name [ strlen ( name ) - 1 ] ;
164     for ( ; fn != name && strchr(seps,*fn) == NULL ; fn-- )
165         /* Search back for a seperator */ ;
166     if ( strchr(seps,*fn) != NULL )
167         fn++ ;
168     return fn ;
169 }
170
171 static ssgSimpleState *
172 find_texture_node (ssgEntity * node, const char * name)
173 {
174   if( node->isAKindOf( ssgTypeLeaf() ) ) {
175     ssgLeaf *leaf = (ssgLeaf *) node;
176     ssgSimpleState *state = (ssgSimpleState *) leaf->getState();
177     if( state ) {
178         ssgTexture *tex = state->getTexture();
179         if( tex ) {
180             const char * texture_name = tex->getFilename();
181             if (texture_name) {
182                 texture_name = strip_path( texture_name );
183                 if ( !strcmp(name, texture_name) )
184                     return state;
185             }
186         }
187     }
188   }
189   else {
190     int nKids = node->getNumKids();
191     for (int i = 0; i < nKids; i++) {
192       ssgSimpleState * result =
193         find_texture_node(((ssgBranch*)node)->getKid(i), name);
194       if (result != 0)
195         return result;
196     }
197   } 
198   return 0;
199 }
200
201 void FGODGauge::set_texture(const char * name, GLuint new_texture) {
202     ssgEntity * root = globals->get_scenery()->get_aircraft_branch();
203     name = strip_path( name );
204     ssgSimpleState * node = find_texture_node( root, name );
205     if( node )
206         node->setTexture( new_texture );
207 }
208
209 void FGODGauge::set2D() {
210     glPushAttrib ( GL_ENABLE_BIT | GL_VIEWPORT_BIT  | GL_TRANSFORM_BIT | GL_LIGHTING_BIT ) ;
211
212     glDisable(GL_LIGHTING);
213     glEnable(GL_COLOR_MATERIAL);
214     glDisable(GL_CULL_FACE);
215     glDisable(GL_FOG);
216     glDisable(GL_DEPTH_TEST);
217     glClearColor(0.0, 0.0, 0.0, 0.0);
218     glEnable(GL_TEXTURE_2D);
219     glDisable(GL_SMOOTH);
220     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
221     glBindTexture(GL_TEXTURE_2D, 0);
222
223     glViewport ( 0, 0, textureWH, textureWH ) ;
224     glMatrixMode   ( GL_PROJECTION ) ;
225     glPushMatrix   () ;
226     glLoadIdentity () ;
227     gluOrtho2D( -256.0, 256.0, -256.0, 256.0 );
228     glMatrixMode   ( GL_MODELVIEW ) ;
229     glPushMatrix   () ;
230     glLoadIdentity () ;
231
232     glAlphaFunc(GL_GREATER, 0.0f);
233
234 }
235
236 void FGODGauge::set3D() {
237     glMatrixMode   ( GL_PROJECTION ) ;
238     glPopMatrix    () ;
239     glMatrixMode   ( GL_MODELVIEW ) ;
240     glPopMatrix    () ;
241     glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
242     glPopAttrib    () ;
243 }