[model] Make alias skin loading a batch operation

Really, this won't make all that much difference because alias models
with more than one skin are quite rare, and those with animated skin
groups are even rarer. However, for those models that do have more than
one skin, it will allow for reduced allocation overheads, and when
supported (glsl, vulkan, maybe gl), loading all the skins into an array
texture (since all skins are the same size, though external skins may
vary), but that's not implemented yet, this just wraps the old one skin
at a time code.
This commit is contained in:
Bill Currie 2022-04-04 15:38:27 +09:00
parent f66df59c43
commit e40f3f4f93
12 changed files with 105 additions and 35 deletions

View file

@ -52,7 +52,7 @@
#include "compat.h"
void *
static void *
gl_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skin, int skinsize,
int snum, int gnum, qboolean group,
maliasskindesc_t *skindesc)
@ -103,6 +103,20 @@ gl_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skin, int skinsize,
return skin + skinsize;
}
void
gl_Mod_LoadAllSkins (mod_alias_ctx_t *alias_ctx)
{
aliashdr_t *header = alias_ctx->header;
int skinsize = header->mdl.skinwidth * header->mdl.skinheight;
for (size_t i = 0; i < alias_ctx->skins.size; i++) {
__auto_type skin = alias_ctx->skins.a + i;
gl_Mod_LoadSkin (alias_ctx, skin->texels, skinsize,
skin->skin_num, skin->group_num,
skin->group_num != -1, skin->skindesc);
}
}
void
gl_Mod_FinalizeAliasModel (mod_alias_ctx_t *alias_ctx)
{

View file

@ -90,7 +90,7 @@ glsl_alias_clear (model_t *m, void *data)
}
}
void *
static void *
glsl_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skin, int skinsize,
int snum, int gnum, qboolean group,
maliasskindesc_t *skindesc)
@ -114,6 +114,20 @@ glsl_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skin, int skinsize,
return skin + skinsize;
}
void
glsl_Mod_LoadAllSkins (mod_alias_ctx_t *alias_ctx)
{
aliashdr_t *header = alias_ctx->header;
int skinsize = header->mdl.skinwidth * header->mdl.skinheight;
for (size_t i = 0; i < alias_ctx->skins.size; i++) {
__auto_type skin = alias_ctx->skins.a + i;
glsl_Mod_LoadSkin (alias_ctx, skin->texels, skinsize,
skin->skin_num, skin->group_num,
skin->group_num != -1, skin->skindesc);
}
}
void
glsl_Mod_FinalizeAliasModel (mod_alias_ctx_t *alias_ctx)
{

View file

@ -75,8 +75,14 @@ Mod_LoadAllSkins (mod_alias_ctx_t *alias_ctx, int numskins,
pskindesc[snum].type = pskintype->type;
if (pskintype->type == ALIAS_SKIN_SINGLE) {
skin = (byte *) (pskintype + 1);
skin = m_funcs->Mod_LoadSkin (alias_ctx, skin, skinsize, snum, 0,
false, &pskindesc[snum]);
mod_alias_skin_t askin = {
.skin_num = snum,
.group_num = -1,
.texels = skin,
.skindesc = &pskindesc[snum],
};
skin += skinsize;
DARRAY_APPEND (&alias_ctx->skins, askin);
} else {
pskintype++;
pinskingroup = (daliasskingroup_t *) pskintype;
@ -107,13 +113,20 @@ Mod_LoadAllSkins (mod_alias_ctx_t *alias_ctx, int numskins,
for (gnum = 0; gnum < groupskins; gnum++) {
paliasskingroup->skindescs[gnum].type = ALIAS_SKIN_SINGLE;
skin = mod_funcs->Mod_LoadSkin (alias_ctx, skin, skinsize,
snum, gnum, true,
&paliasskingroup->skindescs[gnum]);
skin = (byte *) (pskintype + 1);
mod_alias_skin_t askin = {
.skin_num = snum,
.group_num = gnum,
.texels = skin,
.skindesc = &paliasskingroup->skindescs[gnum],
};
skin += skinsize;
DARRAY_APPEND (&alias_ctx->skins, askin);
}
}
pskintype = (daliasskintype_t *) skin;
}
mod_funcs->Mod_LoadAllSkins (alias_ctx);
return pskintype;
}
@ -232,6 +245,7 @@ Mod_LoadAliasModel (model_t *mod, void *buffer, cache_allocator_t allocator)
DARRAY_INIT (&alias_ctx.poseverts, 256);
DARRAY_INIT (&alias_ctx.stverts, 256);
DARRAY_INIT (&alias_ctx.triangles, 256);
DARRAY_INIT (&alias_ctx.skins, 256);
if (LittleLong (* (unsigned int *) buffer) == HEADER_MDL16)
extra = 1; // extra precision bytes
@ -392,4 +406,5 @@ Mod_LoadAliasModel (model_t *mod, void *buffer, cache_allocator_t allocator)
DARRAY_CLEAR (&alias_ctx.poseverts);
DARRAY_CLEAR (&alias_ctx.stverts);
DARRAY_CLEAR (&alias_ctx.triangles);
DARRAY_CLEAR (&alias_ctx.skins);
}

View file

@ -49,7 +49,7 @@
// an animating sequence of poses
void *
static void *
sw_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skin,
int skinsize, int snum, int gnum,
qboolean group, maliasskindesc_t *skindesc)
@ -64,6 +64,20 @@ sw_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skin,
return skin + skinsize;
}
void
sw_Mod_LoadAllSkins (mod_alias_ctx_t *alias_ctx)
{
aliashdr_t *header = alias_ctx->header;
int skinsize = header->mdl.skinwidth * header->mdl.skinheight;
for (size_t i = 0; i < alias_ctx->skins.size; i++) {
__auto_type skin = alias_ctx->skins.a + i;
sw_Mod_LoadSkin (alias_ctx, skin->texels, skinsize,
skin->skin_num, skin->group_num,
skin->group_num != -1, skin->skindesc);
}
}
static void
process_frame (mod_alias_ctx_t *alias_ctx, maliasframedesc_t *frame,
int posenum, int extra)

View file

@ -111,7 +111,7 @@ vulkan_alias_clear (model_t *m, void *data)
}
}
void *
static void *
Vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skinpix, int skinsize,
int snum, int gnum, qboolean group,
maliasskindesc_t *skindesc, vulkan_ctx_t *ctx)
@ -228,6 +228,20 @@ Vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skinpix, int skinsize,
return skinpix + skinsize;
}
void
Vulkan_Mod_LoadAllSkins (mod_alias_ctx_t *alias_ctx, vulkan_ctx_t *ctx)
{
aliashdr_t *header = alias_ctx->header;
int skinsize = header->mdl.skinwidth * header->mdl.skinheight;
for (size_t i = 0; i < alias_ctx->skins.size; i++) {
__auto_type skin = alias_ctx->skins.a + i;
Vulkan_Mod_LoadSkin (alias_ctx, skin->texels, skinsize,
skin->skin_num, skin->group_num,
skin->group_num != -1, skin->skindesc, ctx);
}
}
void
Vulkan_Mod_FinalizeAliasModel (mod_alias_ctx_t *alias_ctx, vulkan_ctx_t *ctx)
{
@ -401,6 +415,9 @@ Vulkan_Mod_MakeAliasModelDisplayLists (mod_alias_ctx_t *alias_ctx, void *_m,
for (i = 0; i < numtris; i++) {
for (j = 0; j < 3; j++) {
int vind = alias_ctx->triangles.a[i].vertindex[j];
// can't use indexmap to do the test because it indicates only
// that the vertex has been duplicated, not whether or not
// the vertex is the original or the duplicate
if (alias_ctx->stverts.a[vind].onseam
&& !alias_ctx->triangles.a[i].facesfront) {
vind = indexmap[vind];