📄 mlrloadobj.cpp
字号:
{
#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(¤t);
reSetMaterial(¤t);
inProgress = 1;
strcpy(current.library, mtlFileList[mtlCount-1]);
sscanf(next, "%s", current.name);
} else if (SAME(token, "Ka"))
{
sscanf(next, "%f %f %f",
¤t.ambient.red,
¤t.ambient.green,
¤t.ambient.blue);
current.defined |= MTL_HAS_AMBIENT;
} else if (SAME(token, "Kd"))
{
sscanf(next, "%f %f %f",
¤t.diffuse.red,
¤t.diffuse.green,
¤t.diffuse.blue);
current.defined |= MTL_HAS_DIFFUSE;
} else if (SAME(token, "Ks"))
{
sscanf(next, "%f %f %f",
¤t.specular.red,
¤t.specular.green,
¤t.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", ¤t.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, ¤t);
current.defined |= MTL_HAS_TEXTURE;
} else if (SAME(token, "refl"))
{
strcpy(current.reflect, "sphere");
parSetexture(next, ¤t);
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(¤t);
// close Wavefront ".mtl" file
fclose(mtlFile);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -