[models] Do full alias skin loading

This includes base, glow and two color maps (pants and shorts).
This commit is contained in:
Bill Currie 2021-01-26 20:33:51 +09:00
parent 69a8b984a5
commit 826e650c27
6 changed files with 131 additions and 20 deletions

View file

@ -37,6 +37,12 @@
#include "QF/modelgen.h"
#include "QF/Vulkan/qf_vid.h"
typedef struct aliasskin_s {
struct qfv_tex_s *tex;
struct qfv_tex_s *glow;
struct qfv_tex_s *colora;
struct qfv_tex_s *colorb;
} aliasskin_t;
typedef struct aliasvrt_s {
float vertex[4];
float normal[4];

View file

@ -278,14 +278,9 @@ typedef struct {
typedef struct {
aliasskintype_t type;
int skin;
union {
struct {
int texnum;
int fb_texnum;
};
void *tex;
};
int skin;
int texnum;
int fb_texnum;
} maliasskindesc_t;
typedef struct {
@ -447,7 +442,8 @@ void Mod_TouchModel (const char *name);
mleaf_t *Mod_PointInLeaf (const vec3_t p, model_t *model) __attribute__((pure));
byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model);
model_t *Mod_FindName (const char *name);
int Mod_CalcFullbright (byte *in, byte *out, int pixels);
int Mod_CalcFullbright (const byte *in, byte *out, int pixels);
void Mod_ClearFullbright (const byte *in, byte *out, int pixels);
int Mod_Fullbright (byte * skin, int width, int height, const char *name);
void *Mod_LoadAliasFrame (void *pin, int *posenum, maliasframedesc_t *frame,
@ -457,7 +453,7 @@ void *Mod_LoadAliasGroup (void *pin, int *posenum, maliasframedesc_t *frame,
void Mod_FindClipDepth (hull_t *hull);
void Mod_LoadBrushModel (model_t *mod, void *buffer);
void Mod_FloodFillSkin (byte * skin, int skinwidth, int skinheight);
void Mod_FloodFillSkin (byte *skin, int skinwidth, int skinheight);
void Mod_Print (void);

View file

@ -62,6 +62,10 @@ void Skin_Init (void);
skin_t *Skin_SetColormap (skin_t *skin, int cmap);
skin_t *Skin_SetSkin (skin_t *skin, int cmap, const char *skinname);
void Skin_SetTranslation (int cmap, int top, int bottom);
int Skin_CalcTopColors (const byte *in, byte *out, int pixels);
int Skin_CalcBottomColors (const byte *in, byte *out, int pixels);
void Skin_ClearTopColors (const byte *in, byte *out, int pixels);
void Skin_ClearBottomColors (const byte *in, byte *out, int pixels);
void sw_Skin_SetupSkin (skin_t *skin, int cmap);
void sw_Skin_ProcessTranslation (int cmap, const byte *translation);

View file

@ -59,6 +59,22 @@ static vec3_t vertex_normals[NUMVERTEXNORMALS] = {
#include "anorms.h"
};
static void
skin_clear (int skin_offset, aliashdr_t *hdr, vulkan_ctx_t *ctx)
{
aliasskin_t *skin = (aliasskin_t *) ((byte *) hdr + skin_offset);
Vulkan_UnloadTex (ctx, skin->tex);
if (skin->glow) {
Vulkan_UnloadTex (ctx, skin->glow);
}
if (skin->colora) {
Vulkan_UnloadTex (ctx, skin->colora);
}
if (skin->colorb) {
Vulkan_UnloadTex (ctx, skin->colorb);
}
}
static void
vulkan_alias_clear (model_t *m, void *data)
{
@ -84,32 +100,50 @@ vulkan_alias_clear (model_t *m, void *data)
__auto_type group = (maliasskingroup_t *)
((byte *) hdr + skins[i].skin);
for (int j = 0; j < group->numskins; j++) {
Vulkan_UnloadTex (ctx, group->skindescs[j].tex);
skin_clear (group->skindescs[j].skin, hdr, ctx);
}
} else {
Vulkan_UnloadTex (ctx, skins[i].tex);
skin_clear (skins[i].skin, hdr, ctx);
}
}
}
void *
Vulkan_Mod_LoadSkin (byte *skin, int skinsize, int snum, int gnum,
Vulkan_Mod_LoadSkin (byte *skinpix, int skinsize, int snum, int gnum,
qboolean group, maliasskindesc_t *skindesc,
vulkan_ctx_t *ctx)
{
aliasskin_t *skin;
byte *tskin;
int w, h;
skin = Hunk_Alloc (sizeof (aliasskin_t));
skindesc->skin = (byte *) skin - (byte *) pheader;//FIXME pheader global
//FIXME move all skins into arrays(?)
//FIXME fullbrights
w = pheader->mdl.skinwidth;
h = pheader->mdl.skinheight;
tskin = malloc (skinsize);
tskin = malloc (2 * skinsize);
memcpy (tskin, skin, skinsize);
Mod_FloodFillSkin (tskin, w, h);
tex_t skin_tex = {w, h, tex_palette, 1, vid.palette, tskin};
skindesc->tex = Vulkan_LoadTex (ctx, &skin_tex, 1);
tex_t skin_tex = {w, h, tex_palette, 1, vid.palette, tskin + skinsize};
if (Mod_CalcFullbright (tskin, tskin + skinsize, skinsize)) {
skin->glow = Vulkan_LoadTex (ctx, &skin_tex, 1);
Mod_ClearFullbright (tskin, tskin, skinsize);
}
if (Skin_CalcTopColors (tskin, tskin + skinsize, skinsize)) {
skin->colora = Vulkan_LoadTex (ctx, &skin_tex, 1);
Skin_ClearTopColors (tskin, tskin, skinsize);
}
if (Skin_CalcBottomColors (tskin, tskin + skinsize, skinsize)) {
skin->colorb = Vulkan_LoadTex (ctx, &skin_tex, 1);
Skin_ClearBottomColors (tskin, tskin, skinsize);
}
skin_tex.data = tskin;
skin->tex = Vulkan_LoadTex (ctx, &skin_tex, 1);
free (tskin);
return skin + skinsize;
}

View file

@ -33,17 +33,28 @@
#include "r_local.h"
VISIBLE int
Mod_CalcFullbright (byte *in, byte *out, int pixels)
Mod_CalcFullbright (const byte *in, byte *out, int pixels)
{
byte fb = 0;
while (pixels--) {
while (pixels-- > 0) {
byte pix = *in++;
byte mask = (pix >= 256 - 32) - 1;
fb |= mask + 1;
// mask is 0 for fullbright, otherwise 0xff
*out++ = pix | mask;
}
return fb;
}
VISIBLE void
Mod_ClearFullbright (const byte *in, byte *out, int pixels)
{
while (pixels-- > 0) {
byte pix = *in++;
byte mask = ~((pix >= 256 - 32) - 1);
// mask is 0xff for fullbright, otherwise 0
*out++ = pix | mask;
}
}

View file

@ -246,3 +246,63 @@ Skin_Init (void)
skin_cache = Hash_NewTable (127, skin_getkey, skin_free, 0, 0);
m_funcs->Skin_InitTranslations ();
}
VISIBLE int
Skin_CalcTopColors (const byte *in, byte *out, int pixels)
{
byte tc = 0;
while (pixels-- > 0) {
byte pix = *in++;
byte a = (pix < TOP_RANGE) - 1;
byte b = (pix > TOP_RANGE + 15) - 1;
byte mask = ~(a & b);
tc |= mask;
// mask is 0 for top color otherwise 0xff
*out++ = (pix - TOP_RANGE) | mask;
}
return tc;
}
VISIBLE int
Skin_CalcBottomColors (const byte *in, byte *out, int pixels)
{
byte bc = 0;
while (pixels-- > 0) {
byte pix = *in++;
byte a = (pix < BOTTOM_RANGE) - 1;
byte b = (pix > BOTTOM_RANGE + 15) - 1;
byte mask = ~(a & b);
bc |= mask;
// mask is 0 for bottom color otherwise 0xff
*out++ = (pix - BOTTOM_RANGE) | mask;
}
return bc;
}
VISIBLE void
Skin_ClearTopColors (const byte *in, byte *out, int pixels)
{
while (pixels-- > 0) {
byte pix = *in++;
byte a = (pix < TOP_RANGE) - 1;
byte b = (pix > TOP_RANGE + 15) - 1;
byte mask = (a & b);
// mask is 0xff for top color otherwise 0
*out++ = (pix - TOP_RANGE) | mask;
}
}
VISIBLE void
Skin_ClearBottomColors (const byte *in, byte *out, int pixels)
{
while (pixels-- > 0) {
byte pix = *in++;
byte a = (pix < BOTTOM_RANGE) - 1;
byte b = (pix > BOTTOM_RANGE + 15) - 1;
byte mask = (a & b);
// mask is 0xff for bottom color otherwise 0
*out++ = (pix - BOTTOM_RANGE) | mask;
}
}