Esempio n. 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;
}
Esempio n. 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;
}