1 // material.cxx -- class to handle material properties
3 // Written by Curtis Olson, started May 1998.
5 // Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
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.
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.
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.
22 // (Log is kept at end of this file)
36 #include <Include/compiler.h>
41 #include <Debug/logstream.hxx>
42 #include <Misc/fgstream.hxx>
43 #include <Main/options.hxx>
44 #include <Main/views.hxx>
45 #include <Scenery/tile.hxx>
47 #include "material.hxx"
48 #include "fragment.hxx"
54 // global material management class
55 fgMATERIAL_MGR material_mgr;
59 fgMATERIAL::fgMATERIAL ( void )
64 ambient[0] = ambient[1] = ambient[2] = ambient[3] = 0.0;
65 diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = 0.0;
66 specular[0] = specular[1] = specular[2] = specular[3] = 0.0;
67 emissive[0] = emissive[1] = emissive[2] = emissive[3] = 0.0;
72 fgMATERIAL::append_sort_list( fgFRAGMENT *object )
74 if ( list_size < FG_MAX_MATERIAL_FRAGS ) {
75 list[ list_size++ ] = object;
84 operator >> ( istream& in, fgMATERIAL& m )
90 if ( token == "texture" )
92 in >> token >> m.texture_name;
94 else if ( token == "ambient" )
96 in >> token >> m.ambient[0] >> m.ambient[1]
97 >> m.ambient[2] >> m.ambient[3];
99 else if ( token == "diffuse" )
101 in >> token >> m.diffuse[0] >> m.diffuse[1]
102 >> m.diffuse[2] >> m.diffuse[3];
104 else if ( token == "specular" )
106 in >> token >> m.specular[0] >> m.specular[1]
107 >> m.specular[2] >> m.specular[3];
109 else if ( token == "emissive" )
111 in >> token >> m.emissive[0] >> m.emissive[1]
112 >> m.emissive[2] >> m.emissive[3];
114 else if ( token == "alpha" )
116 in >> token >> token;
117 if ( token == "yes" )
119 else if ( token == "no" )
123 FG_LOG( FG_TERRAIN, FG_INFO, "Bad alpha value " << token );
126 else if ( token[0] == '}' )
136 fgMATERIAL::load_texture()
141 // create the texture object and bind it
142 #ifdef GL_VERSION_1_1
143 xglGenTextures(1, &texture_id );
144 xglBindTexture(GL_TEXTURE_2D, texture_id );
145 #elif GL_EXT_texture_object
146 xglGenTexturesEXT(1, &texture_id );
147 xglBindTextureEXT(GL_TEXTURE_2D, texture_id );
152 // set the texture parameters for this texture
153 xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ) ;
154 xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ) ;
155 xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
157 // xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
158 // GL_NEAREST_MIPMAP_NEAREST );
159 xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
161 /* GL_NEAREST_MIPMAP_LINEAR */
162 GL_LINEAR_MIPMAP_LINEAR ) ;
164 /* load in the texture data */
165 string tpath = current_options.get_fg_root() + "/Textures/" +
166 texture_name + ".rgb";
167 string fg_tpath = tpath + ".gz";
174 read_rgb_texture(tpath.c_str(), &width, &height)) ==
179 read_rgb_texture(fg_tpath.c_str(), &width, &height))
182 FG_LOG( FG_GENERAL, FG_ALERT,
183 "Error in loading texture " << tpath );
188 /* xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
189 GL_RGB, GL_UNSIGNED_BYTE, texbuf); */
191 gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height,
192 GL_RGB, GL_UNSIGNED_BYTE, texbuf );
193 } else if ( alpha == 1 ) {
194 // load rgba (alpha) texture
198 read_alpha_texture(tpath.c_str(), &width, &height))
203 read_alpha_texture(fg_tpath.c_str(), &width, &height))
206 FG_LOG( FG_GENERAL, FG_ALERT,
207 "Error in loading texture " << tpath );
212 xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
213 GL_RGBA, GL_UNSIGNED_BYTE, texbuf);
219 fgMATERIAL::~fgMATERIAL ( void ) {
224 fgMATERIAL_MGR::fgMATERIAL_MGR ( void ) {
225 textures_loaded = false;
230 fgMATERIAL::render_fragments()
232 int tris_rendered = current_view.get_tris_rendered();
234 // cout << "rendering " + texture_name + " = " << list_size << "\n";
239 if ( current_options.get_textures() )
241 #ifdef GL_VERSION_1_1
242 xglBindTexture(GL_TEXTURE_2D, texture_id);
243 #elif GL_EXT_texture_object
244 xglBindTextureEXT(GL_TEXTURE_2D, texture_id);
249 xglMaterialfv (GL_FRONT, GL_AMBIENT, ambient);
250 xglMaterialfv (GL_FRONT, GL_DIFFUSE, diffuse);
253 fgTILE* last_tile_ptr = NULL;
254 frag_list_iterator current = list.begin();
255 frag_list_iterator last = list.end();
257 for ( ; current != last; ++current ) {
258 fgFRAGMENT* frag_ptr = *current;
259 tris_rendered += frag_ptr->num_faces();
260 if ( frag_ptr->tile_ptr != last_tile_ptr )
262 // new tile, new translate
263 last_tile_ptr = frag_ptr->tile_ptr;
264 xglLoadMatrixd( frag_ptr->tile_ptr->model_view );
267 // Woohoo!!! We finally get to draw something!
268 // printf(" display_list = %d\n", frag_ptr->display_list);
269 xglCallList( frag_ptr->display_list );
272 current_view.set_tris_rendered( tris_rendered );
276 // Load a library of material properties
278 fgMATERIAL_MGR::load_lib ( void )
280 string material_name;
282 // build the path name to the material db
283 string mpath = current_options.get_fg_root() + "/materials";
284 fg_gzifstream in( mpath );
286 FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << mpath );
290 while ( ! in.eof() ) {
291 // printf("%s", line);
293 // strip leading white space and comments
296 // set to zero to prevent its value accidently being '{'
297 // after a failed >> operation.
300 in >> material_name >> token;
302 if ( token == '{' ) {
303 FG_LOG( FG_TERRAIN, FG_INFO,
304 " Loading material " << material_name );
308 if ( current_options.get_textures() ) {
312 material_mgr.material_map[material_name] = m;
316 if ( current_options.get_textures() ) {
317 textures_loaded = true;
324 // Initialize the transient list of fragments for each material property
326 fgMATERIAL_MGR::init_transient_material_lists( void )
328 iterator last = end();
329 for ( iterator it = begin(); it != last; ++it )
331 (*it).second.init_sort_list();
337 fgMATERIAL_MGR::find( const string& material, fgMATERIAL*& mtl_ptr )
339 iterator it = material_map.find( material );
342 mtl_ptr = &((*it).second);
351 fgMATERIAL_MGR::~fgMATERIAL_MGR ( void ) {
356 fgMATERIAL_MGR::render_fragments()
358 current_view.set_tris_rendered( 0 );
360 iterator last = end();
361 for ( iterator current = begin(); current != last; ++current )
362 (*current).second.render_fragments();
367 // Revision 1.14 1999/03/02 01:03:24 curt
368 // Tweaks for building with native SGI compilers.
370 // Revision 1.13 1999/02/26 22:09:58 curt
371 // Added initial support for native SGI compilers.
373 // Revision 1.12 1998/12/09 18:50:30 curt
374 // Converted "class fgVIEW" to "class FGView" and updated to make data
375 // members private and make required accessor functions.
377 // Revision 1.11 1998/11/07 19:07:12 curt
378 // Enable release builds using the --without-logging option to the configure
379 // script. Also a couple log message cleanups, plus some C to C++ comment
382 // Revision 1.10 1998/11/06 21:18:17 curt
383 // Converted to new logstream debugging facility. This allows release
384 // builds with no messages at all (and no performance impact) by using
385 // the -DFG_NDEBUG flag.
387 // Revision 1.9 1998/11/06 14:47:05 curt
388 // Changes to track Bernie's updates to fgstream.
390 // Revision 1.8 1998/10/12 23:49:17 curt
391 // Changes from NHV to make the code more dynamic with fewer hard coded limits.
393 // Revision 1.7 1998/09/17 18:35:52 curt
394 // Tweaks and optimizations by Norman Vine.
396 // Revision 1.6 1998/09/15 01:35:05 curt
397 // cleaned up my fragment.num_faces hack :-) to use the STL (no need in
398 // duplicating work.)
399 // Tweaked fgTileMgrRender() do not calc tile matrix unless necessary.
400 // removed some unneeded stuff from fgTileMgrCurElev()
402 // Revision 1.5 1998/09/10 19:07:11 curt
403 // /Simulator/Objects/fragment.hxx
404 // Nested fgFACE inside fgFRAGMENT since its not used anywhere else.
406 // ./Simulator/Objects/material.cxx
407 // ./Simulator/Objects/material.hxx
408 // Made fgMATERIAL and fgMATERIAL_MGR bona fide classes with private
409 // data members - that should keep the rabble happy :)
411 // ./Simulator/Scenery/tilemgr.cxx
412 // In viewable() delay evaluation of eye[0] and eye[1] in until they're
414 // Change to fgTileMgrRender() to call fgMATERIAL_MGR::render_fragments()
417 // ./Include/fg_stl_config.h
418 // ./Include/auto_ptr.hxx
419 // Added support for g++ 2.7.
420 // Further changes to other files are forthcoming.
422 // Brief summary of changes required for g++ 2.7.
423 // operator->() not supported by iterators: use (*i).x instead of i->x
424 // default template arguments not supported,
425 // <functional> doesn't have mem_fun_ref() needed by callbacks.
426 // some std include files have different names.
427 // template member functions not supported.
429 // Revision 1.4 1998/09/01 19:03:08 curt
430 // Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
431 // - The new classes in libmisc.tgz define a stream interface into zlib.
432 // I've put these in a new directory, Lib/Misc. Feel free to rename it
433 // to something more appropriate. However you'll have to change the
434 // include directives in all the other files. Additionally you'll have
435 // add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
437 // The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
438 // test so I've included the required changes in config.tgz.
440 // There are a fair few changes to Simulator/Objects as I've moved
441 // things around. Loading tiles is quicker but thats not where the delay
442 // is. Tile loading takes a few tenths of a second per file on a P200
443 // but it seems to be the post-processing that leads to a noticeable
444 // blip in framerate. I suppose its time to start profiling to see where
447 // I've included a brief description of each archives contents.
452 // C++ stream interface into zlib.
453 // Taken from zlib-1.1.3/contrib/iostream/.
454 // Minor mods for STL compatibility.
455 // There's no copyright associated with these so I assume they're
456 // covered by zlib's.
460 // FlightGear input stream using gz_ifstream. Tries to open the
461 // given filename. If that fails then filename is examined and a
462 // ".gz" suffix is removed or appended and that file is opened.
465 // A simple timer for benchmarking. Not used in production code.
466 // Taken from the Blitz++ project. Covered by GPL.
470 // Some simple string manipulation routines.
472 // Simulator/Airports/
473 // Load airports database using fgstream.
474 // Changed fgAIRPORTS to use set<> instead of map<>.
475 // Added bool fgAIRPORTS::search() as a neater way doing the lookup.
476 // Returns true if found.
479 // Modified fgStarsInit() to load stars database using fgstream.
481 // Simulator/Objects/
482 // Modified fgObjLoad() to use fgstream.
483 // Modified fgMATERIAL_MGR::load_lib() to use fgstream.
484 // Many changes to fgMATERIAL.
485 // Some changes to fgFRAGMENT but I forget what!
487 // Revision 1.3 1998/08/27 17:02:09 curt
488 // Contributions from Bernie Bright <bbright@c031.aone.net.au>
489 // - use strings for fg_root and airport_id and added methods to return
491 // - inlined all access methods,
492 // - made the parsing functions private methods,
493 // - deleted some unused functions.
494 // - propogated some of these changes out a bit further.
496 // Revision 1.2 1998/08/25 20:53:33 curt
497 // Shuffled $FG_ROOT file layout.
499 // Revision 1.1 1998/08/25 16:51:24 curt
500 // Moved from ../Scenery
502 // Revision 1.13 1998/08/24 20:11:39 curt
505 // Revision 1.12 1998/08/12 21:41:27 curt
506 // Need to negate the test for textures so that textures aren't loaded when
507 // they are disabled rather than visa versa ... :-)
509 // Revision 1.11 1998/08/12 21:13:03 curt
510 // material.cxx: don't load textures if they are disabled
511 // obj.cxx: optimizations from Norman Vine
512 // tile.cxx: minor tweaks
513 // tile.hxx: addition of num_faces
514 // tilemgr.cxx: minor tweaks
516 // Revision 1.10 1998/07/24 21:42:06 curt
517 // material.cxx: whups, double method declaration with no definition.
518 // obj.cxx: tweaks to avoid errors in SGI's CC.
519 // tile.cxx: optimizations by Norman Vine.
520 // tilemgr.cxx: optimizations by Norman Vine.
522 // Revision 1.9 1998/07/13 21:01:57 curt
523 // Wrote access functions for current fgOPTIONS.
525 // Revision 1.8 1998/07/08 14:47:20 curt
526 // Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
527 // polare3d.h renamed to polar3d.hxx
528 // fg{Cartesian,Polar}Point3d consolodated.
529 // Added some initial support for calculating local current ground elevation.
531 // Revision 1.7 1998/07/04 00:54:28 curt
532 // Added automatic mipmap generation.
534 // When rendering fragments, use saved model view matrix from associated tile
535 // rather than recalculating it with push() translate() pop().
537 // Revision 1.6 1998/06/27 16:54:59 curt
538 // Check for GL_VERSION_1_1 or GL_EXT_texture_object to decide whether to use
539 // "EXT" versions of texture management routines.
541 // Revision 1.5 1998/06/17 21:36:39 curt
542 // Load and manage multiple textures defined in the Materials library.
543 // Boost max material fagments for each material property to 800.
544 // Multiple texture support when rendering.
546 // Revision 1.4 1998/06/12 00:58:04 curt
547 // Build only static libraries.
548 // Declare memmove/memset for Sloaris.
550 // Revision 1.3 1998/06/05 22:39:53 curt
551 // Working on sorting by, and rendering by material properties.
553 // Revision 1.2 1998/06/01 17:56:20 curt
554 // Incremental additions to material.cxx (not fully functional)
555 // Tweaked vfc_ratio math to avoid divide by zero.
557 // Revision 1.1 1998/05/30 01:56:45 curt
558 // Added material.cxx material.hxx