From df9f4130eb2cc23f530a76568ddddd3422ca67f6 Mon Sep 17 00:00:00 2001 From: aramis_acg Date: Wed, 5 Nov 2008 12:26:11 +0000 Subject: [PATCH] Further work on the IRR and IRRMESH loaders. IRR is still WIP, IRRMESH loads lightmaps correctly now. Added lightmap viewing support to the viewer. Irrlicht's tone scaling is hardcoded for the moment, a proper implementation will follow with the new viewer. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@232 67173fc5-114c-0410-ac8e-9d2fd5bffc1f --- code/IRRMeshLoader.cpp | 142 +++++++++++++++++++++++++++--- code/IRRMeshLoader.h | 34 ++++++- include/aiMaterial.h | 3 +- tools/assimp_view/AssetHelper.h | 8 +- tools/assimp_view/Material.cpp | 24 +++++ tools/assimp_view/Shaders.cpp | 33 +++++++ tools/assimp_view/assimp_view.cpp | 8 ++ 7 files changed, 234 insertions(+), 18 deletions(-) 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()) {