diff options
Diffstat (limited to 'src/renderer')
-rw-r--r-- | src/renderer/qgl.h | 18 | ||||
-rw-r--r-- | src/renderer/tr_bsp.c | 2 | ||||
-rw-r--r-- | src/renderer/tr_flares.c | 128 | ||||
-rw-r--r-- | src/renderer/tr_image.c | 7 | ||||
-rw-r--r-- | src/renderer/tr_init.c | 16 | ||||
-rw-r--r-- | src/renderer/tr_local.h | 7 | ||||
-rw-r--r-- | src/renderer/tr_shader.c | 24 | ||||
-rw-r--r-- | src/renderer/tr_surface.c | 67 | ||||
-rw-r--r-- | src/renderer/tr_types.h | 4 |
9 files changed, 179 insertions, 94 deletions
diff --git a/src/renderer/qgl.h b/src/renderer/qgl.h index e1945f8b..5bf52e13 100644 --- a/src/renderer/qgl.h +++ b/src/renderer/qgl.h @@ -92,11 +92,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA //=========================================================================== +// <Timbo> I hate this section so much /* ** multitexture extension definitions */ #if !defined(__sun) + #define GL_ACTIVE_TEXTURE_ARB 0x84E0 #define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 #define GL_MAX_ACTIVE_TEXTURES_ARB 0x84E2 @@ -105,10 +107,24 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define GL_TEXTURE1_ARB 0x84C1 #define GL_TEXTURE2_ARB 0x84C2 #define GL_TEXTURE3_ARB 0x84C3 + #else + #define GL_MAX_ACTIVE_TEXTURES_ARB 0x84E2 + #endif /* defined(__sun) */ +// anisotropic filtering constants +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF + +// define for skyboxes without black seams on non SDL-versions. +#if !defined(GL_VERSION_1_2) && !defined(GL_CLAMP_TO_EDGE) + #define GL_CLAMP_TO_EDGE 0x812F +#endif + +//=========================================================================== + // NOTE: some Linux platforms would need those prototypes #if defined(MACOS_X) || ( defined(__sun) && defined(__sparc) ) typedef void (APIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); @@ -175,7 +191,7 @@ extern void ( APIENTRY * qglUnlockArraysEXT) (void); //=========================================================================== -// non-windows systems will just redefine qgl* to gl* +// non-dlopening systems will just redefine qgl* to gl* #if !defined( _WIN32 ) && !defined(MACOS_X) && !defined( __linux__ ) && !defined( __FreeBSD__ ) && !defined(__sun) // rb010123 #include "qgl_linked.h" diff --git a/src/renderer/tr_bsp.c b/src/renderer/tr_bsp.c index eb57da8f..2eff8349 100644 --- a/src/renderer/tr_bsp.c +++ b/src/renderer/tr_bsp.c @@ -1824,7 +1824,7 @@ void RE_LoadWorldMap( const char *name ) { Q_strncpyz( s_worldData.name, name, sizeof( s_worldData.name ) ); Q_strncpyz( s_worldData.baseName, COM_SkipPath( s_worldData.name ), sizeof( s_worldData.name ) ); - COM_StripExtension( s_worldData.baseName, s_worldData.baseName ); + COM_StripExtension(s_worldData.baseName, s_worldData.baseName, sizeof(s_worldData.baseName)); startMarker = ri.Hunk_Alloc(0, h_low); c_gridVerts = 0; diff --git a/src/renderer/tr_flares.c b/src/renderer/tr_flares.c index 17e21976..f8fb222d 100644 --- a/src/renderer/tr_flares.c +++ b/src/renderer/tr_flares.c @@ -76,6 +76,7 @@ typedef struct flare_s { int windowX, windowY; float eyeZ; + vec3_t origin; vec3_t color; } flare_t; @@ -84,6 +85,8 @@ typedef struct flare_s { flare_t r_flareStructs[MAX_FLARES]; flare_t *r_activeFlares, *r_inactiveFlares; +int flareCoeff; + /* ================== R_ClearFlares @@ -114,11 +117,22 @@ void RB_AddFlare( void *surface, int fogNum, vec3_t point, vec3_t color, vec3_t int i; flare_t *f, *oldest; vec3_t local; - float d; + float d = 1; vec4_t eye, clip, normalized, window; backEnd.pc.c_flareAdds++; + if(normal && (normal[0] || normal[1] || normal[2])) + { + VectorSubtract( backEnd.viewParms.or.origin, point, local ); + VectorNormalizeFast(local); + d = DotProduct(local, normal); + + // If the viewer is behind the flare don't add it. + if(d < 0) + return; + } + // if the point is off the screen, don't bother adding it // calculate screen coordinates and depth R_TransformModelToClip( point, backEnd.or.modelMatrix, @@ -172,16 +186,12 @@ void RB_AddFlare( void *surface, int fogNum, vec3_t point, vec3_t color, vec3_t f->addedFrame = backEnd.viewParms.frameCount; f->fogNum = fogNum; + VectorCopy(point, f->origin); VectorCopy( color, f->color ); // fade the intensity of the flare down as the // light surface turns away from the viewer - if ( normal ) { - VectorSubtract( backEnd.viewParms.or.origin, point, local ); - VectorNormalizeFast( local ); - d = DotProduct( local, normal ); - VectorScale( f->color, d, f->color ); - } + VectorScale( f->color, d, f->color ); // save info needed to test f->windowX = backEnd.viewParms.viewportX + window[0]; @@ -198,31 +208,39 @@ RB_AddDlightFlares void RB_AddDlightFlares( void ) { dlight_t *l; int i, j, k; - fog_t *fog; + fog_t *fog = NULL; if ( !r_flares->integer ) { return; } l = backEnd.refdef.dlights; - fog = tr.world->fogs; + + if(tr.world) + fog = tr.world->fogs; + for (i=0 ; i<backEnd.refdef.num_dlights ; i++, l++) { - // find which fog volume the light is in - for ( j = 1 ; j < tr.world->numfogs ; j++ ) { - fog = &tr.world->fogs[j]; - for ( k = 0 ; k < 3 ; k++ ) { - if ( l->origin[k] < fog->bounds[0][k] || l->origin[k] > fog->bounds[1][k] ) { + if(fog) + { + // find which fog volume the light is in + for ( j = 1 ; j < tr.world->numfogs ; j++ ) { + fog = &tr.world->fogs[j]; + for ( k = 0 ; k < 3 ; k++ ) { + if ( l->origin[k] < fog->bounds[0][k] || l->origin[k] > fog->bounds[1][k] ) { + break; + } + } + if ( k == 3 ) { break; } } - if ( k == 3 ) { - break; + if ( j == tr.world->numfogs ) { + j = 0; } } - if ( j == tr.world->numfogs ) { + else j = 0; - } RB_AddFlare( (void *)l, j, l->origin, l->color, NULL ); } @@ -295,16 +313,65 @@ void RB_RenderFlare( flare_t *f ) { float size; vec3_t color; int iColor[3]; + float distance, intensity, factor; + byte fogFactors[3] = {255, 255, 255}; backEnd.pc.c_flareRenders++; - VectorScale( f->color, f->drawIntensity*tr.identityLight, color ); - iColor[0] = color[0] * 255; - iColor[1] = color[1] * 255; - iColor[2] = color[2] * 255; + // We don't want too big values anyways when dividing by distance. + if(f->eyeZ > -1.0f) + distance = 1.0f; + else + distance = -f->eyeZ; + + // calculate the flare size.. + size = backEnd.viewParms.viewportWidth * ( r_flareSize->value/640.0f + 8 / distance ); - size = backEnd.viewParms.viewportWidth * ( r_flareSize->value/640.0f + 8 / -f->eyeZ ); +/* + * This is an alternative to intensity scaling. It changes the size of the flare on screen instead + * with growing distance. See in the description at the top why this is not the way to go. + // size will change ~ 1/r. + size = backEnd.viewParms.viewportWidth * (r_flareSize->value / (distance * -2.0f)); +*/ +/* + * As flare sizes stay nearly constant with increasing distance we must decrease the intensity + * to achieve a reasonable visual result. The intensity is ~ (size^2 / distance^2) which can be + * got by considering the ratio of + * (flaresurface on screen) : (Surface of sphere defined by flare origin and distance from flare) + * An important requirement is: + * intensity <= 1 for all distances. + * + * The formula used here to compute the intensity is as follows: + * intensity = flareCoeff * size^2 / (distance + size*sqrt(flareCoeff))^2 + * As you can see, the intensity will have a max. of 1 when the distance is 0. + * The coefficient flareCoeff will determine the falloff speed with increasing distance. + */ + + factor = distance + size * sqrt(flareCoeff); + + intensity = flareCoeff * size * size / (factor * factor); + + VectorScale(f->color, f->drawIntensity * intensity, color); + +// Calculations for fogging + if(tr.world && f->fogNum < tr.world->numfogs) + { + tess.numVertexes = 1; + VectorCopy(f->origin, tess.xyz[0]); + tess.fogNum = f->fogNum; + + RB_CalcModulateColorsByFog(fogFactors); + + // We don't need to render the flare if colors are 0 anyways. + if(!(fogFactors[0] || fogFactors[1] || fogFactors[2])) + return; + } + + iColor[0] = color[0] * fogFactors[0]; + iColor[1] = color[1] * fogFactors[1]; + iColor[2] = color[2] * fogFactors[2]; + RB_BeginSurface( tr.flareShader, f->fogNum ); // FIXME: use quadstamp? @@ -383,6 +450,21 @@ void RB_RenderFlares (void) { return; } + if(r_flareCoeff->modified) + { + if(r_flareCoeff->value == 0.0f) + flareCoeff = atof(FLARE_STDCOEFF); + else + flareCoeff = r_flareCoeff->value; + + r_flareCoeff->modified = qfalse; + } + + // Reset currentEntity to world so that any previously referenced entities + // don't have influence on the rendering of these flares (i.e. RF_ renderer flags). + backEnd.currentEntity = &tr.worldEntity; + backEnd.or = backEnd.viewParms.world; + // RB_AddDlightFlares(); // perform z buffer readback on each flare in this view diff --git a/src/renderer/tr_image.c b/src/renderer/tr_image.c index 692f00c6..d4beacd8 100644 --- a/src/renderer/tr_image.c +++ b/src/renderer/tr_image.c @@ -700,11 +700,18 @@ done: if (mipmap) { + if ( glConfig.textureFilterAnisotropic ) + qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, + (GLint)Com_Clamp( 1, glConfig.maxAnisotropy, r_ext_max_anisotropy->integer ) ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } else { + if ( glConfig.textureFilterAnisotropic ) + qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1 ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); } diff --git a/src/renderer/tr_init.c b/src/renderer/tr_init.c index 475a37c6..f9cdc911 100644 --- a/src/renderer/tr_init.c +++ b/src/renderer/tr_init.c @@ -25,12 +25,16 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "tr_local.h" glconfig_t glConfig; +qboolean textureFilterAnisotropic = qfalse; +int maxAnisotropy = 0; + glstate_t glState; static void GfxInfo_f( void ); cvar_t *r_flareSize; cvar_t *r_flareFade; +cvar_t *r_flareCoeff; cvar_t *r_railWidth; cvar_t *r_railCoreWidth; @@ -81,6 +85,8 @@ cvar_t *r_ext_gamma_control; cvar_t *r_ext_multitexture; cvar_t *r_ext_compiled_vertex_array; cvar_t *r_ext_texture_env_add; +cvar_t *r_ext_texture_filter_anisotropic; +cvar_t *r_ext_max_anisotropy; cvar_t *r_ignoreGLErrors; cvar_t *r_logFile; @@ -995,6 +1001,10 @@ void R_Register( void ) r_picmip = ri.Cvar_Get ("r_picmip", GENERIC_HW_R_PICMIP_DEFAULT, CVAR_ARCHIVE | CVAR_LATCH ); + r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic", + "0", CVAR_ARCHIVE | CVAR_LATCH ); + r_ext_max_anisotropy = ri.Cvar_Get( "r_ext_max_anisotropy", "2", CVAR_ARCHIVE | CVAR_LATCH ); + r_roundImagesDown = ri.Cvar_Get ("r_roundImagesDown", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_colorMipLevels = ri.Cvar_Get ("r_colorMipLevels", "0", CVAR_LATCH ); AssertCvarRange( r_picmip, 0, 16, qtrue ); @@ -1079,6 +1089,7 @@ void R_Register( void ) r_flareSize = ri.Cvar_Get ("r_flareSize", "40", CVAR_CHEAT); r_flareFade = ri.Cvar_Get ("r_flareFade", "7", CVAR_CHEAT); + r_flareCoeff = ri.Cvar_Get ("r_flareCoeff", FLARE_STDCOEFF, CVAR_CHEAT); r_showSmp = ri.Cvar_Get ("r_showSmp", "0", CVAR_CHEAT); r_skipBackEnd = ri.Cvar_Get ("r_skipBackEnd", "0", CVAR_CHEAT); @@ -1141,6 +1152,11 @@ void R_Init( void ) { Com_Memset( &backEnd, 0, sizeof( backEnd ) ); Com_Memset( &tess, 0, sizeof( tess ) ); + if(sizeof(glconfig_t) != 11332) + { + ri.Error( ERR_FATAL, "Mod ABI incompatible: sizeof(glconfig_t) == %zd != 11332", sizeof(glconfig_t)); + } + // Swap_Init(); if ( (int)tess.xyz & 15 ) { diff --git a/src/renderer/tr_local.h b/src/renderer/tr_local.h index a80590ca..7c694759 100644 --- a/src/renderer/tr_local.h +++ b/src/renderer/tr_local.h @@ -971,12 +971,14 @@ extern trGlobals_t tr; extern glconfig_t glConfig; // outside of TR since it shouldn't be cleared during ref re-init extern glstate_t glState; // outside of TR since it shouldn't be cleared during ref re-init - // // cvars // extern cvar_t *r_flareSize; extern cvar_t *r_flareFade; +// coefficient for the flare intensity falloff function. +#define FLARE_STDCOEFF "150" +extern cvar_t *r_flareCoeff; extern cvar_t *r_railWidth; extern cvar_t *r_railCoreWidth; @@ -1039,6 +1041,9 @@ extern cvar_t *r_ext_multitexture; extern cvar_t *r_ext_compiled_vertex_array; extern cvar_t *r_ext_texture_env_add; +extern cvar_t *r_ext_texture_filter_anisotropic; +extern cvar_t *r_ext_max_anisotropy; + extern cvar_t *r_nobind; // turns off binding to appropriate textures extern cvar_t *r_singleShader; // make most world faces use default shader extern cvar_t *r_roundImagesDown; diff --git a/src/renderer/tr_shader.c b/src/renderer/tr_shader.c index 380f9bf6..0e4504ef 100644 --- a/src/renderer/tr_shader.c +++ b/src/renderer/tr_shader.c @@ -96,7 +96,7 @@ void R_RemapShader(const char *shaderName, const char *newShaderName, const char // remap all the shaders with the given name // even tho they might have different lightmaps - COM_StripExtension( shaderName, strippedName ); + COM_StripExtension(shaderName, strippedName, sizeof(strippedName)); hash = generateHashValue(strippedName, FILE_HASH_SIZE); for (sh = hashTable[hash]; sh; sh = sh->next) { if (Q_stricmp(sh->name, strippedName) == 0) { @@ -2366,7 +2366,7 @@ shader_t *R_FindShaderByName( const char *name ) { return tr.defaultShader; } - COM_StripExtension( name, strippedName ); + COM_StripExtension(name, strippedName, sizeof(strippedName)); hash = generateHashValue(strippedName, FILE_HASH_SIZE); @@ -2434,7 +2434,7 @@ shader_t *R_FindShader( const char *name, int lightmapIndex, qboolean mipRawImag lightmapIndex = LIGHTMAP_BY_VERTEX; } - COM_StripExtension( name, strippedName ); + COM_StripExtension(name, strippedName, sizeof(strippedName)); hash = generateHashValue(strippedName, FILE_HASH_SIZE); @@ -3010,8 +3010,22 @@ static void CreateInternalShaders( void ) { static void CreateExternalShaders( void ) { tr.projectionShadowShader = R_FindShader( "projectionShadow", LIGHTMAP_NONE, qtrue ); - //tr.flareShader = R_FindShader( "flareShader", LIGHTMAP_NONE, qtrue ); - //tr.sunShader = R_FindShader( "sun", LIGHTMAP_NONE, qtrue ); + tr.flareShader = R_FindShader( "flareShader", LIGHTMAP_NONE, qtrue ); + + // Hack to make fogging work correctly on flares. Fog colors are calculated + // in tr_flare.c already. + if(!tr.flareShader->defaultShader) + { + int index; + + for(index = 0; index < tr.flareShader->numUnfoggedPasses; index++) + { + tr.flareShader->stages[index]->adjustColorsForFog = ACFF_NONE; + tr.flareShader->stages[index]->stateBits |= GLS_DEPTHTEST_DISABLE; + } + } + + tr.sunShader = R_FindShader( "sun", LIGHTMAP_NONE, qtrue ); } /* diff --git a/src/renderer/tr_surface.c b/src/renderer/tr_surface.c index a65b17db..2a291c84 100644 --- a/src/renderer/tr_surface.c +++ b/src/renderer/tr_surface.c @@ -1215,71 +1215,12 @@ void RB_SurfaceBad( surfaceType_t *surfType ) { ri.Printf( PRINT_ALL, "Bad surface tesselated.\n" ); } -#if 0 - -void RB_SurfaceFlare( srfFlare_t *surf ) { - vec3_t left, up; - float radius; - byte color[4]; - vec3_t dir; - vec3_t origin; - float d; - - // calculate the xyz locations for the four corners - radius = 30; - VectorScale( backEnd.viewParms.or.axis[1], radius, left ); - VectorScale( backEnd.viewParms.or.axis[2], radius, up ); - if ( backEnd.viewParms.isMirror ) { - VectorSubtract( vec3_origin, left, left ); - } - - color[0] = color[1] = color[2] = color[3] = 255; - - VectorMA( surf->origin, 3, surf->normal, origin ); - VectorSubtract( origin, backEnd.viewParms.or.origin, dir ); - VectorNormalize( dir ); - VectorMA( origin, r_ignore->value, dir, origin ); - - d = -DotProduct( dir, surf->normal ); - if ( d < 0 ) { - return; - } -#if 0 - color[0] *= d; - color[1] *= d; - color[2] *= d; -#endif - - RB_AddQuadStamp( origin, left, up, color ); -} - -#else - -void RB_SurfaceFlare( srfFlare_t *surf ) { -#if 0 - vec3_t left, up; - byte color[4]; - - color[0] = surf->color[0] * 255; - color[1] = surf->color[1] * 255; - color[2] = surf->color[2] * 255; - color[3] = 255; - - VectorClear( left ); - VectorClear( up ); - - left[0] = r_ignore->value; - - up[1] = r_ignore->value; - - RB_AddQuadStampExt( surf->origin, left, up, color, 0, 0, 1, 1 ); -#endif +void RB_SurfaceFlare(srfFlare_t *surf) +{ + if (r_flares->integer) + RB_AddFlare(surf, tess.fogNum, surf->origin, surf->color, surf->normal); } -#endif - - - void RB_SurfaceDisplayList( srfDisplayList_t *surf ) { // all apropriate state must be set in RB_BeginSurface // this isn't implemented yet... diff --git a/src/renderer/tr_types.h b/src/renderer/tr_types.h index e3aabc3b..5aa08aed 100644 --- a/src/renderer/tr_types.h +++ b/src/renderer/tr_types.h @@ -201,6 +201,10 @@ typedef struct { qboolean isFullscreen; qboolean stereoEnabled; qboolean smpActive; // dual processor + + qboolean textureFilterAnisotropic; + int maxAnisotropy; + } glconfig_t; // FIXME: VM should be OS agnostic .. in theory |