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; }
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); } }
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)); } }
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); }
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; }