# include <config.h>
#endif
-#ifdef FG_MATH_EXCEPTION_CLASH
+#ifdef SG_MATH_EXCEPTION_CLASH
# include <math.h>
#endif
#endif
#include <GL/glut.h>
-#include <simgear/xgl/xgl.h>
+#include <GL/gl.h>
#include <simgear/compiler.h>
#include STL_STRING
#include <simgear/debug/logstream.hxx>
-#include <simgear/misc/fgpath.hxx>
-#include <simgear/misc/fgstream.hxx>
+#include <simgear/misc/sg_path.hxx>
+#include <simgear/misc/sgstream.hxx>
-#include <Main/options.hxx>
-#include <Main/views.hxx>
+#include <Include/general.hxx>
+#include <Main/globals.hxx>
+#include <Main/fg_props.hxx>
#include <Scenery/tileentry.hxx>
#include "matlib.hxx"
-FG_USING_STD(string);
+SG_USING_STD(string);
// global material management class
}
+static bool local_file_exists( const string& path ) {
+ sg_gzifstream in( path );
+ if ( ! in.is_open() ) {
+ return false;
+ } else {
+ return true;
+ }
+
+#if 0
+ cout << path << " ";
+ FILE *fp = fopen( path.c_str(), "r" );
+ if ( fp == NULL ) {
+ cout << " doesn't exist\n";
+ return false;
+ } else {
+ cout << " exists\n";
+ return true;
+ }
+#endif
+}
+
+
// Load a library of material properties
bool FGMaterialLib::load( const string& mpath ) {
string material_name;
- fg_gzifstream in( mpath );
+ sg_gzifstream in( mpath );
if ( ! in.is_open() ) {
- FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << mpath );
+ SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << mpath );
exit(-1);
}
// after a failed >> operation.
char token = 0;
- in >> material_name >> token;
-
- if ( token == '{' ) {
- FGNewMat m;
- in >> m;
-
- // build the ssgSimpleState
- FGPath tex_path( current_options.get_fg_root() );
- tex_path.append( "Textures" );
-
- FG_LOG( FG_TERRAIN, FG_INFO, " Loading material "
- << material_name << " (" << tex_path.c_str() << ")");
+ in >> material_name;
+
+ if ( material_name == "alias" ) {
+ string src_mat, dst_mat;
+ in >> dst_mat >> src_mat;
+ SG_LOG( SG_GENERAL, SG_INFO, " Material alias: " << dst_mat <<
+ " mapped to " << src_mat );
+ FGNewMat *m = matlib[src_mat];
+ if ( m != NULL ) {
+ matlib[dst_mat] = m;
+ } else {
+ SG_LOG( SG_GENERAL, SG_ALERT,
+ "Bad material alias pointing to nonexistant material" );
+ }
+ } else {
+ in >> token;
+
+ if ( token == '{' ) {
+ // Read the data into a temporary but stack allocated
+ // copy of the structure
+ FGNewMat tmp;
+ in >> tmp;
+
+ // create a pointer to a heap allocated copy of the structure
+ FGNewMat *m = new FGNewMat;
+ *m = tmp;
+
+ // build the ssgSimpleState
+ SGPath tex_path( globals->get_fg_root() );
+ tex_path.append( "Textures.high" );
+ tex_path.append( m->get_texture_name() );
+ if ( ! local_file_exists(tex_path.str())
+ || general.get_glMaxTexSize() < 512 ) {
+ tex_path = SGPath( globals->get_fg_root() );
+ tex_path.append( "Textures" );
+ tex_path.append( m->get_texture_name() );
+ }
+
+ SG_LOG( SG_TERRAIN, SG_INFO, " Loading material "
+ << material_name << " (" << tex_path.c_str() << ")");
- GLenum shade_model = GL_SMOOTH;
- if ( current_options.get_shading() == 1 ) {
- shade_model = GL_SMOOTH;
- } else {
- shade_model = GL_FLAT;
- }
+ GLenum shade_model = GL_SMOOTH;
+ if ( fgGetBool("/sim/rendering/shading") ) {
+ shade_model = GL_SMOOTH;
+ } else {
+ shade_model = GL_FLAT;
+ }
- m.build_ssg_state( tex_path.str(), shade_model,
- current_options.get_textures() );
+ m->set_texture_name( tex_path.str() );
+ m->build_ssg_state( shade_model,
+ fgGetBool("/sim/rendering/textures"),
+ false );
#if EXTRA_DEBUG
- m.dump_info();
+ m->dump_info();
#endif
- matlib[material_name] = m;
+ matlib[material_name] = m;
+ }
}
}
+ // hard coded light state
+ ssgSimpleState *lights = new ssgSimpleState;
+ lights->ref();
+ lights->disable( GL_TEXTURE_2D );
+ lights->enable( GL_CULL_FACE );
+ lights->enable( GL_COLOR_MATERIAL );
+ lights->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
+ lights->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
+ lights->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
+ lights->enable( GL_BLEND );
+ lights->disable( GL_ALPHA_TEST );
+ lights->disable( GL_LIGHTING );
+
+ FGNewMat *m = new FGNewMat;
+ m->set_ssg_state( lights );
+ matlib["LIGHTS"] = m;
+
return true;
}
// Load a library of material properties
-bool FGMaterialLib::add_item ( const string &path )
+bool FGMaterialLib::add_item ( const string &tex_path )
{
- string material_name = path;
- int pos = path.rfind( "/" );
+ string material_name = tex_path;
+ int pos = tex_path.rfind( "/" );
material_name = material_name.substr( pos + 1 );
- FGNewMat m( material_name );
+ return add_item( material_name, tex_path );
+}
- // build the ssgSimpleState
- FGPath tex_file( path );
- FG_LOG( FG_TERRAIN, FG_INFO, " Loading material "
- << material_name << " (" << tex_file.c_str() << ")");
+// Load a library of material properties
+bool FGMaterialLib::add_item ( const string &mat_name, const string &full_path )
+{
+ int pos = full_path.rfind( "/" );
+ string tex_name = full_path.substr( pos + 1 );
+ string tex_path = full_path.substr( 0, pos );
+
+ FGNewMat *m = new FGNewMat( mat_name, full_path );
+
+ SG_LOG( SG_TERRAIN, SG_INFO, " Loading material "
+ << mat_name << " (" << full_path << ")");
#if EXTRA_DEBUG
- m.dump_info();
+ m->dump_info();
#endif
GLenum shade_model = GL_SMOOTH;
- if ( current_options.get_shading() == 1 ) {
+ if ( fgGetBool("/sim/rendering/shading") ) {
shade_model = GL_SMOOTH;
} else {
shade_model = GL_FLAT;
}
- m.build_ssg_state( path, shade_model, current_options.get_textures() );
+ m->build_ssg_state( shade_model,
+ fgGetBool("/sim/rendering/textures"),
+ true );
- material_lib.matlib[material_name] = m;
+ material_lib.matlib[mat_name] = m;
+
+ return true;
+}
+
+
+// Load a library of material properties
+bool FGMaterialLib::add_item ( const string &mat_name, ssgSimpleState *state )
+{
+ FGNewMat *m = new FGNewMat( mat_name );
+ m->set_ssg_state( state );
+
+ SG_LOG( SG_TERRAIN, SG_INFO, " Loading material given a premade "
+ << "ssgSimpleState = " << mat_name );
+
+#if EXTRA_DEBUG
+ m->dump_info();
+#endif
+
+ material_lib.matlib[mat_name] = m;
return true;
}
FGNewMat *result = NULL;
material_map_iterator it = matlib.find( material );
if ( it != end() ) {
- result = &((*it).second);
+ result = it->second;
return result;
}
// Destructor
FGMaterialLib::~FGMaterialLib ( void ) {
+ // Free up all the material entries first
+ for ( material_map_iterator it = begin(); it != end(); it++ ) {
+ FGNewMat *slot = it->second;
+ if ( slot != NULL ) {
+ delete slot;
+ }
+ }
}
// container::iterator it = begin();
for ( material_map_iterator it = begin(); it != end(); it++ ) {
const string &key = it->first;
- FG_LOG( FG_GENERAL, FG_INFO,
+ SG_LOG( SG_GENERAL, SG_INFO,
"Updating material " << key << " to step " << step );
- FGNewMat &slot = it->second;
- slot.get_state()->selectStep(step);
+ FGNewMat *slot = it->second;
+ slot->get_state()->selectStep(step);
+ }
+}
+
+
+// Load one pending "deferred" texture. Return true if a texture
+// loaded successfully, false if no pending, or error.
+void FGMaterialLib::load_next_deferred() {
+ // container::iterator it = begin();
+ for ( material_map_iterator it = begin(); it != end(); it++ ) {
+ const string &key = it->first;
+ FGNewMat *slot = it->second;
+ // SG_LOG( SG_GENERAL, SG_INFO, "slot = " << slot );
+ if ( ! slot->get_texture_loaded() ) {
+ SG_LOG( SG_GENERAL, SG_INFO, "Loading deferred texture for "
+ << key );
+#ifdef PLIB_1_2_X
+ slot->get_textured()->
+ setTexture( (char *)slot->get_texture_name_c_str(), 0, 0 );
+#else
+ slot->get_textured()->
+ setTexture( (char *)slot->get_texture_name_c_str(), 0, 0, 1 );
+#endif
+ slot->set_texture_loaded( true );
+ }
}
}