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
pull/1/head
aramis_acg 2008-11-05 12:26:11 +00:00
parent 7c50899481
commit df9f4130eb
7 changed files with 234 additions and 18 deletions

View File

@ -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")
{
// 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();

View File

@ -48,10 +48,36 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
// 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|0x5)
#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
// ---------------------------------------------------------------------------

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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 = <DIFFUSE_TEXTURE2>;\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"

View File

@ -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())
{