mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-24 20:51:35 +00:00
[skin] Implement top/bottom colors for gl
They don't work yet if the entity does not have an external skin.
This commit is contained in:
parent
0539f07c1a
commit
346ed29f49
3 changed files with 92 additions and 31 deletions
|
@ -122,9 +122,13 @@ tex_t *Skin_DupTex (const tex_t *tex);
|
|||
typedef struct skin_s {
|
||||
tex_t *tex;
|
||||
uint32_t id;
|
||||
uint32_t fb;
|
||||
} skin_t;
|
||||
|
||||
typedef struct glskin_s {
|
||||
uint32_t id;
|
||||
uint32_t fb;
|
||||
} glskin_t;
|
||||
|
||||
skin_t *Skin_Get (uint32_t skin) __attribute__((pure));
|
||||
|
||||
void sw_Skin_SetupSkin (skin_t *skin, int cmap);
|
||||
|
@ -137,5 +141,6 @@ uint32_t glsl_Skin_Colormap (const colormap_t *colormap);
|
|||
|
||||
void gl_Skin_SetupSkin (skin_t *skin, int cmap);
|
||||
void gl_Skin_Destroy (skin_t *skin);
|
||||
glskin_t gl_Skin_Get (const skin_t *skin, const colormap_t *colormap);
|
||||
|
||||
#endif// __mod_internal_h
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/fbsearch.h"
|
||||
#include "QF/image.h"
|
||||
#include "QF/model.h"
|
||||
#include "QF/skin.h"
|
||||
|
@ -54,11 +55,18 @@
|
|||
#include "mod_internal.h"
|
||||
#include "r_internal.h"
|
||||
|
||||
// FIXME colormap (top/bottom colors)
|
||||
//static byte skin_cmap[MAX_TRANSLATIONS][256];
|
||||
typedef struct {
|
||||
const tex_t *tex;
|
||||
glskin_t skin;
|
||||
} skinpair_t;
|
||||
|
||||
#define MAX_GLSKINS 64
|
||||
|
||||
static skinpair_t skin_table[256][MAX_GLSKINS];
|
||||
static int skin_counts[256];
|
||||
|
||||
static void
|
||||
build_skin_8 (tex_t *tex, int texnum, byte *translate,
|
||||
build_skin_8 (const tex_t *tex, int texnum, byte *translate,
|
||||
unsigned scaled_width, unsigned scaled_height, bool alpha)
|
||||
{
|
||||
// Improvements should be mirrored in GL_ResampleTexture in gl_textures.c
|
||||
|
@ -84,7 +92,7 @@ build_skin_8 (tex_t *tex, int texnum, byte *translate,
|
|||
}
|
||||
|
||||
static void
|
||||
build_skin_32 (tex_t *tex, int texnum, byte *translate,
|
||||
build_skin_32 (const tex_t *tex, int texnum, byte *translate,
|
||||
unsigned scaled_width, unsigned scaled_height, bool alpha)
|
||||
{
|
||||
// Improvements should be mirrored in GL_ResampleTexture in gl_textures.c
|
||||
|
@ -124,12 +132,40 @@ build_skin_32 (tex_t *tex, int texnum, byte *translate,
|
|||
gl_aniso);
|
||||
}
|
||||
|
||||
void
|
||||
gl_Skin_SetupSkin (skin_t *skin, int cmap)
|
||||
static int
|
||||
skinpair_cmp (const void *_tex, const void *_skinpair)
|
||||
{
|
||||
//skin->tex = Skin_DupTex (skin->tex);
|
||||
tex_t *tex = skin->tex;
|
||||
skin->tex = nullptr; // tex memory is only temporarily allocated
|
||||
const tex_t *tex = _tex;
|
||||
const skinpair_t *skinpair = _skinpair;
|
||||
intptr_t diff = (intptr_t) tex - (intptr_t) skinpair->tex;
|
||||
return diff < 0 ? -1 : diff > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
glskin_t
|
||||
gl_Skin_Get (const skin_t *skin, const colormap_t *colormap)
|
||||
{
|
||||
if (!skin || !colormap) {
|
||||
return (glskin_t) {};
|
||||
}
|
||||
|
||||
byte top = colormap->top & 0x0f;
|
||||
byte bot = colormap->bottom & 0x0f;
|
||||
int ind = top | (bot << 4);
|
||||
skinpair_t *sp = fbsearch (skin->tex, skin_table[ind], skin_counts[ind],
|
||||
sizeof (skinpair_t), skinpair_cmp);
|
||||
if (sp && sp->tex == skin->tex) {
|
||||
return sp->skin;
|
||||
}
|
||||
if (skin_counts[ind] == MAX_GLSKINS) {
|
||||
return (glskin_t) {};
|
||||
}
|
||||
sp = sp ? sp + 1 : skin_table[ind];
|
||||
int insert = sp - skin_table[ind];
|
||||
memmove (&skin_table[ind][insert + 1], &skin_table[ind][insert],
|
||||
sizeof (skinpair_t[skin_counts[ind] - insert]));
|
||||
skin_counts[ind]++;
|
||||
|
||||
sp->tex = skin->tex;
|
||||
|
||||
auto build_skin = vid.is8bit ? build_skin_8 : build_skin_32;
|
||||
|
||||
|
@ -141,24 +177,43 @@ gl_Skin_SetupSkin (skin_t *skin, int cmap)
|
|||
swidth = max (swidth, 1);
|
||||
sheight = max (sheight, 1);
|
||||
|
||||
int size = tex->width * tex->height;
|
||||
byte palette[256];
|
||||
Skin_SetPalette (palette, top, bot);
|
||||
qfglGenTextures (1, &sp->skin.id);
|
||||
build_skin_32 (sp->tex, sp->skin.id, palette, swidth, sheight, false);
|
||||
|
||||
int size = sp->tex->width * sp->tex->height;
|
||||
byte fbskin[size];
|
||||
qfglGenTextures (1, &skin->id);
|
||||
// FIXME colormap (top/bottom colors)
|
||||
build_skin_32 (tex, skin->id, vid.colormap8, swidth, sheight, false);
|
||||
if (Mod_CalcFullbright (fbskin, tex->data, size)) {
|
||||
tex_t fb_tex = *tex;
|
||||
if (Mod_CalcFullbright (fbskin, skin->tex->data, size)) {
|
||||
tex_t fb_tex = *sp->tex;
|
||||
fb_tex.data = fbskin;
|
||||
qfglGenTextures (1, &skin->fb);
|
||||
build_skin (&fb_tex, skin->fb, vid.colormap8, swidth, sheight, true);
|
||||
qfglGenTextures (1, &sp->skin.fb);
|
||||
build_skin (&fb_tex, sp->skin.fb, palette, swidth, sheight, true);
|
||||
}
|
||||
return sp->skin;
|
||||
}
|
||||
|
||||
void
|
||||
gl_Skin_SetupSkin (skin_t *skin, int cmap)
|
||||
{
|
||||
skin->tex = Skin_DupTex (skin->tex);
|
||||
}
|
||||
|
||||
void
|
||||
gl_Skin_Destroy (skin_t *skin)
|
||||
{
|
||||
qfglDeleteTextures (1, &skin->id);
|
||||
if (skin->fb) {
|
||||
qfglDeleteTextures (1, &skin->fb);
|
||||
for (int i = 0; i < 256; i++) {
|
||||
for (int j = skin_counts[i]; j-- > 0; ) {
|
||||
auto sp = &skin_table[i][j];
|
||||
if (sp->tex == skin->tex) {
|
||||
qfglDeleteTextures (1, &sp->skin.id);
|
||||
if (sp->skin.fb) {
|
||||
qfglDeleteTextures (1, &sp->skin.fb);
|
||||
}
|
||||
skin_counts[i]--;
|
||||
memmove (&skin_table[i][j], &skin_table[i][j + 1],
|
||||
sizeof (skinpair_t[skin_counts[i] - j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -558,14 +558,14 @@ gl_R_DrawAliasModel (entity_t e)
|
|||
|
||||
// if the model has a colorised/external skin, use it, otherwise use
|
||||
// the skin embedded in the model data
|
||||
if (renderer->skin && !gl_nocolors) {
|
||||
skin_t *skin = Skin_Get (renderer->skin);
|
||||
if (!gl_nocolors) {
|
||||
skin_t *skin = renderer->skin ? Skin_Get (renderer->skin) : nullptr;
|
||||
auto colormap = Entity_GetColormap (e);
|
||||
auto glskin = gl_Skin_Get (skin, colormap);
|
||||
|
||||
if (skin) {
|
||||
texture = skin->id;
|
||||
if (gl_fb_models) {
|
||||
fb_texture = skin->fb;
|
||||
}
|
||||
if (glskin.id) {
|
||||
texture = glskin.id;
|
||||
fb_texture = glskin.fb;
|
||||
}
|
||||
}
|
||||
if (!texture) {
|
||||
|
@ -574,9 +574,10 @@ gl_R_DrawAliasModel (entity_t e)
|
|||
e.reg);
|
||||
skindesc = R_AliasGetSkindesc (animation, renderer->skinnum, paliashdr);
|
||||
texture = skindesc->texnum;
|
||||
if (gl_fb_models && !is_fullbright) {
|
||||
fb_texture = skindesc->fb_texnum;
|
||||
}
|
||||
if (!gl_fb_models || is_fullbright) {
|
||||
fb_texture = 0;
|
||||
}
|
||||
|
||||
if (paliashdr->mdl.ident == HEADER_MDL16) {
|
||||
|
|
Loading…
Reference in a new issue