summaryrefslogtreecommitdiff
path: root/src/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderer')
-rw-r--r--src/renderer/qgl.h18
-rw-r--r--src/renderer/tr_bsp.c2
-rw-r--r--src/renderer/tr_flares.c128
-rw-r--r--src/renderer/tr_image.c7
-rw-r--r--src/renderer/tr_init.c16
-rw-r--r--src/renderer/tr_local.h7
-rw-r--r--src/renderer/tr_shader.c24
-rw-r--r--src/renderer/tr_surface.c67
-rw-r--r--src/renderer/tr_types.h4
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