]> git.mxchange.org Git - flightgear.git/blob - Objects/material.cxx
Converted to new logstream debugging facility. This allows release
[flightgear.git] / Objects / material.cxx
1 // material.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 // (Log is kept at end of this file)
23
24
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28
29 #ifdef HAVE_WINDOWS_H
30 #  include <windows.h>
31 #endif
32
33 #include <GL/glut.h>
34 #include <XGL/xgl.h>
35
36 #include <string.h>
37 #include <string>
38
39 #include "Include/fg_stl_config.h"
40 #include <Debug/logstream.hxx>
41 #include <Main/options.hxx>
42 #include <Misc/fgstream.hxx>
43 #include <Main/views.hxx>
44 #include <Scenery/tile.hxx>
45
46 #include "material.hxx"
47 #include "fragment.hxx"
48 #include "texload.h"
49
50
51 // global material management class
52 fgMATERIAL_MGR material_mgr;
53
54
55 // Constructor
56 fgMATERIAL::fgMATERIAL ( void )
57     : texture_name(""),
58       alpha(0)
59       // , list_size(0)
60 {
61     ambient[0]  = ambient[1]  = ambient[2]  = ambient[3]  = 0.0;
62     diffuse[0]  = diffuse[1]  = diffuse[2]  = diffuse[3]  = 0.0;
63     specular[0] = specular[1] = specular[2] = specular[3] = 0.0;
64     emissive[0] = emissive[1] = emissive[2] = emissive[3] = 0.0;
65 }
66
67 /*
68 int
69 fgMATERIAL::append_sort_list( fgFRAGMENT *object )
70 {
71     if ( list_size < FG_MAX_MATERIAL_FRAGS ) {
72         list[ list_size++ ] = object;
73         return 1;
74     } else {
75         return 0;
76     }
77 }
78 */
79
80 istream&
81 operator >> ( istream& in, fgMATERIAL& m )
82 {
83     string token;
84
85     for (;;) {
86         in >> token;
87         if ( token == "texture" )
88         {
89             in >> token >> m.texture_name;
90         }
91         else if ( token == "ambient" )
92         {
93             in >> token >> m.ambient[0] >> m.ambient[1]
94                         >> m.ambient[2] >> m.ambient[3];
95         }
96         else if ( token == "diffuse" )
97         {
98             in >> token >> m.diffuse[0] >> m.diffuse[1]
99                         >> m.diffuse[2] >> m.diffuse[3];
100         }
101         else if ( token == "specular" )
102         {
103             in >> token >> m.specular[0] >> m.specular[1]
104                         >> m.specular[2] >> m.specular[3];
105         }
106         else if ( token == "emissive" )
107         {
108             in >> token >> m.emissive[0] >> m.emissive[1]
109                         >> m.emissive[2] >> m.emissive[3];
110         }
111         else if ( token == "alpha" )
112         {
113             in >> token >> token;
114             if ( token == "yes" )
115                 m.alpha = 1;
116             else if ( token == "no" )
117                 m.alpha = 0;
118             else
119             {
120                 FG_LOG( FG_TERRAIN, FG_INFO, "Bad alpha value " << token );
121             }
122         }
123         else if ( token[0] == '}' )
124         {
125             break;
126         }
127     }
128
129     return in;
130 }
131
132 void
133 fgMATERIAL::load_texture()
134 {
135         GLubyte *texbuf;
136         int width, height;
137
138         // create the texture object and bind it
139 #ifdef GL_VERSION_1_1
140         xglGenTextures(1, &texture_id );
141         xglBindTexture(GL_TEXTURE_2D, texture_id );
142 #elif GL_EXT_texture_object
143         xglGenTexturesEXT(1, &texture_id );
144         xglBindTextureEXT(GL_TEXTURE_2D, texture_id );
145 #else
146 #  error port me
147 #endif
148
149         // set the texture parameters for this texture
150         xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ) ;
151         xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ) ;
152         xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
153                           GL_LINEAR );
154         // xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
155         //                   GL_NEAREST_MIPMAP_NEAREST );
156         xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
157                           /* GL_LINEAR */ 
158                           /* GL_NEAREST_MIPMAP_LINEAR */
159                           GL_LINEAR_MIPMAP_LINEAR ) ;
160
161         /* load in the texture data */
162         string tpath = current_options.get_fg_root() + "/Textures/" + 
163             texture_name + ".rgb";
164         string fg_tpath = tpath + ".gz";
165
166         if ( alpha == 0 ) {
167             // load rgb texture
168
169             // Try uncompressed
170             if ( (texbuf = 
171                   read_rgb_texture(tpath.c_str(), &width, &height)) == 
172                  NULL )
173             {
174                 // Try compressed
175                 if ( (texbuf = 
176                       read_rgb_texture(fg_tpath.c_str(), &width, &height)) 
177                      == NULL )
178                 {
179                     FG_LOG( FG_GENERAL, FG_ALERT, 
180                             "Error in loading texture " << tpath );
181                     exit(-1);
182                 } 
183             } 
184
185             /* xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
186                GL_RGB, GL_UNSIGNED_BYTE, texbuf); */
187
188             gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height, 
189                                GL_RGB, GL_UNSIGNED_BYTE, texbuf );
190         } else if ( alpha == 1 ) {
191             // load rgba (alpha) texture
192
193             // Try uncompressed
194             if ( (texbuf = 
195                   read_alpha_texture(tpath.c_str(), &width, &height))
196                  == NULL )
197             {
198                 // Try compressed
199                 if ((texbuf = 
200                      read_alpha_texture(fg_tpath.c_str(), &width, &height))
201                     == NULL )
202                 {
203                     FG_LOG( FG_GENERAL, FG_ALERT, 
204                             "Error in loading texture " << tpath );
205                     exit(-1);
206                 } 
207             } 
208
209             xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
210                           GL_RGBA, GL_UNSIGNED_BYTE, texbuf);
211         }
212 }
213
214
215 // Destructor
216 fgMATERIAL::~fgMATERIAL ( void ) {
217 }
218
219
220 // Constructor
221 fgMATERIAL_MGR::fgMATERIAL_MGR ( void ) {
222     textures_loaded = false;
223 }
224
225
226 void
227 fgMATERIAL::render_fragments()
228 {
229     // cout << "rendering " + texture_name + " = " << list_size << "\n";
230
231     if ( empty() )
232         return;
233
234     if ( current_options.get_textures() )
235     {
236 #ifdef GL_VERSION_1_1
237         xglBindTexture(GL_TEXTURE_2D, texture_id);
238 #elif GL_EXT_texture_object
239         xglBindTextureEXT(GL_TEXTURE_2D, texture_id);
240 #else
241 #  error port me
242 #endif
243     } else {
244         xglMaterialfv (GL_FRONT, GL_AMBIENT, ambient);
245         xglMaterialfv (GL_FRONT, GL_DIFFUSE, diffuse);
246     }
247
248     fgTILE* last_tile_ptr = NULL;
249     frag_list_iterator current = list.begin();
250     frag_list_iterator last = list.end();
251
252     for ( ; current != last; ++current ) {
253         fgFRAGMENT* frag_ptr = *current;
254         current_view.tris_rendered += frag_ptr->num_faces();
255         if ( frag_ptr->tile_ptr != last_tile_ptr )
256         {
257             // new tile, new translate
258             last_tile_ptr = frag_ptr->tile_ptr;
259             xglLoadMatrixd( frag_ptr->tile_ptr->model_view );
260         }
261
262         // Woohoo!!!  We finally get to draw something!
263         // printf("  display_list = %d\n", frag_ptr->display_list);
264         xglCallList( frag_ptr->display_list );
265     }
266 }
267
268
269 // Load a library of material properties
270 int
271 fgMATERIAL_MGR::load_lib ( void )
272 {
273     string material_name;
274
275     // build the path name to the material db
276     string mpath = current_options.get_fg_root() + "/materials";
277     fg_gzifstream in( mpath );
278     if ( ! in ) {
279         FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << mpath );
280         exit(-1);
281     }
282
283     while ( ! in.eof() ) {
284         // printf("%s", line);
285
286         // strip leading white space and comments
287         in >> skipcomment;
288
289         // set to zero to prevent its value accidently being '{'
290         // after a failed >> operation.
291         char token = 0;
292
293         in >> material_name >> token;
294
295         if ( token == '{' ) {
296             printf( "  Loading material %s\n", material_name.c_str() );
297             fgMATERIAL m;
298             in >> m;
299
300             if ( current_options.get_textures() ) {
301                 m.load_texture();
302             }
303
304             material_mgr.material_map[material_name] = m;
305         }
306     }
307
308     if ( current_options.get_textures() ) {
309         textures_loaded = true;
310     }
311
312     return(1);
313 }
314
315
316 // Initialize the transient list of fragments for each material property
317 void
318 fgMATERIAL_MGR::init_transient_material_lists( void )
319 {
320     iterator last = end();
321     for ( iterator it = begin(); it != last; ++it )
322     {
323         (*it).second.init_sort_list();
324     }
325 }
326
327
328 bool
329 fgMATERIAL_MGR::find( const string& material, fgMATERIAL*& mtl_ptr )
330 {
331     iterator it = material_map.find( material );
332     if ( it != end() )
333     {
334         mtl_ptr = &((*it).second);
335         return true;
336     }
337
338     return false;
339 }
340
341
342 // Destructor
343 fgMATERIAL_MGR::~fgMATERIAL_MGR ( void ) {
344 }
345
346
347 void
348 fgMATERIAL_MGR::render_fragments()
349 {
350     current_view.tris_rendered = 0;
351     iterator last = end();
352     for ( iterator current = begin(); current != last; ++current )
353         (*current).second.render_fragments();
354 }
355
356
357 // $Log$
358 // Revision 1.10  1998/11/06 21:18:17  curt
359 // Converted to new logstream debugging facility.  This allows release
360 // builds with no messages at all (and no performance impact) by using
361 // the -DFG_NDEBUG flag.
362 //
363 // Revision 1.9  1998/11/06 14:47:05  curt
364 // Changes to track Bernie's updates to fgstream.
365 //
366 // Revision 1.8  1998/10/12 23:49:17  curt
367 // Changes from NHV to make the code more dynamic with fewer hard coded limits.
368 //
369 // Revision 1.7  1998/09/17 18:35:52  curt
370 // Tweaks and optimizations by Norman Vine.
371 //
372 // Revision 1.6  1998/09/15 01:35:05  curt
373 // cleaned up my fragment.num_faces hack :-) to use the STL (no need in
374 // duplicating work.)
375 // Tweaked fgTileMgrRender() do not calc tile matrix unless necessary.
376 // removed some unneeded stuff from fgTileMgrCurElev()
377 //
378 // Revision 1.5  1998/09/10 19:07:11  curt
379 // /Simulator/Objects/fragment.hxx
380 //   Nested fgFACE inside fgFRAGMENT since its not used anywhere else.
381 //
382 // ./Simulator/Objects/material.cxx
383 // ./Simulator/Objects/material.hxx
384 //   Made fgMATERIAL and fgMATERIAL_MGR bona fide classes with private
385 //   data members - that should keep the rabble happy :)
386 //
387 // ./Simulator/Scenery/tilemgr.cxx
388 //   In viewable() delay evaluation of eye[0] and eye[1] in until they're
389 //   actually needed.
390 //   Change to fgTileMgrRender() to call fgMATERIAL_MGR::render_fragments()
391 //   method.
392 //
393 // ./Include/fg_stl_config.h
394 // ./Include/auto_ptr.hxx
395 //   Added support for g++ 2.7.
396 //   Further changes to other files are forthcoming.
397 //
398 // Brief summary of changes required for g++ 2.7.
399 //   operator->() not supported by iterators: use (*i).x instead of i->x
400 //   default template arguments not supported,
401 //   <functional> doesn't have mem_fun_ref() needed by callbacks.
402 //   some std include files have different names.
403 //   template member functions not supported.
404 //
405 // Revision 1.4  1998/09/01 19:03:08  curt
406 // Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
407 //  - The new classes in libmisc.tgz define a stream interface into zlib.
408 //    I've put these in a new directory, Lib/Misc.  Feel free to rename it
409 //    to something more appropriate.  However you'll have to change the
410 //    include directives in all the other files.  Additionally you'll have
411 //    add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
412 //
413 //    The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
414 //    test so I've included the required changes in config.tgz.
415 //
416 //    There are a fair few changes to Simulator/Objects as I've moved
417 //    things around.  Loading tiles is quicker but thats not where the delay
418 //    is.  Tile loading takes a few tenths of a second per file on a P200
419 //    but it seems to be the post-processing that leads to a noticeable
420 //    blip in framerate.  I suppose its time to start profiling to see where
421 //    the delays are.
422 //
423 //    I've included a brief description of each archives contents.
424 //
425 // Lib/Misc/
426 //   zfstream.cxx
427 //   zfstream.hxx
428 //     C++ stream interface into zlib.
429 //     Taken from zlib-1.1.3/contrib/iostream/.
430 //     Minor mods for STL compatibility.
431 //     There's no copyright associated with these so I assume they're
432 //     covered by zlib's.
433 //
434 //   fgstream.cxx
435 //   fgstream.hxx
436 //     FlightGear input stream using gz_ifstream.  Tries to open the
437 //     given filename.  If that fails then filename is examined and a
438 //     ".gz" suffix is removed or appended and that file is opened.
439 //
440 //   stopwatch.hxx
441 //     A simple timer for benchmarking.  Not used in production code.
442 //     Taken from the Blitz++ project.  Covered by GPL.
443 //
444 //   strutils.cxx
445 //   strutils.hxx
446 //     Some simple string manipulation routines.
447 //
448 // Simulator/Airports/
449 //   Load airports database using fgstream.
450 //   Changed fgAIRPORTS to use set<> instead of map<>.
451 //   Added bool fgAIRPORTS::search() as a neater way doing the lookup.
452 //   Returns true if found.
453 //
454 // Simulator/Astro/
455 //   Modified fgStarsInit() to load stars database using fgstream.
456 //
457 // Simulator/Objects/
458 //   Modified fgObjLoad() to use fgstream.
459 //   Modified fgMATERIAL_MGR::load_lib() to use fgstream.
460 //   Many changes to fgMATERIAL.
461 //   Some changes to fgFRAGMENT but I forget what!
462 //
463 // Revision 1.3  1998/08/27 17:02:09  curt
464 // Contributions from Bernie Bright <bbright@c031.aone.net.au>
465 // - use strings for fg_root and airport_id and added methods to return
466 //   them as strings,
467 // - inlined all access methods,
468 // - made the parsing functions private methods,
469 // - deleted some unused functions.
470 // - propogated some of these changes out a bit further.
471 //
472 // Revision 1.2  1998/08/25 20:53:33  curt
473 // Shuffled $FG_ROOT file layout.
474 //
475 // Revision 1.1  1998/08/25 16:51:24  curt
476 // Moved from ../Scenery
477 //
478 // Revision 1.13  1998/08/24 20:11:39  curt
479 // Tweaks ...
480 //
481 // Revision 1.12  1998/08/12 21:41:27  curt
482 // Need to negate the test for textures so that textures aren't loaded when
483 // they are disabled rather than visa versa ... :-)
484 //
485 // Revision 1.11  1998/08/12 21:13:03  curt
486 // material.cxx: don't load textures if they are disabled
487 // obj.cxx: optimizations from Norman Vine
488 // tile.cxx: minor tweaks
489 // tile.hxx: addition of num_faces
490 // tilemgr.cxx: minor tweaks
491 //
492 // Revision 1.10  1998/07/24 21:42:06  curt
493 // material.cxx: whups, double method declaration with no definition.
494 // obj.cxx: tweaks to avoid errors in SGI's CC.
495 // tile.cxx: optimizations by Norman Vine.
496 // tilemgr.cxx: optimizations by Norman Vine.
497 //
498 // Revision 1.9  1998/07/13 21:01:57  curt
499 // Wrote access functions for current fgOPTIONS.
500 //
501 // Revision 1.8  1998/07/08 14:47:20  curt
502 // Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
503 // polare3d.h renamed to polar3d.hxx
504 // fg{Cartesian,Polar}Point3d consolodated.
505 // Added some initial support for calculating local current ground elevation.
506 //
507 // Revision 1.7  1998/07/04 00:54:28  curt
508 // Added automatic mipmap generation.
509 //
510 // When rendering fragments, use saved model view matrix from associated tile
511 // rather than recalculating it with push() translate() pop().
512 //
513 // Revision 1.6  1998/06/27 16:54:59  curt
514 // Check for GL_VERSION_1_1 or GL_EXT_texture_object to decide whether to use
515 //   "EXT" versions of texture management routines.
516 //
517 // Revision 1.5  1998/06/17 21:36:39  curt
518 // Load and manage multiple textures defined in the Materials library.
519 // Boost max material fagments for each material property to 800.
520 // Multiple texture support when rendering.
521 //
522 // Revision 1.4  1998/06/12 00:58:04  curt
523 // Build only static libraries.
524 // Declare memmove/memset for Sloaris.
525 //
526 // Revision 1.3  1998/06/05 22:39:53  curt
527 // Working on sorting by, and rendering by material properties.
528 //
529 // Revision 1.2  1998/06/01 17:56:20  curt
530 // Incremental additions to material.cxx (not fully functional)
531 // Tweaked vfc_ratio math to avoid divide by zero.
532 //
533 // Revision 1.1  1998/05/30 01:56:45  curt
534 // Added material.cxx material.hxx
535 //