示例#1
0
文件: utility.cpp 项目: tommp/V8
GLboolean store_binary_material(const aiScene* scene, const aiMesh* mesh, std::string& material_name) {
	aiMaterial* new_material = scene->mMaterials[mesh->mMaterialIndex];
	std::string material_path;
	std::string diffuse_name;
	std::string specular_name;
	aiString name;

	new_material->Get(AI_MATKEY_NAME,name);

	material_name = name.data;
	if (material_name.empty()) {
		std::cout << __FILE__ << ":" << __LINE__ << ": " << "ERROR: Cannot store material with empty name!" << std::endl;
		errorlogger("ERROR: Cannot store material with empty name!");
		return false;
	}
	diffuse_name = load_material_texture(new_material, aiTextureType_DIFFUSE);
	specular_name = load_material_texture(new_material, aiTextureType_SPECULAR);

	material_path = Utility_vars::folder_path + MATERIAL_DATA_PATH + material_name + ".mat";

	if (file_exists(material_path)) {
		std::cout << __FILE__ << ":" << __LINE__ << ": " << "ERROR: Failed to store binary material, target file exists: " << material_path << std::endl;
		errorlogger("ERROR: Failed to store binary material, target file exists: ", material_path.c_str());
		return false;
	}

	std::ofstream contentf (material_path.c_str(), std::ios::binary);
	if (!contentf.is_open()){
		std::cout << __FILE__ << ":" << __LINE__ << ": " << "FATAL ERROR: Failed to open content file for storing material data: " << material_path << std::endl;
		errorlogger("FATAL ERROR: Failed to open content file for storing material data: ", material_path.c_str());
		exit(EXIT_FAILURE);
	}

	if (!diffuse_name.empty()){
		contentf.write(reinterpret_cast<const char *>(&Utility_consts::TRUE_BOOL), sizeof(GLuint));
		write_string_to_binary_file(contentf, diffuse_name);
	}
	else{
		contentf.write(reinterpret_cast<const char *>(&Utility_consts::FALSE_BOOL), sizeof(GLuint));
	}

	if (!specular_name.empty()){
		contentf.write(reinterpret_cast<const char *>(&Utility_consts::TRUE_BOOL), sizeof(GLuint));
		write_string_to_binary_file(contentf, specular_name);
	}
	else{
		contentf.write(reinterpret_cast<const char *>(&Utility_consts::FALSE_BOOL), sizeof(GLuint));
	}

	contentf.close();

	return true;
}
示例#2
0
void ReaderWriterOBJ::buildMaterialToStateSetMap(obj::Model& model, MaterialToStateSetMap& materialToStateSetMap) const
{
    if (_fixBlackMaterials)
    {
        // hack to fix Maya exported models that contian all black materials.
        int numBlack = 0;
        int numNotBlack = 0;
        obj::Model::MaterialMap::iterator itr;
        for(itr = model.materialMap.begin();
            itr != model.materialMap.end();
            ++itr)
        {
            obj::Material& material = itr->second;
            if (material.ambient==osg::Vec4(0.0f,0.0f,0.0f,1.0f) &&
                material.diffuse==osg::Vec4(0.0f,0.0f,0.0f,1.0f))
            {
                ++numBlack;
            }
            else
            {
                ++numNotBlack;
            }
        }
        
        if (numNotBlack==0 && numBlack!=0)
        {
            for(itr = model.materialMap.begin();
                itr != model.materialMap.end();
                ++itr)
            {
                obj::Material& material = itr->second;
                if (material.ambient==osg::Vec4(0.0f,0.0f,0.0f,1.0f) &&
                    material.diffuse==osg::Vec4(0.0f,0.0f,0.0f,1.0f))
                {
                    material.ambient.set(0.3f,0.3f,0.3f,1.0f);
                    material.diffuse.set(1.0f,1.0f,1.0f,1.0f);
                }
            }
        }
    }
    
    for(obj::Model::MaterialMap::iterator itr = model.materialMap.begin();
        itr != model.materialMap.end();
        ++itr)
    {
        obj::Material& material = itr->second;
        
        osg::ref_ptr< osg::StateSet > stateset = new osg::StateSet;

        bool isTransparent = false;

        // handle material colors
        // http://java3d.j3d.org/utilities/loaders/obj/sun.html
        if (material.illum != 0)
        {
            osg::Material* osg_material = new osg::Material;
            stateset->setAttribute(osg_material);

            osg_material->setAmbient(osg::Material::FRONT_AND_BACK,material.ambient);
            osg_material->setDiffuse(osg::Material::FRONT_AND_BACK,material.diffuse);
            osg_material->setEmission(osg::Material::FRONT_AND_BACK,material.emissive);

            if (material.illum == 2) {
                osg_material->setSpecular(osg::Material::FRONT_AND_BACK,material.specular);
            } else {
                osg_material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,1));
            }
            osg_material->setShininess(osg::Material::FRONT_AND_BACK,(material.Ns/1000.0f)*128.0f ); // note OBJ shiniess is 0..1000.
            
            if (material.ambient[3]!=1.0 ||
                material.diffuse[3]!=1.0 ||
                material.specular[3]!=1.0||
                material.emissive[3]!=1.0)
            {
                osg::notify(osg::INFO)<<"Found transparent material"<<std::endl;
                isTransparent = true;
            }
        }
        
        // handle textures
        enum TextureUnit
        {
            TEXTURE_UNIT_KD = 0,
            TEXTURE_UNIT_OPACITY
        };
        load_material_texture( model, material, stateset.get(), material.map_Kd,       TEXTURE_UNIT_KD );
        load_material_texture( model, material, stateset.get(), material.map_opacity,  TEXTURE_UNIT_OPACITY );
        
        if (isTransparent)
        {
            stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
            stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
        }

        materialToStateSetMap[material.name] = stateset.get();
    }
}
示例#3
0
void ReaderWriterOBJ::buildMaterialToStateSetMap(obj::Model& model, MaterialToStateSetMap& materialToStateSetMap, ObjOptionsStruct& localOptions, const Options* options) const
{
    if (localOptions.fixBlackMaterials)
    {
        // hack to fix Maya exported models that contian all black materials.
        int numBlack = 0;
        int numNotBlack = 0;
        obj::Model::MaterialMap::iterator itr;
        for(itr = model.materialMap.begin();
            itr != model.materialMap.end();
            ++itr)
        {
            obj::Material& material = itr->second;
            if (material.ambient==osg::Vec4(0.0f,0.0f,0.0f,1.0f) &&
                material.diffuse==osg::Vec4(0.0f,0.0f,0.0f,1.0f))
            {
                ++numBlack;
            }
            else
            {
                ++numNotBlack;
            }
        }

        if (numNotBlack==0 && numBlack!=0)
        {
            for(itr = model.materialMap.begin();
                itr != model.materialMap.end();
                ++itr)
            {
                obj::Material& material = itr->second;
                if (material.ambient==osg::Vec4(0.0f,0.0f,0.0f,1.0f) &&
                    material.diffuse==osg::Vec4(0.0f,0.0f,0.0f,1.0f))
                {
                    material.ambient.set(0.3f,0.3f,0.3f,1.0f);
                    material.diffuse.set(1.0f,1.0f,1.0f,1.0f);
                }
            }
        }
    }

    for(obj::Model::MaterialMap::iterator itr = model.materialMap.begin();
        itr != model.materialMap.end();
        ++itr)
    {
        obj::Material& material = itr->second;

        osg::ref_ptr< osg::StateSet > stateset = new osg::StateSet;

        bool isTransparent = false;

        // handle material colors
        // http://java3d.j3d.org/utilities/loaders/obj/sun.html
        if (material.illum != 0)
        {
            osg::Material* osg_material = new osg::Material;
            stateset->setAttribute(osg_material);
            osg_material->setName(material.name);
            osg_material->setAmbient(osg::Material::FRONT_AND_BACK,material.ambient);
            osg_material->setDiffuse(osg::Material::FRONT_AND_BACK,material.diffuse);
            osg_material->setEmission(osg::Material::FRONT_AND_BACK,material.emissive);

            if (material.illum == 2) {
                osg_material->setSpecular(osg::Material::FRONT_AND_BACK,material.specular);
            } else {
                osg_material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,1));
            }
            osg_material->setShininess(osg::Material::FRONT_AND_BACK,(material.Ns/1000.0f)*128.0f ); // note OBJ shiniess is 0..1000.

            if (material.ambient[3]!=1.0 ||
                material.diffuse[3]!=1.0 ||
                material.specular[3]!=1.0||
                material.emissive[3]!=1.0)
            {
                OSG_INFO<<"Found transparent material"<<std::endl;
                isTransparent = true;
            }
        }

        // If the user has explicitly set the required texture type to unit map via the options
        // string, then we load ONLY those textures that are in the map.
        if(localOptions.textureUnitAllocation.size()>0)
        {
            for(unsigned int i=0;i<localOptions.textureUnitAllocation.size();i++)
            {
                // firstly, get the option set pair
                int unit = localOptions.textureUnitAllocation[i].first;
                obj::Material::Map::TextureMapType type = localOptions.textureUnitAllocation[i].second;
                // secondly, see if this texture type (e.g. DIFFUSE) is one of those in the material
                int index = -1;
                for(unsigned int j=0;j<material.maps.size();j++)
                {
                    if(material.maps[j].type == type)
                    {
                        index = (int) j;
                        break;
                    }
                }
                if(index>=0) load_material_texture( model, material.maps[index], stateset.get(), unit, options );
            }
        }
        // If the user has set no options, then we load them up in the order contained in the enum. This
        // latter method is an attempt not to break user's existing code
        else
        {
            int unit = 0;
            for(int i=0;i<(int) obj::Material::Map::UNKNOWN;i++) // for each type
            {
                obj::Material::Map::TextureMapType type = (obj::Material::Map::TextureMapType) i;
                // see if this texture type (e.g. DIFFUSE) is one of those in the material
                int index = -1;
                for(unsigned int j=0;j<material.maps.size();j++)
                {
                    if(material.maps[j].type == type)
                    {
                        index = (int) j;
                        break;
                    }
                }
                if(index>=0)
                {
                    load_material_texture( model, material.maps[index], stateset.get(), unit, options );
                    unit++;
                }
            }
        }

        if (isTransparent)
        {
            stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
            stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
        }

        materialToStateSetMap[material.name] = stateset.get();
    }
}