]> git.mxchange.org Git - flightgear.git/blob - src/Objects/materialmgr.cxx
Initial revisions.
[flightgear.git] / src / Objects / materialmgr.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 <config.h>
26 #endif
27
28 #ifdef FG_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/glut.h>
37 #include <XGL/xgl.h>
38
39 #include <Include/compiler.h>
40
41 #include <string.h>
42 #include STL_STRING
43
44 #include <Debug/logstream.hxx>
45 #include <Misc/fgpath.hxx>
46 #include <Misc/fgstream.hxx>
47 #include <Main/options.hxx>
48 #include <Main/views.hxx>
49 #include <Scenery/tileentry.hxx>
50
51 #include "materialmgr.hxx"
52 #include "fragment.hxx"
53
54 FG_USING_STD(string);
55
56
57 // global material management class
58 fgMATERIAL_MGR material_mgr;
59
60
61 // Constructor
62 FGMaterialSlot::FGMaterialSlot ( void ) { }
63
64
65 // Destructor
66 FGMaterialSlot::~FGMaterialSlot ( void ) {
67 }
68
69
70 // Constructor
71 fgMATERIAL_MGR::fgMATERIAL_MGR ( void ) {
72     materials_loaded = false;
73 }
74
75
76 #if 0
77 void
78 FGMaterialSlot::render_fragments()
79 {
80     FG_LOG( FG_GENERAL, FG_ALERT, 
81             "FGMaterialSlot::render_fragments() is depricated ... " <<
82             "we shouldn't be here!" );
83
84     int tris_rendered = current_view.get_tris_rendered();
85
86     // cout << "rendering " + texture_name + " = " << list_size << "\n";
87
88     if ( empty() ) {
89         return;
90     }
91
92     if ( current_options.get_textures() ) {
93
94         if ( !m.is_loaded() ) {
95             m.load_texture( current_options.get_fg_root() );
96         }
97
98 #ifdef GL_VERSION_1_1
99         xglBindTexture( GL_TEXTURE_2D, m.get_texture_id() );
100 #elif GL_EXT_texture_object
101         xglBindTextureEXT( GL_TEXTURE_2D, m.get_texture_id() );
102 #else
103 #  error port me
104 #endif
105     } else {
106         xglMaterialfv (GL_FRONT, GL_AMBIENT, m.get_ambient() );
107         xglMaterialfv (GL_FRONT, GL_DIFFUSE, m.get_diffuse() );
108     }
109
110     FGTileEntry* last_tile_ptr = NULL;
111     frag_list_iterator current = list.begin();
112     frag_list_iterator last = list.end();
113
114     for ( ; current != last; ++current ) {
115         fgFRAGMENT* frag_ptr = *current;
116         tris_rendered += frag_ptr->num_faces();
117         if ( frag_ptr->tile_ptr != last_tile_ptr ) {
118             // new tile, new translate
119             last_tile_ptr = frag_ptr->tile_ptr;
120             xglLoadMatrixf( frag_ptr->tile_ptr->model_view );
121         }
122
123         // Woohoo!!!  We finally get to draw something!
124         // printf("  display_list = %d\n", frag_ptr->display_list);
125         // xglCallList( frag_ptr->display_list );
126     }
127
128     current_view.set_tris_rendered( tris_rendered );
129 }
130 #endif 
131
132
133 // Load a library of material properties
134 int
135 fgMATERIAL_MGR::load_lib ( void )
136 {
137     string material_name;
138
139     // build the path name to the material db
140     FGPath mpath( current_options.get_fg_root() );
141     mpath.append( "materials" );
142
143     fg_gzifstream in( mpath.str() );
144     if ( ! in.is_open() ) {
145         FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << mpath.str() );
146         exit(-1);
147     }
148
149 #ifndef __MWERKS__
150     while ( ! in.eof() ) {
151 #else
152     char c = '\0';
153     while ( in.get(c) && c != '\0' ) {
154         in.putback(c);
155 #endif
156         // printf("%s", line);
157
158         // strip leading white space and comments
159         in >> skipcomment;
160
161         // set to zero to prevent its value accidently being '{'
162         // after a failed >> operation.
163         char token = 0;
164
165         in >> material_name >> token;
166
167         if ( token == '{' ) {
168             FGMaterial m;
169             in >> m;
170
171             FGMaterialSlot m_slot;
172             m_slot.set_m( m );
173
174             // build the ssgSimpleState
175             FGPath tex_file( current_options.get_fg_root() );
176             tex_file.append( "Textures" );
177             tex_file.append( m.get_texture_name() );
178             tex_file.concat( ".rgb" );
179
180             FG_LOG( FG_TERRAIN, FG_INFO, "  Loading material " 
181                     << material_name << " (" << tex_file.c_str() << ")");
182
183 #if EXTRA_DEBUG
184             m.dump_info();
185 #endif
186             
187             ssgStateSelector *state = new ssgStateSelector(2);
188             ssgSimpleState *textured = new ssgSimpleState();
189             ssgSimpleState *nontextured = new ssgSimpleState();
190
191             // Set up the textured state
192             textured->enable( GL_LIGHTING );
193             if ( current_options.get_shading() == 1 ) {
194                 textured->setShadeModel( GL_SMOOTH );
195             } else {
196                 textured->setShadeModel( GL_FLAT );
197             }
198
199             textured->enable ( GL_CULL_FACE      ) ;
200             textured->enable( GL_TEXTURE_2D );
201             textured->setTexture( (char *)tex_file.c_str() );
202             textured->setMaterial ( GL_AMBIENT_AND_DIFFUSE, 1, 1, 1, 1 ) ;
203             textured->setMaterial ( GL_SPECULAR, 0, 0, 0, 0 ) ;
204             textured->setMaterial ( GL_EMISSION, 0, 0, 0, 0 ) ;
205
206             // Set up the coloured state
207             nontextured->enable( GL_LIGHTING );
208             if ( current_options.get_shading() == 1 ) {
209                 nontextured->setShadeModel( GL_SMOOTH );
210             } else {
211                 nontextured->setShadeModel( GL_FLAT );
212             }
213
214             nontextured->enable ( GL_CULL_FACE      ) ;
215             nontextured->disable( GL_TEXTURE_2D );
216             nontextured->disable( GL_COLOR_MATERIAL );
217             GLfloat *ambient, *diffuse, *specular, *emission;
218             ambient = m.get_ambient();
219             diffuse = m.get_diffuse();
220             specular = m.get_specular();
221             emission = m.get_emission();
222
223             /* cout << "ambient = " << ambient[0] << "," << ambient[1] 
224                << "," << ambient[2] << endl; */
225             nontextured->setMaterial ( GL_AMBIENT, 
226                                    ambient[0], ambient[1], 
227                                    ambient[2], ambient[3] ) ;
228             nontextured->setMaterial ( GL_DIFFUSE, 
229                                    diffuse[0], diffuse[1], 
230                                    diffuse[2], diffuse[3] ) ;
231             nontextured->setMaterial ( GL_SPECULAR, 
232                                    specular[0], specular[1], 
233                                    specular[2], specular[3] ) ;
234             nontextured->setMaterial ( GL_EMISSION, 
235                                    emission[0], emission[1], 
236                                    emission[2], emission[3] ) ;
237
238             state->setStep( 0, textured );    // textured
239             state->setStep( 1, nontextured ); // untextured
240
241                                 // Choose the appropriate starting state.
242             if ( current_options.get_textures() ) {
243                 state->selectStep(0);
244             } else {
245                 state->selectStep(1);
246             }
247
248             m_slot.set_state( state );
249
250             material_mgr.material_map[material_name] = m_slot;
251         }
252     }
253
254     materials_loaded = true;
255     return 1;
256 }
257
258
259 // Initialize the transient list of fragments for each material property
260 void
261 fgMATERIAL_MGR::init_transient_material_lists( void )
262 {
263     iterator last = end();
264     for ( iterator it = begin(); it != last; ++it ) {
265         (*it).second.init_sort_list();
266     }
267 }
268
269
270 bool
271 fgMATERIAL_MGR::find( const string& material, FGMaterialSlot*& mtl_ptr )
272 {
273     iterator it = material_map.find( material );
274     if ( it != end() ) {
275         mtl_ptr = &((*it).second);
276         return true;
277     }
278
279     return false;
280 }
281
282
283 // Destructor
284 fgMATERIAL_MGR::~fgMATERIAL_MGR ( void ) {
285 }
286
287
288 // Set the step for all of the state selectors in the material slots
289 void
290 fgMATERIAL_MGR::set_step ( int step )
291 {
292     // container::iterator it = begin();
293     for (container::iterator it = begin(); it != end(); it++) {
294       const string &key = it->first;
295       FG_LOG( FG_GENERAL, FG_INFO,
296               "Updating material " << key << " to step " << step );
297       FGMaterialSlot &slot = it->second;
298       slot.get_state()->selectStep(step);
299     }
300 }
301
302
303 #if 0
304 void
305 fgMATERIAL_MGR::render_fragments()
306 {
307     current_view.set_tris_rendered( 0 );
308
309     iterator last = end();
310     for ( iterator current = begin(); current != last; ++current ) {
311         (*current).second.render_fragments();
312     }
313 }
314 #endif
315