diff --git a/src/Objects/matlib.cxx b/src/Objects/matlib.cxx new file mode 100644 index 000000000..ea2dc2ae6 --- /dev/null +++ b/src/Objects/matlib.cxx @@ -0,0 +1,190 @@ +// materialmgr.cxx -- class to handle material properties +// +// Written by Curtis Olson, started May 1998. +// +// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef FG_MATH_EXCEPTION_CLASH +# include +#endif + +#ifdef HAVE_WINDOWS_H +# include +#endif + +#include +#include + +#include + +#include +#include STL_STRING + +#include +#include +#include + +#include
+#include
+#include + +#include "matlib.hxx" + +FG_USING_STD(string); + + +// global material management class +FGMaterialLib material_lib; + + +// Constructor +FGMaterialLib::FGMaterialLib ( void ) { +} + + +// Load a library of material properties +bool FGMaterialLib::load( const string& mpath ) { + string material_name; + + fg_gzifstream in( mpath ); + if ( ! in.is_open() ) { + FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << mpath ); + exit(-1); + } + +#ifndef __MWERKS__ + while ( ! in.eof() ) { +#else + char c = '\0'; + while ( in.get(c) && c != '\0' ) { + in.putback(c); +#endif + // printf("%s", line); + + // strip leading white space and comments + in >> skipcomment; + + // set to zero to prevent its value accidently being '{' + // 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() << ")"); + + GLenum shade_model = GL_SMOOTH; + if ( current_options.get_shading() == 1 ) { + shade_model = GL_SMOOTH; + } else { + shade_model = GL_FLAT; + } + + m.build_ssg_state( tex_path.str(), shade_model, + current_options.get_textures() ); + +#if EXTRA_DEBUG + m.dump_info(); +#endif + + matlib[material_name] = m; + } + } + + return true; +} + + +// Load a library of material properties +bool FGMaterialLib::add_item ( const string &path ) +{ + string material_name = path; + int pos = path.rfind( "/" ); + material_name = material_name.substr( pos + 1 ); + + FGNewMat m( material_name ); + + // build the ssgSimpleState + FGPath tex_file( path ); + + FG_LOG( FG_TERRAIN, FG_INFO, " Loading material " + << material_name << " (" << tex_file.c_str() << ")"); + +#if EXTRA_DEBUG + m.dump_info(); +#endif + + GLenum shade_model = GL_SMOOTH; + if ( current_options.get_shading() == 1 ) { + shade_model = GL_SMOOTH; + } else { + shade_model = GL_FLAT; + } + + m.build_ssg_state( path, shade_model, current_options.get_textures() ); + + material_lib.matlib[material_name] = m; + + return true; +} + + +// find a material record by material name +FGNewMat *FGMaterialLib::find( const string& material ) { + FGNewMat *result = NULL; + material_map_iterator it = matlib.find( material ); + if ( it != end() ) { + result = &((*it).second); + return result; + } + + return NULL; +} + + +// Destructor +FGMaterialLib::~FGMaterialLib ( void ) { +} + + +// Set the step for all of the state selectors in the material slots +void FGMaterialLib::set_step ( int step ) +{ + // container::iterator it = begin(); + for ( material_map_iterator it = begin(); it != end(); it++ ) { + const string &key = it->first; + FG_LOG( FG_GENERAL, FG_INFO, + "Updating material " << key << " to step " << step ); + FGNewMat &slot = it->second; + slot.get_state()->selectStep(step); + } +} diff --git a/src/Objects/matlib.hxx b/src/Objects/matlib.hxx new file mode 100644 index 000000000..bb48a7e2c --- /dev/null +++ b/src/Objects/matlib.hxx @@ -0,0 +1,137 @@ +// matlib.hxx -- class to handle material properties +// +// Written by Curtis Olson, started May 1998. +// +// Copyright (C) 1998 - 2000 Curtis L. Olson - curt@flightgear.org +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifndef _MATLIB_HXX +#define _MATLIB_HXX + + +#ifndef __cplusplus +# error This library requires C++ +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_WINDOWS_H +# include +#endif + +#include + +#include +#include + +#include STL_STRING // Standard C++ string library +#include // STL associative "array" +#include // STL "array" + +#include // plib include + +#include "newmat.hxx" + + +FG_USING_STD(string); +FG_USING_STD(map); +FG_USING_STD(vector); +FG_USING_STD(less); + + +#if 0 +// Material property class +class FGMaterialSlotold { + +private: + + FGMaterial m; + + // ssg stage structure + ssgStateSelector *state; + bool state_valid; + +public: + + // Constructor + FGMaterialSlotold ( void ); + + // Destructor + ~FGMaterialSlotold ( void ); + + // friend istream& operator >> ( istream& in, FGMaterialSlot& m ); + + inline FGMaterial get_m() const { return m; } + inline void set_m( FGMaterial new_m ) { m = new_m; } + + // ssg state + inline ssgStateSelector *get_state() { return state; } + inline void set_state( ssgStateSelector *s ) { state = s; } + inline bool get_state_valid() const { return state_valid; } + inline void set_state_valid( bool flag ) { state_valid = flag; } +}; +#endif + + +// Material management class +class FGMaterialLib { + +private: + + // associative array of materials + typedef map < string, FGNewMat, less > material_map; + typedef material_map::iterator material_map_iterator; + typedef material_map::const_iterator const_material_map_iterator; + + material_map matlib; + +public: + + // Constructor + FGMaterialLib ( void ); + + // Load a library of material properties + bool load( const string& mpath ); + + // Add the named texture with default properties + bool add_item( const string &name ); + + // find a material record by material name + FGNewMat *find( const string& material ); + + void set_step (int step); + + material_map_iterator begin() { return matlib.begin(); } + const_material_map_iterator begin() const { return matlib.begin(); } + + material_map_iterator end() { return matlib.end(); } + const_material_map_iterator end() const { return matlib.end(); } + + // Destructor + ~FGMaterialLib ( void ); +}; + + +// global material management class +extern FGMaterialLib material_lib; + + +#endif // _MATLIB_HXX diff --git a/src/Objects/newmat.cxx b/src/Objects/newmat.cxx new file mode 100644 index 000000000..2aa4e33a0 --- /dev/null +++ b/src/Objects/newmat.cxx @@ -0,0 +1,181 @@ +// newmat.cxx -- class to handle material properties +// +// Written by Curtis Olson, started May 1998. +// +// Copyright (C) 1998 - 2000 Curtis L. Olson - curt@flightgear.org +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#ifdef FG_MATH_EXCEPTION_CLASH +# include +#endif + +#include +#include +#include + +#include "newmat.hxx" + + +// Constructor +FGNewMat::FGNewMat ( void ) { +} + + +// Constructor +FGNewMat::FGNewMat ( const string &name ) +{ + 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; +} + + +void FGNewMat::build_ssg_state( const string& path, + GLenum shade_model, bool texture_default ) +{ + FGPath tex_file( path ); + tex_file.append( texture_name ); + + state = new ssgStateSelector(2); + textured = new ssgSimpleState(); + nontextured = new ssgSimpleState(); + + // Set up the textured state + textured->setShadeModel( shade_model ); + 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() ); + textured->enable( GL_COLOR_MATERIAL ); + textured->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); + textured->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); + textured->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); + + // Set up the coloured state + nontextured->enable( GL_LIGHTING ); + nontextured->setShadeModel( shade_model ); + nontextured->enable ( GL_CULL_FACE ) ; + nontextured->disable( GL_TEXTURE_2D ); + nontextured->disable( GL_BLEND ); + 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] ) ; + 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] ) ; + + state->setStep( 0, textured ); // textured + state->setStep( 1, nontextured ); // untextured + + // Choose the appropriate starting state. + if ( texture_default ) { + state->selectStep(0); + } else { + state->selectStep(1); + } +} + + +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 <<"}" ); + +} + + +// Destructor +FGNewMat::~FGNewMat ( void ) { +} + + +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; + } + } + + return in; +} diff --git a/src/Objects/newmat.hxx b/src/Objects/newmat.hxx new file mode 100644 index 000000000..20bbc481d --- /dev/null +++ b/src/Objects/newmat.hxx @@ -0,0 +1,122 @@ +// newmat.hxx -- class to handle material properties +// +// Written by Curtis Olson, started May 1998. +// +// Copyright (C) 1998 - 2000 Curtis L. Olson - curt@flightgear.org +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifndef _NEWMAT_HXX +#define _NEWMAT_HXX + + +#ifndef __cplusplus +# error This library requires C++ +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_WINDOWS_H +# include +#endif + +#include +#include + +#include + +#include + +#include STL_STRING // Standard C++ string library + +FG_USING_STD(string); + + +// MSVC++ 6.0 kuldge - Need forward declaration of friends. +class FGNewMat; +istream& operator >> ( istream& in, FGNewMat& m ); + +// Material property class +class FGNewMat { + +private: + + // names + string material_name; + string texture_name; + + // pointers to ssg states + ssgStateSelector *state; + ssgSimpleState *textured; + ssgSimpleState *nontextured; + + // alpha texture? + int alpha; + + // texture size + double xsize, ysize; + + // material properties + sgVec4 ambient, diffuse, specular, emission; + +public: + + // Constructor + FGNewMat ( void ); + FGNewMat ( const string& name ); + + // Destructor + ~FGNewMat ( void ); + + friend istream& operator >> ( istream& in, FGNewMat& m ); + + // void load_texture( const string& root ); + void build_ssg_state( const string& path, + GLenum shade_model, bool texture_default ); + + inline string get_material_name() const { return material_name; } + inline void set_material_name( const string& n ) { material_name = n; } + + inline string get_texture_name() const { return texture_name; } + inline void set_texture_name( const string& n ) { texture_name = n; } + + inline double get_xsize() const { return xsize; } + inline double get_ysize() const { return ysize; } + inline void set_xsize( double x ) { xsize = x; } + inline void set_ysize( double y ) { ysize = y; } + + inline float *get_ambient() { return ambient; } + inline float *get_diffuse() { return diffuse; } + inline float *get_specular() { return specular; } + inline float *get_emission() { return emission; } + inline void set_ambient( sgVec4 a ) { sgCopyVec4( ambient, a ); } + inline void set_diffuse( sgVec4 d ) { sgCopyVec4( diffuse, d ); } + inline void set_specular( sgVec4 s ) { sgCopyVec4( specular, s ); } + inline void set_emission( sgVec4 e ) { sgCopyVec4( emission, e ); } + + inline ssgStateSelector *get_state() const { return state; } + + void dump_info(); +}; + + +#endif // _NEWMAT_HXX + +