Split MD3 model post-processing into common and Polymer parts and defer the latter if the game is started with a different renderer. This has the benefit of faster startup times and much less memory consumption in that case. When the user switches to Polymer later in-game, all processing is done in one run. I've observed crashes due to the music system if it takes too long, so the it may be unreliable. Also some calloc->malloc where the clearing is unnecessary.

git-svn-id: https://svn.eduke32.com/eduke32@1744 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2010-12-24 15:44:37 +00:00
parent b3194b18cd
commit d3a17f62a2
3 changed files with 114 additions and 13 deletions

View file

@ -243,4 +243,6 @@ void voxfree(voxmodel_t *m);
voxmodel_t *voxload(const char *filnam); voxmodel_t *voxload(const char *filnam);
int32_t voxdraw(voxmodel_t *m, spritetype *tspr); int32_t voxdraw(voxmodel_t *m, spritetype *tspr);
int md3postload_polymer(md3model_t* m);
#endif // !_mdsprite_h_ #endif // !_mdsprite_h_

View file

@ -13362,8 +13362,26 @@ int32_t setrendermode(int32_t renderer)
if (renderer == 4) if (renderer == 4)
{ {
int32_t i;
if (!polymer_init()) if (!polymer_init())
renderer = 3; renderer = 3;
// potentially deferred MD3 postprocessing
for (i=0; i<nextmodelid; i++)
if (models[i]->mdnum==3 && ((md3model_t *)models[i])->head.surfs[0].geometry == NULL)
{
static int32_t warned=0;
if (!warned)
{
OSD_Printf("Post-processing MD3 models for Polymer. This can take a while...\n");
nextpage();
warned = 1;
}
md3postload_polymer((md3model_t *)models[i]);
}
} }
# else # else
else renderer = 3; else renderer = 3;

View file

@ -1029,10 +1029,10 @@ static md2model_t *md2load(int32_t fil, const char *filnam)
m->numglcmds = head.numglcmds; m->numglcmds = head.numglcmds;
m->framebytes = head.framebytes; m->framebytes = head.framebytes;
m->frames = (char *)Bcalloc(m->numframes,m->framebytes); if (!m->frames) { Bfree(m); return(0); } m->frames = (char *)Bmalloc(m->numframes*m->framebytes); if (!m->frames) { Bfree(m); return(0); }
m->glcmds = (int32_t *)Bcalloc(m->numglcmds,sizeof(int32_t)); if (!m->glcmds) { Bfree(m->frames); Bfree(m); return(0); } m->glcmds = (int32_t *)Bmalloc(m->numglcmds*sizeof(int32_t)); if (!m->glcmds) { Bfree(m->frames); Bfree(m); return(0); }
m->tris = (md2tri_t *)Bcalloc(head.numtris, sizeof(md2tri_t)); if (!m->tris) { Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); } m->tris = (md2tri_t *)Bmalloc(head.numtris*sizeof(md2tri_t)); if (!m->tris) { Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); }
m->uv = (md2uv_t *)Bcalloc(head.numuv, sizeof(md2uv_t)); if (!m->uv) { Bfree(m->tris); Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); } m->uv = (md2uv_t *)Bmalloc(head.numuv*sizeof(md2uv_t)); if (!m->uv) { Bfree(m->tris); Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); }
klseek(fil,head.ofsframes,SEEK_SET); klseek(fil,head.ofsframes,SEEK_SET);
if (kread(fil,(char *)m->frames,m->numframes*m->framebytes) != m->numframes*m->framebytes) if (kread(fil,(char *)m->frames,m->numframes*m->framebytes) != m->numframes*m->framebytes)
@ -1093,7 +1093,7 @@ static md2model_t *md2load(int32_t fil, const char *filnam)
m->basepath = (char *)Bmalloc(i+1); if (!m->basepath) { Bfree(m->uv); Bfree(m->tris); Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); } m->basepath = (char *)Bmalloc(i+1); if (!m->basepath) { Bfree(m->uv); Bfree(m->tris); Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); }
strcpy(m->basepath, st); strcpy(m->basepath, st);
m->skinfn = (char *)Bcalloc(m->numskins,64); if (!m->skinfn) { Bfree(m->basepath); Bfree(m->uv); Bfree(m->tris); Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); } m->skinfn = (char *)Bmalloc(m->numskins*64); if (!m->skinfn) { Bfree(m->basepath); Bfree(m->uv); Bfree(m->tris); Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); }
klseek(fil,head.ofsskins,SEEK_SET); klseek(fil,head.ofsskins,SEEK_SET);
if (kread(fil,m->skinfn,64*m->numskins) != 64*m->numskins) if (kread(fil,m->skinfn,64*m->numskins) != 64*m->numskins)
{ Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); } { Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); }
@ -1232,6 +1232,13 @@ static md2model_t *md2load(int32_t fil, const char *filnam)
m3->vindexes = Bmalloc(sizeof(uint16_t) * s->numtris * 3); m3->vindexes = Bmalloc(sizeof(uint16_t) * s->numtris * 3);
m3->maxdepths = Bmalloc(sizeof(float) * s->numtris); m3->maxdepths = Bmalloc(sizeof(float) * s->numtris);
if (!m3->indexes || !m3->vindexes || !m3->maxdepths)
{
initprintf("OUT OF MEMORY in md2load!\n");
uninitengine();
exit(1);
}
m3->vbos = NULL; m3->vbos = NULL;
// die MD2 ! DIE ! // die MD2 ! DIE !
@ -1450,6 +1457,13 @@ static md3model_t *md3load(int32_t fil)
m->vindexes = Bmalloc(sizeof(uint16_t) * maxtrispersurf * 3); m->vindexes = Bmalloc(sizeof(uint16_t) * maxtrispersurf * 3);
m->maxdepths = Bmalloc(sizeof(float) * maxtrispersurf); m->maxdepths = Bmalloc(sizeof(float) * maxtrispersurf);
if (!m->indexes || !m->vindexes || !m->maxdepths)
{
initprintf("OUT OF MEMORY in md3load!\n");
uninitengine();
exit(1);
}
m->vbos = NULL; m->vbos = NULL;
return(m); return(m);
@ -1491,14 +1505,12 @@ static inline void normalize(float* vec)
vec[2] *= norm; vec[2] *= norm;
} }
static int md3postload(md3model_t* m) static void md3postload_common(md3model_t* m)
{ {
int framei, surfi, verti, trii, i; int framei, surfi, verti;
md3surf_t *s;
md3frame_t *frame; md3frame_t *frame;
md3xyzn_t *frameverts; md3xyzn_t *frameverts;
int *numtris; float dist, vec1[5];
float dist, lat, lng, vec1[5], vec2[5], mat[9], r;
// apparently we can't trust loaded models bounding box/sphere information, // apparently we can't trust loaded models bounding box/sphere information,
// so let's compute it ourselves // so let's compute it ourselves
@ -1590,6 +1602,50 @@ static int md3postload(md3model_t* m)
framei++; framei++;
} }
}
#ifdef POLYMER
// pre-check success of conversion since it must not fail later.
// keep in sync with md3postload_polymer!
static int md3postload_polymer_check(md3model_t *m)
{
int surfi, trii;
md3surf_t *s;
surfi = 0;
while (surfi < m->head.numsurfs)
{
s = &m->head.surfs[surfi];
trii = 0;
while (trii < s->numtris)
{
// let the vertices know they're being referenced by a triangle
if (s->tris[trii].i[0] >= s->numverts || s->tris[trii].i[0] < 0 ||
s->tris[trii].i[1] >= s->numverts || s->tris[trii].i[1] < 0 ||
s->tris[trii].i[2] >= s->numverts || s->tris[trii].i[2] < 0) {
// corrupt model
OSD_Printf("Triangle index out of bounds!\n");
return 0;
}
trii++;
}
surfi++;
}
return 1;
}
#endif
int md3postload_polymer(md3model_t* m)
{
#ifdef POLYMER
int framei, surfi, verti, trii, i;
md3surf_t *s;
int *numtris;
float lat, lng, vec1[5], vec2[5], mat[9], r;
// let's also repack the geometry to more usable formats // let's also repack the geometry to more usable formats
@ -1602,6 +1658,13 @@ static int md3postload(md3model_t* m)
numtris = Bcalloc(s->numverts, sizeof(int)); numtris = Bcalloc(s->numverts, sizeof(int));
if (!s->geometry || !numtris)
{
initprintf("OUT OF MEMORY in md3postload_polymer!\n");
uninitengine();
exit(1);
}
verti = 0; verti = 0;
while (verti < (m->head.numframes * s->numverts)) while (verti < (m->head.numframes * s->numverts))
{ {
@ -1717,8 +1780,10 @@ static int md3postload(md3model_t* m)
} }
return 1; return 1;
#endif
} }
static int32_t md3draw(md3model_t *m, spritetype *tspr) static int32_t md3draw(md3model_t *m, spritetype *tspr)
{ {
point3d fp, fp1, fp2, m0, m1, a0; point3d fp, fp1, fp2, m0, m1, a0;
@ -3126,6 +3191,7 @@ mdmodel_t *mdload(const char *filnam)
fil = kopen4load((char *)filnam,0); if (fil < 0) return(0); fil = kopen4load((char *)filnam,0); if (fil < 0) return(0);
kread(fil,&i,4); klseek(fil,0,SEEK_SET); kread(fil,&i,4); klseek(fil,0,SEEK_SET);
switch (B_LITTLE32(i)) switch (B_LITTLE32(i))
{ {
case 0x32504449: case 0x32504449:
@ -3139,10 +3205,25 @@ mdmodel_t *mdload(const char *filnam)
vm = (mdmodel_t*)0; break; vm = (mdmodel_t*)0; break;
} }
kclose(fil); kclose(fil);
if (vm && !md3postload((md3model_t*)vm)) {
mdfree(vm); if (vm)
vm = (mdmodel_t*)0; {
md3postload_common((md3model_t*)vm);
#ifdef POLYMER
// implies defined(POLYMOST) && defined(USE_OPENGL)?
if (glrendmode==4)
i = md3postload_polymer((md3model_t*)vm);
else
i = md3postload_polymer_check((md3model_t*)vm);
if (!i)
{
mdfree(vm);
vm = (mdmodel_t*)0;
}
#endif
} }
return(vm); return(vm);
} }