ref: move common quake sky cloud loading to the engine

This commit is contained in:
Alibek Omarov 2024-06-10 22:00:44 +03:00
parent ec5e9cb6e3
commit 5ab6979633
7 changed files with 135 additions and 129 deletions

View File

@ -2066,6 +2066,118 @@ static qboolean Mod_LooksLikeWaterTexture( const char *name )
return false;
}
static void Mod_InitSkyClouds( mip_t *mt, texture_t *tx, qboolean custom_palette )
{
#if !XASH_DEDICATED
rgbdata_t r_temp, *r_sky;
uint *trans, *rgba;
uint transpix;
int r, g, b;
int i, j, p;
char texname[32];
int solidskyTexture, alphaskyTexture;
if( !ref.initialized )
return;
Q_snprintf( texname, sizeof( texname ), "%s%s.mip", ( mt->offsets[0] > 0 ) ? "#" : "", tx->name );
if( mt->offsets[0] > 0 )
{
size_t size = sizeof( mip_t ) + (( mt->width * mt->height * 85 ) >> 6 );
if( custom_palette )
size += sizeof( short ) + 768;
r_sky = FS_LoadImage( texname, (byte *)mt, size );
}
else
{
// okay loading it from wad
r_sky = FS_LoadImage( texname, NULL, 0 );
}
if( !r_sky || !r_sky->palette || r_sky->type != PF_INDEXED_32 || r_sky->height == 0 )
{
Con_Printf( S_ERROR "%s: unable to load sky texture %s\n", tx->name );
if( r_sky )
FS_FreeImage( r_sky );
return;
}
// make an average value for the back to avoid
// a fringe on the top level
trans = Mem_Malloc( host.mempool, r_sky->height * r_sky->height * sizeof( *trans ));
r = g = b = 0;
for( i = 0; i < r_sky->width >> 1; i++ )
{
for( j = 0; j < r_sky->height; j++ )
{
p = r_sky->buffer[i * r_sky->width + j + r_sky->height];
rgba = (uint *)r_sky->palette + p;
trans[(i * r_sky->height) + j] = *rgba;
r += ((byte *)rgba)[0];
g += ((byte *)rgba)[1];
b += ((byte *)rgba)[2];
}
}
((byte *)&transpix)[0] = r / ( r_sky->height * r_sky->height );
((byte *)&transpix)[1] = g / ( r_sky->height * r_sky->height );
((byte *)&transpix)[2] = b / ( r_sky->height * r_sky->height );
((byte *)&transpix)[3] = 0;
// build a temporary image
r_temp = *r_sky;
r_temp.width = r_sky->width >> 1;
r_temp.height = r_sky->height;
r_temp.type = PF_RGBA_32;
r_temp.flags = IMAGE_HAS_COLOR;
r_temp.size = r_temp.width * r_temp.height * 4;
r_temp.buffer = (byte *)trans;
r_temp.palette = NULL;
// load it in
solidskyTexture = GL_LoadTextureInternal( "solid_sky", &r_temp, TF_NOMIPMAP );
for( i = 0; i < r_sky->width >> 1; i++ )
{
for( j = 0; j < r_sky->height; j++ )
{
p = r_sky->buffer[i * r_sky->width + j];
if( p == 0 )
{
trans[(i * r_sky->height) + j] = transpix;
}
else
{
rgba = (uint *)r_sky->palette + p;
trans[(i * r_sky->height) + j] = *rgba;
}
}
}
r_temp.flags = IMAGE_HAS_COLOR|IMAGE_HAS_ALPHA;
// load it in
alphaskyTexture = GL_LoadTextureInternal( "alpha_sky", &r_temp, TF_NOMIPMAP );
// clean up
FS_FreeImage( r_sky );
Mem_Free( trans );
// notify the renderer
ref.dllFuncs.R_SetSkyCloudsTextures( solidskyTexture, alphaskyTexture );
if( solidskyTexture && alphaskyTexture )
SetBits( world.flags, FWORLD_SKYSPHERE );
#endif // !XASH_DEDICATED
}
static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureIndex )
{
texture_t *texture = NULL;
@ -2093,17 +2205,7 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
// check for multi-layered sky texture (quake1 specific)
if( bmod->isworld && Q_strncmp( mipTex->name, "sky", 3 ) == 0 && ( mipTex->width / mipTex->height ) == 2 )
{
#if !XASH_DEDICATED
if( !Host_IsDedicated( ))
{
ref.dllFuncs.R_InitSkyClouds( mipTex, texture, usesCustomPalette ); // load quake sky
if( R_GetBuiltinTexture( REF_SOLIDSKY_TEXTURE ) && R_GetBuiltinTexture( REF_ALPHASKY_TEXTURE ))
SetBits( world.flags, FWORLD_SKYSPHERE );
}
#endif // !XASH_DEDICATED
// No texture to load in this case, so just exit.
Mod_InitSkyClouds( mipTex, texture, usesCustomPalette ); // load quake sky
return;
}
@ -2376,8 +2478,8 @@ static void Mod_LoadTextures( model_t *mod, dbspmodel_t *bmod )
// release old sky layers first
if( !Host_IsDedicated() && bmod->isworld )
{
ref.dllFuncs.GL_FreeTexture( R_GetBuiltinTexture( REF_ALPHASKY_TEXTURE ));
ref.dllFuncs.GL_FreeTexture( R_GetBuiltinTexture( REF_SOLIDSKY_TEXTURE ));
ref.dllFuncs.GL_FreeTexture( R_GetBuiltinTexture( "alpha_sky" ));
ref.dllFuncs.GL_FreeTexture( R_GetBuiltinTexture( "solid_sky" ));
}
#endif

View File

@ -161,8 +161,6 @@ enum // r_speeds counters
#define REF_WHITE_TEXTURE "*white"
#define REF_BLACK_TEXTURE "*black"
#define REF_PARTICLE_TEXTURE "*particle"
#define REF_SOLIDSKY_TEXTURE "solid_sky"
#define REF_ALPHASKY_TEXTURE "alpha_sky"
typedef enum connstate_e
{
@ -528,7 +526,7 @@ typedef struct ref_interface_s
void (*CL_InitStudioAPI)( void );
// bmodel
void (*R_InitSkyClouds)( struct mip_s *mt, struct texture_s *tx, qboolean custom_palette );
void (*R_SetSkyCloudsTextures)( int solidskyTexture, int alphaskyTexture );
void (*GL_SubdivideSurface)( model_t *mod, msurface_t *fa );
void (*CL_RunLightStyles)( void );

View File

@ -328,6 +328,20 @@ static void GAME_EXPORT R_Flush( unsigned int flags )
// stub
}
/*
=============
R_SetSkyCloudsTextures
Quake sky cloud texture was processed by the engine,
remember them for easier access during rendering
==============
*/
static void GAME_EXPORT R_SetSkyCloudsTextures( int solidskyTexture, int alphaskyTexture )
{
tr.solidskyTexture = solidskyTexture;
tr.alphaskyTexture = alphaskyTexture;
}
static qboolean R_SetDisplayTransform( ref_screen_rotation_t rotate, int offset_x, int offset_y, float scale_x, float scale_y )
{
qboolean ret = true;
@ -424,7 +438,7 @@ ref_interface_t gReffuncs =
R_StudioLerpMovement,
CL_InitStudioAPI,
R_InitSkyClouds,
R_SetSkyCloudsTextures,
GL_SubdivideSurface,
CL_RunLightStyles,

View File

@ -487,7 +487,6 @@ void R_AliasInit( void );
//
// gl_warp.c
//
void R_InitSkyClouds( mip_t *mt, struct texture_s *tx, qboolean custom_palette );
void R_AddSkyBoxSurface( msurface_t *fa );
void R_ClearSkyBox( void );
void R_DrawSkyBox( void );

View File

@ -665,112 +665,6 @@ void R_DrawClouds( void )
pglFogf( GL_FOG_DENSITY, RI.fogDensity );
}
/*
=============
R_InitSkyClouds
A sky texture is 256*128, with the right side being a masked overlay
==============
*/
void R_InitSkyClouds( mip_t *mt, texture_t *tx, qboolean custom_palette )
{
rgbdata_t r_temp, *r_sky;
uint *trans, *rgba;
uint transpix;
int r, g, b;
int i, j, p;
char texname[32];
if( !glw_state.initialized )
return;
Q_snprintf( texname, sizeof( texname ), "%s%s.mip", ( mt->offsets[0] > 0 ) ? "#" : "", tx->name );
if( mt->offsets[0] > 0 )
{
int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6);
if( custom_palette ) size += sizeof( short ) + 768;
r_sky = gEngfuncs.FS_LoadImage( texname, (byte *)mt, size );
}
else
{
// okay, loading it from wad
r_sky = gEngfuncs.FS_LoadImage( texname, NULL, 0 );
}
// make sure what sky image is valid
if( !r_sky || !r_sky->palette || r_sky->type != PF_INDEXED_32 || r_sky->height == 0 )
{
gEngfuncs.Con_Reportf( S_ERROR "R_InitSky: unable to load sky texture %s\n", tx->name );
if( r_sky ) gEngfuncs.FS_FreeImage( r_sky );
return;
}
// make an average value for the back to avoid
// a fringe on the top level
trans = Mem_Malloc( r_temppool, r_sky->height * r_sky->height * sizeof( *trans ));
r = g = b = 0;
for( i = 0; i < r_sky->width >> 1; i++ )
{
for( j = 0; j < r_sky->height; j++ )
{
p = r_sky->buffer[i * r_sky->width + j + r_sky->height];
rgba = (uint *)r_sky->palette + p;
trans[(i * r_sky->height) + j] = *rgba;
r += ((byte *)rgba)[0];
g += ((byte *)rgba)[1];
b += ((byte *)rgba)[2];
}
}
((byte *)&transpix)[0] = r / ( r_sky->height * r_sky->height );
((byte *)&transpix)[1] = g / ( r_sky->height * r_sky->height );
((byte *)&transpix)[2] = b / ( r_sky->height * r_sky->height );
((byte *)&transpix)[3] = 0;
// build a temporary image
r_temp = *r_sky;
r_temp.width = r_sky->width >> 1;
r_temp.height = r_sky->height;
r_temp.type = PF_RGBA_32;
r_temp.flags = IMAGE_HAS_COLOR;
r_temp.size = r_temp.width * r_temp.height * 4;
r_temp.buffer = (byte *)trans;
r_temp.palette = NULL;
// load it in
tr.solidskyTexture = GL_LoadTextureInternal( REF_SOLIDSKY_TEXTURE, &r_temp, TF_NOMIPMAP );
for( i = 0; i < r_sky->width >> 1; i++ )
{
for( j = 0; j < r_sky->height; j++ )
{
p = r_sky->buffer[i * r_sky->width + j];
if( p == 0 )
{
trans[(i * r_sky->height) + j] = transpix;
}
else
{
rgba = (uint *)r_sky->palette + p;
trans[(i * r_sky->height) + j] = *rgba;
}
}
}
r_temp.flags = IMAGE_HAS_COLOR|IMAGE_HAS_ALPHA;
// load it in
tr.alphaskyTexture = GL_LoadTextureInternal( REF_ALPHASKY_TEXTURE, &r_temp, TF_NOMIPMAP );
// clean up
gEngfuncs.FS_FreeImage( r_sky );
Mem_Free( trans );
}
/*
=============
EmitWaterPolys

View File

@ -328,9 +328,10 @@ qboolean GAME_EXPORT VID_CubemapShot(const char *base, uint size, const float *v
return false;
}
void R_InitSkyClouds(mip_t *mt, texture_t *tx, qboolean custom_palette)
static void GAME_EXPORT R_SetSkyCloudsTextures( int solidskyTexture, int alphaskyTexture )
{
tr.solidskyTexture = solidskyTexture;
tr.alphaskyTexture = alphaskyTexture;
}
static void GAME_EXPORT GL_SubdivideSurface( model_t *mod, msurface_t *fa )
@ -456,7 +457,7 @@ ref_interface_t gReffuncs =
R_StudioLerpMovement,
CL_InitStudioAPI,
R_InitSkyClouds,
R_SetSkyCloudsTextures,
GL_SubdivideSurface,
CL_RunLightStyles,

View File

@ -556,7 +556,6 @@ void R_AliasInit( void );
// gl_warp.c
//
void R_InitSkyClouds( mip_t *mt, struct texture_s *tx, qboolean custom_palette );
void R_AddSkyBoxSurface( msurface_t *fa );
void R_ClearSkyBox( void );
void R_DrawSkyBox( void );
@ -564,7 +563,6 @@ void R_DrawClouds( void );
void EmitWaterPolys( msurface_t *warp, qboolean reverse );
#endif
void GAME_EXPORT R_InitSkyClouds( struct mip_s *mt, struct texture_s *tx, qboolean custom_palette );
//
// gl_vgui.c
//