]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/material/mat.cxx
Use bool instead of int to represent boolean values
[simgear.git] / simgear / scene / material / mat.cxx
index 8d197edee6eebad64cd67acc5ce395b746f09000..2d488f345eb7db8da34c8bbebbba5b3a9fcdd932 100644 (file)
@@ -37,14 +37,20 @@ SG_USING_STD(map);
 #  include <math.h>
 #endif
 
+#include <osg/CullFace>
+#include <osg/Material>
+#include <osg/ShadeModel>
+#include <osg/TexEnv>
+#include <osg/Texture2D>
+#include <osgDB/ReadFile>
+
 #include <simgear/debug/logstream.hxx>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/misc/sgstream.hxx>
 
-#include "mat.hxx"
+#include <simgear/scene/model/model.hxx>
 
-static map<string, ssgTexture *> _tex_cache;
-static map<string, ssgTexture *>::iterator _tex_cache_iter;
+#include "mat.hxx"
 
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -56,7 +62,7 @@ SGMaterial::SGMaterial( const string &fg_root, const SGPropertyNode *props, cons
 {
     init();
     read_properties( fg_root, props, season );
-    build_ssg_state( false );
+    build_state( false );
 }
 
 SGMaterial::SGMaterial( const string &texpath )
@@ -66,13 +72,13 @@ SGMaterial::SGMaterial( const string &texpath )
     _internal_state st( NULL, texpath, false );
     _status.push_back( st );
 
-    build_ssg_state( true );
+    build_state( true );
 }
 
-SGMaterial::SGMaterial( ssgSimpleState *s )
+SGMaterial::SGMaterial( osg::StateSet *s )
 {
     init();
-    set_ssg_state( s );
+    set_state( s );
 }
 
 SGMaterial::~SGMaterial (void)
@@ -94,11 +100,6 @@ SGMaterial::read_properties( const string &fg_root, const SGPropertyNode * props
   {
     string tname = textures[i]->getStringValue();
     string otname = tname;
-    if (season && strncmp(season, "summer", 6))
-    {
-        if (tname.substr(0,7) == "Terrain")
-            tname.insert(7,"."+string(season));
-    }
 
     if (tname == "") {
         tname = "unknown.rgb";
@@ -135,6 +136,22 @@ SGMaterial::read_properties( const string &fg_root, const SGPropertyNode * props
   wrapv = props->getBoolValue("wrapv", true);
   mipmap = props->getBoolValue("mipmap", true);
   light_coverage = props->getDoubleValue("light-coverage", 0.0);
+  tree_coverage = props->getDoubleValue("tree-coverage", 0.0);
+  tree_height = props->getDoubleValue("tree-height-m", 0.0);
+  tree_width = props->getDoubleValue("tree-width-m", 0.0);
+  tree_range = props->getDoubleValue("tree-range-m", 0.0);
+  tree_varieties = props->getIntValue("tree-varieties", 1);
+
+  SGPath tpath( fg_root );
+  tpath.append(props->getStringValue("tree-texture"));
+  tree_texture = tpath.str();
+
+  // surface values for use with ground reactions
+  solid = props->getBoolValue("solid", true);
+  friction_factor = props->getDoubleValue("friction-factor", 1.0);
+  rolling_friction = props->getDoubleValue("rolling-friction", 0.02);
+  bumpiness = props->getDoubleValue("bumpiness", 0.0);
+  load_resistance = props->getDoubleValue("load-resistance", 1e30);
 
   // Taken from default values as used in ac3d
   ambient[0] = props->getDoubleValue("ambient/r", 0.2);
@@ -191,6 +208,13 @@ SGMaterial::init ()
 
     mipmap = true;
     light_coverage = 0.0;
+
+    solid = true;
+    friction_factor = 1;
+    rolling_friction = 0.02;
+    bumpiness = 0;
+    load_resistance = 1e30;
+
     shininess = 1.0;
     for (int i = 0; i < 4; i++) {
         ambient[i]  = (i < 3) ? 0.2 : 1.0;
@@ -200,109 +224,106 @@ SGMaterial::init ()
     }
 }
 
-bool
-SGMaterial::load_texture ( int n )
-{
-    int i   = (n >= 0) ? n   : 0 ;
-    int end = (n >= 0) ? n+1 : _status.size();
-
-    for (; i < end; i++)
-    {
-        if ( !_status[i].texture_loaded ) {
-            SG_LOG( SG_GENERAL, SG_INFO, "Loading deferred texture "
-                                          << _status[i].texture_path );
-            assignTexture(_status[i].state, _status[i].texture_path,
-                                         wrapu, wrapv, mipmap );
-            _status[i].texture_loaded = true;
-       }
-    }
-    return true;
-}
-
-ssgSimpleState *
-SGMaterial::get_state (int n) const
+osg::StateSet *
+SGMaterial::get_state (int n)
 {
     if (_status.size() == 0) {
         SG_LOG( SG_GENERAL, SG_WARN, "No state available.");
         return NULL;
     }
+    
+    int i = n >= 0 ? n : _current_ptr;
+
+    if(!_status[i].texture_loaded)
+    {
+        assignTexture(_status[i].state.get(), _status[i].texture_path,
+                      wrapu, wrapv, mipmap);
+        _status[i].texture_loaded = true;
+    }
+    osg::StateSet *st = _status[i].state.get();
 
-    ssgSimpleState *st = (n >= 0) ? _status[n].state
-                                  : _status[_current_ptr].state;
-    ((SGMaterial *)this)->_current_ptr += 1;
+    _current_ptr += 1;
     if (_current_ptr >= _status.size())
-        ((SGMaterial *)this)->_current_ptr = 0;
+        _current_ptr = 0;
 
     return st;
 }
 
 
 void 
-SGMaterial::build_ssg_state( bool defer_tex_load )
+SGMaterial::build_state( bool defer_tex_load )
 {
-    GLenum shade_model = GL_SMOOTH;
-    
     for (unsigned int i = 0; i < _status.size(); i++)
     {
-        ssgSimpleState *state = new ssgSimpleState();
+        osg::StateSet *stateSet = new osg::StateSet;
+        stateSet->setUserData(new SGMaterialUserData(this));
 
         // Set up the textured state
-        state->setShadeModel( shade_model );
-        state->enable( GL_LIGHTING );
-        state->enable ( GL_CULL_FACE ) ;
-        state->enable( GL_TEXTURE_2D );
-        state->disable( GL_BLEND );
-        state->disable( GL_ALPHA_TEST );
-
-        if ( !defer_tex_load ) {
-            SG_LOG(SG_INPUT, SG_INFO, "    " << _status[i].texture_path );
-           assignTexture( state, _status[i].texture_path, wrapu, wrapv );
-            _status[i].texture_loaded = true;
+        osg::ShadeModel* shadeModel = new osg::ShadeModel;
+        shadeModel->setMode(osg::ShadeModel::SMOOTH);
+        stateSet->setAttribute(shadeModel);
+
+        osg::CullFace* cullFace = new osg::CullFace;
+        cullFace->setMode(osg::CullFace::BACK);
+        stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
+        stateSet->setAttribute(cullFace);
+
+        stateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON);
+
+        _status[i].texture_loaded = false;
+
+        osg::Material* material = new osg::Material;
+        material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
+        material->setAmbient(osg::Material::FRONT_AND_BACK, ambient.osg());
+        material->setDiffuse(osg::Material::FRONT_AND_BACK, diffuse.osg());
+        material->setSpecular(osg::Material::FRONT_AND_BACK, specular.osg());
+        material->setEmission(osg::Material::FRONT_AND_BACK, emission.osg());
+        material->setShininess(osg::Material::FRONT_AND_BACK, shininess );
+        stateSet->setAttribute(material);
+
+        if (ambient[3] < 1 || diffuse[3] < 1 ||
+            specular[3] < 1 || emission[3] < 1) {
+          stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+          stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
+          stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON);
         } else {
-            _status[i].texture_loaded = false;
+          stateSet->setRenderingHint(osg::StateSet::OPAQUE_BIN);
+          stateSet->setMode(GL_BLEND, osg::StateAttribute::OFF);
+          stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF);
         }
 
-        state->enable( GL_COLOR_MATERIAL );
-        state->setMaterial ( GL_AMBIENT,
-                             ambient[0], ambient[1],
-                             ambient[2], ambient[3] ) ;
-        state->setMaterial ( GL_DIFFUSE,
-                            diffuse[0], diffuse[1],
-                            diffuse[2], diffuse[3] ) ;
-        state->setMaterial ( GL_SPECULAR,
-                            specular[0], specular[1],
-                            specular[2], specular[3] ) ;
-        state->setMaterial ( GL_EMISSION,
-                            emission[0], emission[1],
-                            emission[2], emission[3] ) ;
-        state->setShininess ( shininess );
-
-        _status[i].state = state;
+        _status[i].state = stateSet;
     }
 }
 
 
-void SGMaterial::set_ssg_state( ssgSimpleState *s )
+void SGMaterial::set_state( osg::StateSet *s )
 {
     _status.push_back( _internal_state( s, "", true ) );
 }
 
-void SGMaterial::assignTexture( ssgSimpleState *state, string &fname,
-                 int _wrapu, int _wrapv, int _mipmap )
+void SGMaterial::assignTexture( osg::StateSet *state, const std::string &fname,
+                 bool _wrapu, bool _wrapv, bool _mipmap )
 {
-   _tex_cache_iter = _tex_cache.find(fname);
-   if (_tex_cache_iter == _tex_cache.end())
-   {
-      state->setTexture((char *)fname.c_str(), _wrapu, _wrapv, _mipmap);
-      _tex_cache[fname] = state->getTexture();
-   }
-   else
-   {
-      state->setTexture(_tex_cache_iter->second);
-      // cout << "Cache hit: " << fname << endl;
-   }
+   osg::Texture2D* texture = SGLoadTexture2D(fname, 0, _wrapu, _wrapv,
+                                             mipmap ? -1 : 0);
+   texture->setMaxAnisotropy( SGGetTextureFilter());
+   state->setTextureAttributeAndModes(0, texture);
+
+   osg::TexEnv* texEnv = new osg::TexEnv;
+   texEnv->setMode(osg::TexEnv::MODULATE);
+   state->setTextureAttributeAndModes(0, texEnv);
 }
 
+SGMaterialGlyph* SGMaterial::get_glyph (const string& name) const
+{
+  map<string, SGSharedPtr<SGMaterialGlyph> >::const_iterator it;
+  it = glyphs.find(name);
+  if (it == glyphs.end())
+    return 0;
+
+  return it->second;
+}
 
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -315,5 +336,12 @@ SGMaterialGlyph::SGMaterialGlyph(SGPropertyNode *p) :
 {
 }
 
+void
+SGSetTextureFilter( int max) {
+       SGSceneFeatures::instance()->setTextureFilter( max);
+}
 
-// end of mat.cxx
+int
+SGGetTextureFilter() {
+       return SGSceneFeatures::instance()->getTextureFilter();
+}