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