]> git.mxchange.org Git - flightgear.git/blob - src/Objects/newmat.cxx
Fixed runway-altitude problem that prevented starts at airports higher
[flightgear.git] / src / Objects / newmat.cxx
1 // newmat.cxx -- class to handle material properties
2 //
3 // Written by Curtis Olson, started May 1998.
4 //
5 // Copyright (C) 1998 - 2000  Curtis L. Olson  - curt@flightgear.org
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // $Id$
22
23
24 #ifdef HAVE_CONFIG_H
25 #  include <config.h>
26 #endif
27
28 #include <simgear/compiler.h>
29
30 #ifdef SG_MATH_EXCEPTION_CLASH
31 #  include <math.h>
32 #endif
33
34 #include <simgear/debug/logstream.hxx>
35 #include <simgear/misc/sg_path.hxx>
36 #include <simgear/misc/sgstream.hxx>
37
38 #include <Main/globals.hxx>
39 #include <Main/fg_props.hxx>
40
41 #include "newmat.hxx"
42
43
44 \f
45 ////////////////////////////////////////////////////////////////////////
46 // Local static functions.
47 ////////////////////////////////////////////////////////////////////////
48
49 /**
50  * Internal method to test whether a file exists.
51  *
52  * TODO: this should be moved to a SimGear library of local file
53  * functions.
54  */
55 static inline bool
56 local_file_exists( const string& path ) {
57     sg_gzifstream in( path );
58     if ( ! in.is_open() ) {
59         return false;
60     } else {
61         return true;
62     }
63 }
64
65
66 \f
67 ////////////////////////////////////////////////////////////////////////
68 // Constructors and destructor.
69 ////////////////////////////////////////////////////////////////////////
70
71
72 FGNewMat::FGNewMat (const SGPropertyNode * props)
73 {
74     init();
75     read_properties(props);
76     build_ssg_state(false);
77 }
78
79 FGNewMat::FGNewMat (const string &texture_path)
80 {
81     init();
82     build_ssg_state(true);
83 }
84
85 FGNewMat::FGNewMat (ssgSimpleState * s)
86 {
87     init();
88     set_ssg_state(s);
89 }
90
91 FGNewMat::~FGNewMat (void)
92 {
93 }
94
95
96 \f
97 ////////////////////////////////////////////////////////////////////////
98 // Public methods.
99 ////////////////////////////////////////////////////////////////////////
100
101 void
102 FGNewMat::read_properties (const SGPropertyNode * props)
103 {
104                                 // Get the path to the texture
105   string tname = props->getStringValue("texture", "unknown.rgb");
106   SGPath tpath(globals->get_fg_root());
107   tpath.append("Textures.high");
108   tpath.append(tname);
109   if (!local_file_exists(tpath.str())) {
110     tpath = SGPath(globals->get_fg_root());
111     tpath.append("Textures");
112     tpath.append(tname);
113   }
114   texture_path = tpath.str();
115
116   xsize = props->getDoubleValue("xsize", 0.0);
117   ysize = props->getDoubleValue("ysize", 0.0);
118   wrapu = props->getBoolValue("wrapu", true);
119   wrapv = props->getBoolValue("wrapv", true);
120   mipmap = props->getBoolValue("mipmap", true);
121   light_coverage = props->getDoubleValue("light-coverage");
122
123   ambient[0] = props->getDoubleValue("ambient/r", 0.0);
124   ambient[1] = props->getDoubleValue("ambient/g", 0.0);
125   ambient[2] = props->getDoubleValue("ambient/b", 0.0);
126   ambient[3] = props->getDoubleValue("ambient/a", 0.0);
127
128   diffuse[0] = props->getDoubleValue("diffuse/r", 0.0);
129   diffuse[1] = props->getDoubleValue("diffuse/g", 0.0);
130   diffuse[2] = props->getDoubleValue("diffuse/b", 0.0);
131   diffuse[3] = props->getDoubleValue("diffuse/a", 0.0);
132
133   specular[0] = props->getDoubleValue("specular/r", 0.0);
134   specular[1] = props->getDoubleValue("specular/g", 0.0);
135   specular[2] = props->getDoubleValue("specular/b", 0.0);
136   specular[3] = props->getDoubleValue("specular/a", 0.0);
137
138   emission[0] = props->getDoubleValue("emissive/r", 0.0);
139   emission[1] = props->getDoubleValue("emissive/g", 0.0);
140   emission[2] = props->getDoubleValue("emissive/b", 0.0);
141   emission[3] = props->getDoubleValue("emissive/a", 0.0);
142 }
143
144
145 \f
146 ////////////////////////////////////////////////////////////////////////
147 // Private methods.
148 ////////////////////////////////////////////////////////////////////////
149
150 void 
151 FGNewMat::init ()
152 {
153   texture_path = "";
154   state = 0;
155   textured = 0;
156   nontextured = 0;
157   xsize = 0;
158   ysize = 0;
159   wrapu = true;
160   wrapv = true;
161   mipmap = true;
162   texture_loaded = false;
163   refcount = 0;
164   for (int i = 0; i < 4; i++)
165     ambient[i] = diffuse[i] = specular[i] = emission[i] = 0.0;
166 }
167
168 bool
169 FGNewMat::load_texture ()
170 {
171   if (texture_loaded) {
172     return false;
173   } else {
174     SG_LOG( SG_GENERAL, SG_INFO, "Loading deferred texture " << texture_path );
175     textured->setTexture((char *)texture_path.c_str(), wrapu, wrapv, mipmap );
176     texture_loaded = true;
177     return true;
178   }
179 }
180
181
182 void 
183 FGNewMat::build_ssg_state (bool defer_tex_load)
184 {
185     GLenum shade_model =
186       (fgGetBool("/sim/rendering/shading") ? GL_SMOOTH : GL_FLAT);
187     bool texture_default = fgGetBool("/sim/rendering/textures");
188
189     state = new ssgStateSelector(2);
190     state->ref();
191
192     textured = new ssgSimpleState();
193     textured->ref();
194
195     nontextured = new ssgSimpleState();
196     nontextured->ref();
197
198     // Set up the textured state
199     textured->setShadeModel( shade_model );
200     textured->enable( GL_LIGHTING );
201     textured->enable ( GL_CULL_FACE ) ;
202     textured->enable( GL_TEXTURE_2D );
203     textured->disable( GL_BLEND );
204     textured->disable( GL_ALPHA_TEST );
205 #if 0
206 #  ifdef GL_EXT_texture_filter_anisotropic
207     float max_anisotropy;
208     glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy );
209     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
210                      max_anisotropy );
211     cout << "Max anisotropy = " << max_anisotropy << endl;
212 #  endif
213 #endif
214     if ( !defer_tex_load ) {
215         textured->setTexture( (char *)texture_path.c_str(), wrapu, wrapv );
216         texture_loaded = true;
217     } else {
218         texture_loaded = false;
219     }
220     textured->enable( GL_COLOR_MATERIAL );
221     textured->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
222     textured->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
223     textured->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
224
225     // Set up the coloured state
226     nontextured->enable( GL_LIGHTING );
227     nontextured->setShadeModel( shade_model );
228     nontextured->enable ( GL_CULL_FACE      ) ;
229     nontextured->disable( GL_TEXTURE_2D );
230     nontextured->disable( GL_BLEND );
231     nontextured->disable( GL_ALPHA_TEST );
232     nontextured->disable( GL_COLOR_MATERIAL );
233
234     nontextured->setMaterial ( GL_AMBIENT, 
235                                ambient[0], ambient[1], 
236                                ambient[2], ambient[3] ) ;
237     nontextured->setMaterial ( GL_DIFFUSE, 
238                                diffuse[0], diffuse[1], 
239                                diffuse[2], diffuse[3] ) ;
240     nontextured->setMaterial ( GL_SPECULAR, 
241                                specular[0], specular[1], 
242                                specular[2], specular[3] ) ;
243     nontextured->setMaterial ( GL_EMISSION, 
244                                emission[0], emission[1], 
245                                emission[2], emission[3] ) ;
246
247     state->setStep( 0, textured );    // textured
248     state->setStep( 1, nontextured ); // untextured
249
250     // Choose the appropriate starting state.
251     if ( texture_default ) {
252         state->selectStep(0);
253     } else {
254         state->selectStep(1);
255     }
256 }
257
258
259 void FGNewMat::set_ssg_state( ssgSimpleState *s )
260 {
261     state = new ssgStateSelector(2);
262     state->ref();
263
264     textured = s;
265
266     nontextured = new ssgSimpleState();
267     nontextured->ref();
268
269     // Set up the coloured state
270     nontextured->enable( GL_LIGHTING );
271     nontextured->setShadeModel( GL_FLAT );
272     nontextured->enable ( GL_CULL_FACE      ) ;
273     nontextured->disable( GL_TEXTURE_2D );
274     nontextured->disable( GL_BLEND );
275     nontextured->disable( GL_ALPHA_TEST );
276     nontextured->disable( GL_COLOR_MATERIAL );
277
278     /* cout << "ambient = " << ambient[0] << "," << ambient[1] 
279        << "," << ambient[2] << endl; */
280     nontextured->setMaterial ( GL_AMBIENT, 
281                                ambient[0], ambient[1], 
282                                ambient[2], ambient[3] ) ;
283     nontextured->setMaterial ( GL_DIFFUSE, 
284                                diffuse[0], diffuse[1], 
285                                diffuse[2], diffuse[3] ) ;
286     nontextured->setMaterial ( GL_SPECULAR, 
287                                specular[0], specular[1], 
288                                specular[2], specular[3] ) ;
289     nontextured->setMaterial ( GL_EMISSION, 
290                                emission[0], emission[1], 
291                                emission[2], emission[3] ) ;
292
293     state->setStep( 0, textured );    // textured
294     state->setStep( 1, nontextured ); // untextured
295
296     // Choose the appropriate starting state.
297     state->selectStep(0);
298 }
299
300 // end of newmat.cxx