]> git.mxchange.org Git - simgear.git/blob - simgear/scene/material/matlib.cxx
d3bd72c5ee8090ce8caf538b0810b6190faf786f
[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 <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, const char *season ) {
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;
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             SGSharedPtr<SGMaterial> m = new SGMaterial( fg_root, node, season );
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                 // cerr << "Material " << name << endl;
201                 matlib[name] = m;
202                 SG_LOG( SG_TERRAIN, SG_INFO, "  Loading material "
203                         << names[j]->getStringValue() );
204             }
205         } else {
206             SG_LOG(SG_INPUT, SG_WARN,
207                    "Skipping bad material entry " << node->getName());
208         }
209     }
210
211     // hard coded ground light state
212     ssgSimpleState *gnd_lights = new ssgSimpleState;
213     gnd_lights->disable( GL_TEXTURE_2D );
214     gnd_lights->enable( GL_CULL_FACE );
215     gnd_lights->enable( GL_COLOR_MATERIAL );
216     gnd_lights->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
217     gnd_lights->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
218     gnd_lights->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
219     gnd_lights->enable( GL_BLEND );
220     gnd_lights->disable( GL_ALPHA_TEST );
221     gnd_lights->disable( GL_LIGHTING );
222     matlib["GROUND_LIGHTS"] = new SGMaterial( gnd_lights );
223
224     GLuint tex_name;
225
226     // hard coded runway white light state
227     tex_name = gen_standard_dir_light_map( 235, 235, 195, 255 );
228     ssgSimpleState *rwy_white_lights = new ssgSimpleState();
229     rwy_white_lights->disable( GL_LIGHTING );
230     rwy_white_lights->enable ( GL_CULL_FACE ) ;
231     rwy_white_lights->enable( GL_TEXTURE_2D );
232     rwy_white_lights->enable( GL_BLEND );
233     rwy_white_lights->enable( GL_ALPHA_TEST );
234     rwy_white_lights->enable( GL_COLOR_MATERIAL );
235     rwy_white_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
236     rwy_white_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
237     rwy_white_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
238     rwy_white_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
239     rwy_white_lights->setTexture( tex_name );
240     matlib["RWY_WHITE_LIGHTS"] = new SGMaterial( rwy_white_lights );
241     // For backwards compatibility ... remove someday
242     matlib["RUNWAY_LIGHTS"] = new SGMaterial( rwy_white_lights );
243     matlib["RWY_LIGHTS"] = new SGMaterial( rwy_white_lights );
244     // end of backwards compatitibilty
245
246     // hard coded runway medium intensity white light state
247     tex_name = gen_standard_dir_light_map( 235, 235, 195, 205 );
248     ssgSimpleState *rwy_white_medium_lights = new ssgSimpleState();
249     rwy_white_medium_lights->disable( GL_LIGHTING );
250     rwy_white_medium_lights->enable ( GL_CULL_FACE ) ;
251     rwy_white_medium_lights->enable( GL_TEXTURE_2D );
252     rwy_white_medium_lights->enable( GL_BLEND );
253     rwy_white_medium_lights->enable( GL_ALPHA_TEST );
254     rwy_white_medium_lights->enable( GL_COLOR_MATERIAL );
255     rwy_white_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
256     rwy_white_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
257     rwy_white_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
258     rwy_white_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
259     rwy_white_medium_lights->setTexture( tex_name );
260     matlib["RWY_WHITE_MEDIUM_LIGHTS"]
261         = new SGMaterial( rwy_white_medium_lights );
262
263     // hard coded runway low intensity white light state
264     tex_name = gen_standard_dir_light_map( 235, 235, 195, 155 );
265     ssgSimpleState *rwy_white_low_lights = new ssgSimpleState();
266     rwy_white_low_lights->disable( GL_LIGHTING );
267     rwy_white_low_lights->enable ( GL_CULL_FACE ) ;
268     rwy_white_low_lights->enable( GL_TEXTURE_2D );
269     rwy_white_low_lights->enable( GL_BLEND );
270     rwy_white_low_lights->enable( GL_ALPHA_TEST );
271     rwy_white_low_lights->enable( GL_COLOR_MATERIAL );
272     rwy_white_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
273     rwy_white_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
274     rwy_white_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
275     rwy_white_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
276     rwy_white_low_lights->setTexture( tex_name );
277     matlib["RWY_WHITE_LOW_LIGHTS"]
278         = new SGMaterial( rwy_white_low_lights );
279
280     // hard coded runway yellow light state
281     tex_name = gen_standard_dir_light_map( 235, 215, 20, 255 );
282     ssgSimpleState *rwy_yellow_lights = new ssgSimpleState();
283     rwy_yellow_lights->disable( GL_LIGHTING );
284     rwy_yellow_lights->enable ( GL_CULL_FACE ) ;
285     rwy_yellow_lights->enable( GL_TEXTURE_2D );
286     rwy_yellow_lights->enable( GL_BLEND );
287     rwy_yellow_lights->enable( GL_ALPHA_TEST );
288     rwy_yellow_lights->enable( GL_COLOR_MATERIAL );
289     rwy_yellow_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
290     rwy_yellow_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
291     rwy_yellow_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
292     rwy_yellow_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
293     rwy_yellow_lights->setTexture( tex_name );
294     matlib["RWY_YELLOW_LIGHTS"] = new SGMaterial( rwy_yellow_lights );
295
296     // hard coded runway medium intensity yellow light state
297     tex_name = gen_standard_dir_light_map( 235, 215, 20, 205 );
298     ssgSimpleState *rwy_yellow_medium_lights = new ssgSimpleState();
299     rwy_yellow_medium_lights->disable( GL_LIGHTING );
300     rwy_yellow_medium_lights->enable ( GL_CULL_FACE ) ;
301     rwy_yellow_medium_lights->enable( GL_TEXTURE_2D );
302     rwy_yellow_medium_lights->enable( GL_BLEND );
303     rwy_yellow_medium_lights->enable( GL_ALPHA_TEST );
304     rwy_yellow_medium_lights->enable( GL_COLOR_MATERIAL );
305     rwy_yellow_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
306     rwy_yellow_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
307     rwy_yellow_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
308     rwy_yellow_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
309     rwy_yellow_medium_lights->setTexture( tex_name );
310     matlib["RWY_YELLOW_MEDIUM_LIGHTS"]
311         = new SGMaterial( rwy_yellow_medium_lights );
312
313     // hard coded runway low intensity yellow light state
314     tex_name = gen_standard_dir_light_map( 235, 215, 20, 155 );
315     ssgSimpleState *rwy_yellow_low_lights = new ssgSimpleState();
316     rwy_yellow_low_lights->disable( GL_LIGHTING );
317     rwy_yellow_low_lights->enable ( GL_CULL_FACE ) ;
318     rwy_yellow_low_lights->enable( GL_TEXTURE_2D );
319     rwy_yellow_low_lights->enable( GL_BLEND );
320     rwy_yellow_low_lights->enable( GL_ALPHA_TEST );
321     rwy_yellow_low_lights->enable( GL_COLOR_MATERIAL );
322     rwy_yellow_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
323     rwy_yellow_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
324     rwy_yellow_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
325     rwy_yellow_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
326     rwy_yellow_low_lights->setTexture( tex_name );
327     matlib["RWY_YELLOW_LOW_LIGHTS"]
328         = new SGMaterial( rwy_yellow_low_lights );
329
330     // hard coded runway red light state
331     tex_name = gen_standard_dir_light_map( 235, 90, 90, 255 );
332     ssgSimpleState *rwy_red_lights = new ssgSimpleState();
333     rwy_red_lights->disable( GL_LIGHTING );
334     rwy_red_lights->enable ( GL_CULL_FACE ) ;
335     rwy_red_lights->enable( GL_TEXTURE_2D );
336     rwy_red_lights->enable( GL_BLEND );
337     rwy_red_lights->enable( GL_ALPHA_TEST );
338     rwy_red_lights->enable( GL_COLOR_MATERIAL );
339     rwy_red_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
340     rwy_red_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
341     rwy_red_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
342     rwy_red_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
343     rwy_red_lights->setTexture( tex_name );
344     matlib["RWY_RED_LIGHTS"]
345         = new SGMaterial( rwy_red_lights );
346
347     // hard coded medium intensity runway red light state
348     tex_name = gen_standard_dir_light_map( 235, 90, 90, 205 );
349     ssgSimpleState *rwy_red_medium_lights = new ssgSimpleState();
350     rwy_red_medium_lights->disable( GL_LIGHTING );
351     rwy_red_medium_lights->enable ( GL_CULL_FACE ) ;
352     rwy_red_medium_lights->enable( GL_TEXTURE_2D );
353     rwy_red_medium_lights->enable( GL_BLEND );
354     rwy_red_medium_lights->enable( GL_ALPHA_TEST );
355     rwy_red_medium_lights->enable( GL_COLOR_MATERIAL );
356     rwy_red_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
357     rwy_red_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
358     rwy_red_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
359     rwy_red_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
360     rwy_red_medium_lights->setTexture( tex_name );
361     matlib["RWY_RED_MEDIUM_LIGHTS"]
362         = new SGMaterial( rwy_red_medium_lights );
363
364     // hard coded low intensity runway red light state
365     tex_name = gen_standard_dir_light_map( 235, 90, 90, 155 );
366     ssgSimpleState *rwy_red_low_lights = new ssgSimpleState();
367     rwy_red_low_lights->disable( GL_LIGHTING );
368     rwy_red_low_lights->enable ( GL_CULL_FACE ) ;
369     rwy_red_low_lights->enable( GL_TEXTURE_2D );
370     rwy_red_low_lights->enable( GL_BLEND );
371     rwy_red_low_lights->enable( GL_ALPHA_TEST );
372     rwy_red_low_lights->enable( GL_COLOR_MATERIAL );
373     rwy_red_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
374     rwy_red_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
375     rwy_red_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
376     rwy_red_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
377     rwy_red_low_lights->setTexture( tex_name );
378     matlib["RWY_RED_LOW_LIGHTS"]
379         = new SGMaterial( rwy_red_low_lights );
380
381     // hard coded runway green light state
382     tex_name = gen_standard_dir_light_map( 20, 235, 20, 255 );
383     ssgSimpleState *rwy_green_lights = new ssgSimpleState();
384     rwy_green_lights->disable( GL_LIGHTING );
385     rwy_green_lights->enable ( GL_CULL_FACE ) ;
386     rwy_green_lights->enable( GL_TEXTURE_2D );
387     rwy_green_lights->enable( GL_BLEND );
388     rwy_green_lights->enable( GL_ALPHA_TEST );
389     rwy_green_lights->enable( GL_COLOR_MATERIAL );
390     rwy_green_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
391     rwy_green_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
392     rwy_green_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
393     rwy_green_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
394     rwy_green_lights->setTexture( tex_name );
395     matlib["RWY_GREEN_LIGHTS"]
396         = new SGMaterial( rwy_green_lights );
397
398     // hard coded medium intensity runway green light state
399     tex_name = gen_standard_dir_light_map( 20, 235, 20, 205 );
400     ssgSimpleState *rwy_green_medium_lights = new ssgSimpleState();
401     rwy_green_medium_lights->disable( GL_LIGHTING );
402     rwy_green_medium_lights->enable ( GL_CULL_FACE ) ;
403     rwy_green_medium_lights->enable( GL_TEXTURE_2D );
404     rwy_green_medium_lights->enable( GL_BLEND );
405     rwy_green_medium_lights->enable( GL_ALPHA_TEST );
406     rwy_green_medium_lights->enable( GL_COLOR_MATERIAL );
407     rwy_green_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
408     rwy_green_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
409     rwy_green_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
410     rwy_green_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
411     rwy_green_medium_lights->setTexture( tex_name );
412     matlib["RWY_GREEN_MEDIUM_LIGHTS"]
413         = new SGMaterial( rwy_green_medium_lights );
414
415     // hard coded low intensity runway green light state
416     tex_name = gen_standard_dir_light_map( 20, 235, 20, 155 );
417     ssgSimpleState *rwy_green_low_lights = new ssgSimpleState();
418     rwy_green_low_lights->disable( GL_LIGHTING );
419     rwy_green_low_lights->enable ( GL_CULL_FACE ) ;
420     rwy_green_low_lights->enable( GL_TEXTURE_2D );
421     rwy_green_low_lights->enable( GL_BLEND );
422     rwy_green_low_lights->enable( GL_ALPHA_TEST );
423     rwy_green_low_lights->enable( GL_COLOR_MATERIAL );
424     rwy_green_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
425     rwy_green_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
426     rwy_green_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
427     rwy_green_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
428     rwy_green_low_lights->setTexture( tex_name );
429     matlib["RWY_GREEN_LOW_LIGHTS"]
430         = new SGMaterial( rwy_green_low_lights );
431     matlib["RWY_GREEN_TAXIWAY_LIGHTS"]
432         = new SGMaterial( rwy_green_low_lights );
433
434     // hard coded low intensity taxiway blue light state
435     tex_name = gen_taxiway_dir_light_map( 90, 90, 235, 205 );
436     ssgSimpleState *taxiway_blue_low_lights = new ssgSimpleState();
437     taxiway_blue_low_lights->disable( GL_LIGHTING );
438     taxiway_blue_low_lights->enable ( GL_CULL_FACE ) ;
439     taxiway_blue_low_lights->enable( GL_TEXTURE_2D );
440     taxiway_blue_low_lights->enable( GL_BLEND );
441     taxiway_blue_low_lights->enable( GL_ALPHA_TEST );
442     taxiway_blue_low_lights->enable( GL_COLOR_MATERIAL );
443     taxiway_blue_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
444     taxiway_blue_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
445     taxiway_blue_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
446     taxiway_blue_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
447     taxiway_blue_low_lights->setTexture( tex_name );
448     matlib["RWY_BLUE_TAXIWAY_LIGHTS"]
449         = new SGMaterial( taxiway_blue_low_lights );
450
451     // hard coded runway vasi light state
452     tex_name = gen_standard_dir_light_map( 235, 235, 195, 255 );
453     ssgSimpleState *rwy_vasi_lights = new ssgSimpleState();
454     rwy_vasi_lights->disable( GL_LIGHTING );
455     rwy_vasi_lights->enable ( GL_CULL_FACE ) ;
456     rwy_vasi_lights->enable( GL_TEXTURE_2D );
457     rwy_vasi_lights->enable( GL_BLEND );
458     rwy_vasi_lights->enable( GL_ALPHA_TEST );
459     rwy_vasi_lights->enable( GL_COLOR_MATERIAL );
460     rwy_vasi_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
461     rwy_vasi_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
462     rwy_vasi_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
463     rwy_vasi_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
464     // rwy_vasi_lights->setTexture( gen_vasi_light_map_old() );
465     rwy_vasi_lights->setTexture( tex_name );
466     matlib["RWY_VASI_LIGHTS"] = new SGMaterial( rwy_vasi_lights );
467
468     return true;
469 }
470
471
472 // Load a library of material properties
473 bool SGMaterialLib::add_item ( const string &tex_path )
474 {
475     string material_name = tex_path;
476     int pos = tex_path.rfind( "/" );
477     material_name = material_name.substr( pos + 1 );
478
479     return add_item( material_name, tex_path );
480 }
481
482
483 // Load a library of material properties
484 bool SGMaterialLib::add_item ( const string &mat_name, const string &full_path )
485 {
486     int pos = full_path.rfind( "/" );
487     string tex_name = full_path.substr( pos + 1 );
488     string tex_path = full_path.substr( 0, pos );
489
490     SG_LOG( SG_TERRAIN, SG_INFO, "  Loading material " 
491             << mat_name << " (" << full_path << ")");
492
493     matlib[mat_name] = new SGMaterial( full_path );
494
495     return true;
496 }
497
498
499 // Load a library of material properties
500 bool SGMaterialLib::add_item ( const string &mat_name, ssgSimpleState *state )
501 {
502     matlib[mat_name] = new SGMaterial( state );
503
504     SG_LOG( SG_TERRAIN, SG_INFO, "  Loading material given a premade "
505             << "ssgSimpleState = " << mat_name );
506
507     return true;
508 }
509
510
511 // find a material record by material name
512 SGMaterial *SGMaterialLib::find( const string& material ) {
513     SGMaterial *result = NULL;
514     material_map_iterator it = matlib.find( material );
515     if ( it != end() ) {
516         result = it->second;
517         return result;
518     }
519
520     return NULL;
521 }
522
523
524 // Destructor
525 SGMaterialLib::~SGMaterialLib ( void ) {
526 }
527
528
529 // Load one pending "deferred" texture.  Return true if a texture
530 // loaded successfully, false if no pending, or error.
531 void SGMaterialLib::load_next_deferred() {
532     // container::iterator it = begin();
533     for ( material_map_iterator it = begin(); it != end(); it++ ) {
534         /* we don't need the key, but here's how we'd get it if we wanted it. */
535         // const string &key = it->first;
536         SGMaterial *slot = it->second;
537         if (slot->load_texture())
538           return;
539     }
540 }
541
542 bool SGMaterialLib::find( ssgSimpleState *state, string & material ) const
543 {
544     bool found = false;
545     ssgSimpleState *state_mat;
546
547     material = "";
548
549     for( const_material_map_iterator iter = begin(); iter != end(); iter++ )
550     {
551          int nb_tex = (*iter).second->get_num();
552
553          // many textures per material
554          for( int i = 0; i < nb_tex; i++ )
555          {
556              // material state
557              state_mat = (*iter).second->get_state( i );
558
559              if( state_mat == state )
560              {
561                  material = (*iter).first.c_str();
562                  found = true;
563                  break;
564              }
565          }
566
567          if( found )
568              break;
569     }
570
571     return found;
572 }
573