From 5ab69796334ffca4007408505c26d6956d23b4bb Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 10 Jun 2024 22:00:44 +0300 Subject: [PATCH] ref: move common quake sky cloud loading to the engine --- engine/common/mod_bmodel.c | 128 +++++++++++++++++++++++++++++++++---- engine/ref_api.h | 4 +- ref/gl/gl_context.c | 16 ++++- ref/gl/gl_local.h | 1 - ref/gl/gl_warp.c | 106 ------------------------------ ref/soft/r_context.c | 7 +- ref/soft/r_local.h | 2 - 7 files changed, 135 insertions(+), 129 deletions(-) diff --git a/engine/common/mod_bmodel.c b/engine/common/mod_bmodel.c index 384035a2..1724fdfc 100644 --- a/engine/common/mod_bmodel.c +++ b/engine/common/mod_bmodel.c @@ -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 diff --git a/engine/ref_api.h b/engine/ref_api.h index ce11df90..02cbfd91 100644 --- a/engine/ref_api.h +++ b/engine/ref_api.h @@ -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 ); diff --git a/ref/gl/gl_context.c b/ref/gl/gl_context.c index 7d0d5682..2a68d540 100644 --- a/ref/gl/gl_context.c +++ b/ref/gl/gl_context.c @@ -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, diff --git a/ref/gl/gl_local.h b/ref/gl/gl_local.h index e276c322..76338b3d 100644 --- a/ref/gl/gl_local.h +++ b/ref/gl/gl_local.h @@ -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 ); diff --git a/ref/gl/gl_warp.c b/ref/gl/gl_warp.c index 146937bf..74a1b79d 100644 --- a/ref/gl/gl_warp.c +++ b/ref/gl/gl_warp.c @@ -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 diff --git a/ref/soft/r_context.c b/ref/soft/r_context.c index 8fcfee4d..46c0f6b4 100644 --- a/ref/soft/r_context.c +++ b/ref/soft/r_context.c @@ -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, diff --git a/ref/soft/r_local.h b/ref/soft/r_local.h index f8227e83..64ca1c54 100644 --- a/ref/soft/r_local.h +++ b/ref/soft/r_local.h @@ -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 //