#include <simgear/compiler.h>
-#ifdef FG_MATH_EXCEPTION_CLASH
+#ifdef SG_MATH_EXCEPTION_CLASH
# include <math.h>
#endif
#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/globals.hxx>
+#include <Main/fg_props.hxx>
#include "newmat.hxx"
-// Constructor
-FGNewMat::FGNewMat ( void ) {
+\f
+////////////////////////////////////////////////////////////////////////
+// Local static functions.
+////////////////////////////////////////////////////////////////////////
+
+/**
+ * Internal method to test whether a file exists.
+ *
+ * TODO: this should be moved to a SimGear library of local file
+ * functions.
+ */
+static inline bool
+local_file_exists( const string& path ) {
+ sg_gzifstream in( path );
+ if ( ! in.is_open() ) {
+ return false;
+ } else {
+ return true;
+ }
}
-// Constructor
-FGNewMat::FGNewMat ( const string &name )
+\f
+////////////////////////////////////////////////////////////////////////
+// Constructors and destructor.
+////////////////////////////////////////////////////////////////////////
+
+
+FGNewMat::FGNewMat (const SGPropertyNode * props)
{
- material_name = name;
- texture_name = name;
- xsize = ysize = 0;
- alpha = 0;
- ambient[0] = ambient[1] = ambient[2] = ambient[3] = 1.0;
- diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = 1.0;
- specular[0] = specular[1] = specular[2] = specular[3] = 1.0;
- emission[0] = emission[1] = emission[2] = emission[3] = 1.0;
+ init();
+ read_properties(props);
+ build_ssg_state(false);
}
+FGNewMat::FGNewMat (const string &texture_path)
+{
+ init();
+ build_ssg_state(true);
+}
-void FGNewMat::build_ssg_state( const string& path,
- GLenum shade_model, bool texture_default )
+FGNewMat::FGNewMat (ssgSimpleState * s)
{
- FGPath tex_file( path );
- tex_file.append( texture_name );
+ init();
+ set_ssg_state(s);
+}
+
+FGNewMat::~FGNewMat (void)
+{
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Public methods.
+////////////////////////////////////////////////////////////////////////
+
+void
+FGNewMat::read_properties (const SGPropertyNode * props)
+{
+ // Get the path to the texture
+ string tname = props->getStringValue("texture", "unknown.rgb");
+ SGPath tpath(globals->get_fg_root());
+ tpath.append("Textures.high");
+ tpath.append(tname);
+ if (!local_file_exists(tpath.str())) {
+ tpath = SGPath(globals->get_fg_root());
+ tpath.append("Textures");
+ tpath.append(tname);
+ }
+ texture_path = tpath.str();
+
+ xsize = props->getDoubleValue("xsize", 0.0);
+ ysize = props->getDoubleValue("ysize", 0.0);
+ wrapu = props->getBoolValue("wrapu", true);
+ wrapv = props->getBoolValue("wrapv", true);
+ mipmap = props->getBoolValue("mipmap", true);
+ light_coverage = props->getDoubleValue("light-coverage");
+
+ ambient[0] = props->getDoubleValue("ambient/r", 0.0);
+ ambient[1] = props->getDoubleValue("ambient/g", 0.0);
+ ambient[2] = props->getDoubleValue("ambient/b", 0.0);
+ ambient[3] = props->getDoubleValue("ambient/a", 0.0);
+
+ diffuse[0] = props->getDoubleValue("diffuse/r", 0.0);
+ diffuse[1] = props->getDoubleValue("diffuse/g", 0.0);
+ diffuse[2] = props->getDoubleValue("diffuse/b", 0.0);
+ diffuse[3] = props->getDoubleValue("diffuse/a", 0.0);
+
+ specular[0] = props->getDoubleValue("specular/r", 0.0);
+ specular[1] = props->getDoubleValue("specular/g", 0.0);
+ specular[2] = props->getDoubleValue("specular/b", 0.0);
+ specular[3] = props->getDoubleValue("specular/a", 0.0);
+
+ emission[0] = props->getDoubleValue("emissive/r", 0.0);
+ emission[1] = props->getDoubleValue("emissive/g", 0.0);
+ emission[2] = props->getDoubleValue("emissive/b", 0.0);
+ emission[3] = props->getDoubleValue("emissive/a", 0.0);
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Private methods.
+////////////////////////////////////////////////////////////////////////
+
+void
+FGNewMat::init ()
+{
+ texture_path = "";
+ state = 0;
+ textured = 0;
+ nontextured = 0;
+ xsize = 0;
+ ysize = 0;
+ wrapu = true;
+ wrapv = true;
+ mipmap = true;
+ texture_loaded = false;
+ refcount = 0;
+ for (int i = 0; i < 4; i++)
+ ambient[i] = diffuse[i] = specular[i] = emission[i] = 0.0;
+}
+
+bool
+FGNewMat::load_texture ()
+{
+ if (texture_loaded) {
+ return false;
+ } else {
+ SG_LOG( SG_GENERAL, SG_INFO, "Loading deferred texture " << texture_path );
+ textured->setTexture((char *)texture_path.c_str(), wrapu, wrapv, mipmap );
+ texture_loaded = true;
+ return true;
+ }
+}
+
+
+void
+FGNewMat::build_ssg_state (bool defer_tex_load)
+{
+ GLenum shade_model =
+ (fgGetBool("/sim/rendering/shading") ? GL_SMOOTH : GL_FLAT);
+ bool texture_default = fgGetBool("/sim/rendering/textures");
state = new ssgStateSelector(2);
+ state->ref();
+
textured = new ssgSimpleState();
+ textured->ref();
+
nontextured = new ssgSimpleState();
+ nontextured->ref();
// Set up the textured state
textured->setShadeModel( shade_model );
+ textured->enable( GL_LIGHTING );
textured->enable ( GL_CULL_FACE ) ;
textured->enable( GL_TEXTURE_2D );
textured->disable( GL_BLEND );
textured->disable( GL_ALPHA_TEST );
- textured->setTexture( (char *)tex_file.c_str() );
+#if 0
+# ifdef GL_EXT_texture_filter_anisotropic
+ float max_anisotropy;
+ glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
+ max_anisotropy );
+ cout << "Max anisotropy = " << max_anisotropy << endl;
+# endif
+#endif
+ if ( !defer_tex_load ) {
+ textured->setTexture( (char *)texture_path.c_str(), wrapu, wrapv );
+ texture_loaded = true;
+ } else {
+ texture_loaded = false;
+ }
textured->enable( GL_COLOR_MATERIAL );
textured->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
textured->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
nontextured->disable( GL_ALPHA_TEST );
nontextured->disable( GL_COLOR_MATERIAL );
- /* cout << "ambient = " << ambient[0] << "," << ambient[1]
- << "," << ambient[2] << endl; */
nontextured->setMaterial ( GL_AMBIENT,
ambient[0], ambient[1],
ambient[2], ambient[3] ) ;
}
-void FGNewMat::dump_info () {
- FG_LOG( FG_TERRAIN, FG_INFO, "{" << endl << " texture = "
- << texture_name );
- FG_LOG( FG_TERRAIN, FG_INFO, " xsize = " << xsize );
- FG_LOG( FG_TERRAIN, FG_INFO, " ysize = " << ysize );
- FG_LOG( FG_TERRAIN, FG_INFO, " ambient = " << ambient[0] << " "
- << ambient[1] <<" "<< ambient[2] <<" "<< ambient[3] );
- FG_LOG( FG_TERRAIN, FG_INFO, " diffuse = " << diffuse[0] << " "
- << diffuse[1] << " " << diffuse[2] << " " << diffuse[3] );
- FG_LOG( FG_TERRAIN, FG_INFO, " specular = " << specular[0] << " "
- << specular[1] << " " << specular[2] << " " << specular[3]);
- FG_LOG( FG_TERRAIN, FG_INFO, " emission = " << emission[0] << " "
- << emission[1] << " " << emission[2] << " " << emission[3]);
- FG_LOG( FG_TERRAIN, FG_INFO, " alpha = " << alpha << endl <<"}" );
-
-}
+void FGNewMat::set_ssg_state( ssgSimpleState *s )
+{
+ state = new ssgStateSelector(2);
+ state->ref();
+ textured = s;
-// Destructor
-FGNewMat::~FGNewMat ( void ) {
-}
+ nontextured = new ssgSimpleState();
+ nontextured->ref();
+ // Set up the coloured state
+ nontextured->enable( GL_LIGHTING );
+ nontextured->setShadeModel( GL_FLAT );
+ nontextured->enable ( GL_CULL_FACE ) ;
+ nontextured->disable( GL_TEXTURE_2D );
+ nontextured->disable( GL_BLEND );
+ nontextured->disable( GL_ALPHA_TEST );
+ nontextured->disable( GL_COLOR_MATERIAL );
-istream&
-operator >> ( istream& in, FGNewMat& m )
-{
- string token;
-
- for (;;) {
- in >> token;
- if ( token == "texture" ) {
- in >> token >> m.texture_name;
- } else if ( token == "xsize" ) {
- in >> token >> m.xsize;
- } else if ( token == "ysize" ) {
- in >> token >> m.ysize;
- } else if ( token == "ambient" ) {
- in >> token >> m.ambient[0] >> m.ambient[1]
- >> m.ambient[2] >> m.ambient[3];
- } else if ( token == "diffuse" ) {
- in >> token >> m.diffuse[0] >> m.diffuse[1]
- >> m.diffuse[2] >> m.diffuse[3];
- } else if ( token == "specular" ) {
- in >> token >> m.specular[0] >> m.specular[1]
- >> m.specular[2] >> m.specular[3];
- } else if ( token == "emission" ) {
- in >> token >> m.emission[0] >> m.emission[1]
- >> m.emission[2] >> m.emission[3];
- } else if ( token == "alpha" ) {
- in >> token >> token;
- if ( token == "yes" ) {
- m.alpha = 1;
- } else if ( token == "no" ) {
- m.alpha = 0;
- } else {
- FG_LOG( FG_TERRAIN, FG_INFO, "Bad alpha value " << token );
- }
- } else if ( token[0] == '}' ) {
- break;
- }
- }
+ /* cout << "ambient = " << ambient[0] << "," << ambient[1]
+ << "," << ambient[2] << endl; */
+ nontextured->setMaterial ( GL_AMBIENT,
+ ambient[0], ambient[1],
+ ambient[2], ambient[3] ) ;
+ nontextured->setMaterial ( GL_DIFFUSE,
+ diffuse[0], diffuse[1],
+ diffuse[2], diffuse[3] ) ;
+ nontextured->setMaterial ( GL_SPECULAR,
+ specular[0], specular[1],
+ specular[2], specular[3] ) ;
+ nontextured->setMaterial ( GL_EMISSION,
+ emission[0], emission[1],
+ emission[2], emission[3] ) ;
- return in;
+ state->setStep( 0, textured ); // textured
+ state->setStep( 1, nontextured ); // untextured
+
+ // Choose the appropriate starting state.
+ state->selectStep(0);
}
+
+// end of newmat.cxx