]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/od_gauge.cxx
kln89 user interface logical pages
[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, 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
20 //
21 //
22
23 #include <plib/ssg.h>
24 #include <simgear/screen/extensions.hxx>
25 #include <simgear/screen/RenderTexture.h>
26 #include <simgear/debug/logstream.hxx>
27 #include SG_GLU_H
28
29 #include <Main/globals.hxx>
30 #include <Scenery/scenery.hxx>
31 #include "od_gauge.hxx"
32
33 FGODGauge::FGODGauge() :
34     rtAvailable( false ),
35     rt( 0 )
36 {
37 }
38
39 // done here and not in init() so we don't allocate a rendering context if it is
40 // never used
41 void FGODGauge::allocRT () {
42     GLint colorBits = 0;
43     glGetIntegerv( GL_BLUE_BITS, &colorBits );
44     textureWH = 256;
45     rt = new RenderTexture();
46     if( colorBits < 8 )
47         rt->Reset("rgba=5,5,5,1 ctt");
48     else
49         rt->Reset("rgba ctt");
50
51     if( rt->Initialize(256, 256, true) ) {
52         SG_LOG(SG_ALL, SG_INFO, "FGODGauge:Initialize sucessfull");
53         if (rt->BeginCapture())
54         {
55             SG_LOG(SG_ALL, SG_INFO, "FGODGauge:BeginCapture sucessfull, RTT available");
56             rtAvailable = true;
57             glViewport(0, 0, textureWH, textureWH);
58             glMatrixMode(GL_PROJECTION);
59             glLoadIdentity();
60             gluOrtho2D( -256.0, 256.0, -256.0, 256.0 );
61             glMatrixMode(GL_MODELVIEW);
62             glLoadIdentity();
63             glDisable(GL_LIGHTING);
64             glEnable(GL_COLOR_MATERIAL);
65             glDisable(GL_CULL_FACE);
66             glDisable(GL_FOG);
67             glDisable(GL_DEPTH_TEST);
68             glClearColor(0.0, 0.0, 0.0, 0.0);
69             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
70             glBindTexture(GL_TEXTURE_2D, 0);
71             glEnable(GL_TEXTURE_2D);
72             glEnable(GL_ALPHA_TEST);
73             glAlphaFunc(GL_GREATER, 0.0f);
74             glDisable(GL_SMOOTH);
75             glEnable(GL_BLEND);
76             glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
77             rt->EndCapture();
78         } else
79             SG_LOG(SG_ALL, SG_WARN, "FGODGauge:BeginCapture failed, RTT not available, using backbuffer");
80     } else
81         SG_LOG(SG_ALL, SG_WARN, "FGODGauge:Initialize failed, RTT not available, using backbuffer");
82 }
83
84 FGODGauge::~FGODGauge() {
85     delete rt;
86 }
87
88 void FGODGauge::init () {
89 }
90
91 void FGODGauge::update (double dt) {
92 }
93
94 void FGODGauge::beginCapture(int viewSize) {
95     if( ! rt )
96         allocRT();
97     if(rtAvailable) {
98         rt->BeginCapture();
99     }
100     else
101         set2D();
102      textureWH = viewSize;
103     glViewport(0, 0, textureWH, textureWH);
104 }
105
106 void FGODGauge::beginCapture(void) {
107     if( ! rt )
108         allocRT();
109     if(rtAvailable) {
110         rt->BeginCapture();
111     }
112     else
113         set2D();
114 }
115
116 void FGODGauge::Clear(void) {
117     if(rtAvailable) {
118         glClear(GL_COLOR_BUFFER_BIT);
119     }
120     else {
121         glDisable(GL_BLEND);
122         glDisable(GL_ALPHA_TEST);
123           glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
124         glRectf(-256.0, -256.0, 256.0, 256.0);
125         glEnable(GL_BLEND);
126         glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
127         glEnable(GL_ALPHA_TEST);
128     }
129 }
130
131 void FGODGauge::endCapture(GLuint texID) {
132     glBindTexture(GL_TEXTURE_2D, texID);
133     // don't use mimaps if we don't update them
134     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
135
136     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, textureWH, textureWH);
137     if(rtAvailable)
138         rt->EndCapture();
139     else
140         set3D();
141     glBindTexture(GL_TEXTURE_2D, 0);
142 }
143
144 void FGODGauge::setSize(int viewSize) {
145     textureWH = viewSize;
146     glViewport(0, 0, textureWH, textureWH);
147 }
148
149 bool FGODGauge::serviceable(void) {
150     return rtAvailable;
151 }
152
153 /**
154  * Locate a texture SSG node in a branch.
155  */
156 static const char *strip_path(const char *name) {
157     /* Remove all leading path information. */
158     const char* seps = "\\/" ;
159     const char* fn = & name [ strlen ( name ) - 1 ] ;
160     for ( ; fn != name && strchr(seps,*fn) == NULL ; fn-- )
161         /* Search back for a seperator */ ;
162     if ( strchr(seps,*fn) != NULL )
163         fn++ ;
164     return fn ;
165 }
166
167 static ssgSimpleState *
168 find_texture_node (ssgEntity * node, const char * name)
169 {
170   if( node->isAKindOf( ssgTypeLeaf() ) ) {
171     ssgLeaf *leaf = (ssgLeaf *) node;
172     ssgSimpleState *state = (ssgSimpleState *) leaf->getState();
173     if( state ) {
174         ssgTexture *tex = state->getTexture();
175         if( tex ) {
176             const char * texture_name = tex->getFilename();
177             if (texture_name) {
178                 texture_name = strip_path( texture_name );
179                 if ( !strcmp(name, texture_name) )
180                     return state;
181             }
182         }
183     }
184   }
185   else {
186     int nKids = node->getNumKids();
187     for (int i = 0; i < nKids; i++) {
188       ssgSimpleState * result =
189         find_texture_node(((ssgBranch*)node)->getKid(i), name);
190       if (result != 0)
191         return result;
192     }
193   } 
194   return 0;
195 }
196
197 void FGODGauge::set_texture(const char * name, GLuint new_texture) {
198     ssgEntity * root = globals->get_scenery()->get_aircraft_branch();
199     name = strip_path( name );
200     ssgSimpleState * node = find_texture_node( root, name );
201     if( node )
202         node->setTexture( new_texture );
203 }
204
205 void FGODGauge::set2D() {
206     glPushAttrib ( GL_ENABLE_BIT | GL_VIEWPORT_BIT  | GL_TRANSFORM_BIT | GL_LIGHTING_BIT ) ;
207
208     glDisable(GL_LIGHTING);
209     glEnable(GL_COLOR_MATERIAL);
210     glDisable(GL_CULL_FACE);
211     glDisable(GL_FOG);
212     glDisable(GL_DEPTH_TEST);
213     glClearColor(0.0, 0.0, 0.0, 0.0);
214     glEnable(GL_TEXTURE_2D);
215     glDisable(GL_SMOOTH);
216     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
217     glBindTexture(GL_TEXTURE_2D, 0);
218
219     glViewport ( 0, 0, textureWH, textureWH ) ;
220     glMatrixMode   ( GL_PROJECTION ) ;
221     glPushMatrix   () ;
222     glLoadIdentity () ;
223     gluOrtho2D( -256.0, 256.0, -256.0, 256.0 );
224     glMatrixMode   ( GL_MODELVIEW ) ;
225     glPushMatrix   () ;
226     glLoadIdentity () ;
227
228     glAlphaFunc(GL_GREATER, 0.0f);
229
230 }
231
232 void FGODGauge::set3D() {
233     glMatrixMode   ( GL_PROJECTION ) ;
234     glPopMatrix    () ;
235     glMatrixMode   ( GL_MODELVIEW ) ;
236     glPopMatrix    () ;
237     glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
238     glPopAttrib    () ;
239 }