diff --git a/code/IRRMeshLoader.cpp b/code/IRRMeshLoader.cpp index 882de0789..a90d773a9 100644 --- a/code/IRRMeshLoader.cpp +++ b/code/IRRMeshLoader.cpp @@ -191,7 +191,9 @@ void ColorFromARGBPacked(uint32_t in, aiColor4D& clr) int ConvertMappingMode(const std::string& mode) { if (mode == "texture_clamp_repeat") + { return aiTextureMapMode_Wrap; + } else if (mode == "texture_clamp_mirror") return aiTextureMapMode_Mirror; @@ -206,7 +208,8 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) aiColor4D clr; aiString s; - matFlags = 0; + matFlags = 0; // zero output flags + int cnt = 0; // number of used texture channels // Continue reading from the file while (reader->read()) @@ -274,8 +277,6 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) { StringProperty prop; ReadStringProperty(prop); - int cnt = 0; - if (prop.value.length()) { // material type (shader) @@ -289,6 +290,10 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) { matFlags = AI_IRRMESH_MAT_lightmap; } + else if (prop.value == "solid_2layer") + { + matFlags = AI_IRRMESH_MAT_solid_2layer; + } else if (prop.value == "lightmap_m2") { matFlags = AI_IRRMESH_MAT_lightmap_m2; @@ -297,32 +302,90 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) { matFlags = AI_IRRMESH_MAT_lightmap_m4; } + else if (prop.value == "lightmap_light") + { + matFlags = AI_IRRMESH_MAT_lightmap_light; + } + else if (prop.value == "lightmap_light_m2") + { + matFlags = AI_IRRMESH_MAT_lightmap_light_m2; + } + else if (prop.value == "lightmap_light_m4") + { + matFlags = AI_IRRMESH_MAT_lightmap_light_m4; + } + else if (prop.value == "lightmap_add") + { + matFlags = AI_IRRMESH_MAT_lightmap_add; + } + // Normal and parallax maps are treated equally + else if (prop.value == "normalmap_solid" || + prop.value == "parallaxmap_solid") + { + matFlags = AI_IRRMESH_MAT_normalmap_solid; + } + else if (prop.value == "normalmap_trans_vertex_alpha" || + prop.value == "parallaxmap_trans_vertex_alpha") + { + matFlags = AI_IRRMESH_MAT_normalmap_tva; + } + else if (prop.value == "normalmap_trans_add" || + prop.value == "parallaxmap_trans_add") + { + matFlags = AI_IRRMESH_MAT_normalmap_ta; + } } // Up to 4 texture channels are supported else if (prop.name == "Texture1") { + // Always accept the primary texture channel ++cnt; s.Set(prop.value); mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0)); } else if (prop.name == "Texture2") { - ++cnt; - s.Set(prop.value); - mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(1)); + // 2-layer material lightmapped? + if (matFlags & (AI_IRRMESH_MAT_solid_2layer | AI_IRRMESH_MAT_lightmap)) + { + ++cnt; + s.Set(prop.value); + mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(1)); + + // set the corresponding material flag + matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE; + } + // alternatively: normal or parallax mapping + else if (matFlags & AI_IRRMESH_MAT_normalmap_solid) + { + ++cnt; + s.Set(prop.value); + mat->AddProperty(&s,AI_MATKEY_TEXTURE_NORMALS(1)); + + // set the corresponding material flag + matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE; + } } else if (prop.name == "Texture3") { + // We don't process the third texture channel as Irrlicht + // does not seem to use it. +#if 0 ++cnt; s.Set(prop.value); mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(2)); +#endif } else if (prop.name == "Texture4" ) { + // We don't process the fourth texture channel as Irrlicht + // does not seem to use it. +#if 0 ++cnt; s.Set(prop.value); mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(3)); +#endif } // Texture mapping options @@ -360,6 +423,47 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) if (/* IRRMESH */ !ASSIMP_stricmp(reader->getNodeName(),"material") || /* IRR */ !ASSIMP_stricmp(reader->getNodeName(),"attributes")) { + // Now process lightmapping flags + // We should have at least one texture, however + // if there are multiple textures we assign the + // lightmap settings to the last texture. + if (cnt && matFlags & AI_IRRMESH_MAT_lightmap) + { + static const char* PropArray[4] = + { + AI_MATKEY_TEXBLEND_DIFFUSE(0), + AI_MATKEY_TEXBLEND_DIFFUSE(1), + AI_MATKEY_TEXBLEND_DIFFUSE(2), + AI_MATKEY_TEXBLEND_DIFFUSE(3) + }; + static const char* PropArray2[4] = + { + AI_MATKEY_TEXOP_DIFFUSE(0), + AI_MATKEY_TEXOP_DIFFUSE(1), + AI_MATKEY_TEXOP_DIFFUSE(2), + AI_MATKEY_TEXOP_DIFFUSE(3) + }; + float f = 1.f; + + // Additive lightmap? + int op = (matFlags & AI_IRRMESH_MAT_lightmap_add + ? aiTextureOp_Add : aiTextureOp_Multiply); + + // Handle Irrlicht's lightmapping scaling factor + if (matFlags & AI_IRRMESH_MAT_lightmap_m2 || + matFlags & AI_IRRMESH_MAT_lightmap_light_m2) + { + f = 2.f; + } + else if (matFlags & AI_IRRMESH_MAT_lightmap_m4 || + matFlags & AI_IRRMESH_MAT_lightmap_light_m4) + { + f = 4.f; + } + mat->AddProperty( &f, 1, PropArray [cnt-1]); + mat->AddProperty( &op,1, PropArray2 [cnt-1]); + } + return mat; } default: @@ -514,6 +618,27 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile, { curUV2s.reserve (num); vertexFormat = 1; + + if (curMatFlags & AI_IRRMESH_EXTRA_2ND_TEXTURE) + { + // ********************************************************* + // We have a second texture! So use this UV channel + // for it. The 2nd texture can be either a normal + // texture (solid_2layer or lightmap_xxx) or a normal + // map (normal_..., parallax_...) + // ********************************************************* + int idx = 1; + MaterialHelper* mat = ( MaterialHelper* ) curMat; + + if (curMatFlags & (AI_IRRMESH_MAT_solid_2layer | AI_IRRMESH_MAT_lightmap)) + { + mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_DIFFUSE(0)); + } + else if (curMatFlags & AI_IRRMESH_MAT_normalmap_solid) + { + mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_NORMALS(0)); + } + } } else if (!ASSIMP_stricmp("tangents", t)) { @@ -789,11 +914,6 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile, if (materials.empty()) throw new ImportErrorException("IRRMESH: Unable to read a mesh from this file"); - if(needLightMap) - { - // Compute light map UV coordinates -// ComputeLightMapUVCoordinates(meshes,materials); - } // now generate the output scene pScene->mNumMeshes = (unsigned int)meshes.size(); diff --git a/code/IRRMeshLoader.h b/code/IRRMeshLoader.h index fa3178cad..b6a57185d 100644 --- a/code/IRRMeshLoader.h +++ b/code/IRRMeshLoader.h @@ -48,10 +48,36 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace Assimp { -#define AI_IRRMESH_MAT_trans_vertex_alpha 0x1 -#define AI_IRRMESH_MAT_lightmap 0x2 -#define AI_IRRMESH_MAT_lightmap_m2 (AI_IRRMESH_MAT_lightmap|0x4) -#define AI_IRRMESH_MAT_lightmap_m4 (AI_IRRMESH_MAT_lightmap|0x5) +// Default: 0 = solid, one texture +#define AI_IRRMESH_MAT_solid_2layer 0x10000 + +// Transparency flags +#define AI_IRRMESH_MAT_trans_vertex_alpha 0x1 +#define AI_IRRMESH_MAT_trans_add 0x2 + +// Lightmapping flags +#define AI_IRRMESH_MAT_lightmap 0x2 +#define AI_IRRMESH_MAT_lightmap_m2 (AI_IRRMESH_MAT_lightmap|0x4) +#define AI_IRRMESH_MAT_lightmap_m4 (AI_IRRMESH_MAT_lightmap|0x8) +#define AI_IRRMESH_MAT_lightmap_light (AI_IRRMESH_MAT_lightmap|0x10) +#define AI_IRRMESH_MAT_lightmap_light_m2 (AI_IRRMESH_MAT_lightmap|0x20) +#define AI_IRRMESH_MAT_lightmap_light_m4 (AI_IRRMESH_MAT_lightmap|0x40) +#define AI_IRRMESH_MAT_lightmap_add (AI_IRRMESH_MAT_lightmap|0x80) + +// Standard NormalMap (or Parallax map, they're treated equally) +#define AI_IRRMESH_MAT_normalmap_solid (0x100) + +// Normal map combined with vertex alpha +#define AI_IRRMESH_MAT_normalmap_tva \ + (AI_IRRMESH_MAT_normalmap_solid | AI_IRRMESH_MAT_trans_vertex_alpha) + +// Normal map combined with additive transparency +#define AI_IRRMESH_MAT_normalmap_ta \ + (AI_IRRMESH_MAT_normalmap_solid | AI_IRRMESH_MAT_trans_add) + +// Special flag. It indicates a second texture has been found +// Its type depends ... either a normal textue or a normal map +#define AI_IRRMESH_EXTRA_2ND_TEXTURE 0x100000 // --------------------------------------------------------------------------- diff --git a/include/aiMaterial.h b/include/aiMaterial.h index 3bac27502..7d3c2ecad 100644 --- a/include/aiMaterial.h +++ b/include/aiMaterial.h @@ -416,7 +416,7 @@ extern "C" { // otherwise ... simply hope the buffer is large enough :-) # define AI_BUILD_KEY(base,index,out) \ - ::sprintf(out,"%s[%i]",base,index); + ::snprintf(out,256,"%s[%i]",base,index); #endif @@ -532,6 +532,7 @@ extern "C" { */ #define AI_MATKEY_COLOR_EMISSIVE "$clr.emissive" + // --------------------------------------------------------------------------- /** @def AI_MATKEY_TEXTURE_DIFFUSE * Defines a specific diffuse texture channel of the material diff --git a/tools/assimp_view/AssetHelper.h b/tools/assimp_view/AssetHelper.h index 91041a51a..98047046d 100644 --- a/tools/assimp_view/AssetHelper.h +++ b/tools/assimp_view/AssetHelper.h @@ -87,6 +87,7 @@ class AssetHelper aiVector3D vTangent; aiVector3D vBitangent; aiVector2D vTextureUV; + aiVector2D vTextureUV2; unsigned char mBoneIndices[4]; unsigned char mBoneWeights[4]; // last Weight not used, calculated inside the vertex shader @@ -101,8 +102,9 @@ class AssetHelper { 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_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0 }, - { 0, 64, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 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 }, D3DDECL_END() }; @@ -140,6 +142,7 @@ class AssetHelper piEffect (NULL), piVBNormals (NULL), piDiffuseTexture (NULL), + piDiffuseTexture2 (NULL), piSpecularTexture (NULL), piAmbientTexture (NULL), piNormalTexture (NULL), @@ -177,6 +180,7 @@ class AssetHelper // material textures IDirect3DTexture9* piDiffuseTexture; + IDirect3DTexture9* piDiffuseTexture2; IDirect3DTexture9* piSpecularTexture; IDirect3DTexture9* piAmbientTexture; IDirect3DTexture9* piEmissiveTexture; diff --git a/tools/assimp_view/Material.cpp b/tools/assimp_view/Material.cpp index 3ff47d6a8..6025b473f 100644 --- a/tools/assimp_view/Material.cpp +++ b/tools/assimp_view/Material.cpp @@ -797,6 +797,17 @@ int CMaterialManager::CreateMaterial( LoadTexture(&pcMesh->piDiffuseTexture,&szPath); } + if (pcSource->mTextureCoords[1]) + { + // + // DIFFUSE TEXTURE2 ------------------------------------------------ + // + if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_DIFFUSE(1),&szPath)) + { + LoadTexture(&pcMesh->piDiffuseTexture2,&szPath); + } + } + // // SPECULAR TEXTURE ------------------------------------------------ // @@ -908,6 +919,9 @@ int CMaterialManager::CreateMaterial( if ((pcMesh->piDiffuseTexture != NULL ? true : false) != (pc->piDiffuseTexture != NULL ? true : false)) continue; + if ((pcMesh->piDiffuseTexture2 != NULL ? true : false) != + (pc->piDiffuseTexture2 != NULL ? true : false)) + continue; if ((pcMesh->piSpecularTexture != NULL ? true : false) != (pc->piSpecularTexture != NULL ? true : false)) continue; @@ -955,6 +969,12 @@ int CMaterialManager::CreateMaterial( sMacro[iCurrent].Definition = "1"; ++iCurrent; } + if (pcMesh->piDiffuseTexture2) + { + sMacro[iCurrent].Name = "AV_DIFFUSE_TEXTURE2"; + sMacro[iCurrent].Definition = "1"; + ++iCurrent; + } if (pcMesh->piSpecularTexture) { sMacro[iCurrent].Name = "AV_SPECULAR_TEXTURE"; @@ -1099,6 +1119,8 @@ int CMaterialManager::CreateMaterial( if (pcMesh->piDiffuseTexture) pcMesh->piEffect->SetTexture("DIFFUSE_TEXTURE",pcMesh->piDiffuseTexture); + if (pcMesh->piDiffuseTexture2) + pcMesh->piEffect->SetTexture("DIFFUSE_TEXTURE2",pcMesh->piDiffuseTexture2); if (pcMesh->piOpacityTexture) pcMesh->piEffect->SetTexture("OPACITY_TEXTURE",pcMesh->piOpacityTexture); if (pcMesh->piSpecularTexture) @@ -1219,6 +1241,8 @@ int CMaterialManager::SetupMaterial ( pcMesh->piEffect->SetTexture("OPACITY_TEXTURE",pcMesh->piOpacityTexture); if (pcMesh->piDiffuseTexture) pcMesh->piEffect->SetTexture("DIFFUSE_TEXTURE",pcMesh->piDiffuseTexture); + if (pcMesh->piDiffuseTexture2) + pcMesh->piEffect->SetTexture("DIFFUSE_TEXTURE2",pcMesh->piDiffuseTexture2); if (pcMesh->piSpecularTexture) pcMesh->piEffect->SetTexture("SPECULAR_TEXTURE",pcMesh->piSpecularTexture); if (pcMesh->piAmbientTexture) diff --git a/tools/assimp_view/Shaders.cpp b/tools/assimp_view/Shaders.cpp index efb9ff532..553903033 100644 --- a/tools/assimp_view/Shaders.cpp +++ b/tools/assimp_view/Shaders.cpp @@ -536,6 +536,17 @@ std::string g_szMaterialShader = std::string( "};\n" "#endif // AV_DIFFUSE_TEXTUR\n" + "#ifdef AV_DIFFUSE_TEXTURE2\n" + "texture DIFFUSE_TEXTURE2;\n" + "sampler DIFFUSE_SAMPLER2\n" + "{\n" + "Texture = ;\n" + "MinFilter=LINEAR;\n" + "MagFilter=LINEAR;\n" + "MipFilter=LINEAR;\n" + "};\n" + "#endif // AV_DIFFUSE_TEXTUR2\n" + "#ifdef AV_SPECULAR_TEXTURE\n" "texture SPECULAR_TEXTURE;\n" "sampler SPECULAR_SAMPLER\n" @@ -614,6 +625,9 @@ std::string g_szMaterialShader = std::string( "float3 Tangent : TANGENT;\n" "float3 Bitangent : BINORMAL;\n" "float2 TexCoord0 : TEXCOORD0;\n" + "#ifdef AV_DIFFUSE_TEXTURE2 \n" + "float2 TexCoord1 : TEXCOORD1;\n" + "#endif \n" "#ifdef AV_SKINNING \n" "float4 BlendIndices : BLENDINDICES;\n" "float4 BlendWeights : BLENDWEIGHT;\n" @@ -633,6 +647,9 @@ std::string g_szMaterialShader = std::string( "#endif\n" "float2 TexCoord0 : TEXCOORD2;\n" + "#ifdef AV_DIFFUSE_TEXTURE2 \n" + "float2 TexCoord1 : TEXCOORD3;\n" + "#endif \n" "#ifdef AV_NORMAL_TEXTURE\n" "float3 Light0 : TEXCOORD3;\n" @@ -712,6 +729,9 @@ std::string g_szMaterialShader = std::string( "Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n" "float3 WorldPos = mul( float4( objPos, 1.0f), World);\n" "Out.TexCoord0 = IN.TexCoord0;\n" + "#ifdef AV_DIFFUSE_TEXTURE2 \n" + "Out.TexCoord1 = IN.TexCoord1;\n" + "#endif\n" "Out.Color = IN.Color;\n" "#ifndef AV_NORMAL_TEXTURE\n" @@ -749,6 +769,9 @@ std::string g_szMaterialShader = std::string( "Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n" "float3 WorldPos = mul( float4( objPos, 1.0f), World);\n" "Out.TexCoord0 = IN.TexCoord0;\n" + "#ifdef AV_DIFFUSE_TEXTURE2 \n" + "Out.TexCoord1 = IN.TexCoord1;\n" + "#endif\n" "Out.Color = IN.Color;\n" "#ifndef AV_NORMAL_TEXTURE\n" @@ -840,13 +863,19 @@ std::string g_szMaterialShader = std::string( "float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n" "#define AV_LIGHT_0 afLightDir[0]\n" "#endif\n" + "#ifdef AV_DIFFUSE_TEXTURE2\n" + "float fHalfLambert = 1.f;\n" + "#else\n" "float fHalfLambert = L1*L1;\n" + "#endif \n" "#ifdef AV_DIFFUSE_TEXTURE\n" "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * fHalfLambert * IN.Color.rgb +\n" "#else\n" "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * fHalfLambert * IN.Color.rgb +\n" "#endif // !AV_DIFFUSE_TEXTURE\n" + + "#ifdef AV_SPECULAR_COMPONENT\n" "#ifndef AV_SKYBOX_LOOKUP\n" "#ifdef AV_SPECULAR_TEXTURE\n" @@ -873,6 +902,10 @@ std::string g_szMaterialShader = std::string( "#else \n" "EMISSIVE_COLOR.rgb;\n" "#endif // !AV_EMISSIVE_TEXTURE\n" + + "#ifdef AV_DIFFUSE_TEXTURE2\n" + "OUT.rgb *= tex2D(DIFFUSE_SAMPLER2,IN.TexCoord1).rgb*4.0f;\n" + "#endif \n" "}\n" "#ifdef AV_OPACITY\n" "OUT.a = TRANSPARENCY;\n" diff --git a/tools/assimp_view/assimp_view.cpp b/tools/assimp_view/assimp_view.cpp index a7959feba..fed293702 100644 --- a/tools/assimp_view/assimp_view.cpp +++ b/tools/assimp_view/assimp_view.cpp @@ -572,6 +572,14 @@ int CreateAssetData() } else pbData2->vTextureUV = aiVector2D(0.5f,0.5f); + if (mesh->HasTextureCoords( 1)) + { + pbData2->vTextureUV2 = aiVector2D( + mesh->mTextureCoords[1][x].x, + mesh->mTextureCoords[1][x].y); + } + else pbData2->vTextureUV2 = aiVector2D(0.5f,0.5f); + // Bone indices and weights if( mesh->HasBones()) {