bool SimpleTexturedMaterial::isTransparent(void) const { return Inherited::isTransparent() || (getImage()!=NULL && (getImage()->hasAlphaChannel() && getEnvMode() != GL_DECAL) ); }
void SimpleTexturedMaterial::changed(BitVector whichField, UInt32 origin) { prepareLocalChunks(); // these two are very expensive, as they need to regenerate the // texture object, do only if really needed if(whichField & ImageFieldMask) { beginEditCP(_textureChunk, TextureChunk::ImageFieldMask); _textureChunk->setImage(getImage()); endEditCP(_textureChunk, TextureChunk::ImageFieldMask); } if(whichField & MinFilterFieldMask || whichField & MagFilterFieldMask) { beginEditCP(_textureChunk, TextureChunk::MinFilterFieldMask | TextureChunk::MagFilterFieldMask); _textureChunk->setMinFilter(getMinFilter()); _textureChunk->setMagFilter(getMagFilter()); endEditCP(_textureChunk, TextureChunk::MinFilterFieldMask | TextureChunk::MagFilterFieldMask); } // this is not as expensive, but why do it more often then needed? if(whichField & EnvModeFieldMask) { beginEditCP(_textureChunk, TextureChunk::EnvModeFieldMask); _textureChunk->setEnvMode(getEnvMode()); endEditCP(_textureChunk, TextureChunk::EnvModeFieldMask); } if(whichField & EnvMapFieldMask) { beginEditCP(_texGenChunk, TexGenChunk::GenFuncSFieldMask | TexGenChunk::GenFuncTFieldMask); if (getEnvMap()) { _texGenChunk->setGenFuncS(GL_SPHERE_MAP); _texGenChunk->setGenFuncT(GL_SPHERE_MAP); } else { _texGenChunk->setGenFuncS(GL_NONE); _texGenChunk->setGenFuncT(GL_NONE); } endEditCP(_texGenChunk, TexGenChunk::GenFuncSFieldMask | TexGenChunk::GenFuncTFieldMask); } Inherited::changed(whichField, origin); }
StatePtr SimpleTexturedMaterial::makeState(void) { StatePtr state = Inherited::makeState(); prepareLocalChunks(); state->addChunk(_textureChunk); state->addChunk(_texGenChunk); if(getImage() != NullFC && getImage()->hasAlphaChannel() && getEnvMode() != GL_DECAL) { if(getImage()->isAlphaBinary()) { if(_blendChunk->getSrcFactor() == GL_SRC_ALPHA) { beginEditCP(_blendChunk); _blendChunk->setSrcFactor(GL_ONE); _blendChunk->setDestFactor(GL_ZERO); _blendChunk->setAlphaFunc(GL_NOTEQUAL); _blendChunk->setAlphaValue(0); endEditCP(_blendChunk); } } else { if(_blendChunk->getSrcFactor() != GL_SRC_ALPHA) { beginEditCP(_blendChunk); _blendChunk->setSrcFactor(GL_SRC_ALPHA); _blendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA); _blendChunk->setAlphaFunc(GL_NONE); _blendChunk->setAlphaValue(0); endEditCP(_blendChunk); } } } return state; }
void SimpleTexturedMaterial::changed(ConstFieldMaskArg whichField, UInt32 origin, BitVector detail) { prepareLocalChunks(); // these two are very expensive, as they need to regenerate the // texture object, do only if really needed if(whichField & ImageFieldMask) { _textureChunk->setImage(getImage()); } if(whichField & MinFilterFieldMask || whichField & MagFilterFieldMask) { _textureChunk->setMinFilter(getMinFilter()); _textureChunk->setMagFilter(getMagFilter()); } // this is not as expensive, but why do it more often then needed? if(whichField & EnvModeFieldMask) { _texEnvChunk->setEnvMode(getEnvMode()); } if(whichField & EnvMapFieldMask) { if (getEnvMap()) { #ifndef OSG_EMBEDDED _texGenChunk->setGenFuncS(GL_SPHERE_MAP); _texGenChunk->setGenFuncT(GL_SPHERE_MAP); #endif } else { _texGenChunk->setGenFuncS(GL_NONE); _texGenChunk->setGenFuncT(GL_NONE); } } Inherited::changed(whichField, origin, detail); }
void SimpleTexturedMaterial::rebuildState(void) { Inherited::rebuildState(); prepareLocalChunks(); _pState->addChunk(_textureChunk); _pState->addChunk(_texGenChunk ); _pState->addChunk(_texEnvChunk ); if(getImage () != NULL && getImage ()->hasAlphaChannel() == true && getEnvMode() != GL_DECAL) { if(getImage()->isAlphaBinary()) { if(_blendChunk->getSrcFactor() == GL_SRC_ALPHA) { _blendChunk->setSrcFactor(GL_ONE); _blendChunk->setDestFactor(GL_ZERO); _blendChunk->setAlphaFunc(GL_NOTEQUAL); _blendChunk->setAlphaValue(0); } } else { if(_blendChunk->getSrcFactor() != GL_SRC_ALPHA) { _blendChunk->setSrcFactor(GL_SRC_ALPHA); _blendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA); _blendChunk->setAlphaFunc(GL_NONE); _blendChunk->setAlphaValue(0); } } } }
osg::Node* traverseAIScene( const std::string& filename, const struct aiScene* aiScene, const struct aiNode* aiNode, TextureMap& textures, const osgDB::Options* options ) const { osg::Geode* geode = new osg::Geode; for ( unsigned int n=0; n<aiNode->mNumMeshes; ++n ) { // Create geometry basic properties const struct aiMesh* mesh = aiScene->mMeshes[ aiNode->mMeshes[n] ]; osg::Geometry* geom = new osg::Geometry; geode->addDrawable( geom ); osg::Vec3Array* va = new osg::Vec3Array(mesh->mNumVertices); osg::Vec3Array* na = (mesh->mNormals ? new osg::Vec3Array(mesh->mNumVertices) : NULL); osg::Vec4Array* ca = (mesh->mColors[0] ? new osg::Vec4Array(mesh->mNumVertices) : NULL); for ( unsigned int i=0; i<mesh->mNumVertices; ++i ) { const aiVector3D& v = mesh->mVertices[i]; (*va)[i].set( v.x, v.y, v.z ); if ( na ) { const aiVector3D& n = mesh->mNormals[i]; (*na)[i].set( n.x, n.y, n.z ); } if ( ca ) { const aiColor4D& c = mesh->mColors[0][i]; (*ca)[i].set( c.r, c.g, c.b, c.a ); } } geom->setVertexArray( va ); if ( na ) { geom->setNormalArray( na ); geom->setNormalBinding( osg::Geometry::BIND_PER_VERTEX ); } if ( ca ) { geom->setColorArray( ca ); geom->setColorBinding( osg::Geometry::BIND_PER_VERTEX ); } // Create geometry texture coordinates unsigned int unit = 0; const aiVector3D* aiTexCoords = mesh->mTextureCoords[unit]; while ( aiTexCoords!=NULL ) { switch ( mesh->mNumUVComponents[unit] ) { case 1: { osg::FloatArray* ta = new osg::FloatArray(mesh->mNumVertices); for ( unsigned int i=0; i<mesh->mNumVertices; ++i ) (*ta)[i] = aiTexCoords[i].x; geom->setTexCoordArray( unit, ta ); } break; case 2: { osg::Vec2Array* ta = new osg::Vec2Array(mesh->mNumVertices); for ( unsigned int i=0; i<mesh->mNumVertices; ++i ) { const aiVector3D& t = aiTexCoords[i]; (*ta)[i].set( t.x, t.y ); } geom->setTexCoordArray( unit, ta ); } break; case 3: { osg::Vec3Array* ta = new osg::Vec3Array(mesh->mNumVertices); for ( unsigned int i=0; i<mesh->mNumVertices; ++i ) { const aiVector3D& t = aiTexCoords[i]; (*ta)[i].set( t.x, t.y, t.z ); } geom->setTexCoordArray( unit, ta ); } break; } aiTexCoords = mesh->mTextureCoords[++unit]; } // Create geometry primitives osg::ref_ptr<osg::DrawElementsUInt> de[5]; de[1] = new osg::DrawElementsUInt(GL_POINTS); de[2] = new osg::DrawElementsUInt(GL_LINES); de[3] = new osg::DrawElementsUInt(GL_TRIANGLES); de[4] = new osg::DrawElementsUInt(GL_QUADS); de[0] = new osg::DrawElementsUInt(GL_POLYGON); osg::DrawElementsUInt* current = NULL; for ( unsigned int f=0; f<mesh->mNumFaces; ++f ) { const struct aiFace& face = mesh->mFaces[f]; if ( face.mNumIndices>4 ) current = de[0].get(); else current = de[face.mNumIndices].get(); for ( unsigned i=0; i<face.mNumIndices; ++i ) current->push_back( face.mIndices[i] ); } for ( unsigned int i=0; i<5; ++i ) { if ( de[i]->size()>0 ) geom->addPrimitiveSet( de[i].get() ); } // Create textures osg::StateSet* ss = geom->getOrCreateStateSet(); const aiMaterial* aiMtl = aiScene->mMaterials[mesh->mMaterialIndex]; aiReturn texFound = AI_SUCCESS; aiTextureOp envOp = aiTextureOp_Multiply; aiTextureMapMode wrapMode[3] = {aiTextureMapMode_Clamp}; unsigned int texIndex = 0; aiString path; while ( texFound==AI_SUCCESS ) { texFound = aiMtl->GetTexture( aiTextureType_DIFFUSE, texIndex++, &path, NULL, &unit, NULL, &envOp, &(wrapMode[0]) ); if ( unit>0 ) unit--; // The output UV seems to start at 1? if ( texFound!=AI_SUCCESS ) break; std::string texFile(path.data); if ( !osgDB::isAbsolutePath(texFile) ) texFile = getFullPath( filename, texFile ); TextureMap::iterator itr = textures.find(texFile); if ( itr==textures.end() ) { osg::ref_ptr<osg::Texture2D> tex2D = new osg::Texture2D; tex2D->setWrap( osg::Texture::WRAP_S, getWrapMode(wrapMode[0]) ); tex2D->setWrap( osg::Texture::WRAP_T, getWrapMode(wrapMode[1]) ); tex2D->setWrap( osg::Texture::WRAP_R, getWrapMode(wrapMode[2]) ); tex2D->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR ); tex2D->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR ); tex2D->setImage( osgDB::readImageFile(texFile, options) ); textures[texFile] = tex2D; } ss->setTextureAttributeAndModes( unit, textures[texFile].get() ); if ( unit>0 ) ss->setTextureAttributeAndModes( unit, new osg::TexEnv(getEnvMode(envOp)) ); } // Create materials createMaterialData( ss, aiMtl ); } aiMatrix4x4 m = aiNode->mTransformation; m.Transpose(); // Create the node and continue looking for children osg::ref_ptr<osg::MatrixTransform> mt; mt = new osg::MatrixTransform; mt->setMatrix( osg::Matrixf((float*)&m) ); for ( unsigned int n=0; n<aiNode->mNumChildren; ++n ) { osg::Node* child = traverseAIScene( filename, aiScene, aiNode->mChildren[n], textures, options ); if ( child ) mt->addChild( child ); } mt->addChild( geode ); return mt.release(); }