/// Called to update the controls of the dialog virtual void Update( TimeValue t, Interval &valid, IParamMap2 *map ) { ICustButton *bmSelectBtn; IParamBlock2 *pblock; int i; long buttons[ 6 ] = { IDC_FRONT_NAME, IDC_BACK_NAME, IDC_LEFT_NAME, IDC_RIGHT_NAME, IDC_TOP_NAME, IDC_BOTTOM_NAME }; BitmapInfo bi; ParamMap2UserDlgProc::Update( t, valid, map ); pblock = map->GetParamBlock(); for( i = plStaticEnvLayer::kBmpFrontBitmap; i <= plStaticEnvLayer::kBmpBottomBitmap; i++ ) { bmSelectBtn = GetICustButton( GetDlgItem( map->GetHWnd(), buttons[ i ] ) ); PBBitmap *pbbm = pblock->GetBitmap( i, t ); if( pbbm ) bmSelectBtn->SetText( (TCHAR *)pbbm->bi.Filename() ); else bmSelectBtn->SetText( _T( "None" ) ); ReleaseICustButton( bmSelectBtn ); } plStaticEnvLayer *layer = (plStaticEnvLayer *)map->GetParamBlock()->GetOwner(); bi.SetName( layer->GetBaseFilename( t ) ); SetDlgItemText( map->GetHWnd(), IDC_BASE_FILENAME, bi.Filename() ); map->Enable( plStaticEnvLayer::kBmpGenerateFaces, ( bi.Name() == NULL || bi.Name()[ 0 ] == 0 ) ? FALSE : TRUE ); bmSelectBtn = GetICustButton( GetDlgItem( map->GetHWnd(), IDC_GENERATE_FACES ) ); bmSelectBtn->SetText( _T( "Generate From Node" ) ); ReleaseICustButton( bmSelectBtn ); i = pblock->GetInt( plStaticEnvLayer::kBmpTextureSize, t ); pblock->SetValue( plStaticEnvLayer::kBmpLastTextureSize, t, i ); }
void ViewFile::View( HWND hWnd ) { int idx; DWORD caps; BitmapInfo bi; Bitmap *map = NULL; TCHAR buf[256]; LoadString(hInst, IDS_DB_VIEW_FILE, buf, _countof(buf)); if (!TheManager->SelectFileInputEx(&bi, hWnd, buf, TRUE)) return; if (bi.Name()[0]) idx = TheManager->ioList.ResolveDevice(&bi); else idx = TheManager->ioList.FindDevice(bi.Device()); if (idx == -1) goto error; caps = TheManager->ioList.GetDeviceCapabilities(bi.Device()); TCHAR title[MAX_PATH]; if (caps & BMMIO_EXTENSION) _tcscpy(title,bi.Filename()); else _tcscpy(title,bi.Device()); if (caps & BMMIO_OWN_VIEWER) { BitmapIO *IO = TheManager->ioList.CreateDevInstance(bi.Device()); if(IO) { BOOL succeeded = IO->ShowImage(hWnd,&bi); delete IO; if(!succeeded) goto normal_view; } } else { normal_view: SetCursor(LoadCursor(NULL,IDC_WAIT)); map = TheManager->Load(&bi); if (map) { map->Display(title, BMM_CN, TRUE, FALSE); } else { error: TCHAR text[128]; TCHAR tmp[128]; LoadString(hInst, IDS_DB_NO_VIEW, tmp, _countof(tmp)); wsprintf(text,tmp,bi.Name()); LoadString(hInst, IDS_DB_VIEW_ERROR, tmp, _countof(tmp)); MessageBox(hWnd,text,tmp,MB_OK); } SetCursor(LoadCursor(NULL,IDC_ARROW)); } }
plLayerInterface *plLayerConverter::IConvertStaticEnvLayer( plPlasmaMAXLayer *layer, plMaxNode *maxNode, uint32_t blendFlags, bool preserveUVOffset, bool upperLayer ) { hsGuardBegin( "plLayerConverter::IConvertStaticEnvLayer" ); IParamBlock2 *bitmapPB; plLocation loc; loc = maxNode->GetLocation(); bitmapPB = layer->GetParamBlockByID( plStaticEnvLayer::kBlkBitmap ); if( !bitmapPB ) { fErrorMsg->Set( !bitmapPB, "Plasma Layer Error", "Bitmap paramblock for Plasma Layer not found" ).Show(); fErrorMsg->Set(); return nil; } // Get a new layer to play with plLayer *plasmaLayer = ICreateLayer( plString::FromUtf8( layer->GetName() ), upperLayer, loc ); // Get the texture info PBBitmap *pbbm = bitmapPB->GetBitmap( plStaticEnvLayer::kBmpFrontBitmap + 0 ); BitmapInfo *bi = nil; if( pbbm ) bi = &pbbm->bi; // If the texture had bad info, assert and return the empty layer if (!bi || !bi->Name() || !strcmp(bi->Name(), "")) { // Or don't assert since it can get annoying when you are using someone // elses file and don't have all the textures. return (plLayerInterface *)plasmaLayer; } // Setup the texture creation parameters plBitmapData bd; bd.fileName = bi->Name(); // Create texture and add it to list if unique int32_t texFlags = 0; // Texture Alpha/Color if( bitmapPB->GetInt( plStaticEnvLayer::kBmpInvertColor ) ) plasmaLayer->SetBlendFlags( plasmaLayer->GetBlendFlags() | hsGMatState::kBlendInvertColor ); if( bitmapPB->GetInt( plStaticEnvLayer::kBmpDiscardColor ) ) plasmaLayer->SetBlendFlags( plasmaLayer->GetBlendFlags() | hsGMatState::kBlendNoTexColor ); if( bitmapPB->GetInt( kBmpDiscardAlpha ) ) plasmaLayer->SetBlendFlags( plasmaLayer->GetBlendFlags() | hsGMatState::kBlendNoTexAlpha ); if( bitmapPB->GetInt( plStaticEnvLayer::kBmpInvertAlpha ) ) bd.invertAlpha = true; // Texture quality if( bitmapPB->GetInt( plStaticEnvLayer::kBmpNonCompressed ) ) texFlags |= plBitmap::kForceNonCompressed; switch( bitmapPB->GetInt( plStaticEnvLayer::kBmpScaling ) ) { case plStaticEnvLayer::kScalingHalf: texFlags |= plBitmap::kHalfSize; break; case plStaticEnvLayer::kScalingNone: texFlags |= plBitmap::kNoMaxSize; break; } bd.texFlags = texFlags; bd.isStaticCubicEnvMap = true; for( int i = 0; i < 6; i++ ) { PBBitmap *face = bitmapPB->GetBitmap( plStaticEnvLayer::kBmpFrontBitmap + i ); if( !face ) return (plLayerInterface *)plasmaLayer; bd.faceNames[ i ] = face->bi.Name(); } // Get detail parameters if( bitmapPB->GetInt( plStaticEnvLayer::kBmpUseDetail ) ) { // TODO: be smarter if( blendFlags & hsGMatState::kBlendAdd ) bd.createFlags = plMipmap::kCreateDetailAdd; else if( blendFlags & hsGMatState::kBlendMult ) bd.createFlags = plMipmap::kCreateDetailMult; else bd.createFlags = plMipmap::kCreateDetailAlpha; bd.detailDropoffStart = float( bitmapPB->GetInt( plStaticEnvLayer::kBmpDetailStartSize ) ) / 100.f; bd.detailDropoffStop = float( bitmapPB->GetInt( plStaticEnvLayer::kBmpDetailStopSize ) ) / 100.f; bd.detailMax = float( bitmapPB->GetInt( plStaticEnvLayer::kBmpDetailStartOpac ) ) / 100.f; bd.detailMin = float( bitmapPB->GetInt( plStaticEnvLayer::kBmpDetailStopOpac ) ) / 100.f; } /// Since we're a cubic environMap, we don't care about the UV transform nor the uvwSrc plasmaLayer->SetUVWSrc( 0 ); plasmaLayer->SetUVWSrc( plasmaLayer->GetUVWSrc() | plLayerInterface::kUVWReflect ); // Create the texture. If it works, assign it to the layer if( ( plasmaLayer = IAssignTexture( &bd, maxNode, plasmaLayer, upperLayer ) ) == nil ) return nil; // Tag this layer as reflective cubic environmentmapping if( bitmapPB->GetInt(plStaticEnvLayer::kBmpRefract) ) plasmaLayer->SetMiscFlags( plasmaLayer->GetMiscFlags() | hsGMatState::kMiscUseRefractionXform ); else plasmaLayer->SetMiscFlags( plasmaLayer->GetMiscFlags() | hsGMatState::kMiscUseReflectionXform ); return (plLayerInterface *)plasmaLayer; hsGuardEnd; }
plLayerInterface *plLayerConverter::IConvertLayerTex( plPlasmaMAXLayer *layer, plMaxNode *maxNode, uint32_t blendFlags, bool preserveUVOffset, bool upperLayer ) { hsGuardBegin( "plLayerConverter::IConvertLayerTex" ); IParamBlock2 *bitmapPB; plLocation loc; loc = maxNode->GetLocation(); bitmapPB = layer->GetParamBlockByID( plLayerTex::kBlkBitmap ); if( !bitmapPB ) { fErrorMsg->Set( !bitmapPB, "Plasma Layer Error", "Bitmap paramblock for Plasma Layer not found" ).Show(); fErrorMsg->Set(); return nil; } // Get a new layer to play with plLayer *plasmaLayer = ICreateLayer( plString::FromUtf8( layer->GetName() ), upperLayer, loc ); // We're using a texture, try and get its info PBBitmap *pbbm = nil; BitmapInfo *bi = nil; if( bitmapPB->GetInt( kBmpUseBitmap ) ) { if( bitmapPB ) pbbm = bitmapPB->GetBitmap( kBmpBitmap ); if( pbbm ) bi = &pbbm->bi; } // If the texture had bad info, assert and return the empty layer if( !bi || !bi->Name() || !strcmp(bi->Name(), "") ) { if( upperLayer ) { if( fErrorMsg->Set( !( fWarned & kWarnedNoUpperTexture ), "Plasma Export Error", sWarnNoUpperTexture, maxNode->GetName() ).CheckAskOrCancel() ) fWarned |= kWarnedNoUpperTexture; fErrorMsg->Set( false ); delete plasmaLayer; return nil; } else { return (plLayerInterface *)plasmaLayer; } } // Setup the texture creation parameters plBitmapData bd; bd.fileName = bi->Name(); // Create texture and add it to list if unique int32_t texFlags = 0;//hsGTexture::kMipMap; // Texture Alpha/Color if( bitmapPB->GetInt( kBmpInvertColor ) ) plasmaLayer->SetBlendFlags( plasmaLayer->GetBlendFlags() | hsGMatState::kBlendInvertColor ); if( bitmapPB->GetInt( kBmpDiscardColor ) ) plasmaLayer->SetBlendFlags( plasmaLayer->GetBlendFlags() | hsGMatState::kBlendNoTexColor ); if( bitmapPB->GetInt( kBmpDiscardAlpha ) ) plasmaLayer->SetBlendFlags( plasmaLayer->GetBlendFlags() | hsGMatState::kBlendNoTexAlpha ); if( bitmapPB->GetInt( kBmpInvertAlpha ) ) bd.invertAlpha = true; // Texture quality if( bitmapPB->GetInt( kBmpNonCompressed ) ) texFlags |= plBitmap::kForceNonCompressed; if( bitmapPB->GetInt( kBmpNoDiscard ) ) texFlags |= plBitmap::kDontThrowAwayImage; switch( bitmapPB->GetInt( kBmpScaling ) ) { case kScalingHalf: texFlags |= plBitmap::kHalfSize; break; case kScalingNone: texFlags |= plBitmap::kNoMaxSize; break; } // Mip map filtering. if( bitmapPB->GetInt( kBmpNoFilter ) ) texFlags |= plBitmap::kForceOneMipLevel; if( bitmapPB->GetInt( kBmpMipBias ) ) { plasmaLayer->SetZFlags( plasmaLayer->GetZFlags() | hsGMatState::kZLODBias ); plasmaLayer->SetLODBias( bitmapPB->GetFloat( kBmpMipBiasAmt, fConverterUtils.GetTime( fInterface ) ) ); } float sig = bitmapPB->GetFloat( kBmpMipBlur ); bd.texFlags = texFlags; bd.sig = sig; // Get detail parameters if( bitmapPB->GetInt( kBmpUseDetail ) ) { // TODO: be smarter if( blendFlags & hsGMatState::kBlendAdd ) bd.createFlags |= plMipmap::kCreateDetailAdd; else if( blendFlags & hsGMatState::kBlendMult ) bd.createFlags |= plMipmap::kCreateDetailMult; else bd.createFlags |= plMipmap::kCreateDetailAlpha; bd.detailDropoffStart = float(bitmapPB->GetInt(kBmpDetailStartSize)) / 100.f; bd.detailDropoffStop = float(bitmapPB->GetInt(kBmpDetailStopSize)) / 100.f; bd.detailMax = float(bitmapPB->GetInt(kBmpDetailStartOpac)) / 100.f; bd.detailMin = float(bitmapPB->GetInt(kBmpDetailStopOpac)) / 100.f; } // Get max export dimension (since the function we eventually call // expects the max of the two dimensions, we figure that out here and // pass it on) bd.maxDimension = bitmapPB->GetInt( kBmpExportWidth ); int expHt = bitmapPB->GetInt( kBmpExportHeight ); if( bd.maxDimension < expHt ) bd.maxDimension = expHt; int clipID = 0, w; for( clipID = 0, w = bi->Width(); w > bd.maxDimension; w >>= 1, clipID++ ); // Do the UV gen (before we do texture, since it could modify the bitmapData struct) IProcessUVGen( layer, plasmaLayer, &bd, preserveUVOffset ); // Create the texture. If it works, assign it to the layer if( ( plasmaLayer = IAssignTexture( &bd, maxNode, plasmaLayer, upperLayer, clipID ) ) == nil ) return nil; // All done! return (plLayerInterface *)plasmaLayer; hsGuardEnd; }
// --[ Method ]--------------------------------------------------------------- // // - Class : CStravaganzaMaxTools // // - prototype : bool BuildShaders() // // - Purpose : Builds the shader list from MAX's materials. // Preview mode requires texture files to be stored with full // path in order to load them. When we export, we only store the // filename. Another thing is that in the export mode, we copy // all textures into the path specified by the user if that // option is checked. // // ----------------------------------------------------------------------------- bool CStravaganzaMaxTools::BuildShaders() { std::vector<Mtl*>::iterator it; assert(m_vecShaders.empty()); if(!m_bPreview && m_bCopyTextures && m_strTexturePath == "") { CLogger::NotifyWindow("Textures won't be copied\nSpecify a valid output texture path first"); } LOG.Write("\n\n-Building shaders: "); for(it = m_vecMaterials.begin(); it != m_vecMaterials.end(); ++it) { Mtl* pMaxMaterial = *it; assert(pMaxMaterial); LOG.Write("\n %s", pMaxMaterial->GetName().data()); CShaderStandard* pShaderStd = new CShaderStandard; pShaderStd->SetName(pMaxMaterial->GetName().data()); // Properties StdMat2 *pMaxStandardMtl = NULL; StdMat2 *pMaxBakedMtl = NULL; float fAlpha; if(pMaxMaterial->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { pMaxStandardMtl = (StdMat2 *)pMaxMaterial; } else if(pMaxMaterial->ClassID() == Class_ID(BAKE_SHELL_CLASS_ID, 0)) { pMaxStandardMtl = (StdMat2 *)pMaxMaterial->GetSubMtl(0); pMaxBakedMtl = (StdMat2 *)pMaxMaterial->GetSubMtl(1); } if(pMaxStandardMtl) { // Standard material fAlpha = pMaxStandardMtl->GetOpacity(0); Shader* pMaxShader = pMaxStandardMtl->GetShader(); CVector4 v4Specular = ColorToVector4(pMaxStandardMtl->GetSpecular(0), 0.0f) * pMaxShader->GetSpecularLevel(0, 0); pShaderStd->SetAmbient (ColorToVector4(pMaxStandardMtl->GetAmbient(0), 0.0f)); pShaderStd->SetDiffuse (ColorToVector4(pMaxStandardMtl->GetDiffuse(0), fAlpha)); pShaderStd->SetSpecular (v4Specular); pShaderStd->SetShininess(pMaxShader->GetGlossiness(0, 0) * 128.0f); if(pMaxStandardMtl->GetTwoSided() == TRUE) { pShaderStd->SetTwoSided(true); } // Need to cast to StdMat2 in order to get access to IsFaceted(). // ¿Is StdMat2 always the interface for standard materials? if(((StdMat2*)pMaxStandardMtl)->IsFaceted()) { pShaderStd->SetFaceted(true); } if(pMaxStandardMtl->GetWire() == TRUE) { pShaderStd->SetPostWire(true); pShaderStd->SetWireLineThickness(pMaxStandardMtl->GetWireSize(0)); } } else { // Material != Standard fAlpha = 1.0f; // pMaxMaterial->GetXParency(); pShaderStd->SetAmbient (ColorToVector4(pMaxMaterial->GetAmbient(), 0.0f)); pShaderStd->SetDiffuse (ColorToVector4(pMaxMaterial->GetDiffuse(), fAlpha)); pShaderStd->SetSpecular (CVector4(0.0f, 0.0f, 0.0f, 0.0f)); pShaderStd->SetShininess(0.0f); } // Layers if(!pMaxStandardMtl) { m_vecShaders.push_back(pShaderStd); continue; } bool bDiffuseMap32Bits = false; StdMat2 *pStandardMtl; for(int i = 0; i < 3; i++) { int nMap; pStandardMtl = pMaxStandardMtl; // 0 = diffuse, 1 == bump, 2 = lightmap (self illumination slot) or envmap (reflection slot) if(i == 0) { nMap = ID_DI; } else if(i == 1) { nMap = ID_BU; // If its a baked material, get the bump map from there if(pMaxBakedMtl) { pStandardMtl = pMaxBakedMtl; } } else if(i == 2) { bool bBaked = false; // If its a baked material, get the map2 (lightmap) from there if(pMaxBakedMtl) { if(pMaxBakedMtl->GetMapState(ID_SI) == MAXMAPSTATE_ENABLED) { bBaked = true; nMap = ID_SI; pStandardMtl = pMaxBakedMtl; } } if(!bBaked) { if(pStandardMtl->GetMapState(ID_SI) == MAXMAPSTATE_ENABLED) { nMap = ID_SI; } else { nMap = ID_RL; } } } // Check validity if(pStandardMtl->GetMapState(nMap) != MAXMAPSTATE_ENABLED) { if(i == 0) { LOG.Write("\n No diffuse. Skipping."); break; } continue; } Texmap* pMaxTexmap = pStandardMtl->GetSubTexmap(nMap); if(!pMaxTexmap) { if(i == 0) { LOG.Write("\n No diffuse. Skipping."); break; } continue; } // Get texmaps std::vector<std::string> vecTextures, vecPaths; CShaderStandard::SLayerInfo layerInfo; CShaderStandard::SBitmapInfo bitmapInfo; if(pMaxTexmap->ClassID() == Class_ID(BMTEX_CLASS_ID, 0)) { BitmapTex* pMaxBitmapTex = (BitmapTex*)pMaxTexmap; Bitmap* pMaxBitmap = pMaxBitmapTex->GetBitmap(SECONDS_TO_TICKS(m_fStartTime)); StdUVGen* pMaxUVGen = pMaxBitmapTex->GetUVGen(); if(!pMaxBitmap) { if(i == 0) { LOG.Write("\n Invalid diffuse. Skipping."); break; } continue; } assert(pMaxUVGen); BitmapInfo bi = pMaxBitmap->Storage()->bi; // bi.Name() returns the full path // bi.Filename() returns just the filename vecTextures.push_back(bi.Filename()); vecPaths. push_back(bi.Name()); LOG.Write("\n Bitmap %s", vecTextures[0].data()); // Check if diffuse texture has alpha channel if(i == 0) { CBitmap bitmap; CInputFile bitmapFile; if(!bitmapFile.Open(bi.Name(), false)) { CLogger::NotifyWindow("WARNING - CStravaganzaMaxTools::BuildShaders():\nUnable to load file %s", bi.Name()); } else { if(!bitmap.Load(&bitmapFile, GetFileExt(bi.Name()))) { CLogger::NotifyWindow("WARNING - CStravaganzaMaxTools::BuildShaders():\nUnable to load bitmap %s", bi.Name()); } else { if(bitmap.GetBpp() == 32) { bDiffuseMap32Bits = true; LOG.Write(" (with alpha channel)"); } bitmap.Free(); } bitmapFile.Close(); } } // Ok, copy properties layerInfo.texInfo.bLoop = false; layerInfo.texInfo.eTextureType = UtilGL::Texturing::CTexture::TEXTURE2D; bitmapInfo.strFile = m_bPreview ? bi.Name() : bi.Filename(); bitmapInfo.bTile = ((pMaxUVGen->GetTextureTiling() & (U_WRAP | V_WRAP)) == (U_WRAP | V_WRAP)) ? true : false; bitmapInfo.fSeconds = 0.0f; bitmapInfo.bForceFiltering = false; bitmapInfo.eFilter = UtilGL::Texturing::FILTER_TRILINEAR; // won't be used (forcefiltering = false) layerInfo.texInfo.m_vecBitmaps.push_back(bitmapInfo); layerInfo.eTexEnv = nMap == ID_RL ? CShaderStandard::TEXENV_ADD : CShaderStandard::TEXENV_MODULATE; layerInfo.eUVGen = pMaxUVGen->GetCoordMapping(0) == UVMAP_SPHERE_ENV ? CShaderStandard::UVGEN_ENVMAPPING : CShaderStandard::UVGEN_EXPLICITMAPPING; layerInfo.uMapChannel = pMaxUVGen->GetMapChannel(); layerInfo.v3ScrollSpeed = CVector3(0.0f, 0.0f, 0.0f); layerInfo.v3RotationSpeed = CVector3(0.0f, 0.0f, 0.0f); layerInfo.v3ScrollOffset = CVector3(pMaxUVGen->GetUOffs(0), pMaxUVGen->GetVOffs(0), 0.0f); layerInfo.v3RotationOffset = CVector3(pMaxUVGen->GetUAng(0), pMaxUVGen->GetVAng(0), pMaxUVGen->GetWAng(0)); } else if(pMaxTexmap->ClassID() == Class_ID(ACUBIC_CLASS_ID, 0)) { ACubic* pMaxCubic = (ACubic*)pMaxTexmap; IParamBlock2* pBlock = pMaxCubic->pblock; Interval validRange = m_pMaxInterface->GetAnimRange(); for(int nFace = 0; nFace < 6; nFace++) { int nMaxFace; switch(nFace) { case 0: nMaxFace = 3; break; case 1: nMaxFace = 2; break; case 2: nMaxFace = 1; break; case 3: nMaxFace = 0; break; case 4: nMaxFace = 5; break; case 5: nMaxFace = 4; break; } TCHAR *name; pBlock->GetValue(acubic_bitmap_names, TICKS_TO_SECONDS(m_fStartTime), name, validRange, nMaxFace); vecPaths.push_back(name); CStr path, file, ext; SplitFilename(CStr(name), &path, &file, &ext); std::string strFile = std::string(file.data()) + ext.data(); vecTextures.push_back(strFile); bitmapInfo.strFile = m_bPreview ? name : strFile; bitmapInfo.bTile = false; bitmapInfo.fSeconds = 0.0f; bitmapInfo.bForceFiltering = false; bitmapInfo.eFilter = UtilGL::Texturing::FILTER_TRILINEAR; layerInfo.texInfo.m_vecBitmaps.push_back(bitmapInfo); } layerInfo.texInfo.bLoop = false; layerInfo.texInfo.eTextureType = UtilGL::Texturing::CTexture::TEXTURECUBEMAP; layerInfo.eTexEnv = nMap == ID_RL ? CShaderStandard::TEXENV_ADD : CShaderStandard::TEXENV_MODULATE; layerInfo.eUVGen = CShaderStandard::UVGEN_ENVMAPPING; layerInfo.uMapChannel = 0; layerInfo.v3ScrollSpeed = CVector3(0.0f, 0.0f, 0.0f); layerInfo.v3RotationSpeed = CVector3(0.0f, 0.0f, 0.0f); layerInfo.v3ScrollOffset = CVector3(0.0f, 0.0f, 0.0f); layerInfo.v3RotationOffset = CVector3(0.0f, 0.0f, 0.0f); } else { if(i == 0) { LOG.Write("\n No diffuse. Skipping."); break; } continue; } if(!m_bPreview && m_bCopyTextures && m_strTexturePath != "") { for(int nTex = 0; nTex != vecTextures.size(); nTex++) { // Copy textures into the specified folder std::string strDestPath = m_strTexturePath; if(strDestPath[strDestPath.length() - 1] != '\\') { strDestPath.append("\\", 1); } strDestPath.append(vecTextures[nTex]); if(!CopyFile(vecPaths[nTex].data(), strDestPath.data(), FALSE)) { CLogger::NotifyWindow("Unable to copy %s to\n%s", vecPaths[i], strDestPath.data()); } } } if(layerInfo.eUVGen == CShaderStandard::UVGEN_ENVMAPPING && i == 1) { CLogger::NotifyWindow("%s : Bump with spheremapping not supported", pShaderStd->GetName().data()); } else { // Add layer switch(i) { case 0: pShaderStd->SetLayer(CShaderStandard::LAYER_DIFF, layerInfo); break; case 1: pShaderStd->SetLayer(CShaderStandard::LAYER_BUMP, layerInfo); break; case 2: pShaderStd->SetLayer(CShaderStandard::LAYER_MAP2, layerInfo); break; } } } // ¿Do we need blending? if(ARE_EQUAL(fAlpha, 1.0f) && !bDiffuseMap32Bits) { pShaderStd->SetBlendSrcFactor(UtilGL::States::BLEND_ONE); pShaderStd->SetBlendDstFactor(UtilGL::States::BLEND_ZERO); } else { pShaderStd->SetBlendSrcFactor(UtilGL::States::BLEND_SRCALPHA); pShaderStd->SetBlendDstFactor(UtilGL::States::BLEND_INVSRCALPHA); } // Add shader m_vecShaders.push_back(pShaderStd); } return true; }
//---------------------------------------------------------------------------- void SceneBuilder::ConvertMaterial (Mtl &mtl, MtlTree &mtlTree) { // 光照属性 PX2::Shine *shine = new0 PX2::Shine; Color color = mtl.GetAmbient(); float alpha = 1.0f - mtl.GetXParency(); shine->Ambient = PX2::Float4(color.r, color.g, color.b, 1.0f); color = mtl.GetDiffuse(); shine->Diffuse = PX2::Float4(color.r, color.g, color.b, alpha); color = mtl.GetSpecular(); float shininess = mtl.GetShininess()*2.0f; shine->Specular = PX2::Float4(color.r, color.g, color.b, shininess); const char *name = (const char*)mtl.GetName(); shine->SetName(name); mtlTree.SetShine(shine); bool IsDirect9Shader = false; if (mtl.ClassID() == Class_ID(CMTL_CLASS_ID, 0) || mtl.ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { StdMat2 *stdMat2 = (StdMat2*)(&mtl); Interval valid = FOREVER; stdMat2->Update(mTimeStart, valid); std::string strName(stdMat2->GetName()); bool doubleSide = (stdMat2->GetTwoSided()==1); char strBitMapName[256]; memset(strBitMapName, 0, 256*sizeof(char)); std::string resourcePath; PX2::Shader::SamplerFilter filter = PX2::Shader::SF_LINEAR_LINEAR; PX2::Shader::SamplerCoordinate uvCoord = PX2::Shader::SC_REPEAT; PX2_UNUSED(uvCoord); if (stdMat2->MapEnabled(ID_DI)) { BitmapTex *tex = (BitmapTex*)stdMat2->GetSubTexmap(ID_DI); BitmapInfo bI; const char *mapName = tex->GetMapName(); TheManager->GetImageInfo(&bI, mapName); strcpy(strBitMapName, bI.Name()); std::string fullName = std::string(strBitMapName); std::string::size_type sizeT = fullName.find_first_not_of(mSettings->SrcRootDir); resourcePath = std::string(strBitMapName).substr(sizeT); StdUVGen* uvGen = tex->GetUVGen(); PX2_UNUSED(uvGen); int filType = tex->GetFilterType(); switch (filType) { case FILTER_PYR: filter = PX2::Shader::SF_LINEAR_LINEAR; break; case FILTER_SAT: filter = PX2::Shader::SF_NEAREST; break; default: break; } } else { sprintf(strBitMapName, "%s/%s", mSettings->SrcRootDir, PX2_DEFAULT_TEXTURE); resourcePath = PX2_DEFAULT_TEXTURE; } PX2::Texture2D *tex2d = PX2::DynamicCast<PX2::Texture2D>( PX2::ResourceManager::GetSingleton().BlockLoad(strBitMapName)); tex2d->SetResourcePath(resourcePath); if (tex2d) { PX2::Texture2DMaterial *tex2dMtl = new0 PX2::Texture2DMaterial(filter, uvCoord, uvCoord); if (doubleSide) { tex2dMtl->GetCullProperty(0, 0)->Enabled = false; } PX2::MaterialInstance *instance = tex2dMtl->CreateInstance(tex2d); mtlTree.SetMaterialInstance(instance); } else { PX2::VertexColor4Material *vcMtl = new0 PX2::VertexColor4Material(); PX2::MaterialInstance *instance = vcMtl->CreateInstance(); mtlTree.SetMaterialInstance(instance); } } else if (mtl.ClassID() == Class_ID(MULTI_CLASS_ID, 0)) { } else if (mtl.ClassID() == DIRECTX_9_SHADER_CLASS_ID) { IsDirect9Shader = true; IDxMaterial* dxMtl = (IDxMaterial*)mtl.GetInterface(IDXMATERIAL_INTERFACE); char *effectName = dxMtl->GetEffectFilename(); IParamBlock2 *paramBlock = mtl.GetParamBlock(0); std::string outPath; std::string outBaseName; std::string outExtention; PX2::StringHelp::SplitFullFilename(effectName, outPath, outBaseName, outExtention); PX2::ShinePtr shineStandard = new0 PX2::Shine(); bool alphaVertex = false; PX2::Texture2DPtr diffTex; bool normalEnable = false; PX2::Texture2DPtr normalTex; float normalScale = 0.0f; bool specEnable = false; PX2::Texture2DPtr specTex; float specPower = 0.0f; bool reflectEnable = false; PX2::TextureCubePtr reflectTex; float reflectPower = 0.0f; bool doubleSide = false; int blendMode = 2; ParamBlockDesc2 *paramDesc = 0; int numParam = 0; if (paramBlock) { paramDesc = paramBlock->GetDesc(); numParam = paramBlock->NumParams(); ParamType2 paramType; for (int i=0; i<numParam; i++) { std::string parmName; PX2::Float4 color4 = PX2::Float4(0.0f, 0.0f, 0.0f, 0.0f); PX2::Float3 color3 = PX2::Float3(0.0f, 0.0f, 0.0f); float floatValue = 0.0f; bool boolValue = false; float *floatTable = 0; int intValue = 0; std::string str; PX2::Texture2D *tex2d = 0; paramType = paramBlock->GetParameterType((ParamID)i); if (TYPE_STRING == paramType) ConvertStringAttrib(paramBlock, i, parmName, str); else if (TYPE_FLOAT == paramType) ConvertFloatAttrib(paramBlock, i, parmName, floatValue); else if (TYPE_INT == paramType) ConvertIntAttrib(paramBlock, i, parmName, intValue); else if (TYPE_RGBA == paramType) ConvertColorAttrib(paramBlock, i, parmName, color4, i); else if (TYPE_POINT3 == paramType) ConvertPoint3Attrib(paramBlock, i, parmName, color3); else if (TYPE_POINT4 == paramType) ConvertPoint4Attrib(paramBlock, i, parmName, color4); else if (TYPE_BOOL == paramType) ConvertBoolAttrib(paramBlock, i, parmName, boolValue); else if (TYPE_FLOAT_TAB == paramType) ConvertFloatTabAttrib(paramBlock, i, parmName, floatTable); else if (TYPE_BITMAP == paramType) ConvertBitMapAttrib(paramBlock, i, parmName, tex2d); else if (TYPE_FRGBA ==paramType) ConvertFRGBAAttrib(paramBlock, i, parmName, color4); // shine if (parmName == "gBlendMode") { blendMode = intValue; } else if (parmName == "gShineEmissive") { shineStandard->Emissive = color4; } else if (parmName == "gShineAmbient") { shineStandard->Ambient = color4; } else if (parmName == "gShineDiffuse") { shineStandard->Diffuse = color4; } // alpha vertex else if (parmName == "gAlphaVertex") { alphaVertex = boolValue; } // diffuse else if (parmName == "gDiffuseTexture") { diffTex = tex2d; } // normal else if (parmName == "gNormalEnable") { normalEnable = boolValue; } else if (parmName == "gNormalTexture") { normalTex = tex2d; } else if (parmName == "gNormalScale") { normalScale = floatValue; } // specular else if (parmName == "gSpecularEnable") { specEnable = boolValue; } else if (parmName == "gSpecularTexture") { specTex = tex2d; } else if (parmName == "gSpecularPower") { specPower = floatValue; } // reflect else if (parmName == "gReflectionEnable") { reflectEnable = boolValue; } else if (parmName == "gReflectTexture") { //reflectTex = tex2d; } else if (parmName == "gReflectPower") { reflectPower = floatValue; } // other else if (parmName == "gDoubleSide") { doubleSide = boolValue; } } } PX2::MaterialInstance *inst = 0; PX2::StandardMaterial *standardMtl = 0; PX2::StandardESMaterial_Default *standardESMtl_D = 0; PX2::StandardESMaterial_Specular *standardESMtl_S = 0; if (outBaseName == "Standard") { char mtlName[256]; memset(mtlName, 0, 256*sizeof(char)); sprintf(mtlName, "%s/%s", mSettings->DstRootDir, "Data/mtls/Standard.pxfx"); standardMtl = new0 PX2::StandardMaterial(mtlName); } else if (outBaseName == "StandardES") { if (false == specEnable) { standardESMtl_D = new0 PX2::StandardESMaterial_Default(); if (0 == blendMode) { standardESMtl_D->GetAlphaProperty(0, 0)->BlendEnabled = false; standardESMtl_D->GetAlphaProperty(0, 0)->CompareEnabled = false; } else if (1 == blendMode) { standardESMtl_D->GetAlphaProperty(0, 0)->BlendEnabled = true; } else if (2 == blendMode) { standardESMtl_D->GetAlphaProperty(0, 0)->BlendEnabled = false; standardESMtl_D->GetAlphaProperty(0, 0)->CompareEnabled = true; standardESMtl_D->GetAlphaProperty(0, 0)->Compare = PX2::AlphaProperty::CM_GEQUAL; standardESMtl_D->GetAlphaProperty(0, 0)->Reference = 0.2f; } } else { char mtlName[256]; memset(mtlName, 0, 256*sizeof(char)); sprintf(mtlName, "%s/%s", mSettings->DstRootDir, "Data/mtls/StandardES_Specular.pxfx"); standardESMtl_S = new0 PX2::StandardESMaterial_Specular(mtlName); } } if (standardMtl && diffTex) { if (doubleSide) { standardMtl->GetCullProperty(0, 0)->Enabled = false; } inst = standardMtl->CreateInstance(diffTex, alphaVertex, normalEnable, normalTex, normalScale, specEnable, specTex, specPower, 0, shineStandard); } else if (standardESMtl_D && diffTex) { if (doubleSide) { standardESMtl_D->GetCullProperty(0, 0)->Enabled = false; } inst = standardESMtl_D->CreateInstance(diffTex, 0, shineStandard); } else if (standardESMtl_S && diffTex && specTex) { if (doubleSide) { standardESMtl_S->GetCullProperty(0, 0)->Enabled = false; } inst = standardESMtl_S->CreateInstance(diffTex, specTex, specPower, 0, shineStandard); } if (inst) { mtlTree.SetMaterialInstance(inst); } else { PX2::MaterialInstance *instance = PX2::VertexColor4Material::CreateUniqueInstance(); mtlTree.SetMaterialInstance(instance); } } else { PX2::VertexColor4Material *vcMtl = new0 PX2::VertexColor4Material(); PX2::MaterialInstance *instance = vcMtl->CreateInstance(); mtlTree.SetMaterialInstance(instance); } // 对子材质进行处理 if (IsDirect9Shader) return; int mQuantity = mtl.NumSubMtls(); // Class_ID(MULTI_CLASS_ID, 0) if (mQuantity > 0) { mtlTree.SetMChildQuantity(mQuantity); for (int i=0; i<mQuantity; i++) { Mtl *subMtl = 0; subMtl = mtl.GetSubMtl(i); if (subMtl) { ConvertMaterial(*subMtl, mtlTree.GetMChild(i)); } } } }