21 Nov 2012

This commit is contained in:
g-cont 2012-11-21 00:00:00 +04:00 committed by Alibek Omarov
parent 68f25c4a05
commit 99a93de377
18 changed files with 382 additions and 63 deletions

View File

@ -358,8 +358,8 @@ static HIMAGE pfnPIC_Load( const char *szPicName, const byte *image_buf, long im
// add default parms to image
flags |= TF_IMAGE;
host.decal_loading = true;
tx = GL_LoadTexture( szPicName, image_buf, image_size, flags );
host.decal_loading = true; // allow decal images for menu
tx = GL_LoadTexture( szPicName, image_buf, image_size, flags, NULL );
host.decal_loading = false;
return tx;

View File

@ -126,7 +126,7 @@ void CL_DuplicateTexture( mstudiotexture_t *ptexture, int topcolor, int bottomco
Q_memcpy( paletteBackup, pal, 768 );
raw = CL_CreateRawTextureFromPixels( tx, &size, topcolor, bottomcolor );
ptexture->index = GL_LoadTexture( texname, raw, size, TF_FORCE_COLOR ); // do copy
ptexture->index = GL_LoadTexture( texname, raw, size, TF_FORCE_COLOR, NULL ); // do copy
GL_SetTextureType( ptexture->index, TEX_REMAP );
// restore original palette

View File

@ -259,7 +259,7 @@ void SCR_DrawPlaque( void )
if(( cl_allow_levelshots->integer && !cls.changelevel ) || Cvar_VariableInteger( "sv_background" ))
{
levelshot = GL_LoadTexture( cl_levelshot_name->string, NULL, 0, TF_IMAGE );
levelshot = GL_LoadTexture( cl_levelshot_name->string, NULL, 0, TF_IMAGE, NULL );
GL_SetRenderMode( kRenderNormal );
R_DrawStretchPic( 0, 0, scr_width->integer, scr_height->integer, 0, 0, 1, 1, levelshot );
@ -445,7 +445,7 @@ static void SCR_LoadCreditsFont( void )
if( cls.creditsFont.valid ) return; // already loaded
cls.creditsFont.hFontTexture = GL_LoadTexture( "gfx.wad/creditsfont.fnt", NULL, 0, TF_IMAGE );
cls.creditsFont.hFontTexture = GL_LoadTexture( "gfx.wad/creditsfont.fnt", NULL, 0, TF_IMAGE, NULL );
R_GetTextureParms( &fontWidth, NULL, cls.creditsFont.hFontTexture );
// setup creditsfont
@ -516,15 +516,15 @@ static void SCR_InstallParticlePalette( void )
void SCR_RegisterShaders( void )
{
cls.fillImage = GL_LoadTexture( "*white", NULL, 0, TF_IMAGE ); // used for FillRGBA
cls.particleImage = GL_LoadTexture( "*particle", NULL, 0, TF_IMAGE );
cls.fillImage = GL_LoadTexture( "*white", NULL, 0, TF_IMAGE, NULL ); // used for FillRGBA
cls.particleImage = GL_LoadTexture( "*particle", NULL, 0, TF_IMAGE, NULL );
// register gfx.wad images
cls.pauseIcon = GL_LoadTexture( "gfx.wad/paused.lmp", NULL, 0, TF_IMAGE );
cls.pauseIcon = GL_LoadTexture( "gfx.wad/paused.lmp", NULL, 0, TF_IMAGE, NULL );
if( cl_allow_levelshots->integer )
cls.loadingBar = GL_LoadTexture( "gfx.wad/lambda.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE );
else cls.loadingBar = GL_LoadTexture( "gfx.wad/lambda.lmp", NULL, 0, TF_IMAGE );
cls.tileImage = GL_LoadTexture( "gfx.wad/backtile.lmp", NULL, 0, TF_UNCOMPRESSED|TF_NOPICMIP|TF_NOMIPMAP );
cls.loadingBar = GL_LoadTexture( "gfx.wad/lambda.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE, NULL );
else cls.loadingBar = GL_LoadTexture( "gfx.wad/lambda.lmp", NULL, 0, TF_IMAGE, NULL );
cls.tileImage = GL_LoadTexture( "gfx.wad/backtile.lmp", NULL, 0, TF_UNCOMPRESSED|TF_NOPICMIP|TF_NOMIPMAP, NULL );
cls.hChromeSprite = pfnSPR_Load( "sprites/shellchrome.spr" );
}

View File

@ -2649,7 +2649,7 @@ int CL_DecalIndex( int id )
Q_snprintf( decalname, sizeof( decalname ), "materials/decals/%s.tga", host.draw_decals[id] );
if( FS_FileExists( decalname, false ))
gl_texturenum = GL_LoadTexture( decalname, NULL, 0, TF_DECAL );
gl_texturenum = GL_LoadTexture( decalname, NULL, 0, TF_DECAL, NULL );
if( gl_texturenum )
{
@ -2670,7 +2670,7 @@ int CL_DecalIndex( int id )
}
}
if( !load_external ) cl.decal_index[id] = GL_LoadTexture( host.draw_decals[id], NULL, 0, TF_DECAL );
if( !load_external ) cl.decal_index[id] = GL_LoadTexture( host.draw_decals[id], NULL, 0, TF_DECAL, NULL );
}
host.decal_loading = false;

View File

@ -464,7 +464,7 @@ qboolean VID_ScreenShot( const char *filename, int shot_type )
break;
}
Image_Process( &r_shot, width, height, 0.0f, flags );
Image_Process( &r_shot, width, height, 0.0f, flags, NULL );
// write image
result = FS_SaveImage( filename, r_shot );
@ -530,7 +530,7 @@ qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qbo
r_side->size = r_side->width * r_side->height * 3;
r_side->buffer = temp;
if( flags ) Image_Process( &r_side, 0, 0, 0.0f, flags );
if( flags ) Image_Process( &r_side, 0, 0, 0.0f, flags, NULL );
Q_memcpy( buffer + (size * size * 3 * i), r_side->buffer, size * size * 3 );
}

View File

@ -879,7 +879,7 @@ GL_UploadTexture
upload texture into video memory
===============
*/
static void GL_UploadTexture( rgbdata_t *pic, gltexture_t *tex, qboolean subImage )
static void GL_UploadTexture( rgbdata_t *pic, gltexture_t *tex, qboolean subImage, imgfilter_t *filter )
{
byte *buf, *data;
const byte *bufend;
@ -929,7 +929,7 @@ static void GL_UploadTexture( rgbdata_t *pic, gltexture_t *tex, qboolean subImag
img_flags |= IMAGE_FORCE_RGBA;
// processing image before uploading (force to rgba, make luma etc)
if( pic->buffer ) Image_Process( &pic, 0, 0, 0.0f, img_flags );
if( pic->buffer ) Image_Process( &pic, 0, 0, 0.0f, img_flags, filter );
if( tex->flags & TF_LUMINANCE )
{
@ -1069,7 +1069,7 @@ static void GL_UploadTexture( rgbdata_t *pic, gltexture_t *tex, qboolean subImag
GL_LoadTexture
================
*/
int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags )
int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags, imgfilter_t *filter )
{
gltexture_t *tex;
rgbdata_t *pic;
@ -1085,7 +1085,7 @@ int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags )
return 0;
}
// get rid of black vertical line on a 'BlackMesa map'
// HACKHACK: get rid of black vertical line on a 'BlackMesa map'
if( !Q_strcmp( name, "#lab1_map1.mip" ) || !Q_strcmp( name, "#lab1_map2.mip" ))
{
flags |= TF_NEAREST;
@ -1138,10 +1138,10 @@ int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags )
tex->texnum = tr.skyboxbasenum++;
else tex->texnum = i; // texnum is used for fast acess into r_textures array too
GL_UploadTexture( pic, tex, false );
GL_UploadTexture( pic, tex, false, filter );
GL_TexFilter( tex, false ); // update texture filter, wrap etc
if(!( flags & (TF_KEEP_8BIT|TF_KEEP_RGBDATA)))
if(!( flags & ( TF_KEEP_8BIT|TF_KEEP_RGBDATA )))
FS_FreeImage( pic ); // release source texture
// add to hash table
@ -1221,7 +1221,7 @@ int GL_LoadTextureInternal( const char *name, rgbdata_t *pic, texFlags_t flags,
tex->flags |= flags;
}
GL_UploadTexture( pic, tex, update );
GL_UploadTexture( pic, tex, update, NULL );
GL_TexFilter( tex, update ); // update texture filter, wrap etc
if( !update )
@ -1319,9 +1319,9 @@ void GL_ProcessTexture( int texnum, float gamma, int topColor, int bottomColor )
// all the operations makes over the image copy not an original
pic = FS_CopyImage( image->original );
Image_Process( &pic, topColor, bottomColor, gamma, flags );
Image_Process( &pic, topColor, bottomColor, gamma, flags, NULL );
GL_UploadTexture( pic, image, true );
GL_UploadTexture( pic, image, true, NULL );
GL_TexFilter( image, true ); // update texture filter, wrap etc
FS_FreeImage( pic );
@ -1992,6 +1992,8 @@ void R_InitImages( void )
// set texture parameters
R_SetTextureParameters();
R_InitBuiltinTextures();
R_ParseTexFilters( "scripts/texfilter.txt" );
}
/*

View File

@ -165,6 +165,7 @@ typedef struct
int lightstylevalue[MAX_LIGHTSTYLES]; // value 0 - 65536
float lightcache[MAX_LIGHTSTYLES];
float viewplanedist;
mplane_t clipPlane;
} ref_instance_t;
@ -307,7 +308,7 @@ void R_UploadStretchRaw( int texture, int cols, int rows, int width, int height,
void R_SetTextureParameters( void );
gltexture_t *R_GetTexture( GLenum texnum );
void GL_SetTextureType( GLenum texnum, GLenum type );
int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags );
int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags, imgfilter_t *filter );
int GL_LoadTextureInternal( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update );
byte *GL_ResampleTexture( const byte *source, int in_w, int in_h, int out_w, int out_h, qboolean isNormalMap );
int GL_CreateTexture( const char *name, int width, int height, const void *buffer, texFlags_t flags );
@ -381,6 +382,11 @@ void Matrix4x4_CreateProjection(matrix4x4 out, float xMax, float xMin, float yMa
void Matrix4x4_CreateOrtho(matrix4x4 m, float xLeft, float xRight, float yBottom, float yTop, float zNear, float zFar);
void Matrix4x4_CreateModelview( matrix4x4 out );
//
// gl_rmisc.
//
void R_ParseTexFilters( const char *filename );
imgfilter_t *R_FindTexFilter( const char *texname );
//
// gl_rsurf.c
@ -443,7 +449,7 @@ void R_Shutdown( void );
qboolean R_Init( void );
void R_Shutdown( void );
void VID_CheckChanges( void );
int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags );
int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags, imgfilter_t *filter );
void GL_FreeImage( const char *name );
qboolean VID_ScreenShot( const char *filename, int shot_type );
qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qboolean skyshot );

View File

@ -780,6 +780,9 @@ static void R_SetupFrame( void )
VectorCopy( RI.refdef.vieworg, RI.vieworg );
AngleVectors( RI.refdef.viewangles, RI.vforward, RI.vright, RI.vup );
// setup viewplane dist
RI.viewplanedist = DotProduct( RI.refdef.vieworg, RI.vforward );
if( !r_lockcull->integer )
{
VectorCopy( RI.vforward, RI.cull_vforward );
@ -1523,6 +1526,11 @@ static const char *GL_TextureName( unsigned int texnum )
return R_GetTexture( texnum )->name;
}
static int GL_LoadTextureNoFilter( const char *name, const byte *buf, size_t size, int flags )
{
return GL_LoadTexture( name, buf, size, flags, NULL );
}
static render_api_t gRenderAPI =
{
GL_RenderGetParm,
@ -1539,7 +1547,7 @@ static render_api_t gRenderAPI =
R_StoreEfrags,
GL_FindTexture,
GL_TextureName,
GL_LoadTexture,
GL_LoadTextureNoFilter,
GL_CreateTexture,
GL_FreeTexture,
DrawSingleDecal,

View File

@ -27,6 +27,15 @@ typedef struct
int lMax;
} dmaterial_t;
typedef struct
{
char texname[64]; // shortname
imgfilter_t filter;
} dfilter_t;
dfilter_t *tex_filters[MAX_TEXTURES];
int num_texfilters;
// default rules for apply detail textures.
// maybe move this to external script?
static const dmaterial_t detail_table[] =
@ -246,7 +255,7 @@ void R_ParseDetailTextures( const char *filename )
if( Q_stricmp( tex->name, texname ))
continue;
tex->dt_texturenum = GL_LoadTexture( detail_texname, NULL, 0, TF_FORCE_COLOR );
tex->dt_texturenum = GL_LoadTexture( detail_texname, NULL, 0, TF_FORCE_COLOR, NULL );
// texture is loaded
if( tex->dt_texturenum )
@ -265,6 +274,117 @@ void R_ParseDetailTextures( const char *filename )
Mem_Free( afile );
}
void R_ParseTexFilters( const char *filename )
{
char *afile, *pfile;
string token, texname;
dfilter_t *tf;
int i;
afile = FS_LoadFile( filename, NULL, false );
if( !afile ) return;
pfile = afile;
// format: 'texturename' 'filtername' 'factor' 'bias' 'blendmode' 'grayscale'
while(( pfile = COM_ParseFile( pfile, token )) != NULL )
{
qboolean parse_filter = false;
imgfilter_t filter;
Q_memset( &filter, 0, sizeof( filter ));
Q_strncpy( texname, token, sizeof( texname ));
// parse filter
pfile = COM_ParseFile( pfile, token );
if( !Q_stricmp( token, "blur" ))
filter.filter = BLUR_FILTER;
else if( !Q_stricmp( token, "blur2" ))
filter.filter = BLUR_FILTER2;
else if( !Q_stricmp( token, "edge" ))
filter.filter = EDGE_FILTER;
else if( !Q_stricmp( token, "emboss" ))
filter.filter = EMBOSS_FILTER;
// reading factor
pfile = COM_ParseFile( pfile, token );
filter.factor = Q_atof( token );
// reading bias
pfile = COM_ParseFile( pfile, token );
filter.bias = Q_atof( token );
// reading blendFunc
pfile = COM_ParseFile( pfile, token );
if( !Q_stricmp( token, "modulate" ) || !Q_stricmp( token, "GL_MODULATE" ))
filter.blendFunc = GL_MODULATE;
else if( !Q_stricmp( token, "replace" ) || !Q_stricmp( token, "GL_REPLACE" ))
filter.blendFunc = GL_REPLACE;
else if( !Q_stricmp( token, "add" ) || !Q_stricmp( token, "GL_ADD" ))
filter.blendFunc = GL_ADD;
else if( !Q_stricmp( token, "decal" ) || !Q_stricmp( token, "GL_DECAL" ))
filter.blendFunc = GL_DECAL;
else if( !Q_stricmp( token, "blend" ) || !Q_stricmp( token, "GL_BLEND" ))
filter.blendFunc = GL_BLEND;
else if( !Q_stricmp( token, "add_signed" ) || !Q_stricmp( token, "GL_ADD_SIGNED" ))
filter.blendFunc = GL_ADD_SIGNED;
else MsgDev( D_WARN, "unknown blendFunc '%s' specified for texture '%s'\n", texname, token );
// reading flags
pfile = COM_ParseFile( pfile, token );
filter.flags = Q_atoi( token );
// make sure what factor is not zeroed
if( filter.factor == 0.0f )
{
MsgDev( D_WARN, "texfilter for texture %s has factor 0! Ignored\n", texname );
continue;
}
// check if already existed
for( i = 0; i < num_texfilters; i++ )
{
tf = tex_filters[i];
if( !Q_stricmp( tf->texname, texname ))
{
MsgDev( D_WARN, "texture %s has specified multiple filters! Ignored\n", texname );
break;
}
}
if( i != num_texfilters )
continue; // already specified
// allocate new texfilter
tf = Z_Malloc( sizeof( dfilter_t ));
tex_filters[num_texfilters++] = tf;
Q_strncpy( tf->texname, texname, sizeof( tf->texname ));
tf->filter = filter;
}
MsgDev( D_INFO, "%i texture filters parsed\n", num_texfilters );
Mem_Free( afile );
}
imgfilter_t *R_FindTexFilter( const char *texname )
{
dfilter_t *tf;
int i;
for( i = 0; i < num_texfilters; i++ )
{
tf = tex_filters[i];
if( !Q_stricmp( tf->texname, texname ))
return &tf->filter;
}
return NULL;
}
void R_NewMap( void )
{
texture_t *tx;

View File

@ -1304,7 +1304,7 @@ static int R_SurfaceCompare( const msurface_t **a, const msurface_t **b )
{
msurface_t *surf1, *surf2;
mextrasurf_t *info1, *info2;
vec3_t vecLength, org1, org2;
vec3_t org1, org2;
float len1, len2;
surf1 = (msurface_t *)*a;
@ -1316,10 +1316,9 @@ static int R_SurfaceCompare( const msurface_t **a, const msurface_t **b )
VectorAdd( RI.currententity->origin, info1->origin, org1 );
VectorAdd( RI.currententity->origin, info2->origin, org2 );
VectorSubtract( RI.vieworg, org1, vecLength );
len1 = VectorLength( vecLength );
VectorSubtract( RI.vieworg, org2, vecLength );
len2 = VectorLength( vecLength );
// compare by plane dists
len1 = DotProduct( org1, RI.vforward ) - RI.viewplanedist;
len2 = DotProduct( org2, RI.vforward ) - RI.viewplanedist;
if( len1 > len2 )
return -1;

View File

@ -66,7 +66,7 @@ static dframetype_t *R_SpriteLoadFrame( model_t *mod, void *pin, mspriteframe_t
if( mod->flags & 256 ) // it's a HUD sprite
{
Q_snprintf( texname, sizeof( texname ), "#HUD/%s_%s_%i%i.spr", mod->name, group_suffix, num / 10, num % 10 );
gl_texturenum = GL_LoadTexture( texname, pin, pinframe->width * pinframe->height, r_texFlags );
gl_texturenum = GL_LoadTexture( texname, pin, pinframe->width * pinframe->height, r_texFlags, NULL );
}
else
{
@ -79,7 +79,7 @@ static dframetype_t *R_SpriteLoadFrame( model_t *mod, void *pin, mspriteframe_t
Q_snprintf( texname, sizeof( texname ), "materials/%s/frame%i%i.tga", sprname, num / 10, num % 10 );
if( FS_FileExists( texname, false ))
gl_texturenum = GL_LoadTexture( texname, NULL, 0, r_texFlags );
gl_texturenum = GL_LoadTexture( texname, NULL, 0, r_texFlags, NULL );
if( gl_texturenum )
load_external = true; // sucessfully loaded
@ -88,7 +88,7 @@ static dframetype_t *R_SpriteLoadFrame( model_t *mod, void *pin, mspriteframe_t
if( !load_external )
{
Q_snprintf( texname, sizeof( texname ), "#%s_%s_%i%i.spr", mod->name, group_suffix, num / 10, num % 10 );
gl_texturenum = GL_LoadTexture( texname, pin, pinframe->width * pinframe->height, r_texFlags );
gl_texturenum = GL_LoadTexture( texname, pin, pinframe->width * pinframe->height, r_texFlags, NULL );
}
else MsgDev( D_NOTE, "loading HQ: %s\n", texname );
}
@ -319,7 +319,7 @@ void Mod_LoadMapSprite( model_t *mod, const void *buffer, size_t size, qboolean
if( h < MAPSPRITE_SIZE ) h = MAPSPRITE_SIZE;
// resample image if needed
Image_Process( &pix, w, h, 0.0f, IMAGE_FORCE_RGBA|IMAGE_RESAMPLE );
Image_Process( &pix, w, h, 0.0f, IMAGE_FORCE_RGBA|IMAGE_RESAMPLE, NULL );
w = h = MAPSPRITE_SIZE;

View File

@ -3373,7 +3373,7 @@ static void R_StudioLoadTexture( model_t *mod, studiohdr_t *phdr, mstudiotexture
Q_snprintf( texname, sizeof( texname ), "materials/%s/%s.tga", mdlname, name );
if( FS_FileExists( texname, false ))
gl_texturenum = GL_LoadTexture( texname, NULL, 0, flags );
gl_texturenum = GL_LoadTexture( texname, NULL, 0, flags, NULL );
if( gl_texturenum )
{
@ -3390,7 +3390,7 @@ static void R_StudioLoadTexture( model_t *mod, studiohdr_t *phdr, mstudiotexture
// build the texname
Q_snprintf( texname, sizeof( texname ), "#%s/%s.mdl", mdlname, name );
ptexture->index = GL_LoadTexture( texname, (byte *)ptexture, size, flags );
ptexture->index = GL_LoadTexture( texname, (byte *)ptexture, size, flags, NULL );
}
else MsgDev( D_NOTE, "loading HQ: %s\n", texname );

View File

@ -444,7 +444,7 @@ void R_SetupSky( const char *skyboxname )
for( i = 0; i < 6; i++ )
{
Q_snprintf( sidename, sizeof( sidename ), "%s%s", loadname, r_skyBoxSuffix[i] );
tr.skyboxTextures[i] = GL_LoadTexture( sidename, NULL, 0, TF_CLAMP|TF_SKY );
tr.skyboxTextures[i] = GL_LoadTexture( sidename, NULL, 0, TF_CLAMP|TF_SKY, NULL );
GL_SetTextureType( tr.skyboxTextures[i], TEX_CUBEMAP );
if( !tr.skyboxTextures[i] ) break;
}
@ -457,7 +457,7 @@ void R_SetupSky( const char *skyboxname )
for( i = 0; i < 6; i++ )
{
Q_snprintf( sidename, sizeof( sidename ), "%s_%s", loadname, r_skyBoxSuffix[i] );
tr.skyboxTextures[i] = GL_LoadTexture( sidename, NULL, 0, TF_CLAMP|TF_SKY );
tr.skyboxTextures[i] = GL_LoadTexture( sidename, NULL, 0, TF_CLAMP|TF_SKY, NULL );
GL_SetTextureType( tr.skyboxTextures[i], TEX_CUBEMAP );
if( !tr.skyboxTextures[i] ) break;
}

View File

@ -474,6 +474,16 @@ typedef enum
IMAGE_REMAP = BIT(27), // interpret width and height as top and bottom color
} imgFlags_t;
// ordering is important!
typedef enum
{
BLUR_FILTER = 0,
BLUR_FILTER2,
EDGE_FILTER,
EMBOSS_FILTER,
NUM_FILTERS,
} pixfilter_t;
typedef struct rgbdata_s
{
word width; // image width
@ -487,6 +497,21 @@ typedef struct rgbdata_s
size_t size; // for bounds checking
} rgbdata_t;
// imgfilter processing flags
typedef enum
{
FILTER_GRAYSCALE = BIT(0),
} flFlags_t;
typedef struct imgfilter_s
{
int filter; // pixfilter_t
float factor; // filter factor value
float bias; // filter bias value
flFlags_t flags; // filter additional flags
uint blendFunc; // blending mode
} imgfilter_t;
//
// imagelib
//
@ -497,7 +522,7 @@ qboolean FS_SaveImage( const char *filename, rgbdata_t *pix );
rgbdata_t *FS_CopyImage( rgbdata_t *in );
void FS_FreeImage( rgbdata_t *pack );
extern const bpc_desc_t PFDesc[]; // image get pixelformat
qboolean Image_Process( rgbdata_t **pix, int width, int height, float gamma, uint flags );
qboolean Image_Process( rgbdata_t **pix, int width, int height, float gamma, uint flags, imgfilter_t *filter );
void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end );
void Image_SetForceFlags( uint flags ); // set image force flags on loading

View File

@ -439,7 +439,7 @@ static void Con_LoadConsoleFont( int fontNumber, cl_font_t *font )
if( font->valid ) return; // already loaded
// loading conchars
font->hFontTexture = GL_LoadTexture( va( "fonts/font%i", fontNumber ), NULL, 0, TF_FONT|TF_NEAREST );
font->hFontTexture = GL_LoadTexture( va( "fonts/font%i", fontNumber ), NULL, 0, TF_FONT|TF_NEAREST, NULL );
R_GetTextureParms( &fontWidth, NULL, font->hFontTexture );
// setup creditsfont
@ -1947,14 +1947,14 @@ void Con_VidInit( void )
if( scr_width->integer < 640 )
{
if( FS_FileExists( "cached/conback400", false ))
con.background = GL_LoadTexture( "cached/conback400", NULL, 0, TF_IMAGE );
else con.background = GL_LoadTexture( "cached/conback", NULL, 0, TF_IMAGE );
con.background = GL_LoadTexture( "cached/conback400", NULL, 0, TF_IMAGE, NULL );
else con.background = GL_LoadTexture( "cached/conback", NULL, 0, TF_IMAGE, NULL );
}
else
{
if( FS_FileExists( "cached/conback640", false ))
con.background = GL_LoadTexture( "cached/conback640", NULL, 0, TF_IMAGE );
else con.background = GL_LoadTexture( "cached/conback", NULL, 0, TF_IMAGE );
con.background = GL_LoadTexture( "cached/conback640", NULL, 0, TF_IMAGE, NULL );
else con.background = GL_LoadTexture( "cached/conback", NULL, 0, TF_IMAGE, NULL );
}
}
else
@ -1962,14 +1962,14 @@ void Con_VidInit( void )
if( scr_width->integer < 640 )
{
if( FS_FileExists( "cached/loading400", false ))
con.background = GL_LoadTexture( "cached/loading400", NULL, 0, TF_IMAGE );
else con.background = GL_LoadTexture( "cached/loading", NULL, 0, TF_IMAGE );
con.background = GL_LoadTexture( "cached/loading400", NULL, 0, TF_IMAGE, NULL );
else con.background = GL_LoadTexture( "cached/loading", NULL, 0, TF_IMAGE, NULL );
}
else
{
if( FS_FileExists( "cached/loading640", false ))
con.background = GL_LoadTexture( "cached/loading640", NULL, 0, TF_IMAGE );
else con.background = GL_LoadTexture( "cached/loading", NULL, 0, TF_IMAGE );
con.background = GL_LoadTexture( "cached/loading640", NULL, 0, TF_IMAGE, NULL );
else con.background = GL_LoadTexture( "cached/loading", NULL, 0, TF_IMAGE, NULL );
}
}

View File

@ -16,10 +16,12 @@ GNU General Public License for more details.
#include "imagelib.h"
#include "mathlib.h"
#include "mod_local.h"
#include "gl_export.h"
convar_t *gl_round_down;
#define LERPBYTE( i ) r = resamplerow1[i]; out[i] = (byte)(((( resamplerow2[i] - r ) * lerp)>>16 ) + r )
#define FILTER_SIZE 5
uint d_8toQ1table[256];
uint d_8toHLtable[256];
@ -81,6 +83,38 @@ static byte palette_hl[768] =
147,255,247,199,255,255,255,159,91,83
};
static float FILTER[NUM_FILTERS][FILTER_SIZE][FILTER_SIZE] =
{
{ // regular blur
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 1.0f, 1.0f, 0.0f },
{ 0.0f, 1.0f, 1.0f, 1.0f, 0.0f },
{ 0.0f, 1.0f, 1.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
},
{ // light blur
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 1.0f, 1.0f, 0.0f },
{ 0.0f, 1.0f, 4.0f, 1.0f, 0.0f },
{ 0.0f, 1.0f, 1.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
},
{ // find edges
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, -1.0f, -1.0f, -1.0f, 0.0f },
{ 0.0f, -1.0f, 8.0f, -1.0f, 0.0f },
{ 0.0f, -1.0f, -1.0f, -1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
},
{ // emboss
{-0.7f, -0.7f, -0.7f, -0.7f, 0.0f },
{-0.7f, -0.7f, -0.7f, 0.0f, 0.7f },
{-0.7f, -0.7f, 0.0f, 0.7f, 0.7f },
{-0.7f, 0.0f, 0.7f, 0.7f, 0.7f },
{ 0.0f, 0.7f, 0.7f, 0.7f, 0.7f },
}
};
/*
=============================================================================
@ -1345,7 +1379,128 @@ qboolean Image_RemapInternal( rgbdata_t *pic, int topColor, int bottomColor )
return true;
}
qboolean Image_Process( rgbdata_t **pix, int width, int height, float gamma, uint flags )
/*
==================
Image_ApplyFilter
Applies a 5 x 5 filtering matrix to the texture, then runs it through a simulated OpenGL texture environment
blend with the original data to derive a new texture. Freaky, funky, and *f--king* *fantastic*. You can do
reasonable enough "fake bumpmapping" with this baby...
Filtering algorithm from http://www.student.kuleuven.ac.be/~m0216922/CG/filtering.html
All credit due
==================
*/
qboolean Image_ApplyFilter( rgbdata_t *pic, int filter, float factor, float bias, flFlags_t flags, GLenum blendFunc )
{
int i, x, y;
uint *fin, *fout;
size_t size;
// first expand the image into 32-bit buffer
pic = Image_DecompressInternal( pic );
size = image.width * image.height * 4;
image.tempbuffer = Mem_Realloc( host.imagepool, image.tempbuffer, size );
fout = (uint *)image.tempbuffer;
fin = (uint *)pic->buffer;
for( x = 0; x < image.width; x++ )
{
for( y = 0; y < image.height; y++ )
{
vec3_t vout = { 0.0f, 0.0f, 0.0f };
int pos_x, pos_y;
for( pos_x = 0; pos_x < FILTER_SIZE; pos_x++ )
{
for( pos_y = 0; pos_y < FILTER_SIZE; pos_y++ )
{
int img_x = (x - (FILTER_SIZE / 2) + pos_x + image.width) % image.width;
int img_y = (y - (FILTER_SIZE / 2) + pos_y + image.height) % image.height;
// casting's a unary operation anyway, so the othermost set of brackets in the left part
// of the rvalue should not be necessary... but i'm paranoid when it comes to C...
vout[0] += ((float)((byte *)&fin[img_y * image.width + img_x])[0]) * FILTER[filter][pos_x][pos_y];
vout[1] += ((float)((byte *)&fin[img_y * image.width + img_x])[1]) * FILTER[filter][pos_x][pos_y];
vout[2] += ((float)((byte *)&fin[img_y * image.width + img_x])[2]) * FILTER[filter][pos_x][pos_y];
}
}
// multiply by factor, add bias, and clamp
for( i = 0; i < 3; i++ )
{
vout[i] *= factor;
vout[i] += bias;
vout[i] = bound( 0.0f, vout[i], 255.0f );
}
if( flags & FILTER_GRAYSCALE )
{
// NTSC greyscale conversion standard
float avg = (vout[0] * 30.0f + vout[1] * 59.0f + vout[2] * 11.0f) / 100.0f;
// divide by 255 so GL operations work as expected
vout[0] = avg / 255.0f;
vout[1] = avg / 255.0f;
vout[2] = avg / 255.0f;
}
// write to temp - first, write data in (to get the alpha channel quickly and
// easily, which will be left well alone by this particular operation...!)
fout[y * image.width + x] = fin[y * image.width + x];
// now write in each element, applying the blend operator. blend
// operators are based on standard OpenGL TexEnv modes, and the
// formulas are derived from the OpenGL specs (http://www.opengl.org).
for( i = 0; i < 3; i++ )
{
// divide by 255 so GL operations work as expected
float src = ((float)((byte *)&fin[y * image.width + x])[i]) / 255.0f;
float tmp;
switch( blendFunc )
{
case GL_ADD:
tmp = vout[i] + src;
break;
case GL_BLEND:
// default is FUNC_ADD here
// CsS + CdD works out as Src * Dst * 2
tmp = vout[i] * src * 2.0f;
break;
case GL_DECAL:
// same as GL_REPLACE unless there's alpha, which we ignore for this
case GL_REPLACE:
tmp = vout[i];
break;
case GL_ADD_SIGNED:
tmp = (vout[i] + src) - 0.5f;
break;
case GL_MODULATE:
default: // same as default
tmp = vout[i] * src;
break;
}
// multiply back by 255 to get the proper byte scale
tmp *= 255.0f;
// bound the temp target again now, cos the operation may have thrown it out
tmp = bound( 0.0f, tmp, 255.0f );
// and copy it in
((byte *)&fout[y * image.width + x])[i] = (byte)tmp;
}
}
}
// copy result back
Q_memcpy( fin, fout, size );
return true;
}
qboolean Image_Process( rgbdata_t **pix, int width, int height, float gamma, uint flags, imgfilter_t *filter )
{
rgbdata_t *pic = *pix;
qboolean result = true;
@ -1359,7 +1514,7 @@ qboolean Image_Process( rgbdata_t **pix, int width, int height, float gamma, uin
return false;
}
if( !flags )
if( !flags && !filter )
{
// clear any force flags
image.force_flags = 0;
@ -1384,6 +1539,8 @@ qboolean Image_Process( rgbdata_t **pix, int width, int height, float gamma, uin
if( flags & IMAGE_FORCE_RGBA ) pic = Image_DecompressInternal( pic );
if( flags & IMAGE_LIGHTGAMMA ) pic = Image_LightGamma( pic, gamma );
if( filter ) Image_ApplyFilter( pic, filter->filter, filter->factor, filter->bias, filter->flags, filter->blendFunc );
// quantize image
if( flags & IMAGE_QUANTIZE ) pic = Image_Quantize( pic );

View File

@ -229,7 +229,7 @@ hull_t *Mod_HullForStudio( model_t *model, float frame, int sequence, vec3_t ang
VectorCopy( angles, angles2 );
angles2[PITCH] = -angles2[PITCH]; // stupid quake bug
pBlendAPI->SV_StudioSetupBones( model, frame, sequence, angles2, origin, pcontroller, pblending, -1, pEdict );
pBlendAPI->SV_StudioSetupBones( model, frame, sequence, angles2, origin, pcontroller, pblending, pEdict, -1 );
phitbox = (mstudiobbox_t *)((byte *)mod_studiohdr + mod_studiohdr->hitboxindex);
for( i = j = 0; i < mod_studiohdr->numhitboxes; i++, j += 6 )
@ -626,7 +626,7 @@ NOTE: pEdict is unused
====================
*/
static void SV_StudioSetupBones( model_t *pModel, float frame, int sequence, const vec3_t angles, const vec3_t origin,
const byte *pcontroller, const byte *pblending, int iBone, const edict_t *pEdict )
const byte *pcontroller, const byte *pblending, const edict_t *pEdict, int iBone )
{
int i, j, numbones = 0;
int boneused[MAXSTUDIOBONES];
@ -749,7 +749,7 @@ void Mod_StudioGetAttachment( const edict_t *e, int iAttachment, float *origin,
angles2[PITCH] = -angles2[PITCH];
pBlendAPI->SV_StudioSetupBones( mod, e->v.frame, e->v.sequence, angles2, e->v.origin,
e->v.controller, e->v.blending, pAtt[iAttachment].bone, e );
e->v.controller, e->v.blending, e, pAtt[iAttachment].bone );
// compute pos and angles
if( origin != NULL )
@ -780,7 +780,7 @@ void Mod_GetBonePosition( const edict_t *e, int iBone, float *origin, float *ang
if( !mod_studiohdr ) return;
pBlendAPI->SV_StudioSetupBones( mod, e->v.frame, e->v.sequence, e->v.angles, e->v.origin,
e->v.controller, e->v.blending, iBone, e );
e->v.controller, e->v.blending, e, iBone );
if( origin ) Matrix3x4_OriginFromMatrix( studio_bones[iBone], origin );
if( angles ) VectorAngles( studio_bones[iBone][0], angles ); // bone forward to angles

View File

@ -612,6 +612,7 @@ static void Mod_LoadTextures( const dlump_t *l )
texture_t *altanims[10];
int num, max, altmax;
char texname[64];
imgfilter_t *filter;
mip_t *mt;
int i, j;
@ -669,6 +670,7 @@ static void Mod_LoadTextures( const dlump_t *l )
// convert to lowercase
Q_strnlwr( mt->name, mt->name, sizeof( mt->name ));
Q_strncpy( tx->name, mt->name, sizeof( tx->name ));
filter = R_FindTexFilter( tx->name ); // grab texture filter
tx->width = mt->width;
tx->height = mt->height;
@ -693,7 +695,7 @@ static void Mod_LoadTextures( const dlump_t *l )
if( load_external )
{
tr.solidskyTexture = GL_LoadTexture( texname, NULL, 0, TF_UNCOMPRESSED|TF_NOMIPMAP );
tr.solidskyTexture = GL_LoadTexture( texname, NULL, 0, TF_UNCOMPRESSED|TF_NOMIPMAP, NULL );
GL_SetTextureType( tr.solidskyTexture, TEX_BRUSH );
load_external = false;
}
@ -715,7 +717,7 @@ static void Mod_LoadTextures( const dlump_t *l )
if( load_external )
{
tr.alphaskyTexture = GL_LoadTexture( texname, NULL, 0, TF_UNCOMPRESSED|TF_NOMIPMAP );
tr.alphaskyTexture = GL_LoadTexture( texname, NULL, 0, TF_UNCOMPRESSED|TF_NOMIPMAP, NULL );
GL_SetTextureType( tr.alphaskyTexture, TEX_BRUSH );
load_external = false;
}
@ -767,12 +769,12 @@ load_wad_textures:
int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6);
if( bmodel_version == HLBSP_VERSION ) size += sizeof( short ) + 768;
tx->gl_texturenum = GL_LoadTexture( texname, (byte *)mt, size, 0 );
tx->gl_texturenum = GL_LoadTexture( texname, (byte *)mt, size, 0, filter );
}
else
{
// okay, loading it from wad
tx->gl_texturenum = GL_LoadTexture( texname, NULL, 0, 0 );
tx->gl_texturenum = GL_LoadTexture( texname, NULL, 0, 0, filter );
if( !tx->gl_texturenum && load_external )
{
@ -817,7 +819,7 @@ load_wad_textures:
int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6);
if( bmodel_version == HLBSP_VERSION ) size += sizeof( short ) + 768;
tx->fb_texturenum = GL_LoadTexture( texname, (byte *)mt, size, TF_NOMIPMAP|TF_MAKELUMA );
tx->fb_texturenum = GL_LoadTexture( texname, (byte *)mt, size, TF_NOMIPMAP|TF_MAKELUMA, NULL );
}
else
{
@ -830,7 +832,7 @@ load_wad_textures:
if( !load_external_luma ) src = FS_LoadFile( va( "%s.mip", tx->name ), &srcSize, false );
// okay, loading it from wad or hi-res version
tx->fb_texturenum = GL_LoadTexture( texname, src, srcSize, TF_NOMIPMAP|TF_MAKELUMA );
tx->fb_texturenum = GL_LoadTexture( texname, src, srcSize, TF_NOMIPMAP|TF_MAKELUMA, NULL );
if( src ) Mem_Free( src );
if( !tx->fb_texturenum && load_external_luma )