Пример #1
0
//-------------------------------------------------------------------------------
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;
}
Пример #2
0
//-------------------------------------------------------------------------------
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;
}
Пример #3
0
//! 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];
	}
}
Пример #4
0
//! 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];
	}
}
Пример #5
0
		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;
		}