📄 surface.cpp
字号:
/******************************************************* Lightwave Object Loader for OSG Copyright (C) 2004 Marco Jez <marco.jez@poste.it> OpenSceneGraph is (C) 2004 Robert Osfield********************************************************/#include "Surface.h"#include <osg/Material>#include <osg/CullFace>#include <osg/Texture2D>#include <osg/TexEnvCombine>#include <osg/TexGen>#include <osg/BlendFunc>#include <osg/Notify>#include <osgFX/SpecularHighlights>#include <osgDB/ReadFile>using namespace lwosg;namespace{ osg::Texture::WrapMode osg_wrap_mode(Image_map::Wrap_type w) { switch (w) { case Image_map::RESET: return osg::Texture::CLAMP; case Image_map::REPEAT: return osg::Texture::REPEAT; case Image_map::MIRROR: return osg::Texture::MIRROR; case Image_map::EDGE: return osg::Texture::CLAMP_TO_EDGE; default: return osg::Texture::REPEAT; }; }}Surface::Surface(): base_color_(0.784f, 0.784f, 0.784f), diffuse_(1.0f), luminosity_(0), specularity_(0), reflection_(0), transparency_(0), translucency_(0), glossiness_(0.4f), sidedness_(FRONT_ONLY), max_smoothing_angle_(0){}Surface::Surface(const lwo2::FORM::SURF *surf, const Clip_map &clips): base_color_(0.784f, 0.784f, 0.784f), diffuse_(1.0f), luminosity_(0), specularity_(0), reflection_(0), transparency_(0), translucency_(0), glossiness_(0.4f), sidedness_(FRONT_ONLY), max_smoothing_angle_(0){ compile(surf, clips);}void Surface::compile(const lwo2::FORM::SURF *surf, const Clip_map &clips){ // invalidate the stateset so it will be rebuilt stateset_ = 0; name_ = surf->name; for (iff::Chunk_list::const_iterator j=surf->attributes.begin(); j!=surf->attributes.end(); ++j) { const lwo2::FORM::SURF::COLR *colr = dynamic_cast<const lwo2::FORM::SURF::COLR *>(*j); if (colr) base_color_ = osg::Vec3(colr->base_color.red, colr->base_color.green, colr->base_color.blue); const lwo2::FORM::SURF::DIFF *diff = dynamic_cast<const lwo2::FORM::SURF::DIFF *>(*j); if (diff) diffuse_ = diff->intensity.fraction; const lwo2::FORM::SURF::LUMI *lumi = dynamic_cast<const lwo2::FORM::SURF::LUMI *>(*j); if (lumi) luminosity_ = lumi->intensity.fraction; const lwo2::FORM::SURF::SPEC *spec = dynamic_cast<const lwo2::FORM::SURF::SPEC *>(*j); if (spec) specularity_ = spec->intensity.fraction; const lwo2::FORM::SURF::REFL *refl = dynamic_cast<const lwo2::FORM::SURF::REFL *>(*j); if (refl) reflection_ = refl->intensity.fraction; const lwo2::FORM::SURF::TRAN *tran = dynamic_cast<const lwo2::FORM::SURF::TRAN *>(*j); if (tran) transparency_ = tran->intensity.fraction; const lwo2::FORM::SURF::TRNL *trnl = dynamic_cast<const lwo2::FORM::SURF::TRNL *>(*j); if (trnl) translucency_ = trnl->intensity.fraction; const lwo2::FORM::SURF::GLOS *glos = dynamic_cast<const lwo2::FORM::SURF::GLOS *>(*j); if (glos) glossiness_ = glos->glossiness.fraction; const lwo2::FORM::SURF::SIDE *side = dynamic_cast<const lwo2::FORM::SURF::SIDE *>(*j); if (side) sidedness_ = static_cast<Sidedness>(side->sidedness); const lwo2::FORM::SURF::SMAN *sman = dynamic_cast<const lwo2::FORM::SURF::SMAN *>(*j); if (sman) max_smoothing_angle_ = sman->max_smoothing_angle.radians; const lwo2::FORM::SURF::VCOL *vcol = dynamic_cast<const lwo2::FORM::SURF::VCOL *>(*j); if (vcol) { color_map_intensity_ = vcol->intensity.fraction; color_map_type_ = std::string(vcol->vmap_type.id, 4); color_map_name_ = vcol->name; } const lwo2::FORM::SURF::BLOK *blok = dynamic_cast<const lwo2::FORM::SURF::BLOK *>(*j); if (blok) { Block new_block(blok); if (new_block.get_type() == "IMAP") { Clip_map::const_iterator i = clips.find(new_block.get_image_map().image_map); if (i != clips.end()) { new_block.get_image_map().clip = &i->second; } else { osg::notify(osg::WARN) << "Warning: lwosg::Surface: cannot find clip number " << new_block.get_image_map().image_map << std::endl; } } blocks_.insert(Block_map::value_type(new_block.get_ordinal(), new_block)); } }}void Surface::generate_stateset(unsigned int max_tex_units, bool force_arb_compression, const osgDB::ReaderWriter::Options* db_options) const{ if (!stateset_.valid()) { stateset_ = new osg::StateSet; osg::ref_ptr<osg::Material> material = new osg::Material; material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(base_color_ * diffuse_, 1-transparency_)); material->setAmbient(osg::Material::FRONT_AND_BACK, material->getDiffuse(osg::Material::FRONT_AND_BACK)); material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(specularity_, specularity_, specularity_, 1)); material->setShininess(osg::Material::FRONT_AND_BACK, powf(2, 10 * glossiness_ + 2)); material->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(base_color_ * luminosity_, 1-transparency_)); stateset_->setAttributeAndModes(material.get()); if (!color_map_name_.empty()) { material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); } if (transparency_ > 0) { osg::ref_ptr<osg::BlendFunc> bf = new osg::BlendFunc; bf->setFunction(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA); stateset_->setAttributeAndModes(bf.get()); stateset_->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); } if (sidedness_ == FRONT_AND_BACK) { stateset_->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); } else { osg::ref_ptr<osg::CullFace> cf = new osg::CullFace; switch (sidedness_) { case NONE: cf->setMode(osg::CullFace::FRONT_AND_BACK); break; case FRONT_ONLY: cf->setMode(osg::CullFace::BACK); break; case BACK_ONLY: cf->setMode(osg::CullFace::FRONT); break; default: ; } stateset_->setAttributeAndModes(cf.get()); } std::map< std::string, unsigned int > unitmap; unitmap[ "COLR" ] = 0; unitmap[ "TRAN" ] = 1; unsigned int unit = 0; for (Block_map::const_iterator i=blocks_.begin(); i!=blocks_.end(); ++i) { const Block &block = i->second; if (!block.enabled()) { continue; } if (block.get_type() == "IMAP") { std::string channel = block.get_channel(); if ( ( channel == "COLR" ) || ( channel == "TRAN" ) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -