engine: implement loading luma in half-life

This commit is contained in:
Alibek Omarov
2025-11-18 14:39:59 +05:00
parent c2448c8881
commit 93dfcc344b
5 changed files with 68 additions and 23 deletions

View File

@@ -70,6 +70,7 @@ typedef enum
IL_OVERVIEW = BIT(6), // overview required some unque operations
IL_LOAD_PLAYER_DECAL = BIT(7), // special mode for player decals
IL_KTX2_RAW = BIT(8), // renderer can consume raw KTX2 files (e.g. ref_vk)
IL_ALLOW_WAD3_LUMA = BIT(9), // allow usage of luma textures in wad3 (tilde textures)
} ilFlags_t;
// goes into rgbdata_t->encode

View File

@@ -358,6 +358,25 @@ qboolean Image_LoadLMP( const char *name, const byte *buffer, fs_offset_t filesi
return Image_AddIndexedImageToPack( fin, image.width, image.height );
}
static int Image_FindBestBlack( const uint *pal )
{
int min_color = 32;
int best_black = -1;
for( int i = 0; i < 256; i++ )
{
int color = pal[i] & 0xFFFFFF;
if( color < min_color )
{
min_color = color;
best_black = i;
}
}
return best_black;
}
/*
=============
Image_LoadMIP
@@ -416,29 +435,27 @@ qboolean Image_LoadMIP( const char *name, const byte *buffer, fs_offset_t filesi
}
else
{
int pal_type;
// NOTE: we can have luma-pixels if quake1 texture
// converted into the hl texture but palette leave unchanged
// this is a good reason for using fullbright pixels
pal_type = Image_ComparePalette( pal );
// check for luma pixels (but ignore liquid textures because they have no lightmap)
if( mip.name[0] != '*' && mip.name[0] != '!' && pal_type == PAL_QUAKE1 )
{
for( i = 0; i < image.width * image.height; i++ )
{
if( fin[i] > 224 )
{
SetBits( image.flags, IMAGE_HAS_LUMA );
image.black_pixel = 0;
break;
}
}
}
const int pal_type = Image_ComparePalette( pal );
if( pal_type == PAL_QUAKE1 )
{
// check for luma pixels (but ignore liquid textures because they have no lightmap)
if( mip.name[0] != '*' && mip.name[0] != '!' )
{
for( i = 0; i < image.width * image.height; i++ )
{
if( fin[i] > 224 )
{
SetBits( image.flags, IMAGE_HAS_LUMA );
image.black_pixel = 0;
break;
}
}
}
SetBits( image.flags, IMAGE_QUAKEPAL );
// if texture was converted from quake to half-life with no palette changes
@@ -449,11 +466,30 @@ qboolean Image_LoadMIP( const char *name, const byte *buffer, fs_offset_t filesi
{
// half-life mips need texgamma applied
rendermode = LUMP_TEXGAMMA;
// three checks here: check if we can load luma, check the texture name and, finally,
// validate that palette isn't NULL
if( Image_CheckFlag( IL_ALLOW_WAD3_LUMA )
&& ( mip.name[0] == '~' || ( mip.name[0] == '+' && isdigit( mip.name[1] ) && mip.name[2] == '~' ))
&& pal != NULL )
{
SetBits( image.flags, IMAGE_HAS_LUMA );
}
}
}
Image_GetPaletteLMP( pal, rendermode );
image.d_currentpal[255] &= 0xFFFFFF;
if( rendermode == LUMP_TEXGAMMA && FBitSet( image.flags, IMAGE_HAS_LUMA ))
{
// thanks to Unkle Mike for an idea of looking best black pixel
image.black_pixel = Image_FindBestBlack( image.d_currentpal );
// failed to find good pixel, refuse to load luma
if( image.black_pixel == -1 )
ClearBits( image.flags, IMAGE_HAS_LUMA );
}
}
else if( image.hint != IL_HINT_HL && filesize >= (int)sizeof(mip) + ((pixels * 85)>>6))
{
@@ -466,7 +502,7 @@ qboolean Image_LoadMIP( const char *name, const byte *buffer, fs_offset_t filesi
// check for luma and alpha pixels
// don't apply luma to water surfaces because they have no lightmap
if( !image.custom_palette && mip.name[0] != '*' && mip.name != '!' )
if( !image.custom_palette && mip.name[0] != '*' && mip.name[0] != '!' )
{
for( i = 0; i < image.width * image.height; i++ )
{

View File

@@ -2583,6 +2583,7 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
const mip_t *mipTex = Mod_GetMipTexForTexture( bmod, textureIndex );
const qboolean usesCustomPalette = Mod_CalcMipTexUsesCustomPalette( mod, bmod, textureIndex );
const qboolean iswater = Mod_LooksLikeWaterTexture( mipTex->name );
const uint texture_force_flags = r_allow_wad3_luma.value ? IL_ALLOW_WAD3_LUMA : 0;
// check for multi-layered sky texture (quake1 specific)
if( bmod->isworld && Q_strncmp( mipTex->name, "sky", 3 ) == 0 && ( mipTex->width / mipTex->height ) == 2 )
@@ -2633,6 +2634,7 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
#if !XASH_DEDICATED
if( !Host_IsDedicated( ) && pic != NULL )
{
Image_SetForceFlags( texture_force_flags );
texture->gl_texturenum = ref.dllFuncs.GL_LoadTextureFromBuffer( texpath, pic, txFlags, false );
FS_FreeImage( pic );
}
@@ -2652,6 +2654,7 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
const size_t size = Mod_CalculateMipTexSize( mipTex, usesCustomPalette );
Q_snprintf( texName, sizeof( texName ), "#%s:%s.mip", loadstat.name, mipTex->name );
Image_SetForceFlags( texture_force_flags );
texture->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texName, (byte *)mipTex, size, txFlags );
}
@@ -2684,6 +2687,8 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
Q_snprintf( texName, sizeof( texName ), "#%s:%s_luma.mip", loadstat.name, mipTex->name );
Image_SetForceFlags( texture_force_flags );
if( mipTex->offsets[0] > 0 )
{
const size_t size = Mod_CalculateMipTexSize( mipTex, usesCustomPalette );

View File

@@ -129,11 +129,12 @@ typedef struct world_static_s
} world_static_t;
#ifndef REF_DLL
extern world_static_t world;
extern poolhandle_t com_studiocache;
extern convar_t mod_studiocache;
extern convar_t r_wadtextures;
extern convar_t r_showhull;
extern world_static_t world;
extern poolhandle_t com_studiocache;
extern convar_t mod_studiocache;
extern convar_t r_wadtextures;
extern convar_t r_showhull;
extern convar_t r_allow_wad3_luma;
extern const mclipnode16_t box_clipnodes16[6];
extern const mclipnode32_t box_clipnodes32[6];

View File

@@ -31,6 +31,7 @@ poolhandle_t com_studiocache; // cache for submodels
CVAR_DEFINE( mod_studiocache, "r_studiocache", "1", FCVAR_ARCHIVE, "enables studio cache for speedup tracing hitboxes" );
CVAR_DEFINE_AUTO( r_wadtextures, "0", 0, "completely ignore textures in the bsp-file if enabled" );
CVAR_DEFINE_AUTO( r_showhull, "0", 0, "draw collision hulls 1-3" );
CVAR_DEFINE_AUTO( r_allow_wad3_luma, "0", FCVAR_ARCHIVE, "allow usage of luma textures in wad3 (tilde textures)" );
/*
===============================================================================
@@ -142,6 +143,7 @@ void Mod_Init( void )
Cvar_RegisterVariable( &mod_studiocache );
Cvar_RegisterVariable( &r_wadtextures );
Cvar_RegisterVariable( &r_showhull );
Cvar_RegisterVariable( &r_allow_wad3_luma );
Cmd_AddCommand( "mapstats", Mod_PrintWorldStats_f, "show stats for currently loaded map" );
Cmd_AddCommand( "modellist", Mod_Modellist_f, "display loaded models list" );