]> git.mxchange.org Git - simgear.git/blob - simgear/scene/material/matlib.cxx
Minor changes to logging messages (to STDOUT).
[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  - curt@me.umn.edu
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 <GL/gl.h>
37
38 #include <simgear/compiler.h>
39 #include <simgear/constants.h>
40 #include <simgear/structure/exception.hxx>
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 // generate the directional vasi light environment texture map
178 static int gen_vasi_light_map() {
179     const int env_tex_res = 256;
180     int half_res = env_tex_res / 2;
181
182     static unsigned char env_map[env_tex_res][env_tex_res][4];
183     GLuint tex_name;
184
185     for ( int i = 0; i < env_tex_res; ++i ) {
186         for ( int j = 0; j < env_tex_res; ++j ) {
187             double x = (i - half_res) / (double)half_res;
188             double y = (j - half_res) / (double)half_res;
189             double dist = sqrt(x*x + y*y);
190             if ( dist > 1.0 ) { dist = 1.0; }
191             double bright = cos( dist * SGD_PI_2 );
192
193             // top half white, bottom half red
194             env_map[i][j][0] = 255;
195             if ( i > half_res ) {
196                 // white
197                 env_map[i][j][1] = 255;
198                 env_map[i][j][2] = 255;
199             } else if ( i == half_res - 1 || i == half_res ) {
200                 // pink
201                 env_map[i][j][1] = 127;
202                 env_map[i][j][2] = 127;
203             } else {
204                 // red
205                 env_map[i][j][1] = 0;
206                 env_map[i][j][2] = 0;
207             }
208             env_map[i][j][3] = (int)(bright * 255);
209         }
210     }
211
212     glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
213     glGenTextures( 1, &tex_name );
214     glBindTexture( GL_TEXTURE_2D, tex_name );
215   
216     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
217     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
218     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
219     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
220     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, env_tex_res, env_tex_res, 0,
221                   GL_RGBA, GL_UNSIGNED_BYTE, env_map);
222
223     return tex_name;
224 }
225
226
227 // Load a library of material properties
228 bool SGMaterialLib::load( const string &fg_root, const string& mpath ) {
229
230     SGPropertyNode materials;
231
232     SG_LOG( SG_INPUT, SG_INFO, "Reading materials from " << mpath );
233     try {
234         readProperties( mpath, &materials );
235     } catch (const sg_exception &ex) {
236         SG_LOG( SG_INPUT, SG_ALERT, "Error reading materials: "
237                 << ex.getMessage() );
238         throw ex;
239     }
240
241     int nMaterials = materials.nChildren();
242     for (int i = 0; i < nMaterials; i++) {
243         const SGPropertyNode * node = materials.getChild(i);
244         if (!strcmp(node->getName(), "material")) {
245             SGMaterial *m = new SGMaterial( fg_root, node );
246
247             vector<SGPropertyNode_ptr>names = node->getChildren("name");
248             for ( unsigned int j = 0; j < names.size(); j++ ) {
249                 string name = names[j]->getStringValue();
250                 m->ref();
251                 // cerr << "Material " << name << endl;
252                 matlib[name] = m;
253                 SG_LOG( SG_TERRAIN, SG_INFO, "  Loading material "
254                         << names[j]->getStringValue() );
255             }
256         } else {
257             SG_LOG(SG_INPUT, SG_WARN,
258                    "Skipping bad material entry " << node->getName());
259         }
260     }
261
262     // hard coded ground light state
263     ssgSimpleState *gnd_lights = new ssgSimpleState;
264     gnd_lights->ref();
265     gnd_lights->disable( GL_TEXTURE_2D );
266     gnd_lights->enable( GL_CULL_FACE );
267     gnd_lights->enable( GL_COLOR_MATERIAL );
268     gnd_lights->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
269     gnd_lights->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
270     gnd_lights->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
271     gnd_lights->enable( GL_BLEND );
272     gnd_lights->disable( GL_ALPHA_TEST );
273     gnd_lights->disable( GL_LIGHTING );
274     matlib["GROUND_LIGHTS"] = new SGMaterial( gnd_lights );
275
276     GLuint tex_name;
277
278     // hard coded runway white light state
279     tex_name = gen_standard_dir_light_map( 235, 235, 195, 255 );
280     ssgSimpleState *rwy_white_lights = new ssgSimpleState();
281     rwy_white_lights->ref();
282     rwy_white_lights->disable( GL_LIGHTING );
283     rwy_white_lights->enable ( GL_CULL_FACE ) ;
284     rwy_white_lights->enable( GL_TEXTURE_2D );
285     rwy_white_lights->enable( GL_BLEND );
286     rwy_white_lights->enable( GL_ALPHA_TEST );
287     rwy_white_lights->enable( GL_COLOR_MATERIAL );
288     rwy_white_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
289     rwy_white_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
290     rwy_white_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
291     rwy_white_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
292     rwy_white_lights->setTexture( tex_name );
293     matlib["RWY_WHITE_LIGHTS"] = new SGMaterial( rwy_white_lights );
294     // For backwards compatibility ... remove someday
295     matlib["RUNWAY_LIGHTS"] = new SGMaterial( rwy_white_lights );
296     matlib["RWY_LIGHTS"] = new SGMaterial( rwy_white_lights );
297     // end of backwards compatitibilty
298
299     // hard coded runway medium intensity white light state
300     tex_name = gen_standard_dir_light_map( 235, 235, 195, 205 );
301     ssgSimpleState *rwy_white_medium_lights = new ssgSimpleState();
302     rwy_white_medium_lights->ref();
303     rwy_white_medium_lights->disable( GL_LIGHTING );
304     rwy_white_medium_lights->enable ( GL_CULL_FACE ) ;
305     rwy_white_medium_lights->enable( GL_TEXTURE_2D );
306     rwy_white_medium_lights->enable( GL_BLEND );
307     rwy_white_medium_lights->enable( GL_ALPHA_TEST );
308     rwy_white_medium_lights->enable( GL_COLOR_MATERIAL );
309     rwy_white_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
310     rwy_white_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
311     rwy_white_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
312     rwy_white_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
313     rwy_white_medium_lights->setTexture( tex_name );
314     matlib["RWY_WHITE_MEDIUM_LIGHTS"]
315         = new SGMaterial( rwy_white_medium_lights );
316
317     // hard coded runway low intensity white light state
318     tex_name = gen_standard_dir_light_map( 235, 235, 195, 155 );
319     ssgSimpleState *rwy_white_low_lights = new ssgSimpleState();
320     rwy_white_low_lights->ref();
321     rwy_white_low_lights->disable( GL_LIGHTING );
322     rwy_white_low_lights->enable ( GL_CULL_FACE ) ;
323     rwy_white_low_lights->enable( GL_TEXTURE_2D );
324     rwy_white_low_lights->enable( GL_BLEND );
325     rwy_white_low_lights->enable( GL_ALPHA_TEST );
326     rwy_white_low_lights->enable( GL_COLOR_MATERIAL );
327     rwy_white_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
328     rwy_white_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
329     rwy_white_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
330     rwy_white_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
331     rwy_white_low_lights->setTexture( tex_name );
332     matlib["RWY_WHITE_LOW_LIGHTS"]
333         = new SGMaterial( rwy_white_low_lights );
334
335     // hard coded runway yellow light state
336     tex_name = gen_standard_dir_light_map( 235, 215, 20, 255 );
337     ssgSimpleState *rwy_yellow_lights = new ssgSimpleState();
338     rwy_yellow_lights->ref();
339     rwy_yellow_lights->disable( GL_LIGHTING );
340     rwy_yellow_lights->enable ( GL_CULL_FACE ) ;
341     rwy_yellow_lights->enable( GL_TEXTURE_2D );
342     rwy_yellow_lights->enable( GL_BLEND );
343     rwy_yellow_lights->enable( GL_ALPHA_TEST );
344     rwy_yellow_lights->enable( GL_COLOR_MATERIAL );
345     rwy_yellow_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
346     rwy_yellow_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
347     rwy_yellow_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
348     rwy_yellow_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
349     rwy_yellow_lights->setTexture( tex_name );
350     matlib["RWY_YELLOW_LIGHTS"] = new SGMaterial( rwy_yellow_lights );
351
352     // hard coded runway medium intensity yellow light state
353     tex_name = gen_standard_dir_light_map( 235, 215, 20, 205 );
354     ssgSimpleState *rwy_yellow_medium_lights = new ssgSimpleState();
355     rwy_yellow_medium_lights->ref();
356     rwy_yellow_medium_lights->disable( GL_LIGHTING );
357     rwy_yellow_medium_lights->enable ( GL_CULL_FACE ) ;
358     rwy_yellow_medium_lights->enable( GL_TEXTURE_2D );
359     rwy_yellow_medium_lights->enable( GL_BLEND );
360     rwy_yellow_medium_lights->enable( GL_ALPHA_TEST );
361     rwy_yellow_medium_lights->enable( GL_COLOR_MATERIAL );
362     rwy_yellow_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
363     rwy_yellow_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
364     rwy_yellow_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
365     rwy_yellow_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
366     rwy_yellow_medium_lights->setTexture( tex_name );
367     matlib["RWY_YELLOW_MEDIUM_LIGHTS"]
368         = new SGMaterial( rwy_yellow_medium_lights );
369
370     // hard coded runway low intensity yellow light state
371     tex_name = gen_standard_dir_light_map( 235, 215, 20, 155 );
372     ssgSimpleState *rwy_yellow_low_lights = new ssgSimpleState();
373     rwy_yellow_low_lights->ref();
374     rwy_yellow_low_lights->disable( GL_LIGHTING );
375     rwy_yellow_low_lights->enable ( GL_CULL_FACE ) ;
376     rwy_yellow_low_lights->enable( GL_TEXTURE_2D );
377     rwy_yellow_low_lights->enable( GL_BLEND );
378     rwy_yellow_low_lights->enable( GL_ALPHA_TEST );
379     rwy_yellow_low_lights->enable( GL_COLOR_MATERIAL );
380     rwy_yellow_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
381     rwy_yellow_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
382     rwy_yellow_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
383     rwy_yellow_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
384     rwy_yellow_low_lights->setTexture( tex_name );
385     matlib["RWY_YELLOW_LOW_LIGHTS"]
386         = new SGMaterial( rwy_yellow_low_lights );
387
388     // hard coded runway red light state
389     tex_name = gen_standard_dir_light_map( 235, 90, 90, 255 );
390     ssgSimpleState *rwy_red_lights = new ssgSimpleState();
391     rwy_red_lights->ref();
392     rwy_red_lights->disable( GL_LIGHTING );
393     rwy_red_lights->enable ( GL_CULL_FACE ) ;
394     rwy_red_lights->enable( GL_TEXTURE_2D );
395     rwy_red_lights->enable( GL_BLEND );
396     rwy_red_lights->enable( GL_ALPHA_TEST );
397     rwy_red_lights->enable( GL_COLOR_MATERIAL );
398     rwy_red_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
399     rwy_red_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
400     rwy_red_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
401     rwy_red_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
402     rwy_red_lights->setTexture( tex_name );
403     matlib["RWY_RED_LIGHTS"]
404         = new SGMaterial( rwy_red_lights );
405
406     // hard coded medium intensity runway red light state
407     tex_name = gen_standard_dir_light_map( 235, 90, 90, 205 );
408     ssgSimpleState *rwy_red_medium_lights = new ssgSimpleState();
409     rwy_red_medium_lights->ref();
410     rwy_red_medium_lights->disable( GL_LIGHTING );
411     rwy_red_medium_lights->enable ( GL_CULL_FACE ) ;
412     rwy_red_medium_lights->enable( GL_TEXTURE_2D );
413     rwy_red_medium_lights->enable( GL_BLEND );
414     rwy_red_medium_lights->enable( GL_ALPHA_TEST );
415     rwy_red_medium_lights->enable( GL_COLOR_MATERIAL );
416     rwy_red_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
417     rwy_red_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
418     rwy_red_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
419     rwy_red_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
420     rwy_red_medium_lights->setTexture( tex_name );
421     matlib["RWY_RED_MEDIUM_LIGHTS"]
422         = new SGMaterial( rwy_red_medium_lights );
423
424     // hard coded low intensity runway red light state
425     tex_name = gen_standard_dir_light_map( 235, 90, 90, 155 );
426     ssgSimpleState *rwy_red_low_lights = new ssgSimpleState();
427     rwy_red_low_lights->ref();
428     rwy_red_low_lights->disable( GL_LIGHTING );
429     rwy_red_low_lights->enable ( GL_CULL_FACE ) ;
430     rwy_red_low_lights->enable( GL_TEXTURE_2D );
431     rwy_red_low_lights->enable( GL_BLEND );
432     rwy_red_low_lights->enable( GL_ALPHA_TEST );
433     rwy_red_low_lights->enable( GL_COLOR_MATERIAL );
434     rwy_red_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
435     rwy_red_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
436     rwy_red_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
437     rwy_red_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
438     rwy_red_low_lights->setTexture( tex_name );
439     matlib["RWY_RED_LOW_LIGHTS"]
440         = new SGMaterial( rwy_red_low_lights );
441
442     // hard coded runway green light state
443     tex_name = gen_standard_dir_light_map( 20, 235, 20, 255 );
444     ssgSimpleState *rwy_green_lights = new ssgSimpleState();
445     rwy_green_lights->ref();
446     rwy_green_lights->disable( GL_LIGHTING );
447     rwy_green_lights->enable ( GL_CULL_FACE ) ;
448     rwy_green_lights->enable( GL_TEXTURE_2D );
449     rwy_green_lights->enable( GL_BLEND );
450     rwy_green_lights->enable( GL_ALPHA_TEST );
451     rwy_green_lights->enable( GL_COLOR_MATERIAL );
452     rwy_green_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
453     rwy_green_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
454     rwy_green_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
455     rwy_green_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
456     rwy_green_lights->setTexture( tex_name );
457     matlib["RWY_GREEN_LIGHTS"]
458         = new SGMaterial( rwy_green_lights );
459
460     // hard coded medium intensity runway green light state
461     tex_name = gen_standard_dir_light_map( 20, 235, 20, 205 );
462     ssgSimpleState *rwy_green_medium_lights = new ssgSimpleState();
463     rwy_green_medium_lights->ref();
464     rwy_green_medium_lights->disable( GL_LIGHTING );
465     rwy_green_medium_lights->enable ( GL_CULL_FACE ) ;
466     rwy_green_medium_lights->enable( GL_TEXTURE_2D );
467     rwy_green_medium_lights->enable( GL_BLEND );
468     rwy_green_medium_lights->enable( GL_ALPHA_TEST );
469     rwy_green_medium_lights->enable( GL_COLOR_MATERIAL );
470     rwy_green_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
471     rwy_green_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
472     rwy_green_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
473     rwy_green_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
474     rwy_green_medium_lights->setTexture( tex_name );
475     matlib["RWY_GREEN_MEDIUM_LIGHTS"]
476         = new SGMaterial( rwy_green_medium_lights );
477
478     // hard coded low intensity runway green light state
479     tex_name = gen_standard_dir_light_map( 20, 235, 20, 155 );
480     ssgSimpleState *rwy_green_low_lights = new ssgSimpleState();
481     rwy_green_low_lights->ref();
482     rwy_green_low_lights->disable( GL_LIGHTING );
483     rwy_green_low_lights->enable ( GL_CULL_FACE ) ;
484     rwy_green_low_lights->enable( GL_TEXTURE_2D );
485     rwy_green_low_lights->enable( GL_BLEND );
486     rwy_green_low_lights->enable( GL_ALPHA_TEST );
487     rwy_green_low_lights->enable( GL_COLOR_MATERIAL );
488     rwy_green_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
489     rwy_green_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
490     rwy_green_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
491     rwy_green_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
492     rwy_green_low_lights->setTexture( tex_name );
493     matlib["RWY_GREEN_LOW_LIGHTS"]
494         = new SGMaterial( rwy_green_low_lights );
495     matlib["RWY_GREEN_TAXIWAY_LIGHTS"]
496         = new SGMaterial( rwy_green_low_lights );
497
498     // hard coded low intensity taxiway blue light state
499     tex_name = gen_taxiway_dir_light_map( 90, 90, 235, 205 );
500     ssgSimpleState *taxiway_blue_low_lights = new ssgSimpleState();
501     taxiway_blue_low_lights->ref();
502     taxiway_blue_low_lights->disable( GL_LIGHTING );
503     taxiway_blue_low_lights->enable ( GL_CULL_FACE ) ;
504     taxiway_blue_low_lights->enable( GL_TEXTURE_2D );
505     taxiway_blue_low_lights->enable( GL_BLEND );
506     taxiway_blue_low_lights->enable( GL_ALPHA_TEST );
507     taxiway_blue_low_lights->enable( GL_COLOR_MATERIAL );
508     taxiway_blue_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
509     taxiway_blue_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
510     taxiway_blue_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
511     taxiway_blue_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
512     taxiway_blue_low_lights->setTexture( tex_name );
513     matlib["RWY_BLUE_TAXIWAY_LIGHTS"]
514         = new SGMaterial( taxiway_blue_low_lights );
515
516     // hard coded runway vasi light state
517     ssgSimpleState *rwy_vasi_lights = new ssgSimpleState();
518     rwy_vasi_lights->ref();
519     rwy_vasi_lights->disable( GL_LIGHTING );
520     rwy_vasi_lights->enable ( GL_CULL_FACE ) ;
521     rwy_vasi_lights->enable( GL_TEXTURE_2D );
522     rwy_vasi_lights->enable( GL_BLEND );
523     rwy_vasi_lights->enable( GL_ALPHA_TEST );
524     rwy_vasi_lights->enable( GL_COLOR_MATERIAL );
525     rwy_vasi_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
526     rwy_vasi_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
527     rwy_vasi_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
528     rwy_vasi_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
529     rwy_vasi_lights->setTexture( gen_vasi_light_map() );
530     matlib["RWY_VASI_LIGHTS"] = new SGMaterial( rwy_vasi_lights );
531
532     return true;
533 }
534
535
536 // Load a library of material properties
537 bool SGMaterialLib::add_item ( const string &tex_path )
538 {
539     string material_name = tex_path;
540     int pos = tex_path.rfind( "/" );
541     material_name = material_name.substr( pos + 1 );
542
543     return add_item( material_name, tex_path );
544 }
545
546
547 // Load a library of material properties
548 bool SGMaterialLib::add_item ( const string &mat_name, const string &full_path )
549 {
550     int pos = full_path.rfind( "/" );
551     string tex_name = full_path.substr( pos + 1 );
552     string tex_path = full_path.substr( 0, pos );
553
554     SG_LOG( SG_TERRAIN, SG_INFO, "  Loading material " 
555             << mat_name << " (" << full_path << ")");
556
557     matlib[mat_name] = new SGMaterial( full_path );
558
559     return true;
560 }
561
562
563 // Load a library of material properties
564 bool SGMaterialLib::add_item ( const string &mat_name, ssgSimpleState *state )
565 {
566     SGMaterial *m = new SGMaterial( state );
567
568     SG_LOG( SG_TERRAIN, SG_INFO, "  Loading material given a premade "
569             << "ssgSimpleState = " << mat_name );
570
571     matlib[mat_name] = m;
572
573     return true;
574 }
575
576
577 // find a material record by material name
578 SGMaterial *SGMaterialLib::find( const string& material ) {
579     SGMaterial *result = NULL;
580     material_map_iterator it = matlib.find( material );
581     if ( it != end() ) {
582         result = it->second;
583         return result;
584     }
585
586     return NULL;
587 }
588
589
590 // Destructor
591 SGMaterialLib::~SGMaterialLib ( void ) {
592     // Free up all the material entries first
593     for ( material_map_iterator it = begin(); it != end(); it++ ) {
594         SGMaterial *slot = it->second;
595         slot->deRef();
596         if ( slot->getRef() <= 0 ) {
597             delete slot;
598         }
599     }
600 }
601
602
603 // Load one pending "deferred" texture.  Return true if a texture
604 // loaded successfully, false if no pending, or error.
605 void SGMaterialLib::load_next_deferred() {
606     // container::iterator it = begin();
607     for ( material_map_iterator it = begin(); it != end(); it++ ) {
608         /* we don't need the key, but here's how we'd get it if we wanted it. */
609         // const string &key = it->first;
610         SGMaterial *slot = it->second;
611         if (slot->load_texture())
612           return;
613     }
614 }