]> git.mxchange.org Git - simgear.git/blob - simgear/scene/material/matlib.cxx
e49758312f98f65e906691de8e9d812835d07039
[simgear.git] / simgear / scene / material / matlib.cxx
1 // materialmgr.cxx -- class to handle material properties
2 //
3 // Written by Curtis Olson, started May 1998.
4 //
5 // Copyright (C) 1998  Curtis L. Olson  - http://www.flightgear.org/~curt
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 // $Id$
22
23
24 #ifdef HAVE_CONFIG_H
25 #  include <simgear_config.h>
26 #endif
27
28 #ifdef SG_MATH_EXCEPTION_CLASH
29 #  include <math.h>
30 #endif
31
32 #ifdef HAVE_WINDOWS_H
33 #  include <windows.h>
34 #endif
35
36 #include <plib/ssg.h>
37
38 #include <simgear/compiler.h>
39 #include <simgear/constants.h>
40 #include <simgear/structure/exception.hxx>
41
42 #include SG_GL_H
43
44 #include <string.h>
45 #include STL_STRING
46
47 #include <simgear/debug/logstream.hxx>
48 #include <simgear/misc/sg_path.hxx>
49 #include <simgear/misc/sgstream.hxx>
50 #include <simgear/props/props_io.hxx>
51 #include <simgear/scene/tgdb/userdata.hxx>
52
53 #include "mat.hxx"
54
55 #include "matlib.hxx"
56
57 SG_USING_NAMESPACE(std);
58 SG_USING_STD(string);
59
60
61 // Constructor
62 SGMaterialLib::SGMaterialLib ( void ) {
63 }
64
65
66 #if 0 // debugging infrastructure
67 static int gen_test_light_map() {
68     static const int env_tex_res = 32;
69     int half_res = env_tex_res / 2;
70     unsigned char env_map[env_tex_res][env_tex_res][4];
71     GLuint tex_name;
72
73     for ( int i = 0; i < env_tex_res; ++i ) {
74         for ( int j = 0; j < env_tex_res; ++j ) {
75             double x = (i - half_res) / (double)half_res;
76             double y = (j - half_res) / (double)half_res;
77             double dist = sqrt(x*x + y*y);
78             if ( dist > 1.0 ) { dist = 1.0; }
79
80             // cout << x << "," << y << " " << (int)(dist * 255) << ","
81             //      << (int)((1.0 - dist) * 255) << endl;
82             env_map[i][j][0] = (int)(dist * 255);
83             env_map[i][j][1] = (int)((1.0 - dist) * 255);
84             env_map[i][j][2] = 0;
85             env_map[i][j][3] = 255;
86         }
87     }
88
89     glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
90     glGenTextures( 1, &tex_name );
91     glBindTexture( GL_TEXTURE_2D, tex_name );
92   
93     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
94     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
95     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
96     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
97     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, env_tex_res, env_tex_res, 0,
98                   GL_RGBA, GL_UNSIGNED_BYTE, env_map);
99
100     return tex_name;
101 }
102 #endif
103
104
105 // generate standard colored directional light environment texture map
106 static int gen_standard_dir_light_map( int r, int g, int b, int alpha ) {
107     const int env_tex_res = 32;
108     int half_res = env_tex_res / 2;
109     unsigned char env_map[env_tex_res][env_tex_res][4];
110     GLuint tex_name;
111
112     for ( int i = 0; i < env_tex_res; ++i ) {
113         for ( int j = 0; j < env_tex_res; ++j ) {
114             double x = (i - half_res) / (double)half_res;
115             double y = (j - half_res) / (double)half_res;
116             double dist = sqrt(x*x + y*y);
117             if ( dist > 1.0 ) { dist = 1.0; }
118             double bright = cos( dist * SGD_PI_2 );
119             if ( bright < 0.3 ) { bright = 0.3; }
120             env_map[i][j][0] = r;
121             env_map[i][j][1] = g;
122             env_map[i][j][2] = b;
123             env_map[i][j][3] = (int)(bright * alpha);
124         }
125     }
126
127     glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
128     glGenTextures( 1, &tex_name );
129     glBindTexture( GL_TEXTURE_2D, tex_name );
130   
131     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
132     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
133     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
134     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
135     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, env_tex_res, env_tex_res, 0,
136                   GL_RGBA, GL_UNSIGNED_BYTE, env_map);
137
138     return tex_name;
139 }
140
141
142 // generate standard colored directional light environment texture map
143 static int gen_taxiway_dir_light_map( int r, int g, int b, int alpha ) {
144     const int env_tex_res = 32;
145     int half_res = env_tex_res / 2;
146     unsigned char env_map[env_tex_res][env_tex_res][4];
147     GLuint tex_name;
148
149     for ( int i = 0; i < env_tex_res; ++i ) {
150         for ( int j = 0; j < env_tex_res; ++j ) {
151             double x = (i - half_res) / (double)half_res;
152             double y = (j - half_res) / (double)half_res;
153             double tmp = sqrt(x*x + y*y);
154             double dist = tmp * tmp;
155             if ( dist > 1.0 ) { dist = 1.0; }
156             double bright = sin( dist * SGD_PI_2 );
157             if ( bright < 0.2 ) { bright = 0.2; }
158             env_map[i][j][0] = r;
159             env_map[i][j][1] = g;
160             env_map[i][j][2] = b;
161             env_map[i][j][3] = (int)(bright * alpha);
162         }
163     }
164
165     glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
166     glGenTextures( 1, &tex_name );
167     glBindTexture( GL_TEXTURE_2D, tex_name );
168   
169     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
170     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
171     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
172     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
173     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, env_tex_res, env_tex_res, 0,
174                   GL_RGBA, GL_UNSIGNED_BYTE, env_map);
175
176     return tex_name;
177 }
178
179
180 // Load a library of material properties
181 bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char *season ) {
182
183     SGPropertyNode materials;
184
185     SG_LOG( SG_INPUT, SG_INFO, "Reading materials from " << mpath );
186     try {
187         readProperties( mpath, &materials );
188     } catch (const sg_exception &ex) {
189         SG_LOG( SG_INPUT, SG_ALERT, "Error reading materials: "
190                 << ex.getMessage() );
191         throw;
192     }
193
194     SGSharedPtr<SGMaterial> m;
195
196     int nMaterials = materials.nChildren();
197     for (int i = 0; i < nMaterials; i++) {
198         const SGPropertyNode * node = materials.getChild(i);
199         if (!strcmp(node->getName(), "material")) {
200             m = new SGMaterial( fg_root, node, season );
201
202             vector<SGPropertyNode_ptr>names = node->getChildren("name");
203             for ( unsigned int j = 0; j < names.size(); j++ ) {
204                 string name = names[j]->getStringValue();
205                 // cerr << "Material " << name << endl;
206                 matlib[name] = m;
207                 m->add_name(name);
208                 SG_LOG( SG_TERRAIN, SG_INFO, "  Loading material "
209                         << names[j]->getStringValue() );
210             }
211         } else {
212             SG_LOG(SG_INPUT, SG_WARN,
213                    "Skipping bad material entry " << node->getName());
214         }
215     }
216
217     // hard coded ground light state
218     ssgSimpleState *gnd_lights = new ssgSimpleState;
219     gnd_lights->disable( GL_TEXTURE_2D );
220     gnd_lights->enable( GL_CULL_FACE );
221     gnd_lights->enable( GL_COLOR_MATERIAL );
222     gnd_lights->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
223     gnd_lights->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
224     gnd_lights->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
225     gnd_lights->enable( GL_BLEND );
226     gnd_lights->disable( GL_ALPHA_TEST );
227     gnd_lights->disable( GL_LIGHTING );
228     m = new SGMaterial( gnd_lights );
229     m->add_name("GROUND_LIGHTS");
230     matlib["GROUND_LIGHTS"] = m;
231
232     GLuint tex_name;
233
234     // hard coded runway white light state
235     tex_name = gen_standard_dir_light_map( 235, 235, 195, 255 );
236     ssgSimpleState *rwy_white_lights = new ssgSimpleState();
237     rwy_white_lights->disable( GL_LIGHTING );
238     rwy_white_lights->enable ( GL_CULL_FACE ) ;
239     rwy_white_lights->enable( GL_TEXTURE_2D );
240     rwy_white_lights->enable( GL_BLEND );
241     rwy_white_lights->enable( GL_ALPHA_TEST );
242     rwy_white_lights->enable( GL_COLOR_MATERIAL );
243     rwy_white_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
244     rwy_white_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
245     rwy_white_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
246     rwy_white_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
247     rwy_white_lights->setTexture( tex_name );
248     m = new SGMaterial( rwy_white_lights );
249     m->add_name("RWY_WHITE_LIGHTS");
250     matlib["RWY_WHITE_LIGHTS"] = m;
251     // For backwards compatibility ... remove someday
252     m->add_name("RUNWAY_LIGHTS");
253     matlib["RUNWAY_LIGHTS"] = m;
254     m->add_name("RWY_LIGHTS");
255     matlib["RWY_LIGHTS"] = m;
256     // end of backwards compatitibilty
257
258     // hard coded runway medium intensity white light state
259     tex_name = gen_standard_dir_light_map( 235, 235, 195, 205 );
260     ssgSimpleState *rwy_white_medium_lights = new ssgSimpleState();
261     rwy_white_medium_lights->disable( GL_LIGHTING );
262     rwy_white_medium_lights->enable ( GL_CULL_FACE ) ;
263     rwy_white_medium_lights->enable( GL_TEXTURE_2D );
264     rwy_white_medium_lights->enable( GL_BLEND );
265     rwy_white_medium_lights->enable( GL_ALPHA_TEST );
266     rwy_white_medium_lights->enable( GL_COLOR_MATERIAL );
267     rwy_white_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
268     rwy_white_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
269     rwy_white_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
270     rwy_white_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
271     rwy_white_medium_lights->setTexture( tex_name );
272     m = new SGMaterial( rwy_white_medium_lights );
273     m->add_name("RWY_WHITE_MEDIUM_LIGHTS");
274     matlib["RWY_WHITE_MEDIUM_LIGHTS"] = m;
275
276     // hard coded runway low intensity white light state
277     tex_name = gen_standard_dir_light_map( 235, 235, 195, 155 );
278     ssgSimpleState *rwy_white_low_lights = new ssgSimpleState();
279     rwy_white_low_lights->disable( GL_LIGHTING );
280     rwy_white_low_lights->enable ( GL_CULL_FACE ) ;
281     rwy_white_low_lights->enable( GL_TEXTURE_2D );
282     rwy_white_low_lights->enable( GL_BLEND );
283     rwy_white_low_lights->enable( GL_ALPHA_TEST );
284     rwy_white_low_lights->enable( GL_COLOR_MATERIAL );
285     rwy_white_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
286     rwy_white_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
287     rwy_white_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
288     rwy_white_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
289     rwy_white_low_lights->setTexture( tex_name );
290     m = new SGMaterial( rwy_white_low_lights );
291     m->add_name("RWY_WHITE_LOW_LIGHTS");
292     matlib["RWY_WHITE_LOW_LIGHTS"] = m;
293
294     // hard coded runway yellow light state
295     tex_name = gen_standard_dir_light_map( 235, 215, 20, 255 );
296     ssgSimpleState *rwy_yellow_lights = new ssgSimpleState();
297     rwy_yellow_lights->disable( GL_LIGHTING );
298     rwy_yellow_lights->enable ( GL_CULL_FACE ) ;
299     rwy_yellow_lights->enable( GL_TEXTURE_2D );
300     rwy_yellow_lights->enable( GL_BLEND );
301     rwy_yellow_lights->enable( GL_ALPHA_TEST );
302     rwy_yellow_lights->enable( GL_COLOR_MATERIAL );
303     rwy_yellow_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
304     rwy_yellow_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
305     rwy_yellow_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
306     rwy_yellow_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
307     rwy_yellow_lights->setTexture( tex_name );
308     m = new SGMaterial( rwy_yellow_lights );
309     m->add_name("RWY_YELLOW_LIGHTS");
310     matlib["RWY_YELLOW_LIGHTS"] = m;
311
312     // hard coded runway medium intensity yellow light state
313     tex_name = gen_standard_dir_light_map( 235, 215, 20, 205 );
314     ssgSimpleState *rwy_yellow_medium_lights = new ssgSimpleState();
315     rwy_yellow_medium_lights->disable( GL_LIGHTING );
316     rwy_yellow_medium_lights->enable ( GL_CULL_FACE ) ;
317     rwy_yellow_medium_lights->enable( GL_TEXTURE_2D );
318     rwy_yellow_medium_lights->enable( GL_BLEND );
319     rwy_yellow_medium_lights->enable( GL_ALPHA_TEST );
320     rwy_yellow_medium_lights->enable( GL_COLOR_MATERIAL );
321     rwy_yellow_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
322     rwy_yellow_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
323     rwy_yellow_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
324     rwy_yellow_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
325     rwy_yellow_medium_lights->setTexture( tex_name );
326     m = new SGMaterial( rwy_yellow_medium_lights );
327     m->add_name("RWY_YELLOW_MEDIUM_LIGHTS");
328     matlib["RWY_YELLOW_MEDIUM_LIGHTS"] = m;
329
330     // hard coded runway low intensity yellow light state
331     tex_name = gen_standard_dir_light_map( 235, 215, 20, 155 );
332     ssgSimpleState *rwy_yellow_low_lights = new ssgSimpleState();
333     rwy_yellow_low_lights->disable( GL_LIGHTING );
334     rwy_yellow_low_lights->enable ( GL_CULL_FACE ) ;
335     rwy_yellow_low_lights->enable( GL_TEXTURE_2D );
336     rwy_yellow_low_lights->enable( GL_BLEND );
337     rwy_yellow_low_lights->enable( GL_ALPHA_TEST );
338     rwy_yellow_low_lights->enable( GL_COLOR_MATERIAL );
339     rwy_yellow_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
340     rwy_yellow_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
341     rwy_yellow_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
342     rwy_yellow_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
343     rwy_yellow_low_lights->setTexture( tex_name );
344     m = new SGMaterial( rwy_yellow_low_lights );
345     m->add_name("RWY_YELLOW_LOW_LIGHTS");
346     matlib["RWY_YELLOW_LOW_LIGHTS"] = m;
347
348     // hard coded runway red light state
349     tex_name = gen_standard_dir_light_map( 235, 90, 90, 255 );
350     ssgSimpleState *rwy_red_lights = new ssgSimpleState();
351     rwy_red_lights->disable( GL_LIGHTING );
352     rwy_red_lights->enable ( GL_CULL_FACE ) ;
353     rwy_red_lights->enable( GL_TEXTURE_2D );
354     rwy_red_lights->enable( GL_BLEND );
355     rwy_red_lights->enable( GL_ALPHA_TEST );
356     rwy_red_lights->enable( GL_COLOR_MATERIAL );
357     rwy_red_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
358     rwy_red_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
359     rwy_red_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
360     rwy_red_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
361     rwy_red_lights->setTexture( tex_name );
362     m = new SGMaterial( rwy_red_lights );
363     m->add_name("RWY_RED_LIGHTS");
364     matlib["RWY_RED_LIGHTS"] = m;
365
366     // hard coded medium intensity runway red light state
367     tex_name = gen_standard_dir_light_map( 235, 90, 90, 205 );
368     ssgSimpleState *rwy_red_medium_lights = new ssgSimpleState();
369     rwy_red_medium_lights->disable( GL_LIGHTING );
370     rwy_red_medium_lights->enable ( GL_CULL_FACE ) ;
371     rwy_red_medium_lights->enable( GL_TEXTURE_2D );
372     rwy_red_medium_lights->enable( GL_BLEND );
373     rwy_red_medium_lights->enable( GL_ALPHA_TEST );
374     rwy_red_medium_lights->enable( GL_COLOR_MATERIAL );
375     rwy_red_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
376     rwy_red_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
377     rwy_red_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
378     rwy_red_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
379     rwy_red_medium_lights->setTexture( tex_name );
380     m = new SGMaterial( rwy_red_medium_lights );
381     m->add_name("RWY_RED_MEDIUM_LIGHTS");
382     matlib["RWY_RED_MEDIUM_LIGHTS"] = m;
383
384     // hard coded low intensity runway red light state
385     tex_name = gen_standard_dir_light_map( 235, 90, 90, 155 );
386     ssgSimpleState *rwy_red_low_lights = new ssgSimpleState();
387     rwy_red_low_lights->disable( GL_LIGHTING );
388     rwy_red_low_lights->enable ( GL_CULL_FACE ) ;
389     rwy_red_low_lights->enable( GL_TEXTURE_2D );
390     rwy_red_low_lights->enable( GL_BLEND );
391     rwy_red_low_lights->enable( GL_ALPHA_TEST );
392     rwy_red_low_lights->enable( GL_COLOR_MATERIAL );
393     rwy_red_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
394     rwy_red_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
395     rwy_red_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
396     rwy_red_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
397     rwy_red_low_lights->setTexture( tex_name );
398     m = new SGMaterial( rwy_red_low_lights );
399     m->add_name("RWY_RED_LOW_LIGHTS");
400     matlib["RWY_RED_LOW_LIGHTS"] = m;
401
402     // hard coded runway green light state
403     tex_name = gen_standard_dir_light_map( 20, 235, 20, 255 );
404     ssgSimpleState *rwy_green_lights = new ssgSimpleState();
405     rwy_green_lights->disable( GL_LIGHTING );
406     rwy_green_lights->enable ( GL_CULL_FACE ) ;
407     rwy_green_lights->enable( GL_TEXTURE_2D );
408     rwy_green_lights->enable( GL_BLEND );
409     rwy_green_lights->enable( GL_ALPHA_TEST );
410     rwy_green_lights->enable( GL_COLOR_MATERIAL );
411     rwy_green_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
412     rwy_green_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
413     rwy_green_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
414     rwy_green_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
415     rwy_green_lights->setTexture( tex_name );
416     m = new SGMaterial( rwy_green_lights );
417     m->add_name("RWY_GREEN_LIGHTS");
418     matlib["RWY_GREEN_LIGHTS"] = m;
419
420     // hard coded medium intensity runway green light state
421     tex_name = gen_standard_dir_light_map( 20, 235, 20, 205 );
422     ssgSimpleState *rwy_green_medium_lights = new ssgSimpleState();
423     rwy_green_medium_lights->disable( GL_LIGHTING );
424     rwy_green_medium_lights->enable ( GL_CULL_FACE ) ;
425     rwy_green_medium_lights->enable( GL_TEXTURE_2D );
426     rwy_green_medium_lights->enable( GL_BLEND );
427     rwy_green_medium_lights->enable( GL_ALPHA_TEST );
428     rwy_green_medium_lights->enable( GL_COLOR_MATERIAL );
429     rwy_green_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
430     rwy_green_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
431     rwy_green_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
432     rwy_green_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
433     rwy_green_medium_lights->setTexture( tex_name );
434     m = new SGMaterial( rwy_green_medium_lights );
435     m->add_name("RWY_GREEN_MEDIUM_LIGHTS");
436     matlib["RWY_GREEN_MEDIUM_LIGHTS"] = m;
437
438     // hard coded low intensity runway green light state
439     tex_name = gen_standard_dir_light_map( 20, 235, 20, 155 );
440     ssgSimpleState *rwy_green_low_lights = new ssgSimpleState();
441     rwy_green_low_lights->disable( GL_LIGHTING );
442     rwy_green_low_lights->enable ( GL_CULL_FACE ) ;
443     rwy_green_low_lights->enable( GL_TEXTURE_2D );
444     rwy_green_low_lights->enable( GL_BLEND );
445     rwy_green_low_lights->enable( GL_ALPHA_TEST );
446     rwy_green_low_lights->enable( GL_COLOR_MATERIAL );
447     rwy_green_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
448     rwy_green_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
449     rwy_green_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
450     rwy_green_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
451     rwy_green_low_lights->setTexture( tex_name );
452     m = new SGMaterial( rwy_green_low_lights );
453     m->add_name("RWY_GREEN_LOW_LIGHTS");
454     matlib["RWY_GREEN_LOW_LIGHTS"] = m;
455     m->add_name("RWY_GREEN_TAXIWAY_LIGHTS");
456     matlib["RWY_GREEN_TAXIWAY_LIGHTS"] = m;
457
458     // hard coded low intensity taxiway blue light state
459     tex_name = gen_taxiway_dir_light_map( 90, 90, 235, 205 );
460     ssgSimpleState *taxiway_blue_low_lights = new ssgSimpleState();
461     taxiway_blue_low_lights->disable( GL_LIGHTING );
462     taxiway_blue_low_lights->enable ( GL_CULL_FACE ) ;
463     taxiway_blue_low_lights->enable( GL_TEXTURE_2D );
464     taxiway_blue_low_lights->enable( GL_BLEND );
465     taxiway_blue_low_lights->enable( GL_ALPHA_TEST );
466     taxiway_blue_low_lights->enable( GL_COLOR_MATERIAL );
467     taxiway_blue_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
468     taxiway_blue_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
469     taxiway_blue_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
470     taxiway_blue_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
471     taxiway_blue_low_lights->setTexture( tex_name );
472     m = new SGMaterial( taxiway_blue_low_lights );
473     m->add_name("RWY_BLUE_TAXIWAY_LIGHTS");
474     matlib["RWY_BLUE_TAXIWAY_LIGHTS"] = m;
475
476     // hard coded runway vasi light state
477     tex_name = gen_standard_dir_light_map( 235, 235, 195, 255 );
478     ssgSimpleState *rwy_vasi_lights = new ssgSimpleState();
479     rwy_vasi_lights->disable( GL_LIGHTING );
480     rwy_vasi_lights->enable ( GL_CULL_FACE ) ;
481     rwy_vasi_lights->enable( GL_TEXTURE_2D );
482     rwy_vasi_lights->enable( GL_BLEND );
483     rwy_vasi_lights->enable( GL_ALPHA_TEST );
484     rwy_vasi_lights->enable( GL_COLOR_MATERIAL );
485     rwy_vasi_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
486     rwy_vasi_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
487     rwy_vasi_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
488     rwy_vasi_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
489     // rwy_vasi_lights->setTexture( gen_vasi_light_map_old() );
490     rwy_vasi_lights->setTexture( tex_name );
491     m = new SGMaterial( rwy_vasi_lights );
492     m->add_name("RWY_VASI_LIGHTS");
493     matlib["RWY_VASI_LIGHTS"] = m;
494
495     return true;
496 }
497
498
499 // Load a library of material properties
500 bool SGMaterialLib::add_item ( const string &tex_path )
501 {
502     string material_name = tex_path;
503     int pos = tex_path.rfind( "/" );
504     material_name = material_name.substr( pos + 1 );
505
506     return add_item( material_name, tex_path );
507 }
508
509
510 // Load a library of material properties
511 bool SGMaterialLib::add_item ( const string &mat_name, const string &full_path )
512 {
513     int pos = full_path.rfind( "/" );
514     string tex_name = full_path.substr( pos + 1 );
515     string tex_path = full_path.substr( 0, pos );
516
517     SG_LOG( SG_TERRAIN, SG_INFO, "  Loading material " 
518             << mat_name << " (" << full_path << ")");
519
520     matlib[mat_name] = new SGMaterial( full_path );
521     matlib[mat_name]->add_name(mat_name);
522
523     return true;
524 }
525
526
527 // Load a library of material properties
528 bool SGMaterialLib::add_item ( const string &mat_name, ssgSimpleState *state )
529 {
530     matlib[mat_name] = new SGMaterial( state );
531     matlib[mat_name]->add_name(mat_name);
532
533     SG_LOG( SG_TERRAIN, SG_INFO, "  Loading material given a premade "
534             << "ssgSimpleState = " << mat_name );
535
536     return true;
537 }
538
539
540 // find a material record by material name
541 SGMaterial *SGMaterialLib::find( const string& material ) {
542     SGMaterial *result = NULL;
543     material_map_iterator it = matlib.find( material );
544     if ( it != end() ) {
545         result = it->second;
546         return result;
547     }
548
549     return NULL;
550 }
551
552
553 // Destructor
554 SGMaterialLib::~SGMaterialLib ( void ) {
555 }
556
557
558 // Load one pending "deferred" texture.  Return true if a texture
559 // loaded successfully, false if no pending, or error.
560 void SGMaterialLib::load_next_deferred() {
561     // container::iterator it = begin();
562     for ( material_map_iterator it = begin(); it != end(); it++ ) {
563         /* we don't need the key, but here's how we'd get it if we wanted it. */
564         // const string &key = it->first;
565         SGMaterial *slot = it->second;
566         if (slot->load_texture())
567           return;
568     }
569 }
570
571 // Return the material from that given leaf
572 const SGMaterial* SGMaterialLib::findMaterial(/*const*/ssgLeaf* leaf) const
573 {
574   if (!leaf)
575     return 0;
576   
577   ssgBase* base = leaf->getUserData();
578   if (!base)
579     return 0;
580
581   SGMaterialUserData* matUserData = dynamic_cast<SGMaterialUserData*>(base);
582   if (!matUserData)
583     return 0;
584
585   return matUserData->getMaterial();
586 }
587
588 bool SGMaterialLib::find( ssgSimpleState* state, string & material ) const
589 {
590   // is obsolete, just kept here to avoid a race condition with
591   // SimGear/flightgear cvs checkouts ...
592     bool found = false;
593     ssgSimpleState *state_mat;
594
595     material = "";
596
597     for( const_material_map_iterator iter = begin(); iter != end(); iter++ )
598     {
599         int nb_tex = (*iter).second->get_num();
600
601         // many textures per material
602         for( int i = 0; i < nb_tex; i++ )
603         {
604             // material state
605             state_mat = (*iter).second->get_state( i );
606
607             if( state_mat == state )
608             {
609                  material = (*iter).first.c_str();
610                 found = true;
611                 break;
612             }
613         }
614
615         if( found )
616             break;
617     }
618
619     return found;
620 }