예제 #1
0
void ShadingManager::SetMaterialProperty(const KFbxSurfaceMaterial * pMaterial,
		const char * pPropertyName,
		const char * pFactorPropertyName,
		unsigned int pOGLProperty) const
{
	const KFbxProperty lProperty = pMaterial->FindProperty(pPropertyName);
	const KFbxProperty lFactorProperty = pMaterial->FindProperty(pFactorPropertyName);
	if (lProperty.IsValid() && lFactorProperty.IsValid())
	{
		fbxDouble3 lColor = fbxDouble3(0, 0, 0);
		lColor = lProperty.Get(&lColor);
		double lFactor = 1;
		lFactor = lFactorProperty.Get(&lFactor);
		if (lFactor != 1)
		{
			lColor[0] *= lFactor;
			lColor[1] *= lFactor;
			lColor[2] *= lFactor;
		}

		const GLfloat lMaterial[] = {(GLfloat)lColor[0], (GLfloat)lColor[1], (GLfloat)lColor[2], 1.0f};
		glMaterialfv(GL_FRONT, pOGLProperty, lMaterial);
	}
}
FBXModel::MaterialCollection FBXModel::getMaterials(const GraphicsDevice& device, KFbxNode* node)
{		
	MaterialCollection materials;

	for (int i = 0; i < node->GetMaterialCount(); ++i)
	{
		FBXMaterial material;

		KFbxSurfaceMaterial* surfaceMaterial = node->GetMaterial(i);

		KFbxProperty prop = surfaceMaterial->FindProperty(KFbxSurfaceMaterial::sDiffuse);

		if	(prop.IsValid())
		{
			int textureCount = prop.GetSrcObjectCount(KFbxFileTexture::ClassId);

			if (textureCount)
			{
				KFbxFileTexture* fbxTexture = prop.GetSrcObject(FBX_TYPE(KFbxFileTexture), 0);

				if (fbxTexture)
					material.texture = Texture::createFromFile(device, fbxTexture->GetFileName());
			}
		}

		if (!material.texture)
			material.texture = defaultTexture;
						
		if	(surfaceMaterial->GetClassId().Is(KFbxSurfacePhong::ClassId))
		{
			Material& mat = material.material;

			KFbxSurfacePhong* phong = (KFbxSurfacePhong*)surfaceMaterial;

			mat.Ambient = convert(phong->Diffuse.Get());
			mat.Diffuse = mat.Ambient;
			mat.Specular = convert(phong->Specular.Get());
			mat.Emissive = convert(phong->Emissive.Get());
			mat.Power = (float)phong->SpecularFactor.Get();
		}

		materials.push_back(material);
	}

	return materials;
}
예제 #3
0
void ShadingManager::SetMaterial(const KFbxNode * pNode, int pMaterialIndex) const
{
	const KFbxSurfaceMaterial * lSurfaceMaterial = pNode->GetMaterial(pMaterialIndex);
	if (!lSurfaceMaterial)
		return;

	if (lSurfaceMaterial == mLastMaterial)
		return;

	mLastMaterial = lSurfaceMaterial;

	SetMaterialProperty(lSurfaceMaterial, KFbxSurfaceMaterial::sEmissive, KFbxSurfaceMaterial::sEmissiveFactor, GL_EMISSION);

	SetMaterialProperty(lSurfaceMaterial, KFbxSurfaceMaterial::sAmbient, KFbxSurfaceMaterial::sAmbientFactor, GL_AMBIENT);

	const TextureObjectsForMaterialType::RecordType * lRecord = mTextureObjectsForMaterial.Find(lSurfaceMaterial);
	if (lRecord)
	{
		glBindTexture(GL_TEXTURE_2D, lRecord->GetValue());
		mLastTextureObject = lRecord->GetValue();
	}
	else
	{
		mLastTextureObject = 0;
	}

	if (!mLastTextureObject)
	{
		SetMaterialProperty(lSurfaceMaterial, KFbxSurfaceMaterial::sDiffuse, KFbxSurfaceMaterial::sDiffuseFactor, GL_DIFFUSE);
	}

	SetMaterialProperty(lSurfaceMaterial, KFbxSurfaceMaterial::sSpecular, KFbxSurfaceMaterial::sSpecularFactor, GL_SPECULAR);
	KFbxProperty lShininessProperty = lSurfaceMaterial->FindProperty(KFbxSurfaceMaterial::sShininess);
	if (lShininessProperty.IsValid())
	{
		double lShininess = 0;
		lShininess = lShininessProperty.Get(&lShininess);
		glMaterialf(GL_FRONT, GL_SHININESS, (GLfloat)lShininess);
	}
}
예제 #4
0
void ShadingManager::Initialize(const KFbxNode* pNode)
{
	if (!pNode)
		return;

	if (pNode->GetNodeAttribute())
	{
		const int lMaterialCount = pNode->GetMaterialCount();
		for (int lMaterialIndex = 0; lMaterialIndex < lMaterialCount; ++lMaterialIndex)
		{
			const KFbxSurfaceMaterial * lMaterial = pNode->GetMaterial(lMaterialIndex);
			if (lMaterial)
			{
				const KFbxProperty lProperty = lMaterial->FindProperty(KFbxSurfaceMaterial::sDiffuse);
				if (lProperty.IsValid())
				{
					const int lTextureCount = lProperty.GetSrcObjectCount(KFbxFileTexture::ClassId);
					if (lTextureCount)
					{
						const KFbxFileTexture* lTexture = lProperty.GetSrcObject(FBX_TYPE(KFbxFileTexture), 0);
						if (lTexture)
						{
							unsigned int lTextureObject;
							mTextureManager->LoadTexture(lTexture, &lTextureObject);
							mTextureObjectsForMaterial.Insert(lMaterial, lTextureObject);
						}
					}
				}
			}
		}
	}

	const int lChildCount = pNode->GetChildCount();
	for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex)
	{
		Initialize(pNode->GetChild(lChildIndex));
	}
}
예제 #5
0
bool	FBXLoader::FindTextureInfo(KFbxProperty prop, bool& disp, int mat_i, Object* o)
{
	if (prop.IsValid())
	{
		Texture*	t;

		t = new (std::nothrow) Texture;
		if (t == NULL)
		{
			std::cout << "[FbxLoader]{__FindTextureInfo} Error: Can not allocate memory\n";
			return (false);
		}
		int	t_count;
		int	i;

		t_count = prop.GetSrcObjectCount(KFbxTexture::ClassId);
		i = 0;
		while (i < t_count)
		{
			KFbxLayeredTexture*	lay_t;

			lay_t = KFbxCast <KFbxLayeredTexture>(prop.GetSrcObject(KFbxLayeredTexture::ClassId, i));
			if (lay_t)
			{
				KFbxLayeredTexture*	lay_t2;
				int			nb_text;
				int			j;

				lay_t2 = KFbxCast <KFbxLayeredTexture>(prop.GetSrcObject(KFbxLayeredTexture::ClassId, i));
				nb_text = lay_t2->GetSrcObjectCount(KFbxTexture::ClassId);
				j = 0;
				while (j < nb_text)
				{
					KFbxTexture*	_t;

					_t = KFbxCast <KFbxTexture> (lay_t2->GetSrcObject(KFbxTexture::ClassId, j));
					if (_t)
					{
						KFbxLayeredTexture::EBlendMode blend_mode;

						if (disp)
							disp = false;
						lay_t2->GetTextureBlendMode(j, blend_mode);
						this->TextureInfoFinded(_t, (int)blend_mode, t);
						o->GetMatList()->at(mat_i)->AddTexture(t);
					}
					++j;
				}
			}
			else
			{
				KFbxTexture*	_t;

				_t = KFbxCast <KFbxTexture> (prop.GetSrcObject(KFbxTexture::ClassId, i));
				if (_t)
				{
					if (disp)
						disp = false;
					if (strcmp(prop.GetName(), "DiffuseColor") == 0)
						t->SetTXTChanel(0);
					else if (strcmp(prop.GetName(), "SpecularColor") == 0)
						t->SetTXTChanel(3);
					this->TextureInfoFinded(_t, -1, t);
					o->GetMatList()->at(mat_i)->AddTexture(t);
				}
			}
			++i;
		}
	}
	return (true);
}
예제 #6
0
StateSetContent
FbxMaterialToOsgStateSet::convert(const KFbxSurfaceMaterial* pFbxMat)
{
    FbxMaterialMap::const_iterator it = _fbxMaterialMap.find(pFbxMat);
    if (it != _fbxMaterialMap.end())
        return it->second;

    osg::ref_ptr<osg::Material> pOsgMat = new osg::Material;
    pOsgMat->setName(pFbxMat->GetName());

    StateSetContent result;

    result.material = pOsgMat;

    fbxString shadingModel = pFbxMat->ShadingModel.Get();

    const KFbxSurfaceLambert* pFbxLambert = KFbxCast<KFbxSurfaceLambert>(pFbxMat);

    // diffuse map...
    const KFbxProperty lProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sDiffuse);
    if (lProperty.IsValid())
    {
        int lNbTex = lProperty.GetSrcObjectCount(KFbxFileTexture::ClassId);
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            KFbxFileTexture* lTexture = KFbxCast<KFbxFileTexture>(lProperty.GetSrcObject(KFbxFileTexture::ClassId, lTextureIndex));
            if (lTexture)
            {
                result.diffuseTexture = fbxTextureToOsgTexture(lTexture);
                result.diffuseChannel = lTexture->UVSet.Get();
                result.diffuseScaleU = lTexture->GetScaleU();
                result.diffuseScaleV = lTexture->GetScaleV();
            }

            //For now only allow 1 texture
            break;
        }
    }

    // opacity map...
    const KFbxProperty lOpacityProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sTransparentColor);
    if (lOpacityProperty.IsValid())
    {
        int lNbTex = lOpacityProperty.GetSrcObjectCount(KFbxFileTexture::ClassId);
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            KFbxFileTexture* lTexture = KFbxCast<KFbxFileTexture>(lOpacityProperty.GetSrcObject(KFbxFileTexture::ClassId, lTextureIndex));
            if (lTexture)
            {
                // TODO: if texture image does NOT have an alpha channel, should it be added?

                result.opacityTexture = fbxTextureToOsgTexture(lTexture);
                result.opacityChannel = lTexture->UVSet.Get();
                result.opacityScaleU = lTexture->GetScaleU();
                result.opacityScaleV = lTexture->GetScaleV();
            }

            //For now only allow 1 texture
            break;
        }
    }

    // reflection map...
    const KFbxProperty lReflectionProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sReflection);
    if (lReflectionProperty.IsValid())
    {
        int lNbTex = lReflectionProperty.GetSrcObjectCount(KFbxFileTexture::ClassId);
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            KFbxFileTexture* lTexture = KFbxCast<KFbxFileTexture>(lReflectionProperty.GetSrcObject(KFbxFileTexture::ClassId, lTextureIndex));
            if (lTexture)
            {
                // support only spherical reflection maps...
                if (KFbxFileTexture::eUMT_ENVIRONMENT == lTexture->CurrentMappingType.Get())
                {
                    result.reflectionTexture = fbxTextureToOsgTexture(lTexture);
                    result.reflectionChannel = lTexture->UVSet.Get();
                }
            }

            //For now only allow 1 texture
            break;
        }
    }

    // emissive map...
    const KFbxProperty lEmissiveProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sEmissive);
    if (lEmissiveProperty.IsValid())
    {
        int lNbTex = lEmissiveProperty.GetSrcObjectCount(KFbxFileTexture::ClassId);
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            KFbxFileTexture* lTexture = KFbxCast<KFbxFileTexture>(lEmissiveProperty.GetSrcObject(KFbxFileTexture::ClassId, lTextureIndex));
            if (lTexture)
            {
                result.emissiveTexture = fbxTextureToOsgTexture(lTexture);
                result.emissiveChannel = lTexture->UVSet.Get();
                result.emissiveScaleU = lTexture->GetScaleU();
                result.emissiveScaleV = lTexture->GetScaleV();
            }

            //For now only allow 1 texture
            break;
        }
    }

    if (pFbxLambert)
    {
        fbxDouble3 color = pFbxLambert->Diffuse.Get();
        double factor = pFbxLambert->DiffuseFactor.Get();
        pOsgMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(
            static_cast<float>(color[0] * factor),
            static_cast<float>(color[1] * factor),
            static_cast<float>(color[2] * factor),
            static_cast<float>(1.0 - pFbxLambert->TransparencyFactor.Get())));

        color = pFbxLambert->Ambient.Get();
        factor = pFbxLambert->AmbientFactor.Get();
        pOsgMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(
            static_cast<float>(color[0] * factor),
            static_cast<float>(color[1] * factor),
            static_cast<float>(color[2] * factor),
            1.0f));

        color = pFbxLambert->Emissive.Get();
        factor = pFbxLambert->EmissiveFactor.Get();
        pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(
            static_cast<float>(color[0] * factor),
            static_cast<float>(color[1] * factor),
            static_cast<float>(color[2] * factor),
            1.0f));

        // get maps factors...
        result.diffuseFactor = pFbxLambert->DiffuseFactor.Get();

        if (const KFbxSurfacePhong* pFbxPhong = KFbxCast<KFbxSurfacePhong>(pFbxLambert))
        {
            color = pFbxPhong->Specular.Get();
            factor = pFbxPhong->SpecularFactor.Get();
            pOsgMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(
                static_cast<float>(color[0] * factor),
                static_cast<float>(color[1] * factor),
                static_cast<float>(color[2] * factor),
                1.0f));

            pOsgMat->setShininess(osg::Material::FRONT_AND_BACK,
                static_cast<float>(pFbxPhong->Shininess.Get()));

            // get maps factors...
            result.reflectionFactor = pFbxPhong->ReflectionFactor.Get();
            // get more factors here...
        }
    }

    if (_lightmapTextures)
    {
        // if using an emission map then adjust material properties accordingly...
        if (result.emissiveTexture)
        {
            osg::Vec4 diffuse = pOsgMat->getDiffuse(osg::Material::FRONT_AND_BACK);
            pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, diffuse);
            pOsgMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,diffuse.a()));
            pOsgMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,diffuse.a()));
        }
    }

    _fbxMaterialMap.insert(FbxMaterialMap::value_type(pFbxMat, result));
    return result;
}