1 // materialmgr.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.
28 #ifdef FG_MATH_EXCEPTION_CLASH
37 #include <simgear/xgl/xgl.h>
39 #include <simgear/compiler.h>
44 #include <simgear/debug/logstream.hxx>
45 #include <simgear/misc/fgpath.hxx>
46 #include <simgear/misc/fgstream.hxx>
48 #include <Main/options.hxx>
49 #include <Main/views.hxx>
50 #include <Scenery/tileentry.hxx>
52 #include "materialmgr.hxx"
53 #include "fragment.hxx"
58 // global material management class
59 fgMATERIAL_MGR material_mgr;
63 FGMaterialSlot::FGMaterialSlot ( void ) { }
67 FGMaterialSlot::~FGMaterialSlot ( void ) {
72 fgMATERIAL_MGR::fgMATERIAL_MGR ( void ) {
73 materials_loaded = false;
79 FGMaterialSlot::render_fragments()
81 FG_LOG( FG_GENERAL, FG_ALERT,
82 "FGMaterialSlot::render_fragments() is depricated ... " <<
83 "we shouldn't be here!" );
85 int tris_rendered = current_view.get_tris_rendered();
87 // cout << "rendering " + texture_name + " = " << list_size << "\n";
93 if ( current_options.get_textures() ) {
95 if ( !m.is_loaded() ) {
96 m.load_texture( current_options.get_fg_root() );
100 xglBindTexture( GL_TEXTURE_2D, m.get_texture_id() );
101 #elif GL_EXT_texture_object
102 xglBindTextureEXT( GL_TEXTURE_2D, m.get_texture_id() );
107 xglMaterialfv (GL_FRONT, GL_AMBIENT, m.get_ambient() );
108 xglMaterialfv (GL_FRONT, GL_DIFFUSE, m.get_diffuse() );
111 FGTileEntry* last_tile_ptr = NULL;
112 frag_list_iterator current = list.begin();
113 frag_list_iterator last = list.end();
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 );
124 // Woohoo!!! We finally get to draw something!
125 // printf(" display_list = %d\n", frag_ptr->display_list);
126 // xglCallList( frag_ptr->display_list );
129 current_view.set_tris_rendered( tris_rendered );
134 // Load a library of material properties
136 fgMATERIAL_MGR::load_lib ( void )
138 string material_name;
140 // build the path name to the material db
141 FGPath mpath( current_options.get_fg_root() );
142 mpath.append( "materials" );
144 fg_gzifstream in( mpath.str() );
145 if ( ! in.is_open() ) {
146 FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << mpath.str() );
151 while ( ! in.eof() ) {
154 while ( in.get(c) && c != '\0' ) {
157 // printf("%s", line);
159 // strip leading white space and comments
162 // set to zero to prevent its value accidently being '{'
163 // after a failed >> operation.
166 in >> material_name >> token;
168 if ( token == '{' ) {
172 FGMaterialSlot m_slot;
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" );
181 FG_LOG( FG_TERRAIN, FG_INFO, " Loading material "
182 << material_name << " (" << tex_file.c_str() << ")");
188 ssgStateSelector *state = new ssgStateSelector(2);
189 ssgSimpleState *textured = new ssgSimpleState();
190 ssgSimpleState *nontextured = new ssgSimpleState();
192 // Set up the textured state
193 textured->enable( GL_LIGHTING );
194 if ( current_options.get_shading() == 1 ) {
195 textured->setShadeModel( GL_SMOOTH );
197 textured->setShadeModel( GL_FLAT );
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 );
209 // Set up the coloured state
210 nontextured->enable( GL_LIGHTING );
211 if ( current_options.get_shading() == 1 ) {
212 nontextured->setShadeModel( GL_SMOOTH );
214 nontextured->setShadeModel( GL_FLAT );
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();
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] ) ;
243 state->setStep( 0, textured ); // textured
244 state->setStep( 1, nontextured ); // untextured
246 // Choose the appropriate starting state.
247 if ( current_options.get_textures() ) {
248 state->selectStep(0);
250 state->selectStep(1);
253 m_slot.set_state( state );
255 material_mgr.material_map[material_name] = m_slot;
259 materials_loaded = true;
264 // Initialize the transient list of fragments for each material property
266 fgMATERIAL_MGR::init_transient_material_lists( void )
268 iterator last = end();
269 for ( iterator it = begin(); it != last; ++it ) {
270 (*it).second.init_sort_list();
276 fgMATERIAL_MGR::find( const string& material, FGMaterialSlot*& mtl_ptr )
278 iterator it = material_map.find( material );
280 mtl_ptr = &((*it).second);
289 fgMATERIAL_MGR::~fgMATERIAL_MGR ( void ) {
293 // Set the step for all of the state selectors in the material slots
295 fgMATERIAL_MGR::set_step ( int step )
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);
310 fgMATERIAL_MGR::render_fragments()
312 current_view.set_tris_rendered( 0 );
314 iterator last = end();
315 for ( iterator current = begin(); current != last; ++current ) {
316 (*current).second.render_fragments();