//------------------------------------------------------------------------------- int CMaterialManager::CreateMaterial( AssetHelper::MeshHelper* pcMesh,const aiMesh* pcSource) { #if 1//??? ai_assert(0 != pcMesh); ai_assert(0 != pcSource); // ID3DXFROMWINEBuffer* piBuffer; // extract all properties from the ASSIMP material structure const aiMaterial* pcMat = mr->GetAsset()->pcScene->mMaterials[pcSource->mMaterialIndex]; // // DIFFUSE COLOR -------------------------------------------------- // if(AI_SUCCESS != aiGetMaterialColor(pcMat,AI_MATKEY_COLOR_DIFFUSE, (aiColor4D*)&pcMesh->vDiffuseColor)) { pcMesh->vDiffuseColor.x = 1.0f; pcMesh->vDiffuseColor.y = 1.0f; pcMesh->vDiffuseColor.z = 1.0f; pcMesh->vDiffuseColor.w = 1.0f; } // // SPECULAR COLOR -------------------------------------------------- // if(AI_SUCCESS != aiGetMaterialColor(pcMat,AI_MATKEY_COLOR_SPECULAR, (aiColor4D*)&pcMesh->vSpecularColor)) { pcMesh->vSpecularColor.x = 1.0f; pcMesh->vSpecularColor.y = 1.0f; pcMesh->vSpecularColor.z = 1.0f; pcMesh->vSpecularColor.w = 1.0f; } // // AMBIENT COLOR -------------------------------------------------- // if(AI_SUCCESS != aiGetMaterialColor(pcMat,AI_MATKEY_COLOR_AMBIENT, (aiColor4D*)&pcMesh->vAmbientColor)) { pcMesh->vAmbientColor.x = 0.0f; pcMesh->vAmbientColor.y = 0.0f; pcMesh->vAmbientColor.z = 0.0f; pcMesh->vAmbientColor.w = 1.0f; } // // EMISSIVE COLOR ------------------------------------------------- // if(AI_SUCCESS != aiGetMaterialColor(pcMat,AI_MATKEY_COLOR_EMISSIVE, (aiColor4D*)&pcMesh->vEmissiveColor)) { pcMesh->vEmissiveColor.x = 0.0f; pcMesh->vEmissiveColor.y = 0.0f; pcMesh->vEmissiveColor.z = 0.0f; pcMesh->vEmissiveColor.w = 1.0f; } // // Opacity -------------------------------------------------------- // if(AI_SUCCESS != aiGetMaterialFloat(pcMat,AI_MATKEY_OPACITY,&pcMesh->fOpacity)) { pcMesh->fOpacity = 1.0f; } // // Shading Model -------------------------------------------------- // bool bDefault = false; if(AI_SUCCESS != aiGetMaterialInteger(pcMat,AI_MATKEY_SHADING_MODEL,(int*)&pcMesh->eShadingMode )) { bDefault = true; pcMesh->eShadingMode = aiShadingMode_Gouraud; } // // Shininess ------------------------------------------------------ // if(AI_SUCCESS != aiGetMaterialFloat(pcMat,AI_MATKEY_SHININESS,&pcMesh->fShininess)) { // assume 15 as default shininess pcMesh->fShininess = 15.0f; } else if (bDefault)pcMesh->eShadingMode = aiShadingMode_Phong; // // Shininess strength ------------------------------------------------------ // if(AI_SUCCESS != aiGetMaterialFloat(pcMat,AI_MATKEY_SHININESS_STRENGTH,&pcMesh->fSpecularStrength)) { // assume 1.0 as default shininess strength pcMesh->fSpecularStrength = 1.0f; } aiString szPath; aiTextureMapMode mapU(aiTextureMapMode_Wrap),mapV(aiTextureMapMode_Wrap); bool bib =false; if (pcSource->mTextureCoords[0]) { // // DIFFUSE TEXTURE ------------------------------------------------ // if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_DIFFUSE(0),&szPath)) { LoadTexture(&pcMesh->piDiffuseTexture,&szPath); aiGetMaterialInteger(pcMat,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0),(int*)&mapU); aiGetMaterialInteger(pcMat,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0),(int*)&mapV); } // // SPECULAR TEXTURE ------------------------------------------------ // if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_SPECULAR(0),&szPath)) { LoadTexture(&pcMesh->piSpecularTexture,&szPath); } // // OPACITY TEXTURE ------------------------------------------------ // if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_OPACITY(0),&szPath)) { LoadTexture(&pcMesh->piOpacityTexture,&szPath); } else { int flags = aiTextureFlags_IgnoreAlpha;//???0; aiGetMaterialInteger(pcMat,AI_MATKEY_TEXFLAGS_DIFFUSE(0),&flags); // try to find out whether the diffuse texture has any // non-opaque pixels. If we find a few, use it as opacity texture if ((pcMesh->piDiffuseTexture!=-1) && !(flags & aiTextureFlags_IgnoreAlpha) && HasAlphaPixels(pcMesh->piDiffuseTexture)) { int iVal; // NOTE: This special value is set by the tree view if the user // manually removes the alpha texture from the view ... if (AI_SUCCESS != aiGetMaterialInteger(pcMat,"no_a_from_d",0,0,&iVal)) { pcMesh->piOpacityTexture = pcMesh->piDiffuseTexture; // pcMesh->piOpacityTexture->AddRef(); } } } // // AMBIENT TEXTURE ------------------------------------------------ // if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_AMBIENT(0),&szPath)) { LoadTexture(&pcMesh->piAmbientTexture,&szPath); } // // EMISSIVE TEXTURE ------------------------------------------------ // if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_EMISSIVE(0),&szPath)) { LoadTexture(&pcMesh->piEmissiveTexture,&szPath); } // // Shininess TEXTURE ------------------------------------------------ // if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_SHININESS(0),&szPath)) { LoadTexture(&pcMesh->piShininessTexture,&szPath); } // // Lightmap TEXTURE ------------------------------------------------ // if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_LIGHTMAP(0),&szPath)) { LoadTexture(&pcMesh->piLightmapTexture,&szPath); } // // NORMAL/HEIGHT MAP ------------------------------------------------ // bool bHM = false; if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_NORMALS(0),&szPath)) { LoadTexture(&pcMesh->piNormalTexture,&szPath); } else { if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_HEIGHT(0),&szPath)) { LoadTexture(&pcMesh->piNormalTexture,&szPath); } else bib = true; bHM = true; } // normal/height maps are sometimes mixed up. Try to detect the type // of the texture automatically if (pcMesh->piNormalTexture!=-1) { HMtoNMIfNecessary(pcMesh->piNormalTexture, &pcMesh->piNormalTexture,bHM); } } // check whether a global background texture is contained // in this material. Some loaders set this value ... if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_GLOBAL_BACKGROUND_IMAGE,&szPath)) { // CBackgroundPainter::Instance().SetTextureBG(szPath.data); } // BUGFIX: If the shininess is 0.0f disable phong lighting // This is a workaround for some meshes in the DX SDK (e.g. tiny.x) // FIX: Added this check to the x-loader, but the line remains to // catch other loader doing the same ... if (0.0f == pcMesh->fShininess){ pcMesh->eShadingMode = aiShadingMode_Gouraud; } int two_sided = 0; aiGetMaterialInteger(pcMat,AI_MATKEY_TWOSIDED,&two_sided); pcMesh->twosided = (two_sided != 0); // check whether we have already a material using the same // shader. This will decrease loading time rapidly ... for (unsigned int i = 0; i < mr->GetAsset()->pcScene->mNumMeshes;++i) { if (mr->GetAsset()->pcScene->mMeshes[i] == pcSource) { break; } AssetHelper::MeshHelper* pc = mr->GetAsset()->apcMeshes[i]; if ((pcMesh->piDiffuseTexture !=-1 ? true : false) != (pc->piDiffuseTexture !=-1 ? true : false)) continue; if ((pcMesh->piSpecularTexture !=-1 ? true : false) != (pc->piSpecularTexture !=-1 ? true : false)) continue; if ((pcMesh->piAmbientTexture !=-1 ? true : false) != (pc->piAmbientTexture !=-1 ? true : false)) continue; if ((pcMesh->piEmissiveTexture !=-1 ? true : false) != (pc->piEmissiveTexture !=-1 ? true : false)) continue; if ((pcMesh->piNormalTexture !=-1 ? true : false) != (pc->piNormalTexture !=-1 ? true : false)) continue; if ((pcMesh->piOpacityTexture !=-1 ? true : false) != (pc->piOpacityTexture !=-1 ? true : false)) continue; if ((pcMesh->piShininessTexture !=-1 ? true : false) != (pc->piShininessTexture !=-1 ? true : false)) continue; if ((pcMesh->piLightmapTexture !=-1 ? true : false) != (pc->piLightmapTexture !=-1 ? true : false)) continue; if ((pcMesh->eShadingMode != aiShadingMode_Gouraud ? true : false) != (pc->eShadingMode != aiShadingMode_Gouraud ? true : false)) continue; if ((pcMesh->fOpacity != 1.0f ? true : false) != (pc->fOpacity != 1.0f ? true : false)) continue; if (pcSource->HasBones() != mr->GetAsset()->pcScene->mMeshes[i]->HasBones()) continue; // we can reuse this material if (pc->piEffect!=-1) { pcMesh->piEffect = pc->piEffect; pc->bSharedFX = pcMesh->bSharedFX = true; // pcMesh->piEffect->AddRef(); return 2; } } m_iShaderCount++; //if(mr->m_piDefaultEffect==-1) if(0) { typedef struct _D3DXFROMWINEMACRO { LPCSTR Name; LPCSTR Definition; } D3DXFROMWINEMACRO, *LPD3DXFROMWINEMACRO; D3DXFROMWINEMACRO sMacro[64]; // build macros for the HLSL compiler unsigned int iCurrent = 0; if (pcMesh->piDiffuseTexture!=-1) { sMacro[iCurrent].Name = "AV_DIFFUSE_TEXTURE"; sMacro[iCurrent].Definition = "1"; ++iCurrent; if (mapU == aiTextureMapMode_Wrap) sMacro[iCurrent].Name = "AV_WRAPU"; else if (mapU == aiTextureMapMode_Mirror) sMacro[iCurrent].Name = "AV_MIRRORU"; else // if (mapU == aiTextureMapMode_Clamp) sMacro[iCurrent].Name = "AV_CLAMPU"; sMacro[iCurrent].Definition = "1"; ++iCurrent; if (mapV == aiTextureMapMode_Wrap) sMacro[iCurrent].Name = "AV_WRAPV"; else if (mapV == aiTextureMapMode_Mirror) sMacro[iCurrent].Name = "AV_MIRRORV"; else // if (mapV == aiTextureMapMode_Clamp) sMacro[iCurrent].Name = "AV_CLAMPV"; sMacro[iCurrent].Definition = "1"; ++iCurrent; } if (pcMesh->piSpecularTexture!=-1) { sMacro[iCurrent].Name = "AV_SPECULAR_TEXTURE"; sMacro[iCurrent].Definition = "1"; ++iCurrent; } if (pcMesh->piAmbientTexture!=-1) { sMacro[iCurrent].Name = "AV_AMBIENT_TEXTURE"; sMacro[iCurrent].Definition = "1"; ++iCurrent; } if (pcMesh->piEmissiveTexture!=-1) { sMacro[iCurrent].Name = "AV_EMISSIVE_TEXTURE"; sMacro[iCurrent].Definition = "1"; ++iCurrent; } char buff[32]; if (pcMesh->piLightmapTexture!=-1) { sMacro[iCurrent].Name = "AV_LIGHTMAP_TEXTURE"; sMacro[iCurrent].Definition = "1"; ++iCurrent; int idx; if(AI_SUCCESS == aiGetMaterialInteger(pcMat,AI_MATKEY_UVWSRC_LIGHTMAP(0),&idx) && idx >= 1 && pcSource->mTextureCoords[idx]) { sMacro[iCurrent].Name = "AV_TWO_UV"; sMacro[iCurrent].Definition = "1"; ++iCurrent; sMacro[iCurrent].Definition = "IN.TexCoord1"; } else sMacro[iCurrent].Definition = "IN.TexCoord0"; sMacro[iCurrent].Name = "AV_LIGHTMAP_TEXTURE_UV_COORD"; ++iCurrent;float f= 1.f; aiGetMaterialFloat(pcMat,AI_MATKEY_TEXBLEND_LIGHTMAP(0),&f); stx_snprintf(buff,32,"%f",f); sMacro[iCurrent].Name = "LM_STRENGTH"; sMacro[iCurrent].Definition = buff; ++iCurrent; } if ((pcMesh->piNormalTexture!=-1) && !bib) { sMacro[iCurrent].Name = "AV_NORMAL_TEXTURE"; sMacro[iCurrent].Definition = "1"; ++iCurrent; } if (pcMesh->piOpacityTexture!=-1) { sMacro[iCurrent].Name = "AV_OPACITY_TEXTURE"; sMacro[iCurrent].Definition = "1"; ++iCurrent; if (pcMesh->piOpacityTexture == pcMesh->piDiffuseTexture) { sMacro[iCurrent].Name = "AV_OPACITY_TEXTURE_REGISTER_MASK"; sMacro[iCurrent].Definition = "a"; ++iCurrent; } else { sMacro[iCurrent].Name = "AV_OPACITY_TEXTURE_REGISTER_MASK"; sMacro[iCurrent].Definition = "r"; ++iCurrent; } } if (pcMesh->eShadingMode != aiShadingMode_Gouraud && !mr->m_sOptions.bNoSpecular) { sMacro[iCurrent].Name = "AV_SPECULAR_COMPONENT"; sMacro[iCurrent].Definition = "1"; ++iCurrent; if (pcMesh->piShininessTexture!=-1) { sMacro[iCurrent].Name = "AV_SHININESS_TEXTURE"; sMacro[iCurrent].Definition = "1"; ++iCurrent; } } if (1.0f != pcMesh->fOpacity) { sMacro[iCurrent].Name = "AV_OPACITY"; sMacro[iCurrent].Definition = "1"; ++iCurrent; } if( pcSource->HasBones()) { sMacro[iCurrent].Name = "AV_SKINNING"; sMacro[iCurrent].Definition = "0";//???"1"; ++iCurrent; } /* // If a cubemap is active, we'll need to lookup it for calculating // a physically correct reflection if (CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode()) { sMacro[iCurrent].Name = "AV_SKYBOX_LOOKUP"; sMacro[iCurrent].Definition = "1"; ++iCurrent; }*/ sMacro[iCurrent].Name = 0; sMacro[iCurrent].Definition = 0; //Construct defines from sMacro and compine with mr->m_szMaterialShader string std::string extra; unsigned int iiCurrent = 0; while ((sMacro[iiCurrent].Name != 0)&& (sMacro[iiCurrent].Definition != 0)) { extra.append("#define "); extra.append(sMacro[iiCurrent].Name); extra.append(" "); extra.append(sMacro[iiCurrent].Definition); extra.append(";\n"); iiCurrent++; } // compile the shader #if 1 const char *ShaderName = mr->m_szShaderName.c_str(); //LOG_PRINT("ShaderName=%s\n", ShaderName); ShaderID shd=MeshRendererShadersFactory::GetShader(ShaderName, "main", "main"); //LOG_PRINT("m_SimpleShader=%s\n", m_SimpleShader); #elif 0 const char *m_SimpleShader = MeshRendererShadersFactory::GetShader("SimpleShader"); mr->m_piDefaultEffect=IRenderer::GetRendererInstance()->addHLSLShader( m_SimpleShader, "main", "main");//D1??? #elif 0 mr->m_piDefaultEffect=IRenderer::GetRendererInstance()->addHLSLShader( g_szMaterialShader.c_str(), "MaterialVShader_D1", "MaterialPShaderSpecular_D1",0,0,extra.c_str());//D1??? #elif 0 mr->m_piDefaultEffect=IRenderer::GetRendererInstance()->addHLSLShader( g_szDefaultShader.c_str(), "DefaultVShader", "DefaultPShaderSpecular_D1",0,0,extra.c_str());//D1??? #endif //mr->m_piMaterialEffect=mr->m_piDefaultEffect; #if 1 FormatDesc Fmt[] = { #if 0 { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, { 0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, { 0, 28, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0 }, { 0, 40, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 }, { 0, 52, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, { 0, 60, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 }, { 0, 68, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0 }, { 0, 72, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0 }, #else {0, TYPE_VERTEX, FORMAT_FLOAT, 3}, {0, TYPE_TEXCOORD, FORMAT_FLOAT, 2}, /* {0, TYPE_NORMAL, FORMAT_FLOAT, 3}, {0, TYPE_TEXCOORD, FORMAT_FLOAT, 3},//??? {0, TYPE_TEXCOORD, FORMAT_FLOAT, 2}, {0, TYPE_TEXCOORD, FORMAT_FLOAT, 4},//??? {0, TYPE_TEXCOORD, FORMAT_FLOAT, 4}//??? */ #endif }; //mr->m_DefaultVertexDecl = IRenderer::GetRendererInstance()->addVertexFormat(Fmt, elementsOf(Fmt), mr->m_piDefaultEffect);//??? #endif } if(0)//-1== mr->m_piMaterialEffect) { // get the name of the material and use it in the log message if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_NAME,&szPath) && '\0' != szPath.data[0]) { std::string sz = "[ERROR] Unable to load material: "; sz.append(szPath.data); //CLogDisplay::Instance().AddEntry(sz); } else { //CLogDisplay::Instance().AddEntry("Unable to load material: UNNAMED"); } return 0; } else { /* // use Fixed Function effect when working with shaderless cards if( mr->m_sCaps.PixelShaderVersion < D3DPS_VERSION(2,0)) { ////LOG_PRINT("mr->m_piDefaultEffect=%d\n",mr->m_piDefaultEffect); IRenderer::GetRendererInstance()->SetTechnique( MaterialFX_FFh); }*/ } // if( piBuffer) piBuffer->Release(); LOG_FNLN; LOG_PRINT("ShaderName=%d\n",mr->m_szShaderName.c_str()); ShaderID shd = MeshRendererShadersFactory::GetShader(mr->m_szShaderName.c_str(), "main", "main"); IRenderer::GetRendererInstance()->setShader(shd); // now commit all constants to the shader // // This is not necessary for shared shader. Shader constants for // shared shaders are automatically recommited before the shader // is being used for a particular mesh if (1.0f != pcMesh->fOpacity) { //???IRenderer::GetRendererInstance()->SetFloat("TRANSPARENCY",pcMesh->fOpacity); } if (pcMesh->eShadingMode != aiShadingMode_Gouraud && !mr->m_sOptions.bNoSpecular) { IRenderer::GetRendererInstance()->SetFloat("SPECULARITY",pcMesh->fShininess);//??? IRenderer::GetRendererInstance()->SetFloat("SPECULAR_STRENGTH",pcMesh->fSpecularStrength); } IRenderer::GetRendererInstance()->SetVector("DIFFUSE_COLOR",&pcMesh->vDiffuseColor); //IRenderer::GetRendererInstance()->SetVector("SPECULAR_COLOR",&pcMesh->vSpecularColor); IRenderer::GetRendererInstance()->SetVector("AMBIENT_COLOR",&pcMesh->vAmbientColor); IRenderer::GetRendererInstance()->SetVector("EMISSIVE_COLOR",&pcMesh->vEmissiveColor); if (pcMesh->piDiffuseTexture!=-1) { IRenderer::GetRendererInstance()->SetTexture("DIFFUSE_SAMPLER",pcMesh->piDiffuseTexture); } if (pcMesh->piOpacityTexture!=-1) { IRenderer::GetRendererInstance()->SetTexture("OPACITY_SAMPLER",pcMesh->piOpacityTexture); } if (pcMesh->piSpecularTexture!=-1) { IRenderer::GetRendererInstance()->SetTexture("SPECULAR_SAMPLER",pcMesh->piSpecularTexture); } if (pcMesh->piAmbientTexture!=-1) { IRenderer::GetRendererInstance()->SetTexture("AMBIENT_SAMPLER",pcMesh->piAmbientTexture); } if (pcMesh->piEmissiveTexture!=-1) { IRenderer::GetRendererInstance()->SetTexture("EMISSIVE_SAMPLER",pcMesh->piEmissiveTexture); } if (pcMesh->piNormalTexture!=-1) { IRenderer::GetRendererInstance()->SetTexture("NORMAL_SAMPLER",pcMesh->piNormalTexture); } if (pcMesh->piShininessTexture!=-1) { IRenderer::GetRendererInstance()->SetTexture("SHININESS_SAMPLER",pcMesh->piShininessTexture); } if (pcMesh->piLightmapTexture!=-1) { IRenderer::GetRendererInstance()->SetTexture("LIGHTMAP_SAMPLER",pcMesh->piLightmapTexture); } /* if (CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode()){ IRenderer::GetRendererInstance()->SetTexture("lw_tex_envmap",CBackgroundPainter::Instance().GetTexture()); }*/ #endif return 1; }
//------------------------------------------------------------------------------- int CMaterialManager::CreateMaterial( AssetHelper::MeshHelper* pcMesh,const aiMesh* pcSource) { ai_assert(NULL != pcMesh); ai_assert(NULL != pcSource); ID3DXBuffer* piBuffer; D3DXMACRO sMacro[64]; // extract all properties from the ASSIMP material structure const aiMaterial* pcMat = g_pcAsset->pcScene->mMaterials[pcSource->mMaterialIndex]; // // DIFFUSE COLOR -------------------------------------------------- // if(AI_SUCCESS != aiGetMaterialColor(pcMat,AI_MATKEY_COLOR_DIFFUSE, (aiColor4D*)&pcMesh->vDiffuseColor)) { pcMesh->vDiffuseColor.x = 1.0f; pcMesh->vDiffuseColor.y = 1.0f; pcMesh->vDiffuseColor.z = 1.0f; pcMesh->vDiffuseColor.w = 1.0f; } // // SPECULAR COLOR -------------------------------------------------- // if(AI_SUCCESS != aiGetMaterialColor(pcMat,AI_MATKEY_COLOR_SPECULAR, (aiColor4D*)&pcMesh->vSpecularColor)) { pcMesh->vSpecularColor.x = 1.0f; pcMesh->vSpecularColor.y = 1.0f; pcMesh->vSpecularColor.z = 1.0f; pcMesh->vSpecularColor.w = 1.0f; } // // AMBIENT COLOR -------------------------------------------------- // if(AI_SUCCESS != aiGetMaterialColor(pcMat,AI_MATKEY_COLOR_AMBIENT, (aiColor4D*)&pcMesh->vAmbientColor)) { pcMesh->vAmbientColor.x = 0.0f; pcMesh->vAmbientColor.y = 0.0f; pcMesh->vAmbientColor.z = 0.0f; pcMesh->vAmbientColor.w = 1.0f; } // // EMISSIVE COLOR ------------------------------------------------- // if(AI_SUCCESS != aiGetMaterialColor(pcMat,AI_MATKEY_COLOR_EMISSIVE, (aiColor4D*)&pcMesh->vEmissiveColor)) { pcMesh->vEmissiveColor.x = 0.0f; pcMesh->vEmissiveColor.y = 0.0f; pcMesh->vEmissiveColor.z = 0.0f; pcMesh->vEmissiveColor.w = 1.0f; } // // Opacity -------------------------------------------------------- // if(AI_SUCCESS != aiGetMaterialFloat(pcMat,AI_MATKEY_OPACITY,&pcMesh->fOpacity)) { pcMesh->fOpacity = 1.0f; } // // Shading Model -------------------------------------------------- // bool bDefault = false; if(AI_SUCCESS != aiGetMaterialInteger(pcMat,AI_MATKEY_SHADING_MODEL,(int*)&pcMesh->eShadingMode )) { bDefault = true; pcMesh->eShadingMode = aiShadingMode_Gouraud; } // // Shininess ------------------------------------------------------ // if(AI_SUCCESS != aiGetMaterialFloat(pcMat,AI_MATKEY_SHININESS,&pcMesh->fShininess)) { // assume 15 as default shininess pcMesh->fShininess = 15.0f; } else if (bDefault)pcMesh->eShadingMode = aiShadingMode_Phong; // // Shininess strength ------------------------------------------------------ // if(AI_SUCCESS != aiGetMaterialFloat(pcMat,AI_MATKEY_SHININESS_STRENGTH,&pcMesh->fSpecularStrength)) { // assume 1.0 as default shininess strength pcMesh->fSpecularStrength = 1.0f; } aiString szPath; aiTextureMapMode mapU(aiTextureMapMode_Wrap),mapV(aiTextureMapMode_Wrap); bool bib =false; if (pcSource->mTextureCoords[0]) { // // DIFFUSE TEXTURE ------------------------------------------------ // if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_DIFFUSE(0),&szPath)) { LoadTexture(&pcMesh->piDiffuseTexture,&szPath); aiGetMaterialInteger(pcMat,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0),(int*)&mapU); aiGetMaterialInteger(pcMat,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0),(int*)&mapV); } // // SPECULAR TEXTURE ------------------------------------------------ // if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_SPECULAR(0),&szPath)) { LoadTexture(&pcMesh->piSpecularTexture,&szPath); } // // OPACITY TEXTURE ------------------------------------------------ // if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_OPACITY(0),&szPath)) { LoadTexture(&pcMesh->piOpacityTexture,&szPath); } else { int flags = 0; aiGetMaterialInteger(pcMat,AI_MATKEY_TEXFLAGS_DIFFUSE(0),&flags); // try to find out whether the diffuse texture has any // non-opaque pixels. If we find a few, use it as opacity texture if (pcMesh->piDiffuseTexture && !(flags & aiTextureFlags_IgnoreAlpha) && HasAlphaPixels(pcMesh->piDiffuseTexture)) { int iVal; // NOTE: This special value is set by the tree view if the user // manually removes the alpha texture from the view ... if (AI_SUCCESS != aiGetMaterialInteger(pcMat,"no_a_from_d",0,0,&iVal)) { pcMesh->piOpacityTexture = pcMesh->piDiffuseTexture; pcMesh->piOpacityTexture->AddRef(); } } } // // AMBIENT TEXTURE ------------------------------------------------ // if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_AMBIENT(0),&szPath)) { LoadTexture(&pcMesh->piAmbientTexture,&szPath); } // // EMISSIVE TEXTURE ------------------------------------------------ // if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_EMISSIVE(0),&szPath)) { LoadTexture(&pcMesh->piEmissiveTexture,&szPath); } // // Shininess TEXTURE ------------------------------------------------ // if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_SHININESS(0),&szPath)) { LoadTexture(&pcMesh->piShininessTexture,&szPath); } // // Lightmap TEXTURE ------------------------------------------------ // if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_LIGHTMAP(0),&szPath)) { LoadTexture(&pcMesh->piLightmapTexture,&szPath); } // // NORMAL/HEIGHT MAP ------------------------------------------------ // bool bHM = false; if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_NORMALS(0),&szPath)) { LoadTexture(&pcMesh->piNormalTexture,&szPath); } else { if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_HEIGHT(0),&szPath)) { LoadTexture(&pcMesh->piNormalTexture,&szPath); } else bib = true; bHM = true; } // normal/height maps are sometimes mixed up. Try to detect the type // of the texture automatically if (pcMesh->piNormalTexture) { HMtoNMIfNecessary(pcMesh->piNormalTexture, &pcMesh->piNormalTexture,bHM); } } // check whether a global background texture is contained // in this material. Some loaders set this value ... if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_GLOBAL_BACKGROUND_IMAGE,&szPath)) { CBackgroundPainter::Instance().SetTextureBG(szPath.data); } // BUGFIX: If the shininess is 0.0f disable phong lighting // This is a workaround for some meshes in the DX SDK (e.g. tiny.x) // FIX: Added this check to the x-loader, but the line remains to // catch other loader doing the same ... if (0.0f == pcMesh->fShininess){ pcMesh->eShadingMode = aiShadingMode_Gouraud; } int two_sided = 0; aiGetMaterialInteger(pcMat,AI_MATKEY_TWOSIDED,&two_sided); pcMesh->twosided = (two_sided != 0); // check whether we have already a material using the same // shader. This will decrease loading time rapidly ... for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i) { if (g_pcAsset->pcScene->mMeshes[i] == pcSource) { break; } AssetHelper::MeshHelper* pc = g_pcAsset->apcMeshes[i]; if ((pcMesh->piDiffuseTexture != NULL ? true : false) != (pc->piDiffuseTexture != NULL ? true : false)) continue; if ((pcMesh->piSpecularTexture != NULL ? true : false) != (pc->piSpecularTexture != NULL ? true : false)) continue; if ((pcMesh->piAmbientTexture != NULL ? true : false) != (pc->piAmbientTexture != NULL ? true : false)) continue; if ((pcMesh->piEmissiveTexture != NULL ? true : false) != (pc->piEmissiveTexture != NULL ? true : false)) continue; if ((pcMesh->piNormalTexture != NULL ? true : false) != (pc->piNormalTexture != NULL ? true : false)) continue; if ((pcMesh->piOpacityTexture != NULL ? true : false) != (pc->piOpacityTexture != NULL ? true : false)) continue; if ((pcMesh->piShininessTexture != NULL ? true : false) != (pc->piShininessTexture != NULL ? true : false)) continue; if ((pcMesh->piLightmapTexture != NULL ? true : false) != (pc->piLightmapTexture != NULL ? true : false)) continue; if ((pcMesh->eShadingMode != aiShadingMode_Gouraud ? true : false) != (pc->eShadingMode != aiShadingMode_Gouraud ? true : false)) continue; if ((pcMesh->fOpacity != 1.0f ? true : false) != (pc->fOpacity != 1.0f ? true : false)) continue; if (pcSource->HasBones() != g_pcAsset->pcScene->mMeshes[i]->HasBones()) continue; // we can reuse this material if (pc->piEffect) { pcMesh->piEffect = pc->piEffect; pc->bSharedFX = pcMesh->bSharedFX = true; pcMesh->piEffect->AddRef(); return 2; } } m_iShaderCount++; // build macros for the HLSL compiler unsigned int iCurrent = 0; if (pcMesh->piDiffuseTexture) { sMacro[iCurrent].Name = "AV_DIFFUSE_TEXTURE"; sMacro[iCurrent].Definition = "1"; ++iCurrent; if (mapU == aiTextureMapMode_Wrap) sMacro[iCurrent].Name = "AV_WRAPU"; else if (mapU == aiTextureMapMode_Mirror) sMacro[iCurrent].Name = "AV_MIRRORU"; else // if (mapU == aiTextureMapMode_Clamp) sMacro[iCurrent].Name = "AV_CLAMPU"; sMacro[iCurrent].Definition = "1"; ++iCurrent; if (mapV == aiTextureMapMode_Wrap) sMacro[iCurrent].Name = "AV_WRAPV"; else if (mapV == aiTextureMapMode_Mirror) sMacro[iCurrent].Name = "AV_MIRRORV"; else // if (mapV == aiTextureMapMode_Clamp) sMacro[iCurrent].Name = "AV_CLAMPV"; sMacro[iCurrent].Definition = "1"; ++iCurrent; } if (pcMesh->piSpecularTexture) { sMacro[iCurrent].Name = "AV_SPECULAR_TEXTURE"; sMacro[iCurrent].Definition = "1"; ++iCurrent; } if (pcMesh->piAmbientTexture) { sMacro[iCurrent].Name = "AV_AMBIENT_TEXTURE"; sMacro[iCurrent].Definition = "1"; ++iCurrent; } if (pcMesh->piEmissiveTexture) { sMacro[iCurrent].Name = "AV_EMISSIVE_TEXTURE"; sMacro[iCurrent].Definition = "1"; ++iCurrent; } char buff[32]; if (pcMesh->piLightmapTexture) { sMacro[iCurrent].Name = "AV_LIGHTMAP_TEXTURE"; sMacro[iCurrent].Definition = "1"; ++iCurrent; int idx; if(AI_SUCCESS == aiGetMaterialInteger(pcMat,AI_MATKEY_UVWSRC_LIGHTMAP(0),&idx) && idx >= 1 && pcSource->mTextureCoords[idx]) { sMacro[iCurrent].Name = "AV_TWO_UV"; sMacro[iCurrent].Definition = "1"; ++iCurrent; sMacro[iCurrent].Definition = "IN.TexCoord1"; } else sMacro[iCurrent].Definition = "IN.TexCoord0"; sMacro[iCurrent].Name = "AV_LIGHTMAP_TEXTURE_UV_COORD"; ++iCurrent;float f= 1.f; aiGetMaterialFloat(pcMat,AI_MATKEY_TEXBLEND_LIGHTMAP(0),&f); sprintf(buff,"%f",f); sMacro[iCurrent].Name = "LM_STRENGTH"; sMacro[iCurrent].Definition = buff; ++iCurrent; } if (pcMesh->piNormalTexture && !bib) { sMacro[iCurrent].Name = "AV_NORMAL_TEXTURE"; sMacro[iCurrent].Definition = "1"; ++iCurrent; } if (pcMesh->piOpacityTexture) { sMacro[iCurrent].Name = "AV_OPACITY_TEXTURE"; sMacro[iCurrent].Definition = "1"; ++iCurrent; if (pcMesh->piOpacityTexture == pcMesh->piDiffuseTexture) { sMacro[iCurrent].Name = "AV_OPACITY_TEXTURE_REGISTER_MASK"; sMacro[iCurrent].Definition = "a"; ++iCurrent; } else { sMacro[iCurrent].Name = "AV_OPACITY_TEXTURE_REGISTER_MASK"; sMacro[iCurrent].Definition = "r"; ++iCurrent; } } if (pcMesh->eShadingMode != aiShadingMode_Gouraud && !g_sOptions.bNoSpecular) { sMacro[iCurrent].Name = "AV_SPECULAR_COMPONENT"; sMacro[iCurrent].Definition = "1"; ++iCurrent; if (pcMesh->piShininessTexture) { sMacro[iCurrent].Name = "AV_SHININESS_TEXTURE"; sMacro[iCurrent].Definition = "1"; ++iCurrent; } } if (1.0f != pcMesh->fOpacity) { sMacro[iCurrent].Name = "AV_OPACITY"; sMacro[iCurrent].Definition = "1"; ++iCurrent; } if( pcSource->HasBones()) { sMacro[iCurrent].Name = "AV_SKINNING"; sMacro[iCurrent].Definition = "1"; ++iCurrent; } // If a cubemap is active, we'll need to lookup it for calculating // a physically correct reflection if (CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode()) { sMacro[iCurrent].Name = "AV_SKYBOX_LOOKUP"; sMacro[iCurrent].Definition = "1"; ++iCurrent; } sMacro[iCurrent].Name = NULL; sMacro[iCurrent].Definition = NULL; // compile the shader if(FAILED( D3DXCreateEffect(g_piDevice, g_szMaterialShader.c_str(),(UINT)g_szMaterialShader.length(), (const D3DXMACRO*)sMacro,NULL,0,NULL,&pcMesh->piEffect,&piBuffer))) { // failed to compile the shader if( piBuffer) { MessageBox(g_hDlg,(LPCSTR)piBuffer->GetBufferPointer(),"HLSL",MB_OK); piBuffer->Release(); } // use the default material instead if (g_piDefaultEffect) { pcMesh->piEffect = g_piDefaultEffect; g_piDefaultEffect->AddRef(); } // get the name of the material and use it in the log message if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_NAME,&szPath) && '\0' != szPath.data[0]) { std::string sz = "[ERROR] Unable to load material: "; sz.append(szPath.data); CLogDisplay::Instance().AddEntry(sz); } else { CLogDisplay::Instance().AddEntry("Unable to load material: UNNAMED"); } return 0; } else { // use Fixed Function effect when working with shaderless cards if( g_sCaps.PixelShaderVersion < D3DPS_VERSION(2,0)) pcMesh->piEffect->SetTechnique( "MaterialFX_FF"); } if( piBuffer) piBuffer->Release(); // now commit all constants to the shader // // This is not necessary for shared shader. Shader constants for // shared shaders are automatically recommited before the shader // is being used for a particular mesh if (1.0f != pcMesh->fOpacity) pcMesh->piEffect->SetFloat("TRANSPARENCY",pcMesh->fOpacity); if (pcMesh->eShadingMode != aiShadingMode_Gouraud && !g_sOptions.bNoSpecular) { pcMesh->piEffect->SetFloat("SPECULARITY",pcMesh->fShininess); pcMesh->piEffect->SetFloat("SPECULAR_STRENGTH",pcMesh->fSpecularStrength); } pcMesh->piEffect->SetVector("DIFFUSE_COLOR",&pcMesh->vDiffuseColor); pcMesh->piEffect->SetVector("SPECULAR_COLOR",&pcMesh->vSpecularColor); pcMesh->piEffect->SetVector("AMBIENT_COLOR",&pcMesh->vAmbientColor); pcMesh->piEffect->SetVector("EMISSIVE_COLOR",&pcMesh->vEmissiveColor); if (pcMesh->piDiffuseTexture) pcMesh->piEffect->SetTexture("DIFFUSE_TEXTURE",pcMesh->piDiffuseTexture); if (pcMesh->piOpacityTexture) pcMesh->piEffect->SetTexture("OPACITY_TEXTURE",pcMesh->piOpacityTexture); if (pcMesh->piSpecularTexture) pcMesh->piEffect->SetTexture("SPECULAR_TEXTURE",pcMesh->piSpecularTexture); if (pcMesh->piAmbientTexture) pcMesh->piEffect->SetTexture("AMBIENT_TEXTURE",pcMesh->piAmbientTexture); if (pcMesh->piEmissiveTexture) pcMesh->piEffect->SetTexture("EMISSIVE_TEXTURE",pcMesh->piEmissiveTexture); if (pcMesh->piNormalTexture) pcMesh->piEffect->SetTexture("NORMAL_TEXTURE",pcMesh->piNormalTexture); if (pcMesh->piShininessTexture) pcMesh->piEffect->SetTexture("SHININESS_TEXTURE",pcMesh->piShininessTexture); if (pcMesh->piLightmapTexture) pcMesh->piEffect->SetTexture("LIGHTMAP_TEXTURE",pcMesh->piLightmapTexture); if (CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode()){ pcMesh->piEffect->SetTexture("lw_tex_envmap",CBackgroundPainter::Instance().GetTexture()); } return 1; }
//! Loads and returns a static model from a file. StaticModel* ModelImporter::LoadStaticModel(string filename) { // Is the model already loaded? if(mStaticModelMap.find(filename) != mStaticModelMap.end()) return mStaticModelMap[filename]; Assimp::Importer importer; mFilename = filename; StaticModel* model = NULL; // Important! Makes sure that if the angle between two face normals is > 80 they are not smoothed together. // Since the angle between a cubes face normals is 90 the lighting looks very bad if we don't specify this. importer.SetPropertyFloat(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, 80.0f); importer.SetPropertyInteger(AI_CONFIG_IMPORT_TER_MAKE_UVS, 1); importer.SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE); // Load scene from the file. const aiScene* scene = importer.ReadFile(filename, aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_SplitLargeMeshes | aiProcess_ConvertToLeftHanded | aiProcess_SortByPType); // Successfully loaded the scene. if(scene) { // Create the model that is getting filled out. model = new StaticModel(); // Loop through all meshes. for(int i = 0; i < scene->mNumMeshes; i++) { aiMesh* assimpMesh = scene->mMeshes[i]; vector<Vertex> vertices; vector<UINT> indices; // Add vertices to the vertex list. for(int i = 0; i < assimpMesh->mNumVertices; i++) { aiVector3D v = assimpMesh->mVertices[i]; aiVector3D n = assimpMesh->mNormals[i]; aiVector3D t = aiVector3D(0, 0, 0); if(assimpMesh->HasTextureCoords(0)) t = assimpMesh->mTextureCoords[0][i]; n = n.Normalize(); Vertex vertex(v.x, v.y, v.z, n.x, n.y, n.z, 0, 0, 0, t.x, t.y); vertices.push_back(vertex); } // Add indices to the index list. for(int i = 0; i < assimpMesh->mNumFaces; i++) for(int j = 0; j < assimpMesh->mFaces[i].mNumIndices; j++) indices.push_back(assimpMesh->mFaces[i].mIndices[j]); // Get the path to the texture in the directory. aiString path; aiMaterial* material = scene->mMaterials[assimpMesh->mMaterialIndex]; material->Get(AI_MATKEY_TEXTURE_DIFFUSE(0), path); FindValidPath(&path); // Extract all the ambient, diffuse and specular colors. aiColor4D ambient, diffuse, specular; material->Get(AI_MATKEY_COLOR_AMBIENT, ambient); material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse); material->Get(AI_MATKEY_COLOR_SPECULAR, specular); // Create the mesh and its primitive. StaticMesh* mesh = new StaticMesh(); Primitive* primitive = new Primitive(GlobalApp::GetD3DDevice(), vertices, indices); mesh->SetPrimitive(primitive); mesh->SetVertices(vertices); mesh->SetIndices(indices); mPrimtiveFactory->AddPrimitive(path.C_Str(), primitive); // Any texture? if(_stricmp(path.C_Str(), "") != 0) mesh->LoadTexture(path.C_Str()); // Any normal map? aiString nmap; material->Get(AI_MATKEY_TEXTURE_HEIGHT(0), nmap); FindValidPath(&nmap); if(_stricmp(nmap.C_Str(), "") != 0) mesh->SetNormalMap(GlobalApp::GetGraphics()->LoadTexture(nmap.C_Str())); // [NOTE] The material is set to white. mesh->SetMaterial(Material(Colors::White)); // Was before [NOTE] model->SetFilename(filename); // Add the mesh to the model. model->AddMesh(mesh); } // Add to the model map and return it. mStaticModelMap[filename] = model; return mStaticModelMap[filename]; } else { char buffer[246]; sprintf(buffer, "Error loading model: %s", filename.c_str()); MessageBox(0, buffer, "Error!", 0); mStaticModelMap[filename] = LoadStaticModel("models/box.obj"); return mStaticModelMap[filename]; } }
//! Loads and returns a skinned model from a file. SkinnedModel* ModelImporter::LoadSkinnedModel(string filename) { // Is the model already loaded? if(mSkinnedModelMap.find(filename) != mSkinnedModelMap.end()) return mSkinnedModelMap[filename]; Assimp::Importer importer; mFilename = filename; SkinnedModel* model = NULL; // Important! Makes sure that if the angle between two face normals is > 80 they are not smoothed together. // Since the angle between a cubes face normals is 90 the lighting looks very bad if we don't specify this. importer.SetPropertyFloat(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, 80.0f); importer.SetPropertyInteger(AI_CONFIG_IMPORT_TER_MAKE_UVS, 1); importer.SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE); // Load scene from the file. const aiScene* scene = importer.ReadFile(filename, aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_SplitLargeMeshes | aiProcess_ConvertToLeftHanded | aiProcess_SortByPType); if(scene) { // Create the model that is getting filled out. model = new SkinnedModel(); // Create the animator. SceneAnimator* animator = new SceneAnimator(); animator->Init(scene); model->SetAnimator(animator); // Loop through all meshes. for(int j = 0; j < scene->mNumMeshes; j++) { aiMesh* assimpMesh = scene->mMeshes[j]; // Calculate vertex weight and bone indices. vector<Weights> weights = CalculateWeights(assimpMesh, animator); vector<SkinnedVertex> vertices; vector<UINT> indices; // Add vertices to the vertex list. for(int i = 0; i < assimpMesh->mNumVertices; i++) { aiVector3D v = assimpMesh->mVertices[i]; aiVector3D n = assimpMesh->mNormals[i]; aiVector3D t = aiVector3D(0, 0, 0); if(assimpMesh->HasTextureCoords(0)) t = assimpMesh->mTextureCoords[0][i]; n = n.Normalize(); // Pos, normal and texture coordinates. SkinnedVertex vertex(v.x, v.y, v.z, n.x, n.y, n.z, 0, 0, 1, t.x, t.y); // Bone indices and weights. for(int k = 0; k < weights[i].boneIndices.size(); k++) vertex.BoneIndices[k] = weights[i].boneIndices[k]; vertex.Weights.x = weights[i].weights.size() >= 1 ? weights[i].weights[0] : 0; vertex.Weights.y = weights[i].weights.size() >= 2 ? weights[i].weights[1] : 0; vertex.Weights.z = weights[i].weights.size() >= 3 ? weights[i].weights[2] : 0; vertices.push_back(vertex); } // Add indices to the index list. for(int i = 0; i < assimpMesh->mNumFaces; i++) for(int k = 0; k < assimpMesh->mFaces[i].mNumIndices; k++) indices.push_back(assimpMesh->mFaces[i].mIndices[k]); // Get the path to the texture in the directory. aiString path; aiMaterial* material = scene->mMaterials[assimpMesh->mMaterialIndex]; material->Get(AI_MATKEY_TEXTURE_DIFFUSE(0), path); FindValidPath(&path); // Extract all the ambient, diffuse and specular colors. aiColor4D ambient, diffuse, specular; material->Get(AI_MATKEY_COLOR_AMBIENT, ambient); material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse); material->Get(AI_MATKEY_COLOR_SPECULAR, specular); // Create the mesh and its primitive. SkinnedMesh* mesh = new SkinnedMesh(); Primitive* primitive = new Primitive(GlobalApp::GetD3DDevice(), vertices, indices); mesh->SetPrimitive(primitive); mesh->SetVertices(vertices); mesh->SetIndices(indices); mPrimtiveFactory->AddPrimitive(path.C_Str(), primitive); // Replace .tga with .bmp [HACK]. string texturePath = path.C_Str(); int tgaPos = texturePath.find_first_of(".tga"); if(tgaPos != string::npos) { texturePath.replace(texturePath.size()-4, 4, ".bmp"); path = texturePath; } // Any texture? if(_stricmp(path.C_Str(), "") != 0) mesh->LoadTexture(path.C_Str()); // Any normal map? aiString nmap; material->Get(AI_MATKEY_TEXTURE_HEIGHT(0), nmap); FindValidPath(&nmap); if(_stricmp(nmap.C_Str(), "") != 0) mesh->SetNormalMap(GlobalApp::GetGraphics()->LoadTexture(nmap.C_Str())); // [NOTE] The material is set to white. mesh->SetMaterial(Material(Colors::White)); //mesh->SetMaterial(Material(diffuse, diffuse, diffuse)); model->SetFilename(filename); // Add the mesh to the model. model->AddMesh(mesh); } // Pre-calculate the bounding box. model->CalculateAABB(); // Add the newly created mesh to the map and return it. mSkinnedModelMap[filename] = model; return mSkinnedModelMap[filename]; } else { char buffer[246]; sprintf(buffer, "Error loading model: %s", filename.c_str()); MessageBox(0, buffer, "Error!", 0); mSkinnedModelMap[filename] = LoadSkinnedModel("models/box.obj"); return mSkinnedModelMap[filename]; } }
static bool load(std::shared_ptr<CookingTask> cookingTask) { if (!cookingTask->dataSet->loadMaterials) return true; auto tid = Singleton<AGE::AE::ConvertorStatusManager>::getInstance()->PushTask("MaterialLoader : loading " + cookingTask->dataSet->filePath.getShortFileName()); if (!cookingTask->assimpScene->HasMaterials()) { Singleton<AGE::AE::ConvertorStatusManager>::getInstance()->PopTask(tid); return true; } if (cookingTask->assimpScene->mNumMaterials <= 1) { return true; } for (unsigned int materialIndex = 1; materialIndex < cookingTask->assimpScene->mNumMaterials; ++materialIndex) { auto &aiMat = cookingTask->assimpScene->mMaterials[materialIndex]; aiColor4D diffuse(1.0f,1.0f,1.0f,1.0f); aiColor4D ambient(1.0f, 1.0f, 1.0f, 1.0f); aiColor4D emissive(1.0f, 1.0f, 1.0f, 1.0f); aiColor4D reflective(1.0f, 1.0f, 1.0f, 1.0f); aiColor4D specular(1.0f, 1.0f, 1.0f, 1.0f); aiGetMaterialColor(aiMat, AI_MATKEY_COLOR_DIFFUSE, &diffuse); aiGetMaterialColor(aiMat, AI_MATKEY_COLOR_AMBIENT, &ambient); aiGetMaterialColor(aiMat, AI_MATKEY_COLOR_EMISSIVE, &emissive); aiGetMaterialColor(aiMat, AI_MATKEY_COLOR_REFLECTIVE, &reflective); aiGetMaterialColor(aiMat, AI_MATKEY_COLOR_SPECULAR, &specular); aiString diffuseTexPath; aiString ambientTexPath; aiString emissiveTexPath; aiString reflexionTexPath; aiString specularTexPath; aiString normalTexPath; aiString bumpTexPath; aiMat->GetTexture(aiTextureType_DIFFUSE, 0, &diffuseTexPath); aiMat->GetTexture(aiTextureType_AMBIENT, 0, &ambientTexPath); aiMat->GetTexture(aiTextureType_EMISSIVE, 0, &emissiveTexPath); aiMat->GetTexture(aiTextureType_REFLECTION, 0, &reflexionTexPath); aiMat->GetTexture(aiTextureType_SPECULAR, 0, &specularTexPath); aiMat->GetTexture(aiTextureType_NORMALS, 0, &normalTexPath); aiMat->Get(AI_MATKEY_TEXTURE_HEIGHT(0), bumpTexPath); auto material = std::make_shared<MaterialData>(); material->diffuse = AssimpLoader::aiColorToGlm(diffuse); material->ambient = AssimpLoader::aiColorToGlm(ambient); material->emissive = AssimpLoader::aiColorToGlm(emissive); material->reflective = AssimpLoader::aiColorToGlm(reflective); material->specular = AssimpLoader::aiColorToGlm(specular); material->diffuseTexPath = diffuseTexPath.length > 0 ? cookingTask->dataSet->filePath.getFolder() + "/" + AssimpLoader::aiStringToStd(diffuseTexPath) : ""; material->ambientTexPath = ambientTexPath.length > 0 ? cookingTask->dataSet->filePath.getFolder() + "/" + AssimpLoader::aiStringToStd(ambientTexPath) : ""; material->emissiveTexPath = emissiveTexPath.length > 0 ? cookingTask->dataSet->filePath.getFolder() + "/" + AssimpLoader::aiStringToStd(emissiveTexPath) : ""; material->reflectiveTexPath = reflexionTexPath.length > 0 ? cookingTask->dataSet->filePath.getFolder() + "/" + AssimpLoader::aiStringToStd(reflexionTexPath) : ""; material->specularTexPath = specularTexPath.length > 0 ? cookingTask->dataSet->filePath.getFolder() + "/" + AssimpLoader::aiStringToStd(specularTexPath) : ""; material->normalTexPath = normalTexPath.length > 0 ? cookingTask->dataSet->filePath.getFolder() + "/" + AssimpLoader::aiStringToStd(normalTexPath) : ""; material->bumpTexPath = bumpTexPath.length > 0 ? cookingTask->dataSet->filePath.getFolder() + "/" + AssimpLoader::aiStringToStd(bumpTexPath) : ""; cookingTask->texturesPath.insert(material->diffuseTexPath); cookingTask->texturesPath.insert(material->ambientTexPath); cookingTask->texturesPath.insert(material->emissiveTexPath); cookingTask->texturesPath.insert(material->reflectiveTexPath); cookingTask->texturesPath.insert(material->specularTexPath); cookingTask->texturesPath.insert(material->normalTexPath); cookingTask->texturesPath.insert(material->bumpTexPath); AssimpLoader::replaceExtension(material->diffuseTexPath, ".dds"); AssimpLoader::replaceExtension(material->ambientTexPath, ".dds"); AssimpLoader::replaceExtension(material->emissiveTexPath, ".dds"); AssimpLoader::replaceExtension(material->reflectiveTexPath, ".dds"); AssimpLoader::replaceExtension(material->specularTexPath, ".dds"); AssimpLoader::replaceExtension(material->normalTexPath, ".dds"); AssimpLoader::replaceExtension(material->bumpTexPath, ".dds"); cookingTask->materials.push_back(material); } if (cookingTask->materials.size() == 0) { Singleton<AGE::AE::ConvertorStatusManager>::getInstance()->PopTask(tid); std::cerr << "MaterialLoader : Materials has not been loaded" << std::endl; return false; } Singleton<AGE::AE::ConvertorStatusManager>::getInstance()->PopTask(tid); return true; }