mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 20:41:20 +00:00
[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:
parent
f66df59c43
commit
e40f3f4f93
12 changed files with 105 additions and 35 deletions
|
@ -94,10 +94,8 @@ struct qfv_renderframe_s;
|
|||
struct entity_s;
|
||||
struct mod_alias_ctx_s;
|
||||
|
||||
void *Vulkan_Mod_LoadSkin (struct mod_alias_ctx_s *alias_ctx, byte *skin,
|
||||
int skinsize, int snum, int gnum, qboolean group,
|
||||
maliasskindesc_t *skindesc,
|
||||
struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Mod_LoadAllSkins (struct mod_alias_ctx_s *alias_ctx,
|
||||
struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Mod_FinalizeAliasModel (struct mod_alias_ctx_s *alias_ctx,
|
||||
struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Mod_LoadExternalSkins (struct mod_alias_ctx_s *alias_ctx,
|
||||
|
|
|
@ -58,9 +58,7 @@ typedef struct vid_model_funcs_s {
|
|||
void (*Mod_LoadSpriteModel) (model_t *mod, void *buffer);
|
||||
void (*Mod_MakeAliasModelDisplayLists) (struct mod_alias_ctx_s *alias_ctx,
|
||||
void *_m, int _s, int extra);
|
||||
void *(*Mod_LoadSkin) (struct mod_alias_ctx_s *alias_ctx, byte *skin,
|
||||
int skinsize, int snum, int gnum,
|
||||
qboolean group, maliasskindesc_t *skindesc);
|
||||
void (*Mod_LoadAllSkins) (struct mod_alias_ctx_s *alias_ctx);
|
||||
void (*Mod_FinalizeAliasModel) (struct mod_alias_ctx_s *alias_ctx);
|
||||
void (*Mod_LoadExternalSkins) (struct mod_alias_ctx_s *alias_ctx);
|
||||
void (*Mod_IQMFinish) (model_t *mod);
|
||||
|
|
|
@ -7,9 +7,17 @@
|
|||
#include "QF/skin.h"
|
||||
#include "QF/plugin/vid_render.h"
|
||||
|
||||
typedef struct mod_alias_skin_s {
|
||||
int skin_num;
|
||||
int group_num; // -1 if not in an animated group
|
||||
byte *texels;
|
||||
maliasskindesc_t *skindesc;
|
||||
} mod_alias_skin_t;
|
||||
|
||||
typedef struct stvertset_s DARRAY_TYPE (stvert_t) stvertset_t;
|
||||
typedef struct mtriangleset_s DARRAY_TYPE (mtriangle_t) mtriangleset_t;
|
||||
typedef struct trivertxset_s DARRAY_TYPE (trivertx_t *) trivertxset_t;
|
||||
typedef struct askinset_s DARRAY_TYPE (mod_alias_skin_t) askinset_t;
|
||||
|
||||
typedef struct mod_alias_ctx_s {
|
||||
aliashdr_t *header;
|
||||
|
@ -17,6 +25,7 @@ typedef struct mod_alias_ctx_s {
|
|||
stvertset_t stverts;
|
||||
mtriangleset_t triangles;
|
||||
trivertxset_t poseverts;
|
||||
askinset_t skins;
|
||||
int aliasbboxmins[3];
|
||||
int aliasbboxmaxs[3];
|
||||
} mod_alias_ctx_t;
|
||||
|
@ -49,27 +58,21 @@ extern vid_model_funcs_t *m_funcs;
|
|||
|
||||
void gl_Mod_MakeAliasModelDisplayLists (mod_alias_ctx_t *alias_ctx, void *_m,
|
||||
int _s, int extra);
|
||||
void *gl_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skin, int skinsize,
|
||||
int snum, int gnum, qboolean group,
|
||||
maliasskindesc_t *skindesc);
|
||||
void gl_Mod_LoadAllSkins (mod_alias_ctx_t *alias_ctx);
|
||||
void gl_Mod_FinalizeAliasModel (mod_alias_ctx_t *alias_ctx);
|
||||
void gl_Mod_LoadExternalSkins (mod_alias_ctx_t *alias_ctx);
|
||||
void gl_Mod_IQMFinish (model_t *mod);
|
||||
|
||||
void glsl_Mod_MakeAliasModelDisplayLists (mod_alias_ctx_t *alias_ctx,
|
||||
void *_m, int _s, int extra);
|
||||
void *glsl_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skin, int skinsize,
|
||||
int snum, int gnum, qboolean group,
|
||||
maliasskindesc_t *skindesc);
|
||||
void glsl_Mod_LoadAllSkins (mod_alias_ctx_t *alias_ctx);
|
||||
void glsl_Mod_FinalizeAliasModel (mod_alias_ctx_t *alias_ctx);
|
||||
void glsl_Mod_LoadExternalSkins (mod_alias_ctx_t *alias_ctx);
|
||||
void glsl_Mod_IQMFinish (model_t *mod);
|
||||
|
||||
void sw_Mod_MakeAliasModelDisplayLists (mod_alias_ctx_t *alias_ctx, void *_m,
|
||||
int _s, int extra);
|
||||
void *sw_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skin, int skinsize,
|
||||
int snum, int gnum, qboolean group,
|
||||
maliasskindesc_t *skindesc);
|
||||
void sw_Mod_LoadAllSkins (mod_alias_ctx_t *alias_ctx);
|
||||
void sw_Mod_IQMFinish (model_t *mod);
|
||||
|
||||
void gl_Mod_LoadLighting (model_t *mod, bsp_t *bsp);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -163,7 +163,7 @@ static vid_model_funcs_t model_funcs = {
|
|||
Mod_LoadSpriteModel,
|
||||
|
||||
gl_Mod_MakeAliasModelDisplayLists,
|
||||
gl_Mod_LoadSkin,
|
||||
gl_Mod_LoadAllSkins,
|
||||
gl_Mod_FinalizeAliasModel,
|
||||
gl_Mod_LoadExternalSkins,
|
||||
gl_Mod_IQMFinish,
|
||||
|
|
|
@ -74,7 +74,7 @@ static vid_model_funcs_t model_funcs = {
|
|||
Mod_LoadSpriteModel,
|
||||
|
||||
glsl_Mod_MakeAliasModelDisplayLists,
|
||||
glsl_Mod_LoadSkin,
|
||||
glsl_Mod_LoadAllSkins,
|
||||
glsl_Mod_FinalizeAliasModel,
|
||||
glsl_Mod_LoadExternalSkins,
|
||||
glsl_Mod_IQMFinish,
|
||||
|
|
|
@ -83,7 +83,7 @@ static vid_model_funcs_t model_funcs = {
|
|||
Mod_LoadSpriteModel,
|
||||
|
||||
sw_Mod_MakeAliasModelDisplayLists,
|
||||
sw_Mod_LoadSkin,
|
||||
sw_Mod_LoadAllSkins,
|
||||
0,
|
||||
0,
|
||||
sw_Mod_IQMFinish,
|
||||
|
|
|
@ -540,13 +540,10 @@ vulkan_Mod_MakeAliasModelDisplayLists (mod_alias_ctx_t *alias_ctx,
|
|||
vulkan_ctx);
|
||||
}
|
||||
|
||||
static void *
|
||||
vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skin, int skinsize,
|
||||
int snum, int gnum, qboolean group,
|
||||
maliasskindesc_t *skindesc)
|
||||
static void
|
||||
vulkan_Mod_LoadAllSkins (mod_alias_ctx_t *alias_ctx)
|
||||
{
|
||||
return Vulkan_Mod_LoadSkin (alias_ctx, skin, skinsize, snum, gnum, group,
|
||||
skindesc, vulkan_ctx);
|
||||
Vulkan_Mod_LoadAllSkins (alias_ctx, vulkan_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -638,7 +635,7 @@ static vid_model_funcs_t model_funcs = {
|
|||
Mod_LoadSpriteModel,
|
||||
|
||||
vulkan_Mod_MakeAliasModelDisplayLists,
|
||||
vulkan_Mod_LoadSkin,
|
||||
vulkan_Mod_LoadAllSkins,
|
||||
vulkan_Mod_FinalizeAliasModel,
|
||||
vulkan_Mod_LoadExternalSkins,
|
||||
vulkan_Mod_IQMFinish,
|
||||
|
|
Loading…
Reference in a new issue