Removed single-texuring surface rendering mode. Moved old functions to r_surface_singletex.c.

Refactored some suface rendering functions.
Moved some lightmap code from r_surface.c to r_warp.c.
This commit is contained in:
Knightmare66 2021-07-09 21:44:55 -04:00
parent 2b9c3da08e
commit 8d9024e33f
10 changed files with 1630 additions and 1157 deletions

View file

@ -135,7 +135,7 @@ How To Run
"-portable" to the command line, or by placing an empty text file called "portable.cfg" in the baseq2 folder.
An OpenGL 1.2 compatible 3D accelerator, OpenGL 1.4 support or higher (GeForce FX/Radeon 9500 or better) recommended.
(Note: 3Dfx cards are NOT supported)
Absolutely MUST have GL_ARB_multitexture support, 3Dfx cards are NOT supported.
Pentium III or Athlon 800MHz+
At least 512MB of RAM (1 GB recommended) for 32-bit operating sytems, at least 2GB for 64-bit operating sytsems.

View file

@ -41,6 +41,8 @@ Changes as of v0.20 update 8:
- Added upscaling of the scrap image (with optional blending by Skuller from Q2Pro) used to atlas 8-bit HUD pics.
Use cvar r_scrap_upscale to enable, value of 1 is pixel copy, value of 2 enables blending.
Requires vid_restart for changes to take effect.
- Removed the old, decrepit single-texturing surface rendering mode. GL_ARB_multitexture support is now required.
- Now reads/writes savegames, config files, demos, etc. to <userprofile>/Saved Games/KMQuake2 on Windows Vista
and later, and to My Documents/My Games/KMQuake2 on Windows 2000/XP/2003.

View file

@ -426,9 +426,6 @@ GL_EnableTexture
*/
void GL_EnableTexture (unsigned tmu)
{
if (tmu > 0 && !glConfig.multitexture)
return;
if (tmu >= MAX_TEXTURE_UNITS || tmu >= glConfig.max_texunits)
return;
@ -446,9 +443,6 @@ GL_DisableTexture
*/
void GL_DisableTexture (unsigned tmu)
{
if (tmu > 0 && !glConfig.multitexture)
return;
if (tmu >= MAX_TEXTURE_UNITS || tmu >= glConfig.max_texunits)
return;
@ -466,9 +460,6 @@ Only used for world drawing
*/
void GL_EnableMultitexture (qboolean enable)
{
if (!glConfig.multitexture)
return;
if (enable)
{
GL_EnableTexture(1);
@ -490,9 +481,6 @@ GL_SelectTexture
*/
void GL_SelectTexture (unsigned tmu)
{
if (!glConfig.multitexture)
return;
if (tmu >= MAX_TEXTURE_UNITS || tmu >= glConfig.max_texunits)
return;

View file

@ -26,7 +26,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
int r_dlightframecount;
void vectoangles (vec3_t value1, vec3_t angles);
gllightmapstate_t gl_lms;
static void LM_InitBlock (void);
static void LM_UploadBlock (qboolean dynamic);
static qboolean LM_AllocBlock (int w, int h, int *x, int *y);
//#define DLIGHT_CUTOFF 64 // Knightmare- no longer hard-coded
@ -566,7 +570,6 @@ void R_SurfLightPoint (msurface_t *surf, vec3_t p, vec3_t color, qboolean baseli
if (baselight)
{
#if 1
VectorCopy (vec3_origin, bestColor);
for (i=0; i<9; i++) // test multiple offset points to avoid dark corners, select brightest
{
@ -583,31 +586,18 @@ void R_SurfLightPoint (msurface_t *surf, vec3_t p, vec3_t color, qboolean baseli
if ( (r != -1) && (VectorLength(pointcolor) > VectorLength(bestColor)) )
VectorCopy (pointcolor, bestColor);
}
#else
for (i=0; i<4; i++) // test multiple points to avoid dark corners
{
VectorCopy (p, start);
VectorAdd (start, startOffset[i], start);
end[0] = start[0];
end[1] = start[1];
end[2] = start[2] - 2048;
r = RecursiveLightPoint (r_worldmodel->nodes, start, end);
if (r != -1) break;
}
#endif
/*
end[0] = p[0];
end[1] = p[1];
end[2] = p[2] - 2048;
r = RecursiveLightPoint (r_worldmodel->nodes, p, end);
*/
if (r == -1)
VectorCopy (vec3_origin, color);
else
VectorCopy (pointcolor, color);
VectorCopy (pointcolor, color);*/
VectorCopy (bestColor, color);
// this catches too bright modulated color
for (i=0; i<3; i++)
@ -641,7 +631,7 @@ void R_SurfLightPoint (msurface_t *surf, vec3_t p, vec3_t color, qboolean baseli
}
VectorSubtract (p, dlorigin, dist);
// end Knightmare
//VectorSubtract (p, dl->origin, dist);
// VectorSubtract (p, dl->origin, dist);
add = dl->intensity - VectorLength(dist);
add *= (DIV256);
@ -734,7 +724,7 @@ void R_ShadowLight (vec3_t pos, vec3_t lightAdd)
//===================================================================
static float s_blocklights[128*128*4]; //Knightmare- was [34*34*3], supports max chop size of 2048?
static float s_blocklights[136*136*3]; //Knightmare- was [34*34*3], supports max chop size of 2048?
/*
===============
R_AddDynamicLights
@ -776,11 +766,9 @@ void R_AddDynamicLights (msurface_t *surf)
VectorCopy (currententity->angles, entAngles);
}
// if (currententity->angles[0] || currententity->angles[1] || currententity->angles[2])
if (entAngles[0] || entAngles[1] || entAngles[2])
{
rotated = true;
// AngleVectors (currententity->angles, forward, right, up);
AngleVectors (entAngles, forward, right, up);
}
@ -798,7 +786,6 @@ void R_AddDynamicLights (msurface_t *surf)
frad = dl->intensity;
VectorCopy (dl->origin, dlorigin);
// VectorSubtract (dlorigin, currententity->origin, dlorigin);
VectorSubtract (dlorigin, entOrigin, dlorigin);
if (rotated)
@ -858,6 +845,137 @@ void R_AddDynamicLights (msurface_t *surf)
}
}
/*
=============================================================================
LIGHTMAP ALLOCATION
=============================================================================
*/
/*
================
LM_InitBlock
================
*/
static void LM_InitBlock (void)
{
memset( gl_lms.allocated, 0, sizeof( gl_lms.allocated ) );
#ifdef BATCH_LM_UPDATES
// alloc lightmap update buffer if needed
if (!gl_lms.lightmap_update[gl_lms.current_lightmap_texture]) {
gl_lms.lightmap_update[gl_lms.current_lightmap_texture] = Z_Malloc (LM_BLOCK_WIDTH*LM_BLOCK_HEIGHT*LIGHTMAP_BYTES);
}
#endif // BATCH_LM_UPDATES
}
/*
================
LM_UploadBlock
================
*/
static void LM_UploadBlock (qboolean dynamic)
{
int texture;
int height = 0;
if ( dynamic )
{
texture = 0;
}
else
{
texture = gl_lms.current_lightmap_texture;
}
GL_Bind( glState.lightmap_textures + texture );
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if ( dynamic )
{
int i;
for ( i = 0; i < LM_BLOCK_WIDTH; i++ )
{
if ( gl_lms.allocated[i] > height )
height = gl_lms.allocated[i];
}
qglTexSubImage2D( GL_TEXTURE_2D,
0,
0, 0,
LM_BLOCK_WIDTH, height,
gl_lms.format,
gl_lms.type,
// GL_LIGHTMAP_FORMAT,
// GL_UNSIGNED_BYTE,
gl_lms.lightmap_buffer );
}
else
{
qglTexImage2D( GL_TEXTURE_2D,
0,
gl_lms.internal_format,
LM_BLOCK_WIDTH, LM_BLOCK_HEIGHT,
0,
gl_lms.format,
gl_lms.type,
// GL_LIGHTMAP_FORMAT,
// GL_UNSIGNED_BYTE,
#ifdef BATCH_LM_UPDATES
gl_lms.lightmap_update[gl_lms.current_lightmap_texture] );
#else
gl_lms.lightmap_buffer );
#endif // BATCH_LM_UPDATES
if ( ++gl_lms.current_lightmap_texture == MAX_LIGHTMAPS )
VID_Error( ERR_DROP, "LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n" );
}
}
/*
================
LM_AllocBlock
returns a texture number and the position inside it
================
*/
static qboolean LM_AllocBlock (int w, int h, int *x, int *y)
{
int i, j;
int best, best2;
best = LM_BLOCK_HEIGHT;
for (i=0 ; i<LM_BLOCK_WIDTH-w ; i++)
{
best2 = 0;
for (j=0 ; j<w ; j++)
{
if (gl_lms.allocated[i+j] >= best)
break;
if (gl_lms.allocated[i+j] > best2)
best2 = gl_lms.allocated[i+j];
}
if (j == w)
{ // this is a valid spot
*x = i;
*y = best = best2;
}
}
if (best + h > LM_BLOCK_HEIGHT)
return false;
for (i=0 ; i<w ; i++)
gl_lms.allocated[*x + i] = best + h;
return true;
}
/*
===============
@ -1190,3 +1308,199 @@ store:
}
}
}
/*
========================
R_CreateSurfaceLightmap
========================
*/
void R_CreateSurfaceLightmap (msurface_t *surf)
{
int smax, tmax;
unsigned *base;
if (surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB))
return;
//if (surf->texinfo->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP))
if (surf->texinfo->flags & (SURF_SKY|SURF_WARP))
return;
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
if ( !LM_AllocBlock (smax, tmax, &surf->light_s, &surf->light_t) )
{
LM_UploadBlock (false);
LM_InitBlock();
if ( !LM_AllocBlock (smax, tmax, &surf->light_s, &surf->light_t) )
{
VID_Error (ERR_FATAL, "Consecutive calls to LM_AllocBlock(%d,%d) failed\n", smax, tmax);
}
}
surf->lightmaptexturenum = gl_lms.current_lightmap_texture;
// copy extents
surf->light_smax = smax;
surf->light_tmax = tmax;
#ifdef BATCH_LM_UPDATES
base = gl_lms.lightmap_update[surf->lightmaptexturenum];
#else
base = gl_lms.lightmap_buffer;
#endif // BATCH_LM_UPDATES
base += (surf->light_t * LM_BLOCK_WIDTH + surf->light_s); // * LIGHTMAP_BYTES
R_SetCacheState (surf);
R_BuildLightMap (surf, (void *)base, LM_BLOCK_WIDTH*LIGHTMAP_BYTES);
}
#define gl_tex_solid_format 3
#define gl_tex_alpha_format 4
/*
==================
R_BeginBuildingLightmaps
==================
*/
void R_BeginBuildingLightmaps (model_t *m)
{
static lightstyle_t lightstyles[MAX_LIGHTSTYLES];
int i;
unsigned dummy[LM_BLOCK_WIDTH*LM_BLOCK_HEIGHT]; // 128*128
memset( gl_lms.allocated, 0, sizeof(gl_lms.allocated) );
#ifdef BATCH_LM_UPDATES
// free lightmap update buffers
for (i=0; i<MAX_LIGHTMAPS; i++)
{
if (gl_lms.lightmap_update[i])
Z_Free(gl_lms.lightmap_update[i]);
gl_lms.lightmap_update[i] = NULL;
gl_lms.modified[i] = false;
gl_lms.lightrect[i].left = LM_BLOCK_WIDTH;
gl_lms.lightrect[i].right = 0;
gl_lms.lightrect[i].top = LM_BLOCK_HEIGHT;
gl_lms.lightrect[i].bottom = 0;
}
#endif // BATCH_LM_UPDATES
r_framecount = 1; // no dlightcache
GL_EnableMultitexture (true);
GL_SelectTexture(1);
// setup the base lightstyles so the lightmaps won't have to be regenerated
// the first time they're seen
for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
{
lightstyles[i].rgb[0] = 1;
lightstyles[i].rgb[1] = 1;
lightstyles[i].rgb[2] = 1;
lightstyles[i].white = 3;
}
r_newrefdef.lightstyles = lightstyles;
if (!glState.lightmap_textures)
{
glState.lightmap_textures = TEXNUM_LIGHTMAPS;
// glState.lightmap_textures = glState.texture_extension_number;
// glState.texture_extension_number = glState.lightmap_textures + MAX_LIGHTMAPS;
}
gl_lms.current_lightmap_texture = 1;
#ifdef BATCH_LM_UPDATES
// alloc lightmap update buffer if needed
if (!gl_lms.lightmap_update[gl_lms.current_lightmap_texture]) {
gl_lms.lightmap_update[gl_lms.current_lightmap_texture] = Z_Malloc (LM_BLOCK_WIDTH*LM_BLOCK_HEIGHT*LIGHTMAP_BYTES);
}
#endif // BATCH_LM_UPDATES
/*
** if mono lightmaps are enabled and we want to use alpha
** blending (a,1-a) then we're likely running on a 3DLabs
** Permedia2. In a perfect world we'd use a GL_ALPHA lightmap
** in order to conserve space and maximize bandwidth, however
** this isn't a perfect world.
**
** So we have to use alpha lightmaps, but stored in GL_RGBA format,
** which means we only get 1/16th the color resolution we should when
** using alpha lightmaps. If we find another board that supports
** only alpha lightmaps but that can at least support the GL_ALPHA
** format then we should change this code to use real alpha maps.
*/
// Knightmare- old internal formats for compatibility with older GPUs/drivers
if ( !glConfig.newLMFormat )
{
if ( toupper( r_monolightmap->string[0] ) == 'A' )
{
gl_lms.internal_format = gl_tex_alpha_format;
}
// try to do hacked colored lighting with a blended texture
else if ( toupper( r_monolightmap->string[0] ) == 'C' )
{
gl_lms.internal_format = gl_tex_alpha_format;
}
else if ( toupper( r_monolightmap->string[0] ) == 'I' )
{
gl_lms.internal_format = GL_INTENSITY8;
}
else if ( toupper( r_monolightmap->string[0] ) == 'L' )
{
gl_lms.internal_format = GL_LUMINANCE8;
}
else
{
gl_lms.internal_format = gl_tex_solid_format;
}
gl_lms.format = GL_RGBA;
gl_lms.type = GL_UNSIGNED_BYTE;
}
else
{
if ( toupper( r_monolightmap->string[0] ) == 'I' )
gl_lms.internal_format = GL_INTENSITY8;
else if ( toupper( r_monolightmap->string[0] ) == 'L' )
gl_lms.internal_format = GL_LUMINANCE8;
else
gl_lms.internal_format = GL_RGBA8;
gl_lms.format = GL_BGRA;
gl_lms.type = GL_UNSIGNED_INT_8_8_8_8_REV;
}
// initialize the dynamic lightmap texture
GL_Bind( glState.lightmap_textures + 0 );
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qglTexImage2D( GL_TEXTURE_2D,
0,
gl_lms.internal_format,
LM_BLOCK_WIDTH, LM_BLOCK_HEIGHT,
0,
gl_lms.format,
gl_lms.type,
// GL_LIGHTMAP_FORMAT,
// GL_UNSIGNED_BYTE,
dummy );
}
/*
=======================
R_EndBuildingLightmaps
=======================
*/
void R_EndBuildingLightmaps (void)
{
LM_UploadBlock (false);
GL_EnableMultitexture (false);
}

View file

@ -260,7 +260,6 @@ extern cvar_t *alt_text_color;
//extern cvar_t *gl_ext_palettedtexture;
//extern cvar_t *gl_ext_pointparameters;
//extern cvar_t *r_ext_swapinterval; // unused
extern cvar_t *r_ext_multitexture;
extern cvar_t *r_ext_draw_range_elements;
extern cvar_t *r_ext_compiled_vertex_array;
extern cvar_t *r_arb_texturenonpoweroftwo;
@ -470,9 +469,17 @@ extern gllightmapstate_t gl_lms;
//void R_LightPoint (vec3_t p, vec3_t color);
void R_LightPoint (vec3_t p, vec3_t color, qboolean isEnt);
void R_LightPointDynamics (vec3_t p, vec3_t color, m_dlight_t *list, int *amount, int max);
void R_SurfLightPoint (msurface_t *surf, vec3_t p, vec3_t color, qboolean baselight);
void R_PushDlights (void);
void R_ShadowLight (vec3_t pos, vec3_t lightAdd);
void R_MarkLights (dlight_t *light, int bit, mnode_t *node);
void R_RenderDlights (void);
void R_AddDynamicLights (msurface_t *surf);
void R_SetCacheState (msurface_t *surf);
void R_BuildLightMap (msurface_t *surf, byte *dest, int stride);
void R_CreateSurfaceLightmap (msurface_t *surf);
void R_EndBuildingLightmaps (void);
void R_BeginBuildingLightmaps (model_t *m);
//====================================================================
@ -484,6 +491,11 @@ extern float d_8to24tablef[256][3]; //Knightmare added
extern int registration_sequence;
//
// cl_utils.c
//
void vectoangles (vec3_t value1, vec3_t angles);
void V_AddBlend (float r, float g, float b, float a, float *v_blend);
//
@ -524,7 +536,7 @@ void R_DrawSpriteModel (entity_t *e);
void R_DrawBeam( entity_t *e );
void R_DrawWorld (void);
void R_RenderDlights (void);
void R_DrawAlphaSurfaces (void);
void R_DrawAllAlphaSurfaces (void);
void R_RenderBrushPoly (msurface_t *fa);
void R_InitMedia (void);
void R_DrawInitLocal (void);
@ -645,8 +657,23 @@ void R_DrawSkyBox (void);
//
// r_surf.c
// r_surface.c
//
//extern surfaceHandle_t r_surfaceHandles[MAX_SURFACE_HANDLES];
void R_DrawWorld (void);
void R_DrawAllAlphaSurfaces (void);
void R_RenderBrushPoly (msurface_t *fa);
void R_DrawBrushModel (entity_t *e);
void R_MarkLeaves (void);
qboolean R_CullBox (vec3_t mins, vec3_t maxs);
void R_BuildPolygonFromSurface (msurface_t *surf);
void R_ResetVertextLights_f (void);
void R_BuildVertexLight (msurface_t *surf);
#ifdef BATCH_LM_UPDATES
void R_UpdateSurfaceLightmap (msurface_t *surf);
void R_RebuildLightmaps (void);
#endif
//
@ -841,7 +868,7 @@ typedef struct
qboolean arbTextureNonPowerOfTwo;
qboolean vertexBufferObject;
qboolean multitexture;
// qboolean multitexture;
qboolean mtexcombine; // added Vic's RGB brightening
qboolean have_stencil;

View file

@ -118,7 +118,6 @@ cvar_t *r_rgbscale; // Vic's RGB brightening
//cvar_t *r_vertex_arrays; // unused
//cvar_t *r_ext_swapinterval; // unused
cvar_t *r_ext_multitexture;
cvar_t *r_ext_draw_range_elements;
cvar_t *r_ext_compiled_vertex_array;
cvar_t *r_arb_texturenonpoweroftwo; // Knightmare- non-power-of-two texture support
@ -719,7 +718,7 @@ void R_RenderView (refdef_t *fd)
R_DrawEntitiesOnList(ents_viewweaps);
R_ParticleStencil (1);
R_DrawAlphaSurfaces ();
R_DrawAllAlphaSurfaces ();
R_ParticleStencil (2);
R_ParticleStencil (3);
@ -1106,8 +1105,6 @@ void R_Register (void)
// gl_ext_palettedtexture = Cvar_Get( "gl_ext_palettedtexture", "0", CVAR_ARCHIVE );
// gl_ext_pointparameters = Cvar_Get( "gl_ext_pointparameters", "1", CVAR_ARCHIVE );
// r_ext_swapinterval = Cvar_Get( "r_ext_swapinterval", "1", CVAR_ARCHIVE ); // unused
r_ext_multitexture = Cvar_Get( "r_ext_multitexture", "1", CVAR_ARCHIVE );
Cvar_SetDescription ("r_ext_multitexture", "Enables multitexture rendering of lightmapped surfaces.");
r_ext_draw_range_elements = Cvar_Get("r_ext_draw_range_elements", "1", CVAR_ARCHIVE /*| CVAR_LATCH*/);
Cvar_SetDescription ("r_ext_draw_range_elements", "Enables use of glDrawRangeElements().");
r_ext_compiled_vertex_array = Cvar_Get( "r_ext_compiled_vertex_array", "1", CVAR_ARCHIVE );
@ -1354,47 +1351,52 @@ Grabs GL extensions
*/
qboolean R_CheckGLExtensions (char *reason)
{
qboolean multitexture_found = false;
// OpenGL multitexture on GL 1.2.1 or later or GL_ARB_multitexture
glConfig.multitexture = false;
glConfig.max_texunits = 1;
// This is checked first, is required
glConfig.max_texunits = 2; // must have at least 2
if ( (glConfig.version_major >= 2) || (glConfig.version_major == 1 && glConfig.version_minor > 2)
|| (glConfig.version_major == 1 && glConfig.version_minor == 2 && glConfig.version_release >= 1) )
{
qglMultiTexCoord2fARB = (void *) qwglGetProcAddress( "glMultiTexCoord2f" );
qglActiveTextureARB = (void *) qwglGetProcAddress( "glActiveTexture" );
qglClientActiveTextureARB = (void *) qwglGetProcAddress( "glClientActiveTexture" );
if (!qglMultiTexCoord2fARB || !qglActiveTextureARB || !qglClientActiveTextureARB)
{
if (!qglMultiTexCoord2fARB || !qglActiveTextureARB || !qglClientActiveTextureARB) {
VID_Printf (PRINT_ALL, "...OpenGL multitexture not found, checking for GL_ARB_multitexture\n" );
}
else {
VID_Printf (PRINT_ALL, "...using OpenGL multitexture\n" );
qglGetIntegerv(GL_MAX_TEXTURE_UNITS, &glConfig.max_texunits);
VID_Printf (PRINT_ALL, "...GL_MAX_TEXTURE_UNITS: %i\n", glConfig.max_texunits);
glConfig.multitexture = true;
multitexture_found = true;
}
}
if ( (!glConfig.multitexture) && Q_StrScanToken( glConfig.extensions_string, "GL_ARB_multitexture", false ) )
if ( (!multitexture_found) && Q_StrScanToken( glConfig.extensions_string, "GL_ARB_multitexture", false ) )
{
if (r_ext_multitexture->integer)
{
qglMultiTexCoord2fARB = (void *) qwglGetProcAddress( "glMultiTexCoord2fARB" );
qglActiveTextureARB = (void *) qwglGetProcAddress( "glActiveTextureARB" );
qglClientActiveTextureARB = (void *) qwglGetProcAddress( "glClientActiveTextureARB" );
if (!qglMultiTexCoord2fARB || !qglActiveTextureARB || !qglClientActiveTextureARB)
VID_Printf (PRINT_ALL, "..." S_COLOR_RED "GL_ARB_multitexture not properly supported!\n"S_COLOR_YELLOW"WARNING: glow/caustic texture effects not enabled\n");
else {
VID_Printf (PRINT_ALL, "...using GL_ARB_multitexture\n" );
qglGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &glConfig.max_texunits);
VID_Printf (PRINT_ALL, "...GL_MAX_TEXTURE_UNITS_ARB: %i\n", glConfig.max_texunits);
glConfig.multitexture = true;
}
qglMultiTexCoord2fARB = (void *) qwglGetProcAddress( "glMultiTexCoord2fARB" );
qglActiveTextureARB = (void *) qwglGetProcAddress( "glActiveTextureARB" );
qglClientActiveTextureARB = (void *) qwglGetProcAddress( "glClientActiveTextureARB" );
if (!qglMultiTexCoord2fARB || !qglActiveTextureARB || !qglClientActiveTextureARB) {
QGL_Shutdown();
VID_Printf (PRINT_ALL, "R_Init() - GL_ARB_multitexture functions not implemented in driver!\n" );
memcpy (reason, "GL_ARB_multitexture not properly implemented in driver!\0", 55);
return false;
}
else {
VID_Printf (PRINT_ALL, "...using GL_ARB_multitexture\n" );
qglGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &glConfig.max_texunits);
VID_Printf (PRINT_ALL, "...GL_MAX_TEXTURE_UNITS_ARB: %i\n", glConfig.max_texunits);
multitexture_found = true;
}
else
VID_Printf (PRINT_ALL, "...ignoring GL_ARB_multitexture\n"S_COLOR_YELLOW"WARNING: glow/caustic texture effects not enabled\n" );
}
if (!glConfig.multitexture)
VID_Printf (PRINT_ALL, "...GL_ARB_multitexture not found\n"S_COLOR_YELLOW"WARNING: glow/caustic texture effects not supported\n" );
if (!multitexture_found)
{
QGL_Shutdown();
VID_Printf (PRINT_ALL, "R_Init() - GL_ARB_multitexture not found\n" );
memcpy (reason, "GL_ARB_multitexture not supported by driver!\0", 44);
return false;
}
// GL_EXT_compiled_vertex_array
// GL_SGI_compiled_vertex_array

View file

@ -97,7 +97,7 @@ typedef struct
vec2_t texture_st;
vec2_t lightmap_st;
byte basecolor[4];
byte color[4];
byte lightcolor[4];
} mpolyvertex_t;
*/
@ -161,12 +161,13 @@ typedef struct msurface_s
} msurface_t;
typedef struct malphasurface_s
typedef struct surfaceHandle_s
{
msurface_t *surf;
entity_t *entity; // entity pointer
struct malphasurface_s *surfacechain;
} malphasurface_t;
msurface_t *surf;
entity_t *entity; // entity pointer
int flags; // entity-specific surface flags
struct surfaceHandle_s *surfacechain; // next surface
} surfaceHandle_t;
typedef struct mnode_s

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,924 @@
/*
===========================================================================
Copyright (C) 1997-2001 Id Software, Inc.
This file is part of Quake 2 source code.
Quake 2 source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Quake 2 source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Quake 2 source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// r_surf_singletex.c: old single-texture 2-pass world rendering (no longer used)
#include "r_local.h"
#if USE_SINGLETEXTURE_MODE
/*
================
R_DrawWarpPoly
================
*/
void R_DrawWarpPoly (msurface_t *surf)
{
if (!(surf->flags & SURF_DRAWTURB))
return;
R_BuildVertexLight (surf);
// warp texture, no lightmaps
GL_EnableMultitexture (false);
// GL_TexEnv(GL_MODULATE);
R_DrawWarpSurface (surf, 1.0, true);
// GL_TexEnv(GL_REPLACE);
GL_EnableMultitexture (true);
}
/*
================
R_DrawTriangleOutlines
================
*/
void R_DrawTriangleOutlines (void)
{
int i, j, nv;
float *v;
msurface_t *surf;
glpoly_t *p;
// not used in multitexture mode
if (glConfig.multitexture)
return;
if (!r_showtris->integer)
return;
if (r_showtris->integer == 1)
GL_Disable(GL_DEPTH_TEST);
GL_DisableTexture (0);
qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
rb_vertex = rb_index = 0;
for (i = 0; i < MAX_LIGHTMAPS; i++)
{
for (surf = gl_lms.lightmap_surfaces[i]; surf != 0; surf = surf->lightmapchain)
{
for (p = surf->polys; p; p = p->chain)
{
v = p->verts[0];
nv = p->numverts;
if (RB_CheckArrayOverflow (nv, (nv-2)*3))
RB_RenderMeshGeneric (false);
for (j=0; j < nv-2; j++) {
indexArray[rb_index++] = rb_vertex;
indexArray[rb_index++] = rb_vertex+j+1;
indexArray[rb_index++] = rb_vertex+j+2;
}
for (j=0; j < nv; j++, v+= VERTEXSIZE)
{
VA_SetElem3(vertexArray[rb_vertex], v[0], v[1], v[2]);
VA_SetElem4(colorArray[rb_vertex], 1, 1, 1, 1);
rb_vertex++;
}
}
}
}
// RB_DrawArrays ();
RB_RenderMeshGeneric (false);
qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
GL_EnableTexture(0);
if (r_showtris->integer == 1)
GL_Enable(GL_DEPTH_TEST);
}
/*
================
R_DrawGLPolyChain
================
*/
void R_DrawGLPolyChain (glpoly_t *p, float soffset, float toffset)
{
float *v;
int j, nv;
rb_vertex = rb_index = 0;
for ( ; p != 0; p = p->chain)
{
v = p->verts[0];
nv = p->numverts;
if (RB_CheckArrayOverflow (nv, (nv-2)*3))
RB_RenderMeshGeneric (false);
for (j=0; j < nv-2; j++) {
indexArray[rb_index++] = rb_vertex;
indexArray[rb_index++] = rb_vertex+j+1;
indexArray[rb_index++] = rb_vertex+j+2;
}
for (j=0; j < nv; j++, v+= VERTEXSIZE)
{
VA_SetElem2(texCoordArray[0][rb_vertex], v[5] - soffset, v[6] - toffset);
VA_SetElem3(vertexArray[rb_vertex], v[0], v[1], v[2]);
VA_SetElem4(colorArray[rb_vertex], 1, 1, 1, 1);
rb_vertex++;
}
}
// RB_DrawArrays ();
RB_RenderMeshGeneric (false);
}
/*
================
R_DrawAlphaSurfaces
Draw trans water surfaces and windows.
The BSP tree is waled front to back, so unwinding the chain
of alpha_surfaces will draw back to front, giving proper ordering.
================
*/
void R_DrawAlphaSurfaces (void)
{
msurface_t *s;
qboolean light; //solidAlpha, envMap;
// the textures are prescaled up for a better lighting range,
// so scale it back down
rb_vertex = rb_index = 0;
for (s = r_alpha_surfaces; s; s = s->texturechain)
{
// go back to the world matrix
qglLoadMatrixf (r_world_matrix);
R_BuildVertexLight (s);
GL_Enable (GL_BLEND);
GL_TexEnv (GL_MODULATE);
GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// disable depth testing for all bmodel surfs except solid alphas
if ( s->entity && !((s->flags & SURF_TRANS33) && (s->flags & SURF_TRANS66)) )
GL_DepthMask (false);
else
GL_DepthMask (true);
// moving trans brushes - spaz
if (s->entity)
R_RotateForEntity (s->entity, true);
light = R_SurfIsLit(s);
// solidAlpha = ( (s->texinfo->flags & SURF_TRANS33|SURF_TRANS66) == SURF_TRANS33|SURF_TRANS66 );
// envMap = ( (s->flags & SURF_ENVMAP) && r_glass_envmaps->integer && !solidAlpha);
if (s->flags & SURF_DRAWTURB)
R_DrawWarpSurface (s, R_SurfAlphaCalc(s->texinfo->flags), !R_SurfsAreBatchable (s, s->texturechain));
else if ( (r_trans_lighting->integer == 2) && glConfig.multitexture && light && s->lightmaptexturenum )
{
GL_EnableMultitexture (true);
R_SetLightingMode (RF_TRANSLUCENT);
R_DrawLightmappedSurface (s, true);
GL_EnableMultitexture (false);
}
else
R_DrawGLPoly (s, !R_SurfsAreBatchable (s, s->texturechain));// true);
}
// go back to the world matrix after shifting trans faces
qglLoadMatrixf (r_world_matrix);
GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GL_TexEnv (GL_REPLACE);
qglColor4f (1,1,1,1);
GL_Disable (GL_BLEND);
GL_DepthMask (true);
r_alpha_surfaces = NULL;
}
/*
================
R_BlendLightMaps
This routine takes all the given light mapped surfaces in the world and
blends them into the framebuffer.
================
*/
void R_BlendLightmaps (void)
{
int i;
msurface_t *surf, *newdrawsurf = 0;
// not used in multitexture mode
if (glConfig.multitexture)
return;
// don't bother if we're set to fullbright
if (r_fullbright->integer)
return;
if (!r_worldmodel->lightdata)
return;
// don't bother writing Z
GL_DepthMask (false);
// set the appropriate blending mode unless we're only looking at the
// lightmaps.
if (!r_lightmap->integer)
{
GL_Enable (GL_BLEND);
if (r_saturatelighting->integer)
{
GL_BlendFunc( GL_ONE, GL_ONE );
}
else
{
if (r_monolightmap->string[0] != '0')
{
switch (toupper(r_monolightmap->string[0]))
{
case 'I':
GL_BlendFunc (GL_ZERO, GL_SRC_COLOR);
break;
case 'L':
GL_BlendFunc (GL_ZERO, GL_SRC_COLOR);
break;
case 'A':
default:
GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break;
}
}
else
{
GL_BlendFunc (GL_ZERO, GL_SRC_COLOR);
}
}
}
if (currentmodel == r_worldmodel)
c_visible_lightmaps = 0;
// render static lightmaps first
for (i = 1; i < MAX_LIGHTMAPS; i++)
{
if (gl_lms.lightmap_surfaces[i])
{
if (currentmodel == r_worldmodel)
c_visible_lightmaps++;
GL_Bind( glState.lightmap_textures + i);
for (surf = gl_lms.lightmap_surfaces[i]; surf != 0; surf = surf->lightmapchain)
{
if (surf->polys)
R_DrawGLPolyChain(surf->polys, 0, 0);
}
}
}
// render dynamic lightmaps
if (r_dynamic->integer)
{
LM_InitBlock();
GL_Bind(glState.lightmap_textures+0);
if (currentmodel == r_worldmodel)
c_visible_lightmaps++;
newdrawsurf = gl_lms.lightmap_surfaces[0];
for (surf = gl_lms.lightmap_surfaces[0]; surf != 0; surf = surf->lightmapchain)
{
int smax, tmax;
unsigned *base;
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
if ( LM_AllocBlock( smax, tmax, &surf->dlight_s, &surf->dlight_t ) )
{
base = gl_lms.lightmap_buffer;
base += (surf->dlight_t * LM_BLOCK_WIDTH + surf->dlight_s); // * LIGHTMAP_BYTES
R_BuildLightMap (surf, (void *)base, LM_BLOCK_WIDTH*LIGHTMAP_BYTES);
}
else
{
msurface_t *drawsurf;
// upload what we have so far
LM_UploadBlock(true);
// draw all surfaces that use this lightmap
for ( drawsurf = newdrawsurf; drawsurf != surf; drawsurf = drawsurf->lightmapchain )
{
if (drawsurf->polys)
R_DrawGLPolyChain( drawsurf->polys,
(drawsurf->light_s - drawsurf->dlight_s) * (1.0 / 128.0),
(drawsurf->light_t - drawsurf->dlight_t) * (1.0 / 128.0) );
}
newdrawsurf = drawsurf;
// clear the block
LM_InitBlock();
// try uploading the block now
if (!LM_AllocBlock(smax, tmax, &surf->dlight_s, &surf->dlight_t))
{
VID_Error( ERR_FATAL, "Consecutive calls to LM_AllocBlock(%d,%d) failed (dynamic)\n", smax, tmax );
}
base = gl_lms.lightmap_buffer;
base += (surf->dlight_t * LM_BLOCK_WIDTH + surf->dlight_s); // * LIGHTMAP_BYTES
R_BuildLightMap (surf, (void *)base, LM_BLOCK_WIDTH*LIGHTMAP_BYTES);
}
}
// draw remainder of dynamic lightmaps that haven't been uploaded yet
if (newdrawsurf)
LM_UploadBlock( true );
for (surf = newdrawsurf; surf != 0; surf = surf->lightmapchain)
{
if (surf->polys)
R_DrawGLPolyChain( surf->polys, (surf->light_s - surf->dlight_s) * (1.0 / 128.0), (surf->light_t - surf->dlight_t) * (1.0 / 128.0) );
}
}
// restore state
GL_Disable (GL_BLEND);
GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GL_DepthMask (true);
}
/*
================
R_RenderBrushPoly
================
*/
void R_RenderBrushPoly (msurface_t *fa)
{
int maps;
// qboolean is_dynamic = false;
if (fa->flags & SURF_DRAWTURB)
{
R_BuildVertexLight (fa);
// warp texture, no lightmaps
GL_TexEnv(GL_MODULATE);
R_DrawWarpSurface (fa, 1.0, true);
GL_TexEnv(GL_REPLACE);
return;
}
GL_TexEnv(GL_REPLACE);
R_DrawGLPoly (fa, true);
#if 0
//
// check for lightmap modification
//
for (maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++)
{
if (r_newrefdef.lightstyles[fa->styles[maps]].white != fa->cached_light[maps])
goto dynamic;
}
// dynamic this frame or dynamic previously
if ((fa->dlightframe == r_framecount))
{
dynamic:
if (r_dynamic->integer)
{
if ( !(fa->texinfo->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP)) )
{
is_dynamic = true;
}
}
}
#endif
if (R_SurfIsDynamic(fa, &maps))
{
if ( (fa->styles[maps] >= 32 || fa->styles[maps] == 0) && (fa->dlightframe != r_framecount) )
{
unsigned temp[34*34];
int smax, tmax;
smax = (fa->extents[0]>>4)+1;
tmax = (fa->extents[1]>>4)+1;
R_BuildLightMap(fa, (void *)temp, smax*4);
R_SetCacheState(fa);
GL_Bind(glState.lightmap_textures + fa->lightmaptexturenum);
qglTexSubImage2D( GL_TEXTURE_2D, 0,
fa->light_s, fa->light_t,
smax, tmax,
// GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE,
gl_lms.format, gl_lms.type,
temp);
fa->lightmapchain = gl_lms.lightmap_surfaces[fa->lightmaptexturenum];
gl_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
}
else
{
fa->lightmapchain = gl_lms.lightmap_surfaces[0];
gl_lms.lightmap_surfaces[0] = fa;
}
}
else
{
fa->lightmapchain = gl_lms.lightmap_surfaces[fa->lightmaptexturenum];
gl_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
}
}
/*
================
R_DrawSingleTextureChains
Draws all solid textures in 2-pass mode
================
*/
void R_DrawSingleTextureChains (void)
{
int i;
msurface_t *s;
image_t *image;
c_visible_textures = 0;
for (i=0, image=gltextures; i<numgltextures; i++, image++)
{
if (!image->registration_sequence)
continue;
if (!image->texturechain)
continue;
c_visible_textures++;
rb_vertex = rb_index = 0;
for (s = image->texturechain; s; s=s->texturechain)
R_RenderBrushPoly (s);
image->texturechain = NULL;
}
for (i=0, image=gltextures; i<numgltextures; i++, image++)
{
if (!image->registration_sequence)
continue;
if (!image->warp_texturechain)
continue;
// c_visible_textures++;
rb_vertex = rb_index = 0;
for (s = image->warp_texturechain; s; s=s->texturechain)
R_RenderBrushPoly (s);
image->warp_texturechain = NULL;
}
GL_TexEnv (GL_REPLACE);
}
/*
=================
R_DrawInlineBModel_Old
=================
*/
void R_DrawInlineBModel_Old (entity_t *e, int causticflag)
{
int i, k;
cplane_t *pplane;
float dot;
msurface_t *psurf, *s;
dlight_t *lt;
qboolean duplicate;
image_t *image;
psurf = &currentmodel->surfaces[currentmodel->firstmodelsurface];
for (i=0; i<currentmodel->nummodelsurfaces; i++, psurf++)
{
// find which side of the face we are on
pplane = psurf->plane;
if ( pplane->type < 3 )
dot = modelorg[pplane->type] - pplane->dist;
else
dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
// cull the polygon
if (dot > BACKFACE_EPSILON)
psurf->visframe = r_framecount;
}
// calculate dynamic lighting for bmodel
if (!r_flashblend->integer)
{
lt = r_newrefdef.dlights;
if (currententity->angles[0] || currententity->angles[1] || currententity->angles[2])
{
vec3_t temp;
vec3_t forward, right, up;
AngleVectors (currententity->angles, forward, right, up);
for (k=0; k<r_newrefdef.num_dlights; k++, lt++)
{
VectorSubtract (lt->origin, currententity->origin, temp);
lt->origin[0] = DotProduct (temp, forward);
lt->origin[1] = -DotProduct (temp, right);
lt->origin[2] = DotProduct (temp, up);
R_MarkLights (lt, k, currentmodel->nodes + currentmodel->firstnode);
VectorAdd (temp, currententity->origin, lt->origin);
}
}
else
{
for (k=0; k<r_newrefdef.num_dlights; k++, lt++)
{
VectorSubtract (lt->origin, currententity->origin, lt->origin);
R_MarkLights (lt, k, currentmodel->nodes + currentmodel->firstnode);
VectorAdd (lt->origin, currententity->origin, lt->origin);
}
}
}
#ifdef MULTITEXTURE_CHAINS
if (!glConfig.multitexture)
#endif // MULTITEXTURE_CHAINS
{
if (currententity->flags & RF_TRANSLUCENT)
{
GL_DepthMask (false);
GL_TexEnv (GL_MODULATE);
GL_Enable (GL_BLEND);
GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
}
//
// draw standard surfaces
//
R_SetLightingMode (e->flags); // set up texture combiners
psurf = &currentmodel->surfaces[currentmodel->firstmodelsurface];
for (i = 0; i < currentmodel->nummodelsurfaces; i++, psurf++)
{
// find which side of the node we are on
pplane = psurf->plane;
dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
// draw the polygon
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
{
#ifdef BATCH_LM_UPDATES
if ( glConfig.multitexture && !(psurf->texinfo->flags & (SURF_SKY|SURF_WARP)) )
R_UpdateSurfaceLightmap (psurf);
#endif
psurf->entity = NULL;
psurf->flags &= ~SURF_MASK_CAUSTIC; // clear old caustics
if ( psurf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66) )
{ // add to the translucent chain
// if bmodel is used by multiple entities, adding surface
// to linked list more than once would result in an infinite loop
duplicate = false;
for (s = r_alpha_surfaces; s; s = s->texturechain)
if (s == psurf)
{ duplicate = true; break; }
if (!duplicate) // Don't allow surface to be added twice (fixes hang)
{
#if 0
msurface_t *last = NULL;
psurf->entity = e; // entity pointer to support movement
for (s = r_alpha_surfaces; s; last = s, s = s->texturechain)
{
if (SurfInFront (s, psurf)) // s is in front of psurf
break; // we know to insert here
}
if (last) { // if in front of at least one surface
psurf->texturechain = s;
last->texturechain = psurf;
}
else { // stuff in beginning of chain
psurf->texturechain = r_alpha_surfaces;
r_alpha_surfaces = psurf;
}
#else
psurf->flags |= causticflag; // set caustics
psurf->texturechain = r_alpha_surfaces;
r_alpha_surfaces = psurf;
psurf->entity = e; // entity pointer to support movement
#endif
}
}
else
{
image = R_TextureAnimation (psurf);
if ( glConfig.multitexture &/ !(psurf->flags & SURF_DRAWTURB) )
{
psurf->flags |= causticflag; // set caustics
#ifdef MULTITEXTURE_CHAINS
psurf->texturechain = image->texturechain;
image->texturechain = psurf;
#else
R_DrawLightmappedSurface (psurf, true);
#endif // MULTITEXTURE_CHAINS
}
else if ( glConfig.multitexture && (psurf->flags & SURF_DRAWTURB) ) // warp surface
{
#ifdef MULTITEXTURE_CHAINS
psurf->texturechain = image->warp_texturechain;
image->warp_texturechain = psurf;
#else
continue;
#endif // MULTITEXTURE_CHAINS */
}
else // 2-pass mode
{
GL_EnableMultitexture (false);
R_RenderBrushPoly (psurf);
GL_EnableMultitexture (true);
// 2-pass mode-specific stuff
R_BlendLightmaps ();
R_DrawTriangleOutlines ();
}
}
}
}
#ifndef MULTITEXTURE_CHAINS
//
// draw warp surfaces
//
psurf = &currentmodel->surfaces[currentmodel->firstmodelsurface];
for (i = 0; i < currentmodel->nummodelsurfaces; i++, psurf++)
{
// find which side of the node we are on
pplane = psurf->plane;
dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
// draw the polygon
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
{
if ( psurf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66) )
continue;
else if (!(psurf->flags & SURF_DRAWTURB)) // non-warp surface
continue;
else // warp surface
R_DrawWarpPoly (psurf);
}
}
#else // MULTITEXTURE_CHAINS
if (glConfig.multitexture)
{
if (currententity->flags & RF_TRANSLUCENT)
{
GL_DepthMask (false);
GL_TexEnv (GL_MODULATE);
GL_Enable (GL_BLEND);
GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
R_DrawMultiTextureChains ();
}
#endif // MULTITEXTURE_CHAINS
if (currententity->flags & RF_TRANSLUCENT)
{
GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GL_Disable (GL_BLEND);
GL_TexEnv (GL_REPLACE);
GL_DepthMask (true);
}
}
/*
================
R_RecursiveWorldNode_Old
================
*/
void R_RecursiveWorldNode_Old (mnode_t *node)
{
int c, side, sidebit;
cplane_t *plane;
msurface_t *surf, **mark;
mleaf_t *pleaf;
float dot;
image_t *image;
if (node->contents == CONTENTS_SOLID)
return; // solid
if (node->visframe != r_visframecount)
return;
if (R_CullBox (node->minmaxs, node->minmaxs+3))
return;
// if a leaf node, draw stuff
if (node->contents != -1)
{
pleaf = (mleaf_t *)node;
// check for door connected areas
if (r_newrefdef.areabits)
{
if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
return; // not visible
}
mark = pleaf->firstmarksurface;
c = pleaf->nummarksurfaces;
if (c)
{
do
{
(*mark)->visframe = r_framecount;
mark++;
} while (--c);
}
return;
}
// node is just a decision point, so go down the apropriate sides
// find which side of the node we are on
plane = node->plane;
switch (plane->type)
{
case PLANE_X:
dot = modelorg[0] - plane->dist;
break;
case PLANE_Y:
dot = modelorg[1] - plane->dist;
break;
case PLANE_Z:
dot = modelorg[2] - plane->dist;
break;
default:
dot = DotProduct (modelorg, plane->normal) - plane->dist;
break;
}
if (dot >= 0)
{
side = 0;
sidebit = 0;
}
else
{
side = 1;
sidebit = SURF_PLANEBACK;
}
// recurse down the children, front side first
R_RecursiveWorldNode_Old (node->children[side]);
// draw stuff
for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++)
{
if (surf->visframe != r_framecount)
continue;
if ((surf->flags & SURF_PLANEBACK) != sidebit)
continue; // wrong side
surf->entity = NULL;
#ifdef BATCH_LM_UPDATES
if ( glConfig.multitexture && !(surf->texinfo->flags & (SURF_SKY|SURF_DRAWTURB)) )
R_UpdateSurfaceLightmap (surf);
#endif
if (surf->texinfo->flags & SURF_SKY)
{ // just adds to visible sky bounds
R_AddSkySurface (surf);
}
else if (surf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
{ // add to the translucent chain
surf->texturechain = r_alpha_surfaces;
r_alpha_surfaces = surf;
}
#ifndef MULTITEXTURE_CHAINS
else if (glConfig.multitexture && !(surf->flags & SURF_DRAWTURB))
{
R_DrawLightmappedSurface (surf, true);
}
#endif // MULTITEXTURE_CHAINS
else
{
// the polygon is visible, so add it to the texture chain
image = R_TextureAnimation (surf);
if ( !(surf->flags & SURF_DRAWTURB) ) {
surf->texturechain = image->texturechain;
image->texturechain = surf;
}
else {
surf->texturechain = image->warp_texturechain;
image->warp_texturechain = surf;
}
}
}
// recurse down the back side
R_RecursiveWorldNode_Old (node->children[!side]);
}
/*
=============
R_DrawWorld_Old
=============
*/
void R_DrawWorld_Old (void)
{
entity_t ent;
if (!r_drawworld->integer)
return;
if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
return;
currentmodel = r_worldmodel;
VectorCopy (r_newrefdef.vieworg, modelorg);
// auto cycle the world frame for texture animation
memset (&ent, 0, sizeof(ent));
// Knightmare added r_worldframe for trans animations
ent.frame = r_worldframe = (int)(r_newrefdef.time*2);
currententity = &ent;
glState.currenttextures[0] = glState.currenttextures[1] = -1;
qglColor3f (1,1,1);
memset (gl_lms.lightmap_surfaces, 0, sizeof(gl_lms.lightmap_surfaces));
R_ClearSkyBox ();
if (glConfig.multitexture)
{
#ifndef MULTITEXTURE_CHAINS
GL_EnableMultitexture (true);
R_SetLightingMode (0);
#endif // MULTITEXTURE_CHAINS
R_RecursiveWorldNode_Old (r_worldmodel->nodes);
#ifndef MULTITEXTURE_CHAINS
GL_EnableMultitexture (false);
#endif // MULTITEXTURE_CHAINS
R_DrawMultiTextureChains (); // draw solid warp surfaces
}
else
{ // add surfaces to texture chains for 2-pass rendering
R_RecursiveWorldNode_Old (r_worldmodel->nodes);
R_DrawSingleTextureChains ();
R_BlendLightmaps ();
R_DrawTriangleOutlines ();
}
R_DrawSkyBox ();
}
#endif // USE_SINGLETEXTURE_MODE

View file

@ -311,8 +311,8 @@ void RB_RenderWarpSurface (msurface_t *fa)
float alpha = colorArray[0][3];
image_t *image = R_TextureAnimation (fa);
qboolean light = r_warp_lighting->integer && !(fa->texinfo->flags & SURF_NOLIGHTENV);
qboolean texShaderWarpNV = glConfig.NV_texshaders && glConfig.multitexture && r_pixel_shader_warp->integer;
qboolean texShaderWarpARB = glConfig.arb_fragment_program && glConfig.multitexture && r_pixel_shader_warp->integer;
qboolean texShaderWarpNV = glConfig.NV_texshaders && r_pixel_shader_warp->integer;
qboolean texShaderWarpARB = glConfig.arb_fragment_program && r_pixel_shader_warp->integer;
qboolean texShaderWarp = (texShaderWarpNV || texShaderWarpARB);
if (texShaderWarpNV && texShaderWarpARB)
texShaderWarpARB = (r_pixel_shader_warp->integer == 1);
@ -418,7 +418,7 @@ void R_DrawWarpSurface (msurface_t *fa, float alpha, qboolean render)
vec3_t point;
int i;
qboolean light = r_warp_lighting->integer && !r_fullbright->integer && !(fa->texinfo->flags & SURF_NOLIGHTENV);
qboolean texShaderNV = glConfig.NV_texshaders && glConfig.multitexture
qboolean texShaderNV = glConfig.NV_texshaders
&& ( (!glConfig.arb_fragment_program && r_pixel_shader_warp->integer)
|| (glConfig.arb_fragment_program && r_pixel_shader_warp->integer > 1) );