MF_API void MFMaterial_UnregisterMaterialType(const char *pName) { MFCALLSTACK; MFMaterialType *pMatType = MaterialInternal_GetMaterialType(pName); MFDebug_Assert(pMatType, MFStr("Material type '%s' doesn't exist!", pName)); if(pMatType) { pMatType->materialCallbacks.pUnregisterMaterial(); gMaterialRegistry.Destroy(pMatType); MFHeap_Free(pMatType); } }
MF_API MFMaterial* MFMaterial_Create(const char *pName) { MFCALLSTACK; MFMaterial *pMat = MFMaterial_Find(pName); if(!pMat) { pMat = (MFMaterial*)MFHeap_AllocAndZero(sizeof(MFMaterial) + MFString_Length(pName) + 1); pName = MFString_Copy((char*)&pMat[1], pName); MFResource_AddResource(pMat, MFRT_Material, MFUtil_HashString(pName) ^ 0x0a7e01a1, pName); // TODO: how to determine size? pMat->pMaterialState = MFStateBlock_Create(256); pMat->bStateDirty = true; MaterialDefinition *pDef = pDefinitionRegistry; while(pDef) { MFIniLine *pLine = pDef->pIni->GetFirstLine()->FindEntry("section",pName); if (pLine) { MaterialInternal_InitialiseFromDefinition(pDef->pIni, pMat, pName); break; } pDef = pDef->pNextDefinition; } if(!pDef) { // assign material type pMat->pType = MaterialInternal_GetMaterialType("Standard"); pMat->pInstanceData = MFHeap_AllocAndZero(pMat->pType->instanceDataSize); pMat->pType->materialCallbacks.pCreateInstance(pMat); // set diffuse map parameter MFMaterial_SetParameterS(pMat, MFMatStandard_Texture, MFMatStandard_Tex_DifuseMap, pName); } } return pMat; }
MF_API MFMaterial* MFMaterial_Create(const char *pName) { MFCALLSTACK; MFMaterial *pMat = MFMaterial_Find(pName); if(!pMat) { pMat = (MFMaterial*)MFHeap_Alloc(sizeof(MFMaterial) + MFString_Length(pName) + 1); MFZeroMemory(pMat, sizeof(MFMaterial)); pMat->pName = (char*)&pMat[1]; MFString_Copy(pMat->pName, pName); gMaterialList.Create(pMat); MaterialDefinition *pDef = pDefinitionRegistry; while(pDef) { MFIniLine *pLine = pDef->pIni->GetFirstLine()->FindEntry("section",pName); if (pLine) { MaterialInternal_InitialiseFromDefinition(pDef->pIni, pMat, pName); break; } pDef = pDef->pNextDefinition; } if(!pDef) { // assign material type pMat->pType = MaterialInternal_GetMaterialType("Standard"); pMat->pType->materialCallbacks.pCreateInstance(pMat); // set diffuse map parameter MFMaterial_SetParameterS(pMat, MFMatStandard_Texture, MFMatStandard_Tex_DifuseMap, pName); } } pMat->refCount++; return pMat; }
void MaterialInternal_InitialiseFromDefinition(MFIni *pDefIni, MFMaterial *pMat, const char *pDefinition) { MFCALLSTACK; MFIniLine *pLine = pDefIni->GetFirstLine()->FindEntry("section", pDefinition); if(pLine) { pLine = pLine->Sub(); if(pLine && pLine->IsString(0, "type")) { pMat->pType = MaterialInternal_GetMaterialType(pLine->GetString(1)); if(!pMat->pType) pMat->pType = MaterialInternal_GetMaterialType("Standard"); pLine = pLine->Next(); } else { pMat->pType = MaterialInternal_GetMaterialType("Standard"); } if(pMat->pType->materialCallbacks.pCreateInstance) pMat->pType->materialCallbacks.pCreateInstance(pMat); while(pLine) { if(pLine->IsString(0,"type")) { MFDebug_Warn(2, MFStr("'type' MUST be the first parameter in a material definition... Ignored, Using type '%s'.", pMat->pType->pTypeName)); } else if(pLine->IsString(0,"alias")) { MFDebug_Warn(2, "'alias' MUST be the first parameter in a material definition... Ignored."); MFDebug_Assert(false, "Fix Me!!!"); // const char *pAlias = pLine->GetString(1); // MaterialInternal_InitialiseFromDefinition(pDefIni, pMat, pAlias); } else { const char *pParam = pLine->GetString(0); MFMaterialParameterInfo *pInfo = MFMaterial_GetParameterInfoFromName(pMat, pParam); int lineArg = 1; int param = pInfo->parameterIndex; int argIndex = 0; switch(pInfo->argIndex.type) { case MFParamType_Int: argIndex = pLine->GetInt(lineArg++); break; case MFParamType_Enum: argIndex = pLine->GetEnum(lineArg++, pInfo->argIndex.pEnumKeys); break; default: argIndex = pInfo->argIndex.defaultValue; break; } switch(pInfo->argIndexHigh.type) { case MFParamType_Int: argIndex |= pLine->GetInt(lineArg++) << 16; break; case MFParamType_Enum: argIndex |= pLine->GetEnum(lineArg++, pInfo->argIndexHigh.pEnumKeys) << 16; break; default: argIndex |= pInfo->argIndexHigh.defaultValue << 16; break; } if(pInfo->numValues == 1) { switch(pInfo->pValues[0].type) { case MFParamType_Constant: { MFMaterial_SetParameterI(pMat, param, argIndex, pInfo->pValues[0].defaultValue); break; } case MFParamType_String: { const char *pString = pLine->GetString(lineArg); MFMaterial_SetParameterS(pMat, param, argIndex, pString); break; } case MFParamType_Float: { float value = pLine->GetFloat(lineArg); MFMaterial_SetParameterF(pMat, param, argIndex, value); break; } case MFParamType_Int: { int value = pLine->GetStringCount() > lineArg ? pLine->GetInt(lineArg) : pInfo->pValues[0].defaultValue; MFMaterial_SetParameterI(pMat, param, argIndex, value); break; } case MFParamType_Enum: { int value; if(pLine->GetStringCount() > lineArg) value = pLine->GetEnum(lineArg, pInfo->pValues[0].pEnumKeys); else value = pInfo->pValues[0].defaultValue; MFMaterial_SetParameterI(pMat, param, argIndex, value); break; } case MFParamType_Bool: { bool value = pLine->GetStringCount() > lineArg ? pLine->GetBool(lineArg) : !!pInfo->pValues[0].defaultValue; MFMaterial_SetParameterI(pMat, param, argIndex, value ? 1 : 0); break; } case MFParamType_Colour: { MFVector vector = pLine->GetColour(lineArg); MFMaterial_SetParameterV(pMat, param, argIndex, vector); break; } case MFParamType_Vector3: { MFVector vector = pLine->GetVector3(lineArg); MFMaterial_SetParameterV(pMat, param, argIndex, vector); break; } case MFParamType_Vector4: { MFVector vector = pLine->GetVector4(lineArg); MFMaterial_SetParameterV(pMat, param, argIndex, vector); break; } case MFParamType_Matrix: { MFDebug_Assert(false, "Cant read a matrix from an ini file... yet..."); break; } default: MFDebug_Assert(false, "Unknown parameter type.."); } } else if(pInfo->numValues > 1) { // produce a struct representing the args MFALIGN_BEGIN(16) char argBuffer[256] MFALIGN_END(16); int offset = 0; for(int a=0; a<pInfo->numValues; a++) { switch(pInfo->pValues[a].type) { case MFParamType_Constant: { offset = MFALIGN(offset, sizeof(int)); (int&)argBuffer[offset] = pInfo->pValues[a].defaultValue; offset += sizeof(int); break; } case MFParamType_String: { offset = MFALIGN(offset, sizeof(const char *)); (const char *&)argBuffer[offset] = pLine->GetString(lineArg++); offset += sizeof(const char *); break; } case MFParamType_Float: { offset = MFALIGN(offset, sizeof(float)); (float&)argBuffer[offset] = pLine->GetFloat(lineArg++); offset += sizeof(float); break; } case MFParamType_Int: { offset = MFALIGN(offset, sizeof(int)); (int&)argBuffer[offset] = pLine->GetInt(lineArg++); offset += sizeof(int); break; } case MFParamType_Enum: { offset = MFALIGN(offset, sizeof(int)); (int&)argBuffer[offset] = pLine->GetEnum(lineArg++, pInfo->pValues[a].pEnumKeys); offset += sizeof(int); break; } case MFParamType_Bool: { offset = MFALIGN(offset, sizeof(bool)); (bool&)argBuffer[offset] = pLine->GetBool(lineArg++); offset += sizeof(bool); break; } case MFParamType_Colour: case MFParamType_Vector3: case MFParamType_Vector4: case MFParamType_Matrix: { MFDebug_Assert(false, "Cant read type into structure... yet..."); break; } default: MFDebug_Assert(false, "Unknown parameter type.."); } } MFMaterial_SetParameter(pMat, param, argIndex, (uintp)argBuffer); } } pLine = pLine->Next(); } }