X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fscene%2Fmaterial%2Fmat.cxx;h=2d488f345eb7db8da34c8bbebbba5b3a9fcdd932;hb=373a0e4a7d59c3f8ed1d66ff6145de61ecd46279;hp=6bded1509c86b3a8b57ffd615d385aa35a33b017;hpb=7fc8c026884b2d0a1b683765c089a9bef5ac47c8;p=simgear.git diff --git a/simgear/scene/material/mat.cxx b/simgear/scene/material/mat.cxx index 6bded150..2d488f34 100644 --- a/simgear/scene/material/mat.cxx +++ b/simgear/scene/material/mat.cxx @@ -16,7 +16,7 @@ // // 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. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ @@ -27,6 +27,7 @@ #include +#include #include SG_USING_STD(map); @@ -36,10 +37,19 @@ SG_USING_STD(map); # include #endif +#include +#include +#include +#include +#include +#include + #include #include #include +#include + #include "mat.hxx" @@ -48,11 +58,11 @@ SG_USING_STD(map); //////////////////////////////////////////////////////////////////////// -SGMaterial::SGMaterial( const string &fg_root, const SGPropertyNode *props ) +SGMaterial::SGMaterial( const string &fg_root, const SGPropertyNode *props, const char *season ) { init(); - read_properties( fg_root, props ); - build_ssg_state( false ); + read_properties( fg_root, props, season ); + build_state( false ); } SGMaterial::SGMaterial( const string &texpath ) @@ -62,21 +72,17 @@ 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) { - for (unsigned int i = 0; i < object_groups.size(); i++) { - delete object_groups[i]; - object_groups[i] = 0; - } } @@ -86,13 +92,15 @@ SGMaterial::~SGMaterial (void) //////////////////////////////////////////////////////////////////////// void -SGMaterial::read_properties( const string &fg_root, const SGPropertyNode * props ) +SGMaterial::read_properties( const string &fg_root, const SGPropertyNode * props, const char *season ) { // Gather the path(s) to the texture(s) vector textures = props->getChildren("texture"); for (unsigned int i = 0; i < textures.size(); i++) { string tname = textures[i]->getStringValue(); + string otname = tname; + if (tname == "") { tname = "unknown.rgb"; } @@ -116,6 +124,7 @@ SGMaterial::read_properties( const string &fg_root, const SGPropertyNode * props string tname = "unknown.rgb"; SGPath tpath( fg_root ); tpath.append("Textures"); + tpath.append("Terrain"); tpath.append(tname); _internal_state st( NULL, tpath.str(), true ); _status.push_back( st ); @@ -127,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); @@ -155,6 +180,14 @@ SGMaterial::read_properties( const string &fg_root, const SGPropertyNode * props ((SGPropertyNode *)props)->getChildren("object-group"); for (unsigned int i = 0; i < object_group_nodes.size(); i++) object_groups.push_back(new SGMatModelGroup(object_group_nodes[i])); + + // read glyph table for taxi-/runway-signs + vector glyph_nodes = props->getChildren("glyph"); + for (unsigned int i = 0; i < glyph_nodes.size(); i++) { + const char *name = glyph_nodes[i]->getStringValue("name"); + if (name) + glyphs[name] = new SGMaterialGlyph(glyph_nodes[i]); + } } @@ -172,9 +205,16 @@ SGMaterial::init () ysize = 0; wrapu = true; wrapv = true; + mipmap = true; light_coverage = 0.0; - refcount = 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; @@ -184,96 +224,124 @@ 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 ); - _status[i].state->setTexture( - (char *)_status[i].texture_path.c_str(), - 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; - ssgSimpleState *st = (n >= 0) ? _status[n].state - : _status[_current_ptr].state; - ((SGMaterial *)this)->_current_ptr += 1; + 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(); + + _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(); - state->ref(); + 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 ); - state->setTexture( (char *)_status[i].texture_path.c_str(), - 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 ) { - _internal_state st( s, "", true ); - st.state->ref(); - _status.push_back( st ); + _status.push_back( _internal_state( s, "", true ) ); +} + +void SGMaterial::assignTexture( osg::StateSet *state, const std::string &fname, + bool _wrapu, bool _wrapv, bool _mipmap ) +{ + 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 >::const_iterator it; + it = glyphs.find(name); + if (it == glyphs.end()) + return 0; + + return it->second; } -// end of mat.cxx + +//////////////////////////////////////////////////////////////////////// +// SGMaterialGlyph. +//////////////////////////////////////////////////////////////////////// + +SGMaterialGlyph::SGMaterialGlyph(SGPropertyNode *p) : + _left(p->getDoubleValue("left", 0.0)), + _right(p->getDoubleValue("right", 1.0)) +{ +} + +void +SGSetTextureFilter( int max) { + SGSceneFeatures::instance()->setTextureFilter( max); +} + +int +SGGetTextureFilter() { + return SGSceneFeatures::instance()->getTextureFilter(); +}