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