From c63e13c8f4beff72e5798dc8d035c3dc55e11d80 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Tue, 14 Apr 2026 13:47:07 +0500 Subject: [PATCH] engine: move handling of AVI textures into the engine --- engine/client/avi/avi_ffmpeg.c | 7 +- engine/client/cl_render.c | 8 +- engine/client/cl_video.c | 7 ++ engine/client/client.h | 1 + engine/ref_api.h | 4 +- ref/gl/gl_context.c | 4 +- ref/gl/gl_draw.c | 129 ++++++++++----------------------- ref/gl/gl_image.c | 3 - ref/gl/gl_local.h | 5 +- ref/null/r_context.c | 11 +-- ref/soft/r_context.c | 4 +- ref/soft/r_draw.c | 13 +--- ref/soft/r_image.c | 3 - ref/soft/r_local.h | 4 +- 14 files changed, 72 insertions(+), 131 deletions(-) diff --git a/engine/client/avi/avi_ffmpeg.c b/engine/client/avi/avi_ffmpeg.c index a569e370..a691b382 100644 --- a/engine/client/avi/avi_ffmpeg.c +++ b/engine/client/avi/avi_ffmpeg.c @@ -444,13 +444,16 @@ qboolean AVI_Think( movie_state_t *Avi ) if( Avi->texture == 0 ) { + int cinTexture = SCR_GetCinematicTexture(); int w = Avi->w >= 0 ? Avi->w : refState.width; int h = Avi->h >= 0 ? Avi->h : refState.height; - ref.dllFuncs.R_DrawStretchRaw( Avi->x, Avi->y, w, h, Avi->xres, Avi->yres, Avi->dst, redraw ); + if( redraw ) + ref.dllFuncs.GL_UpdateTexture( cinTexture, Avi->xres, Avi->yres, Avi->xres, Avi->yres, Avi->dst, PF_BGRA_32 ); + ref.dllFuncs.R_DrawStretchPic( Avi->x, Avi->y, w, h, 0, 0, 1, 1, cinTexture ); } else if( redraw && Avi->texture > 0 ) - ref.dllFuncs.AVI_UploadRawFrame( Avi->texture, Avi->xres, Avi->yres, Avi->w, Avi->h, Avi->dst ); + ref.dllFuncs.GL_UpdateTexture( Avi->texture, Avi->xres, Avi->yres, Avi->w, Avi->h, Avi->dst, PF_BGRA_32 ); if( flushing && !decoded ) return false; // probably hit an EOF diff --git a/engine/client/cl_render.c b/engine/client/cl_render.c index 938b80cb..c30141b6 100644 --- a/engine/client/cl_render.c +++ b/engine/client/cl_render.c @@ -214,6 +214,11 @@ static void pfnAVI_StreamSound( movie_state_t *avi, int entnum, float fvol, floa return; // stub, use AVI_SetParm and AVI_Think to stream AVI sound } +static void pfnAVI_UploadRawFrame( int texture, int cols, int rows, int width, int height, const byte *data ) +{ + ref.dllFuncs.GL_UpdateTexture( texture, cols, rows, width, height, data, PF_BGRA_32 ); +} + static render_api_t gRenderAPI = { pfnRenderGetParm, // GL_RenderGetParm, @@ -243,7 +248,7 @@ static render_api_t gRenderAPI = AVI_GetVideoInfo, AVI_GetVideoFrameNumber, AVI_GetVideoFrame, - NULL, // R_UploadStretchRaw, + pfnAVI_UploadRawFrame, // AVI_UploadRawFrame AVI_FreeVideo, AVI_IsActive, pfnAVI_StreamSound, @@ -301,7 +306,6 @@ qboolean R_InitRenderAPI( void ) gRenderAPI.GL_TextureData = ref.dllFuncs.GL_TextureData; gRenderAPI.GL_LoadTexture = ref.dllFuncs.GL_LoadTexture; gRenderAPI.GL_FreeTexture = ref.dllFuncs.GL_FreeTexture; - gRenderAPI.AVI_UploadRawFrame = ref.dllFuncs.AVI_UploadRawFrame; gRenderAPI.GL_Bind = ref.dllFuncs.GL_Bind; ref.dllFuncs.R_FillRenderAPI( &gRenderAPI ); diff --git a/engine/client/cl_video.c b/engine/client/cl_video.c index 981a4e6b..00008de1 100644 --- a/engine/client/cl_video.c +++ b/engine/client/cl_video.c @@ -25,6 +25,7 @@ AVI PLAYING */ static movie_state_t *cin_state; +static int cin_texture; /* ================== @@ -281,6 +282,12 @@ void SCR_InitCinematic( void ) { AVI_Initailize (); cin_state = AVI_GetState( CIN_MAIN ); + cin_texture = ref.dllFuncs.GL_CreateTexture( "*cintexture", 64, 64, NULL, TF_NOMIPMAP|TF_CLAMP ); +} + +int SCR_GetCinematicTexture( void ) +{ + return cin_texture; } /* diff --git a/engine/client/client.h b/engine/client/client.h index ab18db39..d49de2dd 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -1215,6 +1215,7 @@ void SteamBroker_TerminateGameConnection( void ); // cl_video.c // void SCR_InitCinematic( void ); +int SCR_GetCinematicTexture( void ); void SCR_FreeCinematic( void ); qboolean SCR_PlayCinematic( const char *name ); qboolean SCR_DrawCinematic( void ); diff --git a/engine/ref_api.h b/engine/ref_api.h index a44a0024..b32e977a 100644 --- a/engine/ref_api.h +++ b/engine/ref_api.h @@ -599,6 +599,7 @@ typedef struct ref_interface_s void (*R_SetDetailScaleForTexture)( int texture, float xScale, float yScale ); // Texture tools (used by engine directly) + int (*GL_CreateTexture)( const char *name, int width, int height, const void *buffer, texFlags_t flags ); int (*GL_FindTexture)( const char *name ); const char* (*GL_TextureName)( unsigned int texnum ); const byte* (*GL_TextureData)( unsigned int texnum ); // may be NULL @@ -606,8 +607,7 @@ typedef struct ref_interface_s void (*GL_FreeTexture)( unsigned int texnum ); void (*R_OverrideTextureSourceSize)( unsigned int texnum, unsigned int srcWidth, unsigned int srcHeight ); // used to override decal size for texture replacement - // AVI - void (*AVI_UploadRawFrame)( int texture, int cols, int rows, int width, int height, const byte *data ); + void (*GL_UpdateTexture)( int texnum, int cols, int rows, int width, int height, const byte *buffer, pixformat_t fmt ); // glState related calls (used by engine directly) void (*GL_Bind)( int tmu, unsigned int texnum ); diff --git a/ref/gl/gl_context.c b/ref/gl/gl_context.c index 23a56a8c..96f6bc70 100644 --- a/ref/gl/gl_context.c +++ b/ref/gl/gl_context.c @@ -525,7 +525,6 @@ const ref_interface_t gReffuncs = R_SetupSky, R_Set2DMode, - R_DrawStretchRaw, R_DrawStretchPic, CL_FillRGBA, R_WorldToScreen, @@ -562,6 +561,7 @@ const ref_interface_t gReffuncs = R_GetDetailScaleForTexture, R_SetDetailScaleForTexture, + GL_CreateTexture, GL_FindTexture, GL_TextureName, GL_TextureData, @@ -569,7 +569,7 @@ const ref_interface_t gReffuncs = GL_FreeTexture, R_OverrideTextureSourceSize, - R_UploadStretchRaw, + GL_UpdateTexture, GL_Bind, diff --git a/ref/gl/gl_draw.c b/ref/gl/gl_draw.c index e77a365b..6307e80b 100644 --- a/ref/gl/gl_draw.c +++ b/ref/gl/gl_draw.c @@ -55,120 +55,71 @@ void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, f /* ============= -R_DrawStretchRaw +GL_UpdateTexture + +Upload raw BGRA pixel data to an existing texture ============= */ -void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty ) +void GL_UpdateTexture( int texnum, int cols, int rows, int width, int height, const byte *buffer, pixformat_t fmt ) { byte *raw = NULL; gl_texture_t *tex; + GLenum gl_format; + + switch( fmt ) + { + case PF_RGBA_32: + gl_format = GL_RGBA; + break; + case PF_BGRA_32: + gl_format = GL_BGRA; + break; + case PF_RGB_24: + gl_format = GL_RGB; + break; + case PF_BGR_24: + gl_format = GL_BGR; + break; + case PF_LUMINANCE: + gl_format = GL_LUMINANCE; + break; + default: + gEngfuncs.Con_DPrintf( S_ERROR "%s: unsupported pixel format %i\n", __func__, fmt ); + return; + } if( !GL_Support( GL_ARB_TEXTURE_NPOT_EXT )) { - int width = 1, height = 1; - - // check the dimensions - width = NearestPOW( cols, true ); - height = NearestPOW( rows, false ); - - if( cols != width || rows != height ) - { - raw = GL_ResampleTexture( data, cols, rows, width, height, false ); - cols = width; - rows = height; - } - } - else - { - raw = (byte *)data; - } - - if( cols > glConfig.max_2d_texture_size ) - gEngfuncs.Host_Error( "%s: size %i exceeds hardware limits\n", __func__, cols ); - if( rows > glConfig.max_2d_texture_size ) - gEngfuncs.Host_Error( "%s: size %i exceeds hardware limits\n", __func__, rows ); - - pglDisable( GL_BLEND ); - pglDisable( GL_ALPHA_TEST ); - pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); - - tex = R_GetTexture( tr.cinTexture ); - GL_Bind( XASH_TEXTURE0, tr.cinTexture ); - - if( cols == tex->width && rows == tex->height ) - { - if( dirty ) - { - pglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_BGRA, GL_UNSIGNED_BYTE, raw ); - } - } - else - { - tex->size = cols * rows * 4; - tex->width = cols; - tex->height = rows; - if( dirty ) - { - pglTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, cols, rows, 0, GL_BGRA, GL_UNSIGNED_BYTE, raw ); - } - } - - pglBegin( GL_QUADS ); - pglTexCoord2f( 0, 0 ); - pglVertex2f( x, y ); - pglTexCoord2f( 1, 0 ); - pglVertex2f( x + w, y ); - pglTexCoord2f( 1, 1 ); - pglVertex2f( x + w, y + h ); - pglTexCoord2f( 0, 1 ); - pglVertex2f( x, y + h ); - pglEnd(); -} - -/* -============= -R_UploadStretchRaw -============= -*/ -void R_UploadStretchRaw( int texture, int cols, int rows, int width, int height, const byte *data ) -{ - byte *raw = NULL; - gl_texture_t *tex; - - if( !GL_Support( GL_ARB_TEXTURE_NPOT_EXT )) - { - // check the dimensions width = NearestPOW( width, true ); height = NearestPOW( height, false ); } - else - { - width = bound( 128, width, glConfig.max_2d_texture_size ); - height = bound( 128, height, glConfig.max_2d_texture_size ); - } if( cols != width || rows != height ) { - raw = GL_ResampleTexture( data, cols, rows, width, height, false ); + raw = GL_ResampleTexture( buffer, cols, rows, width, height, false ); cols = width; rows = height; } else - { - raw = (byte *)data; - } + raw = (byte *)buffer; if( cols > glConfig.max_2d_texture_size ) gEngfuncs.Host_Error( "%s: size %i exceeds hardware limits\n", __func__, cols ); if( rows > glConfig.max_2d_texture_size ) gEngfuncs.Host_Error( "%s: size %i exceeds hardware limits\n", __func__, rows ); - tex = R_GetTexture( texture ); - GL_Bind( GL_KEEP_UNIT, texture ); - tex->width = cols; - tex->height = rows; + tex = R_GetTexture( texnum ); + GL_Bind( GL_KEEP_UNIT, texnum ); + + if( cols == tex->width && rows == tex->height ) + pglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, gl_format, GL_UNSIGNED_BYTE, raw ); + else + { + tex->width = cols; + tex->height = rows; + pglTexImage2D( GL_TEXTURE_2D, 0, tex->format, cols, rows, 0, gl_format, GL_UNSIGNED_BYTE, raw ); + } - pglTexImage2D( GL_TEXTURE_2D, 0, tex->format, cols, rows, 0, GL_BGRA, GL_UNSIGNED_BYTE, raw ); GL_ApplyTextureParams( tex ); } diff --git a/ref/gl/gl_image.c b/ref/gl/gl_image.c index ff3b95ac..a44b4c89 100644 --- a/ref/gl/gl_image.c +++ b/ref/gl/gl_image.c @@ -1971,9 +1971,6 @@ static void GL_CreateInternalTextures( void ) ((uint *)pic->buffer)[x] = 0xFF000000; tr.blackTexture = GL_LoadTextureInternal( REF_BLACK_TEXTURE, pic, TF_COLORMAP ); - // cinematic dummy - pic = GL_FakeImage( 640, 100, 1, IMAGE_HAS_COLOR ); - tr.cinTexture = GL_LoadTextureInternal( "*cintexture", pic, TF_NOMIPMAP|TF_CLAMP ); } /* diff --git a/ref/gl/gl_local.h b/ref/gl/gl_local.h index a3fa866c..57a40a8d 100644 --- a/ref/gl/gl_local.h +++ b/ref/gl/gl_local.h @@ -187,8 +187,6 @@ typedef struct int lightmapTextures[MAX_LIGHTMAPS]; int dlightTexture; // custom dlight texture int skyboxTextures[SKYBOX_MAX_SIDES]; // skybox sides - int cinTexture; // cinematic texture - int skytexturenum; // this not a gl_texturenum! int skyboxbasenum; // start with 5800 @@ -318,7 +316,7 @@ void R_ClearDecals( void ); // gl_draw.c // void R_Set2DMode( qboolean enable ); -void R_UploadStretchRaw( int texture, int cols, int rows, int width, int height, const byte *data ); +void GL_UpdateTexture( int texnum, int cols, int rows, int width, int height, const byte *buffer, pixformat_t fmt ); // // gl_image.c @@ -459,7 +457,6 @@ void R_RenderFrame( const struct ref_viewpass_s *vp ); void R_EndFrame( void ); void R_ClearScene( void ); void R_GetTextureParms( int *w, int *h, int texnum ); -void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty ); void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum ); qboolean R_SpeedsMessage( char *out, size_t size ); qboolean R_CullBox( const vec3_t mins, const vec3_t maxs ); diff --git a/ref/null/r_context.c b/ref/null/r_context.c index 32914200..1901838d 100644 --- a/ref/null/r_context.c +++ b/ref/null/r_context.c @@ -131,11 +131,6 @@ static void R_SetupSky( int *skytextures ) ; } -static void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty ) -{ - ; -} - static void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum ) { ; @@ -319,7 +314,7 @@ static void R_EntityRemoveDecals( struct model_s *mod ) ; } -static void AVI_UploadRawFrame( int texture, int cols, int rows, int width, int height, const byte *data ) +static void GL_UpdateTexture( int texnum, int cols, int rows, int width, int height, const byte *buffer, pixformat_t fmt ) { ; } @@ -475,7 +470,6 @@ static const ref_interface_t gReffuncs = .R_SetupSky = R_SetupSky, .R_Set2DMode = R_SimpleStubBool, - .R_DrawStretchRaw = R_DrawStretchRaw, .R_DrawStretchPic = R_DrawStretchPic, .FillRGBA = FillRGBA, .WorldToScreen = WorldToScreen, @@ -512,6 +506,7 @@ static const ref_interface_t gReffuncs = .R_GetDetailScaleForTexture = R_GetDetailScaleForTexture, .R_SetDetailScaleForTexture = R_SetDetailScaleForTexture, + .GL_CreateTexture = GL_CreateTexture, .GL_FindTexture = GL_FindTexture, .GL_TextureName = GL_TextureName, .GL_TextureData = GL_TextureData, @@ -519,7 +514,7 @@ static const ref_interface_t gReffuncs = .GL_FreeTexture = R_SimpleStubUInt, .R_OverrideTextureSourceSize = R_OverrideTextureSourceSize, - .AVI_UploadRawFrame = AVI_UploadRawFrame, + .GL_UpdateTexture = GL_UpdateTexture, .GL_Bind = GL_Bind, diff --git a/ref/soft/r_context.c b/ref/soft/r_context.c index 37c85c4a..5ee0c558 100644 --- a/ref/soft/r_context.c +++ b/ref/soft/r_context.c @@ -464,7 +464,6 @@ const ref_interface_t gReffuncs = R_SetupSky, R_Set2DMode, - R_DrawStretchRaw, R_DrawStretchPic, CL_FillRGBA, R_WorldToScreen, @@ -501,6 +500,7 @@ const ref_interface_t gReffuncs = R_GetDetailScaleForTexture, R_SetDetailScaleForTexture, + GL_CreateTexture, GL_FindTexture, GL_TextureName, GL_TextureData, @@ -508,7 +508,7 @@ const ref_interface_t gReffuncs = GL_FreeTexture, R_OverrideTextureSourceSize, - R_UploadStretchRaw, + GL_UpdateTexture, GL_Bind, diff --git a/ref/soft/r_draw.c b/ref/soft/r_draw.c index d83e916d..13312535 100644 --- a/ref/soft/r_draw.c +++ b/ref/soft/r_draw.c @@ -219,19 +219,10 @@ void Draw_Fill( int x, int y, int w, int h ) /* ============= -R_DrawStretchRaw +GL_UpdateTexture ============= */ -void GAME_EXPORT R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty ) -{ -} - -/* -============= -R_UploadStretchRaw -============= -*/ -void GAME_EXPORT R_UploadStretchRaw( int texture, int cols, int rows, int width, int height, const byte *data ) +void GAME_EXPORT GL_UpdateTexture( int texnum, int cols, int rows, int width, int height, const byte *buffer, pixformat_t fmt ) { } diff --git a/ref/soft/r_image.c b/ref/soft/r_image.c index 38e6182a..4e771854 100644 --- a/ref/soft/r_image.c +++ b/ref/soft/r_image.c @@ -901,9 +901,6 @@ static void GL_CreateInternalTextures( void ) ((uint *)pic->buffer )[x] = 0xFF000000; tr.blackTexture = GL_LoadTextureInternal( REF_BLACK_TEXTURE, pic, TF_COLORMAP ); - // cinematic dummy - pic = GL_FakeImage( 640, 100, 1, IMAGE_HAS_COLOR ); - tr.cinTexture = GL_LoadTextureInternal( "*cintexture", pic, TF_NOMIPMAP | TF_CLAMP ); } /* diff --git a/ref/soft/r_local.h b/ref/soft/r_local.h index 10d539aa..15bdecd3 100644 --- a/ref/soft/r_local.h +++ b/ref/soft/r_local.h @@ -205,7 +205,6 @@ typedef struct int lightmapTextures[MAX_LIGHTMAPS]; int dlightTexture; // custom dlight texture int skyboxTextures[6]; // skybox sides - int cinTexture; // cinematic texture // entity lists draw_list_t draw_stack[MAX_DRAW_STACK]; @@ -335,7 +334,7 @@ void GL_Bind( int tmu, unsigned int texnum ); // gl_draw.c // void R_Set2DMode( qboolean enable ); -void R_UploadStretchRaw( int texture, int cols, int rows, int width, int height, const byte *data ); // +void GL_UpdateTexture( int texnum, int cols, int rows, int width, int height, const byte *buffer, pixformat_t fmt ); // gl_image.c // @@ -451,7 +450,6 @@ void R_RenderFrame( const struct ref_viewpass_s *vp ); void R_EndFrame( void ); void R_ClearScene( void ); void R_GetTextureParms( int *w, int *h, int texnum ); -void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty ); void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum ); qboolean R_SpeedsMessage( char *out, size_t size ); qboolean R_CullBox( const vec3_t mins, const vec3_t maxs );