⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mlrloadobj.cpp

📁 机甲指挥官2源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{
#if 0
	static char        *suffix[] = 
	{
		".pfi", 
		".sgi", 
		".rgb", 
		".rgba", 
		".int", 
		".inta", 
		".bw"
	};
	static int numSuffix = sizeof(suffix)/sizeof(suffix[0]);

	pfMaterial *material   = new pfMaterial;
	pfTexture  *texture    = new pfTexture;

	material->SetColorMode (PFMTL_FRONT, PFMTL_CMODE_OFF);
	pfdMakeDefaultObject((pfObject *)material);

	if (m->defined & (MTL_HAS_AMBIENT  | MTL_HAS_DIFFUSE  | 
				MTL_HAS_SPECULAR | MTL_HAS_ALPHA))
	{
		if (m->defined & MTL_HAS_AMBIENT)
		{
			material->SetColor (PFMTL_AMBIENT, 
					                m->ambient[0], m->ambient[1], m->ambient[2]);
		}

		if (m->defined & MTL_HAS_DIFFUSE)
		{
			material->SetColor (PFMTL_DIFFUSE, 
					                m->diffuse[0], m->diffuse[1], m->diffuse[2]);
		}

		if (m->defined & MTL_HAS_SPECULAR)
		{
			material->SetColor (PFMTL_SPECULAR, 
					                m->specular[0], m->specular[1], m->specular[2]);
		}

		if (m->defined & MTL_HAS_SHININESS)
		{
			material->SetShininess (m->shininess);
		}

		if (m->defined & MTL_HAS_ALPHA)
		{
			material->SetAlpha (m->alpha);
			pfdBldrStateMode(PFSTATE_TRANSPARENCY, PFTR_HIGH_QUALITY);
		}

		pfdBldrStateAttr(PFSTATE_FRONTMTL, material);

		if (m->defined & MTL_IS_TWO_SIDED)
		{
			lm->SetTwoSide (PF_ON);
			pfdBldrStateAttr (PFSTATE_LIGHTMODEL, lm);
			pfdBldrStateMode (PFSTATE_CULLFACE, PFCF_OFF);

			pfdBldrStateAttr (PFSTATE_BACKMTL, material);
		}
	}

	if (m->defined & (MTL_HAS_TEXTURE | MTL_HAS_REFLECTION))
	{
		int                  j, foo;
		static int				comp;
		unsigned int        *image;
		char                *sp;

// convert texture name from blah.rla to blah.rgb etc. 
		for (j = 0; j < numSuffix; j++)
		{
			char         texPath[PF_MAXSTRING];

// remove ".rla" or whatever suffix from file name 
			if ((sp = strrchr(m->texture, (int)'.')) != 0)
				*sp = '\0';

// append one of the known image file extensions 
			strcat(m->texture, suffix[j]);

// see if file is locatable with this extension 
			if (pfFindFile(m->texture, texPath, R_OK))
				break;
		}

		if (j < numSuffix)
		{
			pfTexture *realTexture;

			texture->SetName (m->texture);

			texture->SetRepeat(PFTEX_WRAP, PFTEX_REPEAT);

			pfdBldrStateAttr(PFSTATE_TEXTURE, texture);

			realTexture = (pfTexture *)pfdGetBldrStateAttr(PFSTATE_TEXTURE);
			realTexture->getImage (&image, &comp, &foo, &foo, &foo);

			if (comp == 2 || comp == 4)
			{
				pfdBldrStateMode(PFSTATE_TRANSPARENCY, PFTR_HIGH_QUALITY);
			}

			if (m->defined & MTL_HAS_REFLECTION)
			{
				pfTexGen   *texturegen = new pfTexGen;

				if (strcmp(m->reflect, "sphere") == 0)
				{
					texturegen->SetMode (PF_S, PFTG_SPHERE_MAP);
					texturegen->SetMode (PF_T, PFTG_SPHERE_MAP);
				}
				pfdBldrStateAttr(PFSTATE_TEXGEN, texturegen);
				pfdBldrStateMode(PFSTATE_ENTEXGEN, PF_ON);

				pfdReSetObject((pfObject *)texturegen);
			}
		} else {
// file not found -- Set name to 0 string 
			if ((sp = strrchr(m->texture, (int)'.')) != 0)
				*sp = '\0';
			pfNotify(PFNFY_WARN, PFNFY_RESOURCE,
					      "can't find texture \"%s\" for material \"%s\"", 
					      m->texture, m->name);
		}
	}

	if (0 == (enableSwitches & TEXTURE_ENABLE))
	{
		pfdBldrStateMode (PFSTATE_ENTEXTURE, PF_OFF);
	}
	else
	{
		pfdBldrStateMode (PFSTATE_ENTEXTURE, PF_ON);
	}

	if (0 == (enableSwitches & LIGHTING_ENABLE))
	{
		pfdBldrStateMode (PFSTATE_ENLIGHTING, PF_OFF);
	}
	else
	{
		pfdBldrStateMode (PFSTATE_ENLIGHTING, PF_ON);
	}

	pfdSaveBldrState(strdup(m->name));

	pfdReSetObject((pfObject *)material);
	pfdReSetObject((pfObject *)texture);
	pfdReSetObject((pfObject *)lm);

	pfdReSetBldrState();
#endif

	m->defined |= MTL_HAS_GEOSTATE;

	if (m->defined & MTL_HAS_ALPHA)
	{
		currentState.SetAlpha(MLRState::AlphaOnMode);
	}

	if (m->defined & MTL_HAS_TEXTURE)
	{
		currentState.SetTexture(m->texture);
	}
}

static void
	useMtl (char *name)
{
	int i;

// reSet to default state 
//	pfdReSetBldrState();

// look for name in material list 
	for (i = 0; i < mtlListCount; i++)
	{
		if (strcmp(name, mtlList[i].name) == 0)
		{
// is this a "missing" material 
			if (mtlList[i].defined & MTL_NOT_DEFINED)
			{
			} else {
// define state before first use 
				if ((mtlList[i].defined & MTL_HAS_GEOSTATE) == 0)
					defineMtl(&mtlList[i]);

// specify the state by name 
//				pfdLoadBldrState(name);
			}

			return;
		}
	}
		
// if we can't find material, then use default 
	if (i >= mtlListCount)
	{
		objMaterial missing;

// print warning once 
		fprintf(stderr, "material \"%s\" not defined", name);

// remember missing material's name and status 
		reSetMaterial(&missing);
		strcpy(missing.name, name);
		missing.defined = MTL_NOT_DEFINED;
		rememberMaterial(&missing);
	}
}

// parse wafefront material file texture definition
 
static void
	parSetexture (char *next, objMaterial *m)
{
	int                 width = 0;

// Set default texture scale factors 
	m->su = 1.0f;
	m->sv = 1.0f;

// parse texture name 
	sscanf(next, "%s%n", m->texture, &width);

// parse texture option strings 
	do
	{
		next += width;

		if (strcmp(m->texture, "-mm") == 0)
		{
			sscanf(next, "%f %f %s%n", &m->su, &m->sv, m->texture, &width);
		} else {
			if (strcmp(m->texture, "-s") == 0)
			{
				sscanf(next, "%f %f %*f %s%n", &m->su, &m->sv, m->texture, &width);
			} else {
				if (strcmp(m->texture, "-t") == 0)
				{
					sscanf(next, "%f %f %*f %s%n", &m->su, &m->sv, m->texture, &width);
				} else {
					if (strcmp(m->texture, "-type") == 0)
					  sscanf(next, "%s %s%n", m->reflect, m->texture, &width);
					else
					  break;
				}
			}
		}
	} while (1);
}

static char        *mtlFileList[MAX_MTL_FILES];
static int         mtlCount = 0;

#ifdef        FORGETFUL
static void
	forgetMaterialFiles (void)
{
	int                i;

	for (i = 0; i < mtlCount; i++)
	if (mtlFileList[i] != 0)
		free(mtlFileList[i]);

	mtlCount = 0;
}
#endif

// load a wavefront-format material file (".mtl")
 
static void
	loadMtl (char *fileName)
{
	FILE        *mtlFile;
	char         buffer[BUFFER_SIZE];
	char         token[BUFFER_SIZE];
	char        *next;
	char        *backslash;
	int          width        = 0;
	int          i;
	int          inProgress = 0;
	objMaterial  current;

// have we already loaded this file ? 
	for (i = 0; i < mtlCount; i++)
	if (strcmp(fileName, mtlFileList[i]) == 0)
	{
		//DEBUG_STREAM << "(" << mtlCount << ") " << 
		//	"Material library '" << mtlFileList[i] << "' already loaded" << endl;
// bail out 
		return;
	}

// remember file name for future reference 
	if (i < MAX_MTL_FILES)
	{
		mtlFileList[mtlCount++] = strdup(fileName);
		DEBUG_STREAM << "> Reading material library '" << mtlFileList[mtlCount-1] <<
			"' (" << mtlCount << ") " << endl;
	} else {
		fprintf(stderr, "more than %d unique mtllibs. enlarge MAX_MTL_FILES", 
					  MAX_MTL_FILES);
	}

// open file 
	if ((mtlFile = fopen(fileName, "rt")) == 0)
	{
		fprintf(stderr, "can't open material library %s", fileName);
		return;
	}

// read Wavefront ".mtl" file 
	while (fgets(buffer, BUFFER_SIZE, mtlFile) != 0)
	{
// concatenate continuation lines 
		while ((backslash = strchr(buffer, '\\')) != 0)
		if (fgets(backslash, BUFFER_SIZE - strlen(buffer), mtlFile) == 0)
			break;

// find first non-"space" character in line 
		for (next = buffer; *next != '\0' && isspace(*next); next++)  {};

// skip blank lines and comments ('$' is comment in "cow.obj") 
		if (*next == '\0' || *next == '#' || *next == '!' || *next == '$')
			continue;

// extract token 
		sscanf(next, "%s%n", token, &width);
			next += width;

// identify token 
		if (SAME(token, "newmtl"))
		{
// save material definition 
			if (inProgress)
				rememberMaterial(&current);

			reSetMaterial(&current);
			inProgress = 1;
			strcpy(current.library, mtlFileList[mtlCount-1]);
			sscanf(next, "%s", current.name);
		} else if (SAME(token, "Ka"))
		{
			sscanf(next, "%f %f %f", 
					      &current.ambient.red, 
					      &current.ambient.green, 
					      &current.ambient.blue);
			current.defined |= MTL_HAS_AMBIENT;
		} else if (SAME(token, "Kd"))
		{
			sscanf(next, "%f %f %f", 
					      &current.diffuse.red, 
					      &current.diffuse.green, 
					      &current.diffuse.blue);
			current.defined |= MTL_HAS_DIFFUSE;
		} else if (SAME(token, "Ks"))
		{
			sscanf(next, "%f %f %f", 
					      &current.specular.red, 
					      &current.specular.green, 
					      &current.specular.blue);
			current.defined |= MTL_HAS_SPECULAR;
		} else if (SAME(token, "Tr"))
		{
			float alpha = 1.0f;
			sscanf(next, "%f", &alpha);
			current.alpha = 1.0f - alpha;
			current.defined |= MTL_HAS_ALPHA;
		} else if (SAME(token, "Ns"))
		{
			sscanf(next, "%f", &current.shininess);

// clamp shininess range 
			if (current.shininess <   0.0f)
				current.shininess =   0.0f;
			else
				if (current.shininess > 128.0f)
					current.shininess = 128.0f;

			current.defined |= MTL_HAS_SHININESS;
		} else if (SAME(token, "map_Kd"))
		{
			parSetexture(next, &current);
			current.defined |= MTL_HAS_TEXTURE;
		} else if (SAME(token, "refl"))
		{
			strcpy(current.reflect, "sphere");
			parSetexture(next, &current);
			current.defined |= MTL_HAS_REFLECTION;
		} else if (
					  SAME(token, "Ni")        ||
					  SAME(token, "Tf")        ||
					  SAME(token, "bump")      ||
					  SAME(token, "d")         ||
					  SAME(token, "decal")     ||
					  SAME(token, "illum")     ||
					  SAME(token, "map_Ka")    ||
					  SAME(token, "map_Ks")    ||
					  SAME(token, "map_Ns")    ||
					  SAME(token, "map_d")     ||
					  SAME(token, "sharpness") ||
					  SAME(token, "vp"))
		{
			numSkip++;
		}
#ifndef        STRICT_OBJ_FORMAT
// indicate that this material is two-sided
				 
		else
		if (SAME(token, "TWOSIDE"))
		{
			current.defined |= MTL_IS_TWO_SIDED;
		}
#endif
			else {
			fprintf(stderr, " unrecognized: %s", buffer);
			numOther++;
		}
	}
#if 0
	DEBUG_STREAM << fileName << endl << flush;
#endif

	if (inProgress)
		rememberMaterial(&current);

// close Wavefront ".mtl" file 
	fclose(mtlFile);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -