From 23f71485d127fba985049e8e006cec595284d792 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 2 Jan 2005 14:23:20 +0000 Subject: [PATCH] more tree recovering. This includes Despair's anisotropy support work. --- NEWS | 7 +++-- include/QF/GL/extensions.h | 32 +++++++++++++------ include/QF/GL/qf_textures.h | 3 +- include/QF/progs.h | 2 +- include/r_cvar.h | 1 + include/r_dynamic.h | 2 +- include/r_local.h | 2 +- libs/gamecode/engine/pr_debug.c | 10 +++--- libs/gamecode/engine/pr_edict.c | 5 +-- libs/gamecode/engine/pr_parse.c | 4 +-- libs/ruamoko/rua_obj.c | 14 ++++----- libs/util/zone.c | 17 +++++----- libs/video/renderer/gl/gl_dyn_part.c | 2 +- libs/video/renderer/gl/gl_lightmap.c | 3 ++ libs/video/renderer/gl/gl_skin.c | 3 ++ libs/video/renderer/gl/gl_sky.c | 9 ++++++ libs/video/renderer/gl/gl_textures.c | 13 ++++++-- libs/video/targets/vid_common_gl.c | 47 ++++++++++++++++++++++++++-- 18 files changed, 128 insertions(+), 48 deletions(-) diff --git a/NEWS b/NEWS index b4fe365a4..65e92cfbe 100644 --- a/NEWS +++ b/NEWS @@ -51,7 +51,7 @@ Changes from 0.5.4 * treat server clients like non-client entities for GIB "frag" event * expand ~ for fs_dirconf * don't write config.cfg until /after/ it's been read :) - * ATI's libGL needs to be loaded with global symbols in order to work + * ATI's libGL needed to be loaded with global symbols in order to work properly * oss sound doesn't block if the sound device is busy (from Grievre) * add snd_bits/rate/stereo cvars to win and dx sound targets @@ -62,12 +62,13 @@ Changes from 0.5.4 * curses server console scrollback works * qfdefs nuked. no longer needed as "standard" progs get resolved staticly - * TruForm support. Controlled by gl_tessellate + * Anisotropy support, controlled by gl_anisotropy + * TruForm support, controlled by gl_tessellate * Improvements in time accounting. Accurate to +-0.5ms, instead of -1,0 like others. Based on Grievre's and zquake's code * mangled sounds on gamedir change fixed thanks to Grievre * mtex support for world rendering. - * alias models us GL lighting + * alias models use GL lighting * support for 7 mouse buttons * all archived cvars get written to config.cfg prefixed with "seta" (new command that sets the archive bit) diff --git a/include/QF/GL/extensions.h b/include/QF/GL/extensions.h index 1911108af..a4b933bb5 100644 --- a/include/QF/GL/extensions.h +++ b/include/QF/GL/extensions.h @@ -73,6 +73,12 @@ # define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED #endif +#ifndef GL_EXT_texture_filter_anisotropic +# define GL_EXT_texture_filter_anisotropic +# define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84fe +# define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84ff +#endif + #ifndef GL_EXT_texture_object # define GL_EXT_texture_object # define GL_TEXTURE_PRIORITY_EXT 0x8066 @@ -82,12 +88,12 @@ # define GL_TEXTURE_3D_BINDING_EXT 0x806A #endif -#ifndef GL_EXT_point_parameters -# define GL_EXT_point_parameters -# define GL_POINT_SIZE_MIN_EXT 0x8126 -# define GL_POINT_SIZE_MAX_EXT 0x8127 -# define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 -# define GL_DISTANCE_ATTENUATION_EXT 0x8129 +#ifndef GL_ARB_point_parameters +# define GL_ARB_point_parameters +# define GL_POINT_SIZE_MIN_ARB 0x8126 +# define GL_POINT_SIZE_MAX_ARB 0x8127 +# define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +# define GL_DISTANCE_ATTENUATION_ARB 0x8129 #endif #ifndef GL_EXT_shared_texture_palette @@ -134,6 +140,12 @@ # define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 #endif +#ifndef GL_ARB_point_sprite +# define GL_ARB_point_sprite +# define GL_POINT_SPRITE_ARB 0x8861 +# define GL_COORD_REPLACE_ARB 0x8862 +#endif + #ifndef GL_ARB_texture_cube_map # define GL_ARB_texture_cube_map # define GL_NORMAL_MAP_ARB 0x8511 @@ -265,16 +277,16 @@ typedef void (GLAPIENTRY *QF_glMultiTexCoord2sv) (GLenum target, const GLshort * typedef void (GLAPIENTRY *QF_glMultiTexCoord3sv) (GLenum target, const GLshort *v); typedef void (GLAPIENTRY *QF_glMultiTexCoord4sv) (GLenum target, const GLshort *v); +// GL_ARB_point_parameters +typedef void (GLAPIENTRY *QF_glPointParameterfARB) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY *QF_glPointParameterfvARB) (GLenum pname, const GLfloat *params); + // GL_EXT_paletted_texture typedef void (GLAPIENTRY *QF_glColorTableEXT) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); typedef void (GLAPIENTRY *QF_glGetColorTableEXT) (GLenum target, GLenum format, GLenum type, GLvoid *data); typedef void (GLAPIENTRY *QF_glGetColorTableParameterivEXT) (GLenum target, GLenum pname, GLint *params); typedef void (GLAPIENTRY *QF_glGetColorTableParameterfvEXT) (GLenum target, GLenum pname, GLfloat *params); -// GL_EXT_point_parameters -typedef void (GLAPIENTRY *QF_glPointParameterfEXT) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY *QF_glPointParameterfvEXT) (GLenum pname, const GLfloat *params); - // GL_EXT_subtexture typedef void (GLAPIENTRY *QF_glTexSubImage1DEXT) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); typedef void (GLAPIENTRY *QF_glTexSubImage2DEXT) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); diff --git a/include/QF/GL/qf_textures.h b/include/QF/GL/qf_textures.h index ba19bbc1d..b798e0a27 100644 --- a/include/QF/GL/qf_textures.h +++ b/include/QF/GL/qf_textures.h @@ -38,7 +38,8 @@ extern int gl_solid_format; extern int gl_lightmap_format; extern int gl_filter_min; extern int gl_filter_max; - +extern qboolean Anisotropy; +extern float aniso; extern int part_tex; /* extern int part_tex_dot; diff --git a/include/QF/progs.h b/include/QF/progs.h index 22e78e200..0f0a2ce77 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -218,7 +218,7 @@ void ED_EntityParseFunction (progs_t *pr); #define PR_edicts(p) ((byte *) *(p)->edicts) #define NEXT_EDICT(p,e) ((edict_t *) ((byte *) e + (p)->pr_edict_size)) -#define EDICT_TO_PROG(p,e) ((byte *) (e) - PR_edicts (p)) +#define EDICT_TO_PROG(p,e) ((long) ((byte *) (e) - PR_edicts (p))) #define PROG_TO_EDICT(p,e) ((edict_t *) (PR_edicts (p) + (e))) #define NUM_FOR_BAD_EDICT(p,e) (EDICT_TO_PROG (p, e) / (p)->pr_edict_size) #ifndef PR_PARANOID_PROGS diff --git a/include/r_cvar.h b/include/r_cvar.h index fd77424c5..2bb632577 100644 --- a/include/r_cvar.h +++ b/include/r_cvar.h @@ -14,6 +14,7 @@ extern struct cvar_s *d_mipcap; extern struct cvar_s *d_mipscale; extern struct cvar_s *gl_affinemodels; +extern struct cvar_s *gl_anisotropy; extern struct cvar_s *gl_clear; extern struct cvar_s *gl_conspin; extern struct cvar_s *gl_constretch; diff --git a/include/r_dynamic.h b/include/r_dynamic.h index 4a9f75595..289515bac 100644 --- a/include/r_dynamic.h +++ b/include/r_dynamic.h @@ -79,7 +79,7 @@ void R_Particles_Init_Cvars (void); void R_InitBubble (void); void R_InitParticles (void); -inline void R_ClearParticles (void); +void R_ClearParticles (void); void R_DrawParticles (void); struct cvar_s; void R_MaxParticlesCheck (struct cvar_s *r_particles, diff --git a/include/r_local.h b/include/r_local.h index 4f79c9a47..f762452d4 100644 --- a/include/r_local.h +++ b/include/r_local.h @@ -255,7 +255,7 @@ qboolean R_AliasCheckBBox (void); void R_DrawParticles (void); void R_InitParticles (void); -inline void R_ClearParticles (void); +void R_ClearParticles (void); void R_ReadPointFile_f (void); void R_InitSprites (void); void R_SurfacePatch (void); diff --git a/libs/gamecode/engine/pr_debug.c b/libs/gamecode/engine/pr_debug.c index d8c010c2a..6cb031ed1 100644 --- a/libs/gamecode/engine/pr_debug.c +++ b/libs/gamecode/engine/pr_debug.c @@ -473,7 +473,7 @@ value_string (progs_t *pr, etype_t type, pr_type_t *val) break; case ev_entity: edict = PROG_TO_EDICT (pr, val->entity_var); - dsprintf (line, "entity %i", NUM_FOR_BAD_EDICT (pr, edict)); + dsprintf (line, "entity %ld", NUM_FOR_BAD_EDICT (pr, edict)); break; case ev_func: if (val->func_var < 0 || val->func_var >= pr->progs->numfunctions) @@ -640,8 +640,7 @@ PR_PrintStatement (progs_t * pr, dstatement_t *s, int contents) fmt += 2; } else { const char *str; - char mode = fmt[1]; - char opchar = fmt[2]; + char mode = fmt[1], opchar = fmt[2]; long opval; etype_t optype; @@ -782,10 +781,9 @@ PR_Profile (progs_t * pr) void ED_Print (progs_t *pr, edict_t *ed) { - int l; + int type, l; unsigned int i; const char *name; - int type; ddef_t *d; pr_type_t *v; @@ -794,7 +792,7 @@ ED_Print (progs_t *pr, edict_t *ed) return; } - Sys_Printf ("\nEDICT %i:\n", NUM_FOR_BAD_EDICT (pr, ed)); + Sys_Printf ("\nEDICT %ld:\n", NUM_FOR_BAD_EDICT (pr, ed)); for (i = 0; i < pr->progs->numfielddefs; i++) { d = &pr->pr_fielddefs[i]; if (!d->s_name) // null field def (probably 1st) diff --git a/libs/gamecode/engine/pr_edict.c b/libs/gamecode/engine/pr_edict.c index 5e03e1136..8fd855eba 100644 --- a/libs/gamecode/engine/pr_edict.c +++ b/libs/gamecode/engine/pr_edict.c @@ -66,8 +66,9 @@ ED_ClearEdict (progs_t *pr, edict_t *e, int val) { unsigned int i; - if (NUM_FOR_EDICT(pr,e)<*pr->reserved_edicts) - Sys_Printf("clearing reserved edict %d\n", NUM_FOR_EDICT(pr,e)); + if (NUM_FOR_EDICT (pr, e) < *pr->reserved_edicts) + Sys_Printf ("clearing reserved edict %ld\n", + NUM_FOR_EDICT (pr, e)); for (i=0; i < pr->progs->entityfields; i++) e->v[i].integer_var = val; e->free = false; diff --git a/libs/gamecode/engine/pr_parse.c b/libs/gamecode/engine/pr_parse.c index 31d84c91e..5151136d4 100644 --- a/libs/gamecode/engine/pr_parse.c +++ b/libs/gamecode/engine/pr_parse.c @@ -66,7 +66,7 @@ static __attribute__ ((unused)) const char rcsid[] = static char * PR_UglyValueString (progs_t *pr, etype_t type, pr_type_t *val) { - static char line[256]; + static char line[256]; ddef_t *def; dfunction_t *f; @@ -78,7 +78,7 @@ PR_UglyValueString (progs_t *pr, etype_t type, pr_type_t *val) PR_GetString (pr, val->string_var)); break; case ev_entity: - snprintf (line, sizeof (line), "%i", + snprintf (line, sizeof (line), "%ld", NUM_FOR_BAD_EDICT (pr, PROG_TO_EDICT (pr, val->entity_var))); break; case ev_func: diff --git a/libs/ruamoko/rua_obj.c b/libs/ruamoko/rua_obj.c index 304dc42df..93a966ef2 100644 --- a/libs/ruamoko/rua_obj.c +++ b/libs/ruamoko/rua_obj.c @@ -288,7 +288,7 @@ static const char * selector_get_key (void *s, void *_pr) { progs_t *pr = (progs_t *) _pr; - return PR_GetString (pr, pr->selector_names[(int) s]); + return PR_GetString (pr, pr->selector_names[(long) s]); } static const char * @@ -404,11 +404,11 @@ static pr_sel_t * sel_register_typed_name (progs_t *pr, const char *name, const char *types, pr_sel_t *sel) { - int index; - int is_new = 0; + long index; + int is_new = 0; obj_list *l; - index = (int) Hash_Find (pr->selector_hash, name); + index = (long) Hash_Find (pr->selector_hash, name); if (index) { for (l = ((obj_list **) pr->selector_sels)[index]; l; l = l->next) { pr_sel_t *s = l->data; @@ -444,7 +444,7 @@ sel_register_typed_name (progs_t *pr, const char *name, const char *types, ((obj_list **) pr->selector_sels)[index] = l; if (is_new) - Hash_Add (pr->selector_hash, (void *)index); + Hash_Add (pr->selector_hash, (void *) index); return sel; } @@ -581,8 +581,8 @@ obj_send_message_in_list (progs_t *pr, pr_method_list_t *method_list, pr_method_t *mth = &method_list->method_list[i]; if (mth->method_name && sel_eq (&G_STRUCT (pr, pr_sel_t, mth->method_name), op) - && !Hash_FindElement (pr->load_methods, (void *)mth->method_imp)) { - Hash_AddElement (pr->load_methods, (void *)mth->method_imp); + && !Hash_FindElement (pr->load_methods, (void *) (long) mth->method_imp)) { + Hash_AddElement (pr->load_methods, (void *) (long) mth->method_imp); PR_ExecuteProgram (pr, mth->method_imp); break; diff --git a/libs/util/zone.c b/libs/util/zone.c index 2e7ec4151..928758f73 100644 --- a/libs/util/zone.c +++ b/libs/util/zone.c @@ -265,15 +265,15 @@ void Z_Print (memzone_t *zone) { memblock_t *block; - + Sys_Printf ("zone size: %i location: %p used: %i\n", zone->size, zone, zone->used); - - for (block = zone->blocklist.next ; ; block = block->next) - { + + for (block = zone->blocklist.next ; ; block = block->next) { Sys_Printf ("block:%p size:%7i tag:%3i ofs:%d\n", - block, block->size, block->tag, (byte *) block - (byte *) zone); - + block, block->size, block->tag, + (int) ((byte *) block - (byte *) zone)); + if (block->next == &zone->blocklist) break; // all blocks have been hit if ( (byte *)block + block->size != (byte *)block->next) @@ -293,9 +293,8 @@ void Z_CheckHeap (memzone_t *zone) { memblock_t *block; - - for (block = zone->blocklist.next ; ; block = block->next) - { + + for (block = zone->blocklist.next ; ; block = block->next) { if (block->next == &zone->blocklist) break; // all blocks have been hit if ( (byte *)block + block->size != (byte *)block->next) diff --git a/libs/video/renderer/gl/gl_dyn_part.c b/libs/video/renderer/gl/gl_dyn_part.c index fd878ed9b..03f3bb941 100644 --- a/libs/video/renderer/gl/gl_dyn_part.c +++ b/libs/video/renderer/gl/gl_dyn_part.c @@ -145,7 +145,7 @@ particle_new_veryrandom (ptype_t type, int texnum, const vec3_t org, } */ -inline void +void R_ClearParticles (void) { numparticles = 0; diff --git a/libs/video/renderer/gl/gl_lightmap.c b/libs/video/renderer/gl/gl_lightmap.c index c3a5f9c6b..fd99a2a1c 100644 --- a/libs/video/renderer/gl/gl_lightmap.c +++ b/libs/video/renderer/gl/gl_lightmap.c @@ -793,6 +793,9 @@ GL_BuildLightmaps (model_t **models, int num_models) qfglBindTexture (GL_TEXTURE_2D, lightmap_textures + i); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if (Anisotropy) + qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, + aniso); qfglTexImage2D (GL_TEXTURE_2D, 0, lightmap_bytes, BLOCK_WIDTH, BLOCK_HEIGHT, 0, gl_lightmap_format, GL_UNSIGNED_BYTE, lightmaps[i]); diff --git a/libs/video/renderer/gl/gl_skin.c b/libs/video/renderer/gl/gl_skin.c index b81bbe98f..d4eb9125a 100644 --- a/libs/video/renderer/gl/gl_skin.c +++ b/libs/video/renderer/gl/gl_skin.c @@ -150,6 +150,9 @@ build_skin_32 (byte * original, int tinwidth, int tinheight, qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if (Anisotropy) + qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, + aniso); } static void diff --git a/libs/video/renderer/gl/gl_sky.c b/libs/video/renderer/gl/gl_sky.c index 3c8812a76..33a7c2b02 100644 --- a/libs/video/renderer/gl/gl_sky.c +++ b/libs/video/renderer/gl/gl_sky.c @@ -147,6 +147,9 @@ R_LoadSkys (const char *skyname) qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if (Anisotropy) + qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, + aniso); qfglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); qfglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -430,6 +433,9 @@ R_InitSky (texture_t *mt) GL_UNSIGNED_BYTE, trans); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if (Anisotropy) + qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, + aniso); for (i = 0; i < 128; i++) for (j = 0; j < 128; j++) { @@ -447,4 +453,7 @@ R_InitSky (texture_t *mt) GL_UNSIGNED_BYTE, trans); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if (Anisotropy) + qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, + aniso); } diff --git a/libs/video/renderer/gl/gl_textures.c b/libs/video/renderer/gl/gl_textures.c index c54bcaa57..981744094 100644 --- a/libs/video/renderer/gl/gl_textures.c +++ b/libs/video/renderer/gl/gl_textures.c @@ -222,9 +222,12 @@ GL_TextureMode_f (void) if (glt->mipmap) { qfglBindTexture (GL_TEXTURE_2D, glt->texnum); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - gl_filter_min); + gl_filter_min); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - gl_filter_max); + gl_filter_max); + if (Anisotropy) + qfglTexParameterf (GL_TEXTURE_2D, + GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso); } } } @@ -428,6 +431,9 @@ GL_Upload32 (unsigned int *data, int width, int height, qboolean mipmap, qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } + if (Anisotropy) + qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, + aniso); free (scaled); } @@ -502,6 +508,9 @@ GL_Upload8_EXT (byte *data, int width, int height, qboolean mipmap, qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } + if (Anisotropy) + qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, + aniso); free (scaled); } diff --git a/libs/video/targets/vid_common_gl.c b/libs/video/targets/vid_common_gl.c index 2743356c9..90f342a63 100644 --- a/libs/video/targets/vid_common_gl.c +++ b/libs/video/targets/vid_common_gl.c @@ -83,7 +83,7 @@ int use_bgra; int gl_va_capable; int vaelements; int texture_extension_number = 1; -int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST; +int gl_filter_min = GL_LINEAR_MIPMAP_LINEAR; int gl_filter_max = GL_LINEAR; float gldepthmin, gldepthmax; @@ -104,7 +104,12 @@ qboolean is8bit = false; qboolean gl_feature_mach64 = false; -// ATI PN_triangles +// GL_EXT_texture_filter_anisotropic +qboolean Anisotropy; +static float aniso_max; +float aniso; + +// GL_ATI_pn_triangles static qboolean TruForm; static int tess_max; int tess; @@ -112,6 +117,7 @@ int tess; // GL_LIGHT int gl_max_lights; +cvar_t *gl_anisotropy; cvar_t *gl_doublebright; cvar_t *gl_fb_bmodels; cvar_t *gl_finish; @@ -231,6 +237,22 @@ gl_screenshot_byte_swap_f (cvar_t *var) var->int_val ? GL_TRUE : GL_FALSE); } +static void +gl_anisotropy_f (cvar_t * var) +{ + if (Anisotropy) { + if (var) + aniso = (bound (1.0, var->value, aniso_max)); + else + aniso = 1.0; + } else { + aniso = 1.0; + if (var) + Con_Printf ("Anisotropy (GL_EXT_texture_filter_anisotropic) is " + "not supported by your hardware and/or drivers.\n"); + } +} + static void gl_tessellate_f (cvar_t * var) { @@ -271,6 +293,11 @@ GL_Common_Init_Cvars (void) gl_screenshot_byte_swap_f, "Swap the bytes for gl " "screenshots. Needed if you get screenshots with red and " "blue swapped."); + gl_anisotropy = + Cvar_Get ("gl_anisotropy", "1.0", CVAR_NONE, gl_anisotropy_f, + nva ("Specifies degree of anisotropy, from 1.0 to %f. " + "Higher anisotropy means less distortion of textures " + "at shallow angles to the viewer.", aniso_max)); gl_tessellate = Cvar_Get ("gl_tessellate", "0", CVAR_NONE, gl_tessellate_f, nva ("Specifies tessellation level from 0 to %i. Higher " @@ -321,6 +348,18 @@ CheckGLVersionString (void) gl_feature_mach64 = true; } +static void +CheckAnisotropyExtensions (void) +{ + if (QFGL_ExtensionPresent ("GL_EXT_texture_filter_anisotropic")) { + Anisotropy = true; + qfglGetFloatv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &aniso_max); + } else { + Anisotropy = false; + aniso_max = 1.0; + } +} + static void CheckBGRAExtensions (void) { @@ -556,9 +595,13 @@ GL_Init_Common (void) qfglEnable (GL_BLEND); qfglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + CheckAnisotropyExtensions (); qfglTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + if (Anisotropy) + qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, + aniso); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);